9
votes

I file /bin/ls and get the output:

/bin/ls: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, stripped

And I found the reason is that my gentoo is compiling everything with -pie .

If I pass -nopie to gcc, I will get the right answer:

a.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, not stripped

Also, I find something at building a .so that is also an executable. It uses -pie to make a DSO executable.

In gcc's man page, it describes in brief:

-pie
Produce a position independent executable on targets that support it.

So I'm wondering what -pie do exactly? How it makes my executable to be recognized as a shared object?

1

1 Answers

10
votes

The distinction between "executable" and "shared object" is largely artificial. What the file command is showing you is whether the ELF e_type header is ET_EXEC or ET_DYN. This is a rather technical distinction and has to do with how the loader treats them. file (via its magic file) should probably be taught to distinguish between "shared object" in the sense of "shared library" and "PIE executable" by looking for other characteristics like the presence of a PT_INTERP program header (which libraries generally won't have) or perhaps an entry point address (although some libraries seem to have a meaningless one).

To address what -pie does, it produces an executable that can be loaded at an arbitrary base address, rather than "normal" executables whose load addresses are fixed at ld-time. These use the same type of position-independent code and load headers used in shared libraries, which are also loadable at arbitrary addresses (and which need to be loadable at arbitrary addresses since any fixed address might already be taken by the main executable or another library). PIE is generally considered a hardening mechanism (allowing address randomization to affect the address of code and data in the main program) but it can also have other uses like making binaries more appropriate for MMU-less systems.