Staticke linkovani

Jan Otte jotte na suse.cz
Čtvrtek Březen 8 09:49:08 CET 2007


> Jak se prilinkuji nektere knihovny staticky a nektere dynamicky? Mam 
> takove tuseni, ze jsem to pred lety nekde videl. Mozna by mi to tak 

Staci instruovat linker (ld), primy popis viz napr. diskuze

http://www-gatago.com/comp/os/linux/development/apps/35115985.html


> stacilo. Glibc se uz asi dostala ze stavu, kdy nove verze byly binarne 
> nekompatiblini se starymi.

No...

Ono to podle me neni jen o kompatibilite.

Problem je v tom to jak si to nalinkujete. Kdyz bude vase binarka
pozadovat libc.so.6, bude chtit prilinkovat libc.so.6

Zkuste si treba prelozit vas program (nebo nejaky jednodussi) dynamicky.

Napr. zavolani readelf -d:

--- cut here ---
> readelf -d testme

Dynamic section at offset 0xe50 contains 20 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000c (INIT)               0x400500
 0x000000000000000d (FINI)               0x4007e4
 0x0000000000000004 (HASH)               0x4002c8
 0x0000000000000005 (STRTAB)             0x4003c0
 0x0000000000000006 (SYMTAB)             0x400300
 0x000000000000000a (STRSZ)              97 (bytes)
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000015 (DEBUG)              0x0
 0x0000000000000003 (PLTGOT)             0x600fe8
 0x0000000000000002 (PLTRELSZ)           144 (bytes)
 0x0000000000000014 (PLTREL)             RELA
 0x0000000000000017 (JMPREL)             0x400470
 0x0000000000000007 (RELA)               0x400458
 0x0000000000000008 (RELASZ)             24 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x000000006ffffffe (VERNEED)            0x400438
 0x000000006fffffff (VERNEEDNUM)         1
 0x000000006ffffff0 (VERSYM)             0x400422
 0x0000000000000000 (NULL)               0x0
--- cut here ---

abyste videl jak se to ve vasem systemu namapuje tak samozrejme ldd:

--- cut here ---
> ldd testme
        libc.so.6 => /lib64/libc.so.6 (0x00002b40cb627000)
        /lib64/ld-linux-x86-64.so.2 (0x00002b40cb409000)
--- cut here ---

No ale kdyz se podivate jake symboly jsou v binarce nedefinovane napr.
pomoci nm:

--- cut here ---
> nm testme
0000000000600e50 d _DYNAMIC
0000000000600fe8 d _GLOBAL_OFFSET_TABLE_
00000000004007f4 R _IO_stdin_used
                 w _Jv_RegisterClasses
0000000000600e30 d __CTOR_END__
0000000000600e28 d __CTOR_LIST__
0000000000600e40 d __DTOR_END__
0000000000600e38 d __DTOR_LIST__
00000000004008e0 r __FRAME_END__
0000000000600e48 d __JCR_END__
0000000000600e48 d __JCR_LIST__
0000000000601048 A __bss_start
0000000000601030 D __data_start
00000000004007b0 t __do_global_ctors_aux
00000000004005e0 t __do_global_dtors_aux
0000000000601038 D __dso_handle
                 w __gmon_start__
0000000000600e24 t __init_array_end
0000000000600e24 t __init_array_start
0000000000400710 T __libc_csu_fini
0000000000400720 T __libc_csu_init
                 U __libc_start_main@@GLIBC_2.2.5
0000000000601048 A _edata
0000000000601050 A _end
00000000004007e4 T _fini
0000000000400500 T _init
0000000000400590 T _start
00000000004005bc t call_gmon_start
0000000000601048 b completed.6094
0000000000601030 W data_start
                 U exit@@GLIBC_2.2.5
0000000000400620 t frame_dummy
                 U gethostbyname@@GLIBC_2.2.5
                 U inet_ntoa@@GLIBC_2.2.5
0000000000400648 T main
0000000000601040 d p.6092
                 U printf@@GLIBC_2.2.5
                 U puts@@GLIBC_2.2.5
--- cut here ---

Vidite, napr. printf@@GLIBC_2.2.5.

A tohle vsechno muzete ovlivnit. Muzete specifikovat presnejsi verzi
libc (potazmo kterekoliv knihovny) kterou chcete, muzete ovlivnit jmena
symbolu a samozrejme muzete si potrebne knihovny prilinkovavat sam --
viz treba dlopen(3) a podobne. Tim ze si to budete resit sam muzete
udelat spoustu magie ale... musite si zvazit jestli vam to usili stoji
za to.

Pokud chcete vedet co presne a jak muzete udelat, musite pockat na
odpoved nekoho kdo s tim ma prakticke zkusenosti (uz to na Linuxu delal)
nebo si to nastudovat (a hlavne pokladat otazky co nejpresneji). Mozna by
nebylo na skodu zeptat se i na nejake konferenci zabyvajici se gcc
nebo ld.

Doporucuji zacit u gcc, linkeru a verzi glibc (:-)


Zdravim,
Honza


Další informace o konferenci Linux