I know libc.so is executeable because:
- libc.so has a entry point function.
- There is .interp section in libc.so.
And I refered many documents, .interp section is considered to be necessary for an executable so. When I use call libonload.so, I can execute libonload.so, but readelf shows no .interp section. I don't know how it works. I run libonload.so, the result is:
[root@localhost onload-7.1.1.75]# /usr/lib64/libonload.so
Onload 7.1.1.75
Copyright 2019-2021 Xilinx, 2006-2019 Solarflare Communications, 2002-2005 Level 5 Networks
Built: Mar 4 2024 15:49:30 (release)
Build profile header: <ci/internal/transport_config_opt_extra.h>
readelf -l /usr/lib64/libonload.so:
[root@localhost onload-7.1.1.75]# readelf -l /usr/lib64/libonload.so
Elf file type is DYN (Shared object file)
Entry point 0xa2e0
There are 8 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x00000000000a5ff0 0x00000000000a5ff0 R E 200000
LOAD 0x00000000000a6818 0x00000000002a6818 0x00000000002a6818
0x0000000000002770 0x0000000000003060 RW 200000
DYNAMIC 0x00000000000a6d90 0x00000000002a6d90 0x00000000002a6d90
0x00000000000001f0 0x00000000000001f0 RW 8
NOTE 0x0000000000000200 0x0000000000000200 0x0000000000000200
0x0000000000000024 0x0000000000000024 R 4
TLS 0x00000000000a6818 0x00000000002a6818 0x00000000002a6818
0x0000000000000000 0x0000000000000bec R 8
GNU_EH_FRAME 0x0000000000094684 0x0000000000094684 0x0000000000094684
0x000000000000245c 0x000000000000245c R 4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 10
GNU_RELRO 0x00000000000a6818 0x00000000002a6818 0x00000000002a6818
0x00000000000007e8 0x00000000000007e8 R 1
Section to Segment mapping:
Segment Sections...
00 .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .plt .text .rodata .eh_frame_hdr .eh_frame
01 .init_array .data.rel.ro .dynamic .got .got.plt .data .bss
02 .dynamic
03 .note.gnu.build-id
04 .tbss
05 .eh_frame_hdr
06
07 .init_array .data.rel.ro .dynamic .got
Btw, libonload.so is a driver for SolarFlare Nic.Source code can be got at [https://github.com/Xilinx-CNS/onload][1] [1]: https://github.com/Xilinx-CNS/onload
I write a demo according to onload source:
#include <sys/uio.h>
#include <linux/unistd.h>
#include <unistd.h>
int my_do_syscall3(int num, long a1, long a2, long a3)
{
int rc;
__asm__ __volatile__(
"syscall"
: "=a" (rc)
: "0"((long)num), "D"(a1), "S"(a2), "d"(a3)
: "r11","rcx","memory"
);
return rc;
}
#define my_syscall3(call, a1, a2, a3) \
my_do_syscall3(__NR_##call, (a1), (a2), (a3))
extern "C" int func()
{
struct iovec v[1];
static const char msg0[] = "Hello so\n";
v[0].iov_base = (void*) msg0;
v[0].iov_len = sizeof(msg0)-1;
my_syscall3(writev, STDOUT_FILENO, (long) v, 1);
my_syscall3(exit, 0, 0, 0);
return 0;
}
My build command is :
gcc -fPIC -shared -e func test.cpp -o libtest.so
I execute ./libtest.so, resulting in segmention faults. Then I add .interp section in test.cpp:
extern const char elf_interpreter[] __attribute__((section(".interp"))) = "/lib64/ld-linux-x86-64.so.2";
And compile and execute again.It runs well as expected.
At last, I do it successfully.Adding static to my_do_syscall3 and it can work without an interpreter.
Interp is (only) needed if you want an interpreter to run, like glibc or musl. You can hardcode syscalls and do all the stuff yourself without an
ld.sointerpreter, seeman ld.so. It has nothing to do with shared library vs executable. Actually, any ELF executable is a shared library, any shared library can be an executable, it's all ELF format.Because it was built that way. See https://github.com/majek/openonload/blob/aff60a36ed3543446d9ff179905f47c47d1e300b/src/lib/transport/unix/mmake.mk#L85 and
man ld. See https://unix.stackexchange.com/questions/588240/what-mandates-the-start-entrypoint-kernel-ld-linux-so-etc and the linked articles https://lwn.net/Articles/630727/ and https://lwn.net/Articles/631631/ . Seeman elfdocumentation one_entry.There are a lot of executables and libraries without interp on my system: