Frage

Linux-Binärdateien sind in der Regel dynamisch an die Core-System-Bibliothek verknüpft (libc). Dies hält den Speicherbedarf des binären recht klein, aber Binärdateien, die auf den aktuellen Bibliotheken abhängig sind, werden auf älteren Systemen nicht ausgeführt werden. Im Gegensatz dazu Binärdateien älteren Bibliotheken gelinkt werden gerne auf den neuesten Systemen laufen.

Deshalb, um unsere Anwendung, um sicherzustellen, hat eine gute Abdeckung während der Verteilung wir aus der ältesten Abbildung benötigen libc wir unterstützen können und verknüpfen unsere binäre dagegen.

Wie sollten wir die älteste Version bestimmen von libc wir verknüpfen?

War es hilfreich?

Lösung

Arbeit heraus, welche Symbole in der ausführbaren Datei auf der unerwünschten Version von glibc, die Abhängigkeit zu schaffen.

$ objdump -p myprog
...
Version References:
  required from libc.so.6:
    0x09691972 0x00 05 GLIBC_2.3
    0x09691a75 0x00 03 GLIBC_2.2.5

$ objdump -T myprog | fgrep GLIBC_2.3
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.3   realpath

Schauen Sie innerhalb der abhing-upon-Bibliothek zu sehen, ob es irgendwelche Symbole in älteren Versionen sind, dass Sie einen Link gegen können:

$ objdump -T /lib/libc.so.6 | grep -w realpath
0000000000105d90 g    DF .text  0000000000000021 (GLIBC_2.2.5) realpath
000000000003e7b0 g    DF .text  00000000000004bf  GLIBC_2.3   realpath

Wir haben Glück!

Fordern Sie die Version von GLIBC_2.2.5 im Code:

#include <limits.h>
#include <stdlib.h>

__asm__(".symver realpath,realpath@GLIBC_2.2.5");

int main () {
    realpath ("foo", "bar");
}

Beachten Sie, dass GLIBC_2.3 nicht mehr benötigt wird:

$ objdump -p myprog
...
Version References:
  required from libc.so.6:
    0x09691a75 0x00 02 GLIBC_2.2.5

$ objdump -T myprog | grep realpath
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 realpath

Weitere Informationen finden Sie unter http://web.archive.org/web/20160107032111/http://www.trevorpounds.com/blog/?p=103 .

Andere Tipps

Leider @ Sams Lösung funktioniert nicht gut in meiner Situation. Aber nach seiner Art und Weise, fand ich meine eigene Art und Weise zu lösen.

Das ist meine Situation:

Ich schreibe ein C ++ Programm mit dem Thrift Rahmen (es ist eine RPC-Middleware). Ich ziehe es statischen Link zu Dynamic Link, so mein Programm verknüpft ist libthrift.a statisch anstelle von libthrift.so . Allerdings libthrift.a dynamisch glibc verbunden ist, und da mein libthrift.a ist Build auf meinem System mit glibc 2.15, mein libthrift.a Anwendungen memcpy die Version 2.14 ( memcpy@GLIBC_2.14 ) um 2,15 glibc zur Verfügung gestellt.

Aber das Problem ist, dass unsere Server-Maschinen haben nur die glibc Version 2.5, die nur hat memcpy@GLIBC_2.2.5 . Es ist viel niedriger als memcpy@GLIBC_2.14 . Also, natürlich, kann mein Server-Programm nicht auf diesen Maschinen ausgeführt werden.

Und ich diese solusion gefunden:

  1. .symver Mit dem ref memcpy@GLIBC_2.2.5 .

  2. zu erhalten
  3. Schreiben meine eigene __ wrap_memcpy Funktion, die nur Anrufe memcpy@GLIBC_2.2.5 direkt.

  4. Wenn mein Programm verknüpft, add -Wl, - wrap = Memcpy Option gcc / g ++

  5. .

Der Code beteiligt in Schritt 1 und 2 ist hier: https://gist.github.com/nicky-zs/ 7541169

Um dies zu tun in einer automatisierten Art und Weise, können Sie das folgende Skript verwenden, um eine Liste aller Symbole zu erstellen, die neueren in Ihrem GLIBC sind als in einer bestimmten Version (gesetzt auf Linie 2). Es schafft eine glibc.h Datei (Dateiname durch das Skript Argument gesetzt), die alle notwendigen .symver Erklärungen enthält. Sie können dann -include glibc.h auf Ihre CFLAGS hinzuzufügen sicherzustellen, dass es überall in Ihrer Zusammenstellung aufgenommen wird.

Dies ist ausreichend, wenn Sie keine statischen Bibliotheken verwenden, die ohne die oben umfassen zusammengestellt wurden. Wenn Sie das tun, und Sie wollen nicht neu kompilieren, können Sie objcopy verwenden, um eine Kopie der Bibliothek mit den Symbolen auf den alten Versionen umbenannt zu erstellen. Die zweite nach unten Zeile des Skripts erzeugt eine Version des Systems libstdc++.a, die gegen die alten glibc Symbole verbinden wird. Hinzufügen -L. (oder -Lpath/to/libstdc++.a/) wird Ihr Programm statisch libstdc Link ++ ohne in einem Bündel von neuen Symbolen zu verknüpfen. Wenn Sie dies nicht benötigen, löschen Sie die letzten beiden Zeilen und die printf ... redeff Linie.

#!/bin/bash
maxver=2.9
headerf=${1:-glibc.h}
set -e
for lib in libc.so.6 libm.so.6 libpthread.so.0 libdl.so.2 libresolv.so.2 librt.so.1; do
objdump -T /usr/lib/$lib
done | awk -v maxver=${maxver} -vheaderf=${headerf} -vredeff=${headerf}.redef -f <(cat <<'EOF'
BEGIN {
split(maxver, ver, /\./)
limit_ver = ver[1] * 10000 + ver[2]*100 + ver[3]
}
/GLIBC_/ {
gsub(/\(|\)/, "",$(NF-1))
split($(NF-1), ver, /GLIBC_|\./)
vers = ver[2] * 10000 + ver[3]*100 + ver[4]
if (vers > 0) {
    if (symvertext[$(NF)] != $(NF-1))
        count[$(NF)]++
    if (vers <= limit_ver && vers > symvers[$(NF)]) {
        symvers[$(NF)] = vers
        symvertext[$(NF)] = $(NF-1)
    }
}
}
END {
for (s in symvers) {
    if (count[s] > 1) {
        printf("__asm__(\".symver %s,%s@%s\");\n", s, s, symvertext[s]) > headerf
        printf("%s %s@%s\n", s, s, symvertext[s]) > redeff
    }
}
}
EOF
)
sort ${headerf} -o ${headerf}
objcopy --redefine-syms=${headerf}.redef /usr/lib/libstdc++.a libstdc++.a
rm ${headerf}.redef

glibc 2.2 ist eine ziemlich gemeinsame Mindestversion. Doch eine Bauplattform zu finden für diese Version nicht-trivial sein kann.

Wahrscheinlich eine bessere Richtung geht um die älteste OS Sie denken wollen unterstützen und zu bauen, dass auf.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top