
Learn through the super-clean Baeldung Pro experience:
>> Membership and Baeldung Pro.
No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.
Last updated: March 18, 2024
We can install both 32-bit and 64-bit libraries on a 64-bit Linux system to run our applications. Here, we’re talking about C/C++ libraries, compiled for specific architectures.
We may sometimes wish to know if a given library is 32-bit or 64-bit. In this short tutorial, we’ll learn a few ways to determine the format of a library.
A library groups a collection of pre-compiled code into a single file so it can be used in different programs.
In Linux, we have two types of libraries:
A static library isn’t an executable. Instead, it’s a file in the ar format. It’s simply an archive of other files, such as ELF object files.
On the other hand, a shared library is an ELF file.
The ELF header defines whether the library uses 32-bit or 64-bit addresses.
In this tutorial, we’ll use the file and objdump commands to determine the format of a library. We’ll look at how this applies to both static and shared libraries.
The file command is a convenient utility to check file types. We can use file to tell us the format of a library.
First, let’s test it on two shared libraries:
$ file /usr/lib/libc-2.33.so
/usr/lib/libc-2.33.so: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, ....
$ file /usr/lib32/libc-2.33.so
/usr/lib32/libc-2.33.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (GNU/Linux), dynamically linked, ...
Here, we’ve executed file on 32-bit and a 64-bit library files. As we can see, the file command reads the ELF header and reports each library’s detailed information, including the address width it uses.
Next, let’s do similar tests on static libraries:
$ file /usr/lib/libc.a
/usr/lib/libc.a: current ar archive
$ file /usr/lib32/libc.a
/usr/lib32/libc.a: current ar archive
This time, the file command just tells us they are ar archives but doesn’t report if they are 32-bit or 64-bit.
This is because a static library is merely an archive instead of an ELF file. The file command does not look at all ELF object files in a static library and reads their headers.
The objdump command is a member of the package GNU Binutils. It displays information from object files.
We can use the -f option to read the header of an ELF file.
First, let’s see what objdump outputs if we execute it on some shared libraries:
$ objdump -f /usr/lib/libc-2.33.so
/usr/lib/libc-2.33.so: file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x0000000000027c60
$ objdump -f /usr/lib32/libc-2.33.so
/usr/lib32/libc-2.33.so: file format elf32-i386
architecture: i386, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x0001ebc0
In the output above, the “file format” field reports the ELF file uses 64-bit (elf64-…) or 32-bit (elf32-…) addresses.
Therefore, the “/usr/lib/libc-2.33.so” file is a 64-bit library and the other one is a 32-bit library. Also, if we have a look at their “start address” fields, they have 64-bit and 32-bit wide addresses respectively.
Next, let’s run the same command on a static library:
$ objdump -f /usr/lib/libc.a
In archive /usr/lib/libc.a:
init-first.o: file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x0000000000000000
libc-start.o: file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x0000000000000000
sysdep.o: file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000000:
start address 0x0000000000000000
...
The output above shows the objdump command working through all object files in the static library outputting their ELF headers.
This solution works but can produce a large output. For example, the output above runs to over 10,000 lines.
To summarize the ELF header information, we can pipe the output of objdump to awk to extract the file format value by search and replace, and remove duplicates:
$ objdump -f /usr/lib/libc.a | awk 'sub(/.*file format /,"") && !a[$0]++'
elf64-x86-64
Now, the output means all object files in the static library are using 64-bit addresses. So, we can say /usr/lib/libc.a is a 64-bit static library.
Finally, let’s test the command on a 32-bit static library:
$ objdump -f /usr/lib32/libc.a | awk 'sub(/.*file format /,"") && !a[$0]++'
elf32-i386
The “elf32-*” indicates all object files in the library use 32-bit addresses. Thus, it’s a 32-bit library.
In this article, we learned how to check if a library is 32-bit or 64-bit in Linux.
If it’s a shared library, the file command is probably the most straightforward solution.
However, if it’s a static library, then we need to read the headers of object files in the library, for which we can use objdump.