GNU/Linux >> Belajar Linux >  >> Linux

Menautkan ke versi simbol lama dalam file .so

Saya menemukan solusi kerja berikut. Pertama buat file memcpy.c:

#include <string.h>

/* some systems do not have newest [email protected]@GLIBC_2.14 - stay with old good one */
asm (".symver memcpy, [email protected]_2.2.5");

void *__wrap_memcpy(void *dest, const void *src, size_t n)
{
    return memcpy(dest, src, n);
}

Tidak diperlukan CFLAGS tambahan untuk mengkompilasi file ini. Kemudian tautkan program Anda dengan -Wl,--wrap=memcpy .


Saya memiliki masalah yang sama. Mencoba menginstal beberapa komponen oracle di RHEL 7.1, saya mendapatkan ini:

$ gcc -o /some/oracle/bin/foo .... -L/some/oracle/lib ... 
/some/oracle/lib/libfoo.so: undefined reference to `[email protected]_2.14'

Tampaknya glibc RHEL (saya) hanya mendefinisikan [email protected]_2.2.5:

$ readelf -Ws /usr/lib/x86_64-redhat-linux6E/lib64/libc_real.so | fgrep [email protected]
   367: 000000000001bfe0    16 FUNC    GLOBAL DEFAULT    8 [email protected]@GLIBC_2.2.5
  1166: 0000000000019250    16 FUNC    WEAK   DEFAULT    8 [email protected]@GLIBC_2.2.5

Jadi, saya berhasil menyiasatinya, dengan terlebih dahulu membuat file memcpy.c tanpa pembungkus, sebagai berikut:

#include <string.h>
asm (".symver old_memcpy, [email protected]_2.2.5");       // hook old_memcpy as [email protected]
void *old_memcpy(void *, const void *, size_t );
void *memcpy(void *dest, const void *src, size_t n)   // then export memcpy
{
    return old_memcpy(dest, src, n);
}

dan file memcpy.map yang mengekspor memcpy kami sebagai [email protected]_2.14:

GLIBC_2.14 {
   memcpy;
};

Saya kemudian mengkompilasi memcpy.c saya sendiri ke dalam lib bersama seperti ini:

$ gcc -shared -fPIC -c memcpy.c
$ gcc -shared -fPIC -Wl,--version-script memcpy.map -o libmemcpy-2.14.so memcpy.o -lc

, memindahkan libmemcpy-2.14.so ke /some/Oracle/lib (ditunjukkan oleh argumen -L dalam penautan saya), dan ditautkan lagi oleh

$ gcc -o /some/oracle/bin/foo .... -L/some/oracle/lib ... /some/oracle/lib/libmemcpy-2.14.so -lfoo ...

(yang dikompilasi tanpa kesalahan) dan memverifikasinya dengan:

$ ldd /some/oracle/bin/foo
    linux-vdso.so.1 =>  (0x00007fff9f3fe000)
    /some/oracle/lib/libmemcpy-2.14.so (0x00007f963a63e000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007f963a428000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f963a20c000)
    librt.so.1 => /lib64/librt.so.1 (0x00007f963a003000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f9639c42000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f963aa5b000)

Ini bekerja untuk saya. Saya harap ini juga berlaku untuk Anda.


Saya memiliki masalah serupa. Pustaka pihak ketiga yang kami gunakan membutuhkan [email protected]_2.2.5 lama . Solusi saya adalah pendekatan yang diperluas @anight diposting.

Saya juga membengkokkan memcpy perintah, tetapi saya harus menggunakan pendekatan yang sedikit berbeda, karena solusi @anight diposting tidak bekerja untuk saya.

memcpy_wrap.c:

#include <stddef.h>
#include <string.h>

asm (".symver wrap_memcpy, [email protected]_2.2.5");
void *wrap_memcpy(void *dest, const void *src, size_t n) {
  return memcpy(dest, src, n);
}

memcpy_wrap.map:

GLIBC_2.2.5 {
   memcpy;
};

Bangun pembungkusnya:

gcc -c memcpy_wrap.c -o memcpy_wrap.o

Sekarang akhirnya saat menautkan program, tambahkan

  • -Wl,--version-script memcpy_wrap.map
  • memcpy_wrap.o

sehingga Anda akan berakhir dengan sesuatu seperti:

g++ <some flags> -Wl,--version-script memcpy_wrap.map <some .o files> memcpy_wrap.o <some libs>

Cukup tautkan memcpy secara statis - tarik memcpy.o dari libc.a ar x /path/to/libc.a memcpy.o (versi apa pun - memcpy adalah fungsi yang berdiri sendiri) dan sertakan di tautan terakhir Anda. Perhatikan bahwa penautan statis dapat memperumit masalah lisensi jika proyek Anda didistribusikan ke publik dan bukan sumber terbuka.

Sebagai alternatif, Anda dapat mengimplementasikan memcpy sendiri, meskipun versi rakitan yang disesuaikan dengan tangan di glibc cenderung lebih efisien

Perhatikan bahwa [email protected]_2.2.5 dipetakan ke memmove (versi lama memcpy secara konsisten disalin ke arah yang dapat diprediksi, yang terkadang menyebabkannya disalahgunakan ketika memmove seharusnya digunakan), dan ini adalah satu-satunya alasan untuk peningkatan versi - Anda cukup mengganti memcpy dengan memmove dalam kode Anda untuk kasus khusus ini.

Atau Anda dapat menggunakan penautan statis, atau Anda dapat memastikan bahwa semua sistem di jaringan Anda memiliki versi yang sama atau lebih baik daripada mesin build Anda.


Linux
  1. peringatan libpng:Versi libpng tidak kompatibel dalam aplikasi dan pustaka

  2. grep daftar besar terhadap file besar

  3. temukan dan hapus file atau folder yang lebih lama dari x hari

  1. Tidak setuju tentang versi simbol symbol_name setelah insmod

  2. Cara menginstal gcc versi lama di Fedora

  3. Membuka File Geodatabase di QGIS untuk Ubuntu?

  1. Gunakan Libreoffice Versi Lama?

  2. Tautkan dengan libstdc++ versi lama

  3. Menautkan ke libc versi lama untuk menyediakan cakupan aplikasi yang lebih luas