Why Would the Elf Header of a Shared Library Specify Linux as the Osabi

Why would the ELF header of a shared library specify Linux as the OSABI?

Possibly the vendor is cross compiling on FreeBSD or using a very recent Fedora system where anything using STT_GNU_IFUNC will be marked as ELFOSABI_LINUX. If you are trying to use it on Linux there should be no problems with changing it to ELFOSABI_NONE like you have done.

ELF shared library portability

Will be I able to dlopen/dlsym/dlclose this shared library among different UNIX flavors(Linux, FreeBSD, Solaris)?

Assuming your library is completely self-contained and does not call any external routines, nor issues any system calls ... the answer is still no.

In the ELF header e_ident[EI_OSABI] byte, you will have one of ELFOSABI_GNU, ELFOSABI_FREEBSD, or ELFOSABI_SOLARIS. The loader will (or at least should) reject attempts to dlopen the library built for the "wrong" OS.

However, if you patch that one byte to match the current OS, then dlopen would likely work.

What is the best way to look for ELF Shared Libraries under linux in C

/usr/lib64 and /lib64 for 64-bit binaries or /usr/lib and /lib for 32-bit binaries, than paths taken from /etc/ld.so.conf and included configs

From man ldconfig

ldconfig creates the necessary links and cache to the most recent shared libraries found in the directories specified on the command line, in the file /etc/ld.so.conf, and in the trusted directories, /lib and /usr/lib (on some 64-bit architectures such as x86-64, /lib and /usr/lib are the trusted directories for 32-bit libraries, while /lib64 and /usr/lib64 are used for 64-bit libraries).

The cache is used by the run-time linker, ld.so or ld-linux.so.

...

/etc/ld.so.conf File containing a list of directories, one per line, in which to search for libraries.

Note that this info is for openSUSE, other distros may use different paths.

How do I compile on linux to share with all distributions?

The statement: "ELF file OS ABI invalid", means that the Application Binary Interface is non compatible between binaries used (i.e. one is trying to mix host and target binaries, which may not work as expected). The e_ident[EI_OSABI] byte of the ELF header contains the operating system/ABI identification. Your Fedora system is setting this to ELFOSABI_LINUX (3) while your friend's CentOS system is setting it to ELFOSABI_SYSV (ELFOSABI_NONE or 0).

You may be able to compile the FreeBSD brandelf utility (brandelf.c) and use it to set the OSABI to ELFOSABI_SYSV (brandelf -f 0 <file> or brandelf -t SVR4 <file>.

I am not aware of any gcc flags for specifying this value at compile/link time. I believe that the version of binutils used by gcc on your Fedora system is responsible for setting the OSABI to Linux. It is my understanding that the linker only specifies the ABI if a STT_GNU_IFUNC symbol ends up in the output file (see ifunc.txt at http://groups.google.com/group/generic-abi for details on STT_GNU_IFUNC).


The readelf(1) command can be used to retrieve and display the ABI information stored in the ELF header (readelf -h <file>).


This similar question may also be of interest.

Update ELF shared object generated with -Bsymbolic linker option

No, -Bsymbolic cannot be undone. The reason is that the link editor applies relaxations which eliminate certain relocations. For example, consider this source code, to be compiled into a shared object:

int f1(void) { }
int f2(void) { f1(); }

If compiled and linked with gcc-O2 -shared -fpic, there is an R_X86_64_JUMP_SLOT relocation:

Relocation section '.rela.plt' at offset 0x510 contains 1 entries:
Offset Info Type Symbol's Value Symbol's Name + Addend
0000000000201018 0000000800000007 R_X86_64_JUMP_SLOT 0000000000000670 f1 + 0

This comes from the call to f1 in f2, which has to go through the PLT to enable interposition:

0000000000000670 <f1>:
670: repz retq
672: nopl 0x0(%rax)
676: nopw %cs:0x0(%rax,%rax,1)

0000000000000680 <f2>:
680: jmpq 550 <f1@plt>

If compiled and linked with -O2 -shared -fpic -Wl,-Bsymbolic, it is gone completely because the link editor was able to resolve the reference and use a direct jump to f1:

0000000000000650 <f1>:
650: repz retq
652: nopl 0x0(%rax)
656: nopw %cs:0x0(%rax,%rax,1)

0000000000000660 <f2>:
660: jmpq 650 <f1>

There is no automated way to put back a PLT into the shared object.

In the ELF spec, what does BA_OS and KE_OS mean?

It turns out that page 11 of the latest base document describes "components of conforming systems", wherein "BA" means "base system", "KE" means "kernel extension" while "OS" means "operating system service routines" and "LIB" means "general library routines".



Related Topics



Leave a reply



Submit