Monday, February 02, 2009

How to run a shared library on Linux

How to run a shared library on Linux

In my prevoius blog I have written how to run the shared libraries on

Shared object should have following entries to run:
1. +x permission that is by default is given by the static
linker(program linker) when creating a shared object.
2. Entry point at which the program/shared library is starts to run.
3. Interpreter(Run time linker) that is used to run any shared library
after loaded by kernel part exec().

Entry point at which the program/shared library is starts to run can be
given by passing -Wl,-e entry_point to the linker at command line:

To create .interp section by using GNU gcc, use the follwing line of
code on linux:
const char my_interp[] __attribute__((section(".interp"))) =

Where /lib/ is the path of interpreter(Run time linker)  in linux.

In open solaris we passed -Wl,-I,/usr/lib/ to the sun linker to
create this section.
I think in gnu linker this option is available but do other things.

Demo on Linux machine:
$ cat func.c
const char my_interp[] __attribute__((section(".interp"))) =
void bar();

exit (0);


$ gcc -fPIC -o -shared -Wl,-e,func func.c

You can see that have .interp section and interp program header.
# readelf -l
Elf file type is DYN (Shared object file)
Entry point 0x4dc
There are 7 program headers, starting at offset 52

Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000034 0x00000034 0x00000034 0x000e0 0x000e0 R E 0x4
INTERP 0x0005a3 0x000005a3 0x000005a3 0x00013 0x00013 R 0x1
[Requesting program interpreter: /lib/]
LOAD 0x000000 0x00000000 0x00000000 0x005bc 0x005bc R E 0x1000
LOAD 0x0005bc 0x000015bc 0x000015bc 0x00104 0x0010c RW 0x1000
DYNAMIC 0x0005d4 0x000015d4 0x000015d4 0x000c0 0x000c0 RW 0x4
NOTE 0x000114 0x00000114 0x00000114 0x00024 0x00024 R 0x4
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4

Section to Segment mapping:
Segment Sections...
01 .interp
02 .gnu.hash .dynsym .dynstr .gnu.version
.gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata
.interp .eh_frame
03 .ctors .dtors .jcr .dynamic .got .got.plt .bss
04 .dynamic

You can cleary see, have .interp section and INTERP program header.
Now try to run
$ ./

1 comment:

Bri said...

For C++, declare and invoke _init(); at the start of your "main", and invoke _fini(); at the end of your "main".