Я работаю над некоторым программным обеспечением, которое загружает набор пользовательских общих объектов.
Я хотел бы добавить некоторый код в наш компонент «загрузчик», который может запрашивать каждый указанный общий объект
и выясните, какой компилятор и какая версия компилятора использовались для сборки / компоновки этого общего объекта.
В прошлом я мог использовать подход «strings -a | grep», как показано ниже.
Однако этот подход не работает для кода, скомпилированного с g ++ 4.8 для Power AIX,
и это не очень хорошо работает для кода, скомпилированного с g ++ 4.8 на x86 linux.
Я также хотел бы найти более чистый способ получения этой информации, чем поиск строк, если это возможно.
Может ли кто-нибудь дать совет о том, как запросить у общего объекта имя компилятора, который его создал, а также версию этого компилятора?
Вот пример команды и вывод из моей текущей техники:
на x86 linux g ++ 4.1 скомпилированный общий объект:
$ strings -a libshareme.so | grep GNU
GCC: (GNU) 4.1.2 20080704 (Red Hat 4.1.2-50)
<etc>
(много повторяющихся выводов здесь, но ясно, что версия GCC 4.1.2)
на мощном скомпилированном объекте AIX xlC v11
$ strings -a libshareme.so | grep XL
XL
IBM XL C/C++ for AIX, Version 11.1.0.6
IBM XL C/C++ for AIX, Version 10.1.0.6
(немного сбивает с толку, что это показывает v11 и v10, но XL C ясно)
на x86 linux g ++ 4.8 скомпилированный общий объект:
$ strings -a libshareme.so | grep GNU
GCC: (GNU) 4.4.6 20120305 (Red Hat 4.4.6-4)
GCC: (GNU) 4.8.2 20131111 (Red Hat 4.8.2-4)
GNU C++ 4.8.2 20131111 (Red Hat 4.8.2-4) -m32 -mtune=generic -march=i686 -g -fmessage-length=0 -fPIC
(также немного сбивает с толку, что он показывает несколько версий)
на мощном скомпилированном объекте AIX g ++ 4.8
$ strings -a libshareme.so | grep GNU
<no output>
В x86 / linux я обычно вижу строку типа «GNU» в выходных данных «strings -a», которым я могу соответствовать. Однако использование строк -a в этом libshareme.so, скомпилированных в power / aix с g ++ 4.8, не показывает мне ничего очевидного в отношении версии компилятора.
Я нашел этот способ благодаря коллеге, чтобы определить, скомпилирована ли библиотека с g ++ в AIX:
dump -X32_64 -Tv libshareme.so | grep libgcc
[1] 0x00000000 undef IMP DS EXTref libgcc_s.a(shr.o) __cxa_finalize
[2] 0x00000000 undef IMP DS EXTref libgcc_s.a(shr.o) __register_frame_info_table
[3] 0x00000000 undef IMP DS EXTref libgcc_s.a(shr.o) __deregister_frame_info
[4] 0x00000000 undef IMP DS EXTref libgcc_s.a(shr.o) __cmpdi2
[5] 0x00000000 undef IMP DS EXTref libgcc_s.a(shr.o) __gcc_qdiv
[6] 0x00000000 undef IMP DS EXTref libgcc_s.a(shr.o) __udivdi3
[7] 0x00000000 undef IMP DS EXTref libgcc_s.a(shr.o) _Unwind_Resume
[635] 0x20118d70 .data EXP DS Ldef [noIMid] __init_aix_libgcc_cxa_atex
Это
Этот подход плюс те, что были в оригинальном вопросе, по сути, позволяют мне писать код, который обнаруживает компиляторы (по крайней мере те, с которыми я работаю) и любое возможное несоответствие компиляторов во время сбоя загрузки.
Невозможно безошибочно делать то, что вы хотите достичь. Иногда вы можете найти случайные признаки компилятора или некоторые флаги компилятора, но, конечно, нет никакого общего способа получить эту информацию. И большая часть этой информации просто отсутствует в объектных файлах (ни один из известных мне компиляторов не хранит точные флаги компилятора, используемые в объектных файлах, например).
Вы можете посмотреть, что сделали авторы других пакетов, я бы сначала проверил Perl. Perl использует свой собственный скрипт ./configure, который собирает пути различных инструментов и флаги, которые будут использоваться с ними, а затем эта информация используется при компиляции двоичного файла perl и стандартных модулей, поставляемых там. Эта информация также компилируется в двоичный файл perl и может быть позже распечатана для удобства (perl -V
) или используется для компиляции «совпадающих» дополнительных модулей perl с помощью собственной библиотеки perl make helper (см. perl Makefile.PL
). Даже средства Perl не являются надежными, так как вы можете попытаться загрузить несовместимо скомпилированные / связанные общие библиотеки.