fahrradler
fahrradler

Reputation: 151

Determining compiler and version used to build a shared object on *ix operating system

I work on some software that loads a set of user specified shared objects. I'd like to add some code to our "loader" component that can query each specified shared object and find out what compiler and what compiler version was used to build/link that shared object.

In the past, I've been able to use a "strings -a | grep " approach as shown below. However, this approach is not working for code compiled with g++ 4.8 on power AIX, and it's not working particularly well for code compiled with g++ 4.8 on x86 linux.

I would also love to find some cleaner way of obtaining this information than grepping for strings if possible.

Can anyone provide advice on how to query a shared object for the name of the compiler that built it and also the version of that compiler?


Here's some example command and output from my current technique:

on an x86 linux g++ 4.1 compiled shared object:

$ strings -a libshareme.so | grep GNU
GCC: (GNU) 4.1.2 20080704 (Red Hat 4.1.2-50)
<etc>

(lots of repetitive output here, but it's clear that the version is GCC 4.1.2)

on a power AIX xlC v11 compiled object

$ 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

(kind of confusing that it shows v11 and v10, but XL C is clear)

on an x86 linux g++ 4.8 compiled shared object:

$ 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

(also kind of confusing here that it shows multiple versions)

on a power AIX g++ 4.8 compiled object

$ strings -a libshareme.so | grep GNU
<no output>

On x86/linux, I usually see a "GNU" type string in 'strings -a' output I can match. However, using strings -a on this libshareme.so compiled on power/aix with g++4.8 doesn't show me anything obvious regarding compiler version.

Upvotes: 3

Views: 5982

Answers (2)

fahrradler
fahrradler

Reputation: 151

I found this way thanks to a coworker to detect if a library is compiled with g++ on 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

it

This approach plus the ones in the original question essentially work to let me write code that detects compilers (at least the ones I'm working with) and any potential mismatch of compilers during a load fail.

Upvotes: 1

Laszlo Valko
Laszlo Valko

Reputation: 2743

It's not possible to foolproofly do what you want to achieve. You may sometimes be able to find random signs of the compiler or some compiler flags, but surely there's no general way to obtain this information. And most of this information is simply not present in the object files (no compiler I know of stores the exact compiler flags used into the object files, for example).

You may look at what the authors of other packages have done, I'd first check Perl. Perl uses its own "./configure" script, which gathers the paths of different tools and the flags to be used with them, and then this information is used when compiling the perl binary and the standard modules supplied there. This information also gets compiled into the perl binary, and can be later printed for convenience (perl -V), or used in order to compile "matching" extra perl modules by perl's own make helper library (see perl Makefile.PL). Even perl's facility is not foolproof, as you may try to load incompatibly compiled/linked shared libs.

Upvotes: 0

Related Questions