Като се има предвид напълно свързан 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 вместо само symbol, но все още не налага, че версията 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, също е „FILE“. Използвам инструменталната верига GreenHills за това. При някои други компилатори полученият ELF не съдържа тази информация. - person bombos; 29.07.2019