Re: Wie die Lib zu undefinierten Symbolen finden?

David Haller <[email protected]> Thu, 12 Jan 2012 04:25:18 +0100
Newsgroups gmane.linux.suse.programming
Organization What?
Message-ID <[email protected]>
Hallo,

Am Wed, 11 Jan 2012, Philipp Thomas schrieb:
>On Tue, 10 Jan 2012 12:51:10 +0100, Thomas Michalka=20
>>Warum ist dann die Lib, in der das Symbol definiert ist, nicht unter den
>>NEEDED-Eintr=E4ge des Programms aufgelistet?
>
>Mir fallen zwei m=F6gliche Gr=FCnde ein. Zum einen k=F6nnte es sich um eine
>indirekte Abh=E4ngigkeit handeln, sprich eine der in NEEDED
>verzeichneten Bibliotheken ben=F6tigt das Symbol (unwahrscheinlich in
>diesem Fall) oder aber die Bibliothek wird explizit mittels dlopen
>geladen und dann die ben=F6tigten Symbole mittels dlsym eingebunden.
>Sicheren Aufschluss k=F6nnen nur die Quellen des Pakets liefern.

'strings' kann aber schon (evtl. sogar ausreichende) Hinweise geben, z.B.:

,----[ foo.c ]
| int answer(void) {
|     return 42;
| }
`----
,----[ dlopen_demo.c ]
| #include <stdlib.h>
| #include <stdio.h>
| #include <dlfcn.h>
| int main(void) {
|     void * lib_handle;
|     int (*answer)(void);
|     if( !(lib_handle =3D dlopen("libfoo.so", RTLD_NOW)) ) {
|         fprintf(stderr, "%s\n", dlerror());
|         exit(1);
|     }
|     answer =3D dlsym(lib_handle, "answer");
|     printf("%i\n", (*answer)());
|     return dlclose(lib_handle);
| }
`----

$ gcc -shared -o libfoo.so foo.c
$ make LDFLAGS=3D"-ldl" dlopen_demo && ./dlopen_demo
42
$ nm dlopen_demo | grep ' U '
                 U __fprintf_chk@@GLIBC_2.3.4
                 U __libc_start_main@@GLIBC_2.2.5
                 U __printf_chk@@GLIBC_2.3.4
                 U dlclose@@GLIBC_2.2.5
                 U dlerror@@GLIBC_2.2.5
                 U dlopen@@GLIBC_2.2.5
                 U dlsym@@GLIBC_2.2.5
                 U exit@@GLIBC_2.2.5

@Thomas: Die nm Ausgabe hei=DFt: per ldd/nm/objdump wirst du
libfoo/answer nicht finden. Da diese aber als String im Quelltext
stehen geht selbst bei nem gestrippten Binary:

$ strings dlopen_demo | grep 'answer\|foo'
libfoo.so
answer

Ein

    strings foo | grep '^lib'

w=E4re einen Versuch jedenfalls wert, da k=F6nnte man die Kandidaten der
*.so aus denen das Symbol stammen kann schonmal deutlich eindampfen...

Es sei denn, das Programm bastelt den/die Library-Namen zusammen
(strcat, sprintf oder sonstwie), dann wird's schwierig oder eher fast
unm=F6glich ... ;)

Evtl. hilft auch:

$ ltrace -f ./dlopen_demo
__libc_start_main(0x400800, 1, 0x7fff8929ea28, 0x400870, 0x400900 <unfinish=
ed ...>
dlopen("libfoo.so", 2)                           =3D 0x00602030
dlsym(0x00602030, "answer")                      =3D 0x7f19b00a05ac
__printf_chk(1, 0x400979, 42, 0x7f19b00a0360, 0x3c8ac2142
) =3D 3
dlclose(0x00602030)                              =3D 0
+++ exited (status 0) +++

Ggfs. um die Optionen '-S -s 128' erg=E4nzt wg. Kontext.

Soweit meine Tricks zum Thema ;)

>>Richtig. Hier habe ich aber auch keinen Hinweis auf die
>>libborqt-6.9-qt2.3.so; wieso nicht, wenn das undefinierte Symbol darin
>>definiert ist?
>
>Im Binary werden die Informationen unabh=E4ngig von einander
>gespeichert. Da ist zum einen der Name der Bibliothek gegen die das
>Programm gelinkt wird und zum anderen das ben=F6tigte Symbol. Es wird
>beim Linken nicht festgehalten, aus welcher Bibliothek welches Symbol
>benutzt wurde.

Jap. @Thomas: Vgl. auch oben ;)

>>=FCbrigens ist das neben einem Symlink die einzige Datei in dem RPM-Paket
>>gewesen, das ich installiert habe. Ich h=E4tte sie wohl auch aus einem
>>*.tar.gz holen und manuell nach /usr/lib kopieren k=F6nnen. Ich wollte
>>u.a. sehen, ob initPAnsiStrings darin enthalten ist.
>
>Wenn die Bibliothek nicht f=FCr die Distribution gebaut wurde sollte man
>das nicht probieren sondern die Bibliothek f=FCr die eigene Distribution
>kompilieren.

Sofern das m=F6glich ist: definitiv.

>Wo der dynamische Linker ld-linux.so die Bibliotheken sucht ist in
>/etc/ld.so.conf festgehalten. Wenn die Bibliothek in einem der
>angegebenen Veryeichnisse liegt wird sie bei Bedarf geladen.

Und dann w=E4re da noch LD_LIBRARY_PATH ... Da=DF _du_ das vergisst,
Philipp ... *tsk* :-P

-dnh

--=20
Microsoft Windows Setup scheint den Bootsektor von Brain 1.0
zu ueberschreiben, was dazu fuehrt, dass Brain am naechsten Morgen
nicht mehr gestartet wird.             -- Juergen P. Meier in dcsf
-- 
To unsubscribe, e-mail: [email protected]
To contact the owner, e-mail: [email protected]