Учитывая полностью связанный a.out, который определяет символ foo, как я могу определить, из какого объектного файла было взято это определение, не перекомпоновывая a.out?

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

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


person bombos    schedule 26.07.2019    source источник
comment
Обычный случай: у вас есть символ, определенный в одном файле и указанный как неопределенный в нескольких других файлах. Затем вы связываете неопределенные символы с определенным символом. Однако есть несколько особых случаев слабо определенных символов, которые перекрываются строго определенными символами и другими подобными вещами. Детали довольно сложные   -  person Ctx    schedule 26.07.2019
comment
Непонятно, чего вы добиваетесь. Это что-то, о чем nm object_file.o и nm -D stripped_shared_object.so или nm -D stripped_binary вам не сказали?   -  person mosvy    schedule 26.07.2019
comment
В программе нет ничего, что говорило бы о том, какие неопределенные символы находятся в какой динамической библиотеке. Каждая из библиотек загружается по очереди, и из этой библиотеки разрешается как можно больше символов. Это позволяет, например, спуфинг библиотеки с помощью LD_PRELOAD. Есть тег версии, но это другое. Тег версии эффективно заставляет сопоставитель найти символ с именем symbol@version вместо простого символа, но он по-прежнему не гарантирует, что версия glib_4 фактически определяется glib.so, а не intercept_glib.so.   -  person Gem Taylor    schedule 26.07.2019


Ответы (1)


Я пытаюсь разобрать файл ELF и создать список символов, определенных в каждом объектном файле.

Вы обрабатываете отдельные объектные файлы ELF или полностью связанный исполняемый файл или общую библиотеку? Поскольку ваш вопрос имеет смысл только во втором случае, давайте предположим, что ваш фактический вопрос таков:

Учитывая полностью связанный a.out, который определяет символ foo, как я могу определить, из какого объектного файла было взято это определение, не связывая a.out повторно?.

В общем, нельзя.

Во-первых, не каждый символ, определенный в a.out, может даже исходить из объектного файла: некоторые из них могут быть определены с помощью скрипта компоновщика или аргумента командной строки --defsym.

Во-вторых, слабые символы могут быть определены в нескольких объектных файлах, и компоновщик может выбрать любой из них.

Наконец, в файле a.out нет абсолютно никакой записи об ассоциации объектного файла -> символа. На самом деле, вы даже не можете извлечь список .o файлов, которые были связаны (без повторной ссылки и запроса компоновщика напечатать их).

Вы можете восстановить эту связь, взглянув на отладочную информацию, в которой будет указано, из какой единицы перевода был получен символ, а затем предположите, что вероятно foo.c был скомпилирован в foo.o, но это снова может привести к ошибке, так как foo.c может быть скомпилирован в bar.o и baz.o (с разными определениями -DFOO).

person Employed Russian    schedule 27.07.2019
comment
Извините за неполный вопрос. Это именно то, что я хотел спросить. Ответ тоже довольно ясен. - person bombos; 29.07.2019
comment
Что касается вашего комментария по извлечению списка файлов .o, когда я использую readelf, первыми символами в таблице символов являются файлы .c, которые были скомпилированы, а затем связаны отдельно. «Тип», о котором сообщает readelf, также является «ФАЙЛ». Для этого я использую набор инструментов GreenHills. В некоторых других компиляторах результирующий файл ELF не содержит этой информации. - person bombos; 29.07.2019