Warum (und wie) habe ich (scheinbar!) doppelte Symbole in meinen gemeinsam genutzten Bibliotheken?

Warum (und wie) habe ich (scheinbar!) doppelte Symbole in meinen gemeinsam genutzten Bibliotheken?

Ich musste aus einer flachen Liste exportierter Symbole aus gemeinsam genutzten Bibliotheken herausfinden, welche Symbole von welcher Bibliothek exportiert wurden. Die Liste enthielt gerade genug Symbole (etwa 20), sodass ich nicht jedes Symbol manuell vergleichen wollte.

Ich fand, dass das nm -A -D -f sysv <library-name>eine nützliche Ausgabe zu produzieren schien - ich konnte nach Zeilen suchen, die enthielten, FUNCdass in der zweiten Spalte auch eine Adresse aufgeführt war. Also führte ich diesen Befehl für alles in aus und /usr/libleitete es in eine Datei um.

Zu meiner Überraschung meldete die Plausibilitätsprüfung im Skript, das ich zum Parsen der Datei erstellt hatte, dass es doppelte Symbole gab! Nach der Untersuchung stellte ich fest, dassBibliotheken schienen doppelte Symbole zu exportieren?!?

Ich habe dies mithilfe einiger Shell-Skripte überprüft und konnte die von mir verwendeten Befehle wie folgt umwandeln (technisch) Einzeiler:

readlink -f /lib/* /usr/lib/* \
  | grep -F .so. | sort | uniq \
  | while read x; do nm -A -D -f sysv $x; done \
  | grep FUNC | cut -d'|' -f1 | sort -g | uniq -c | sort -g \
  | sed -n '/^ \+1/!{s/^ \+[0-9]\+ \+//p}' | sed 's/ //g' \
  | tr '\n' '\v' \
  | sed ':1;s/\([^ ]\+\):\([^\v$]\+\)\v\1:/\1:\2|/g;t1' \
  | tr '\v' '\n' \
  | while IFS=: read -a x; do \
     nm -A -D -f sysv "${x[0]}" | grep ":\\(${x[1]//|/\\|}\\).*FUNC"; \
  done

Der obige Befehl lässt Ihre Festplatte für einen kurzen Zeitraum suchen. Sie können es in Blöcke aufteilen, die zu temporären Dateien umleiten, wenn Sie möchten. AußerdemDie Ausgabe wird sehr breit sein(~150 Spalten).

Ich habe das Originalskript zunächst auf einem Debian-Squeeze-Chroot ausgeführt, in dem ich gearbeitet habe, aber aus Neugierde habe ich das obige auf meinem Hostsystem ausgeführt, um herauszufinden, ob das Chroot aus irgendeinem Grund nicht funktionierte.

Nun ... das Chroot hat etwas über 90 Duplikate gemeldet, aber mein Hostsystem (Arch) hat anscheinend ungefähr 267.

Der Befehl funktioniert, indem er nmdie Ausgabe von greppt, sodass die Ergebnisse etwas verrauscht sind, aber es sieht so aus:

/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_access|00043700|   T  |              FUNC|00000037|     |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_access|000436c0|   T  |              FUNC|0000003c|     |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_access_mask|000458f0|   T  |              FUNC|00000058|     |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_buffer_size|000432a0|   T  |              FUNC|00000037|     |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_buffer_size|00043260|   T  |              FUNC|0000003c|     |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_buffer_size_max|00044ff0|   T  |              FUNC|0000003c|     |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_buffer_size_max|00045030|   T  |              FUNC|00000037|     |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_buffer_size_min|000453c0|   T  |              FUNC|00000037|     |.text
/usr/lib/libasound.so.2.0.0:snd_pcm_hw_params_get_buffer_size_min|00045380|   T  |              FUNC|0000003c|     |.text

Beachten Sie, dass jedes Symbol zweimal vorhanden ist.Die Adresse ist anders, ja, aber ... ich dachte, dynamisches Verknüpfen funktioniert nach Symbolnamen, und das war's. Meine Verwirrung wird noch dadurch verstärkt, dass (wenn Sie in der obigen Auflistung nach rechts scrollen) die Symbole alle vom Typ FUNCund aus dem .textAbschnitt sind.

Ich poste das, um zu erfahren, welche interessante Magie hier unter der Haube vor sich geht. (Da mein System funktioniert...)

Wenn irgendjemand eine gute Idee hat, wo ich etwa 600 Zeilen Text ablegen könnte – Pastebin scheint nicht mehr in Mode zu sein und ich verwende GitHub nicht –, teile ich gern die vollständige Ausgabe.

Antwort1

Die Symbole erscheinen doppelt, weil die von bereitgestellten Informationen nmunvollständig sind: Die betreffenden Symbole sind versioniert. Sie können dies mit sehen objdump -T:

0000000000059d00 g    DF .text  0000000000000044 (ALSA_0.9)   snd_pcm_hw_params_get_access
0000000000056040 g    DF .text  000000000000004b  ALSA_0.9.0rc4 snd_pcm_hw_params_get_access

oder nmOption --with-symbol-versions:

/usr/lib/x86_64-linux-gnu/libasound.so.2.0.0:snd_pcm_hw_params_get_access|0000000000059d00|   T  |              FUNC|0000000000000044|     |.text@ALSA_0.9
/usr/lib/x86_64-linux-gnu/libasound.so.2.0.0:snd_pcm_hw_params_get_access|0000000000056040|   T  |              FUNC|000000000000004b|     |.text@@ALSA_0.9.0rc4

Binärdateien werden mit einer bestimmten Version des Symbols verknüpft und erhalten beim Verknüpfen die richtige Version. Dadurch können APIs geändert werden, während die Abwärtskompatibilität erhalten bleibt.

verwandte Informationen