Как перечислять функции, присутствующие в объектном файле?

Я пытаюсь понять процесс компиляции и компоновки в C/С++. Я знаю, что исходные файлы сначала преобразуются в объектные файлы компилятором. Затем компоновщик генерирует библиотеки или исполняемые файлы из объектных файлов.

Я пытаюсь сначала прочитать информацию в объектных файлах. Вот программа, которую я написал для экспериментов.

func.h

#include <iostream>

void beautifulprint(char *str);

func.cpp

#include "stdafx.h"
#include "func.h"

using namespace std;

void beautifulprint(char *str) {
    cout << "*** " << str << " ***" << endl;
}

TestApp.cpp

#include "stdafx.h"
#include "func.h"

int _tmain(int argc, _TCHAR* argv[])
{
    beautifulprint("Hello, world!");

    return 0;
}

После создания проекта в VS 2010 я получаю func.obj. Я предположил, что где-то в func.obj должна быть ссылка на функцию beautifulprint. Я запускал ниже для отладки и выпуска версий func.obj

dumpbin /HEADERS func.obj > funchead.txt

Ниже представлен результат.

Отладочная версия (полный вывод не включен, поскольку он очень большой)

...

SECTION HEADER #41
   .text name
       0 physical address
       0 virtual address
      78 size of raw data
    5B94 file pointer to raw data (00005B94 to 00005C0B)
    5C0C file pointer to relocation table
       0 file pointer to line numbers
       A number of relocations
       0 number of line numbers
60501020 flags
         Code
         COMDAT; sym= "void __cdecl beautifulprint(char *)" ([email protected]@[email protected])
         16 byte align
         Execute Read

SECTION HEADER #42
.debug$S name
       0 physical address
       0 virtual address
      E8 size of raw data
    5C70 file pointer to raw data (00005C70 to 00005D57)
    5D58 file pointer to relocation table
       0 file pointer to line numbers
       7 number of relocations
       0 number of line numbers
42101040 flags
         Initialized Data
         COMDAT (no symbol)
         Discardable
         1 byte align
         Read Only

...

версия выпуска (полный выход!)

Microsoft (R) COFF/PE Dumper Version 10.00.30319.01
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file func.obj

File Type: ANONYMOUS OBJECT

ANON OBJECT HEADER VALUES
               1 version
             14C machine (x86)
        50213733 time date stamp Tue Aug 07 16:41:39 2012
                 ClassID: {0CB3FE38-D9A5-4DAB-AC9B-D6B6222653C2}
             2D1 size
               0 flags

И вот мои вопросы. Как и ожидалось, func.obj Debug version имеет ссылку на beautifulprint. Но, к моему удивлению, в версии Release нет ссылки на beautifulprint? Как бы линкер знал, что эта функция присутствует в объектном файле.

Также почему версия debug obj имеет функции от iostream? Не должны ли они присутствовать в какой-то стандартной библиотеке вместо этого obj?

Изменить. Я открыл версию func.obj в VS 2010 в формате Hex. Я искал красивый рисунок и его настоящее в правой колонке (ASCII). Это означает, что ссылка присутствует. Почему демпбин не показывает это? Мне нужен какой-то инструмент, чтобы просмотреть его в удобном для чтения формате.

Ответы

Ответ 1

Сбросьте символы вместо этого. Все файлы .obj имеют таблицу символов. Он покажет вам те символы, которые определены внутри, и те, которые нуждаются в разрешении. Символы IO, которые вы видите, могут быть символами UNDEF, но таблица символов должна сделать ее более понятной.

DUMPBIN /SYMBOLS func.obj

Имейте в виду, что /SYMBOLS недоступен, когда объект скомпилирован с /GL (оптимизация всей программы). Объектные модули, созданные с помощью /GL (а также библиотеки), создаются с форматом, который не гарантированно совместим с одной версией компилятора до следующей.

Оптимизация всей программы означает, что оптимизатор может оптимизировать все модули, а не только в каждом модуле. Функции могут стать "встроенными" и другими трюками, которые, по-видимому, не очень совместимы с COFF. Рекомендуется, чтобы в поставляемых библиотеках не был установлен параметр /GL, если вы не поставляете библиотеки для всех поддерживаемых версий компилятора.