отладочный двоичный файл: как сбросить, из какого .a / .o был получен каждый символ?

#debugging #linker #gdb #debug-symbols #nm

#отладка #компоновщик #gdb #debug-symbols #nm

Вопрос:

У меня есть двоичный файл с поддержкой отладки, коллекция файлов .a, с которыми он был статически связан, и источник для всего.

Как я могу получить анализируемый дамп, в котором перечислены имена каждого символа в конечном исполняемом двоичном файле и который .a и .o он был получен? (Плюс оригинал .c/.cpp файл, если это возможно.)

В библиотеках есть ряд перекрестных зависимостей, циклических зависимостей и даже несколько множественных определенных символов, которые я пытаюсь отобразить с конечной целью воссоздать систему сборки. Каким-то образом старой системе сборки удалось связать все вместе. (Я думаю, скорее случайно, чем по замыслу …)

До сих пор я пробовал различные вызовы nm , но, похоже, не могу получить эти данные. Возможно nm , это неправильный инструмент.

Ответ №1:

К моменту связывания окончательного двоичного файла информация о том, какой символ был получен из какого .o или .a , теряется.

Поскольку у вас есть доступная отладочная информация, вы можете знать источник каждого символа, и это может помочь вам восстановить потерянную информацию (или нет: если foo.c скомпилировано в foo1.o , foo2.o и foo3.o (например, с разными -DFOO=1 и т. Д. флагами), А затем помещено в разные архивные библиотеки, Тогда простого способа нетчтобы указать, какой объект внес символ в конечный двоичный файл. Надеюсь, ваша старая система сборки была не такой уж плохой.

Итак,

 # list of global symbols and their addresses
nm a.out | egrep ' [TDW] '

# dump source for every symbol
addr2line a.out < /list/of/addresses/from/above

# list all objects in all libraries
ar t *.a
  

Теперь у вас достаточно информации, чтобы сопоставить большинство символов с объектами, из которых они пришли. Вероятно, будет <= 10% источников, в которых имя исходного файла не совпадает с именем объектного файла. Их вам придется решать вручную.