Để làm điều này một cách tự động, bạn có thể sử dụng kịch bản sau đây để tạo ra một danh sách tất cả những biểu tượng mà mới trong GLIBC của bạn hơn trong một phiên bản nhất định (được đặt trên dòng 2). Nó tạo ra một tệp glibc.h
(tên tệp được đặt bởi đối số tập lệnh) chứa tất cả các khai báo .symver
cần thiết. Sau đó, bạn có thể thêm -include glibc.h
vào CFLAGS của mình để đảm bảo rằng nó được chọn ở mọi nơi trong quá trình biên dịch của bạn.
Điều này là đủ nếu bạn không sử dụng bất kỳ thư viện tĩnh nào được biên dịch mà không có các điều kiện trên bao gồm. Nếu bạn làm thế, và bạn không muốn biên dịch lại, bạn có thể sử dụng objcopy
để tạo một bản sao của thư viện với các biểu tượng được đổi tên thành các phiên bản cũ. Dòng thứ hai đến cuối của tập lệnh tạo ra phiên bản hệ thống của bạn libstdc++.a
sẽ liên kết với các biểu tượng glibc cũ. Thêm -L.
(hoặc -Lpath/to/libstdc++.a/
) sẽ làm cho chương trình của bạn liên kết tĩnh libstdC++ mà không cần liên kết trong một loạt các ký hiệu mới. Nếu bạn không cần điều này, hãy xóa hai dòng cuối cùng và dòng printf ... redeff
.
#!/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,%[email protected]%s\");\n", s, s, symvertext[s]) > headerf
printf("%s %[email protected]%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
Tôi cũng sẽ thêm rằng thường chỉ có một hoặc hai biểu tượng gây ra sự phụ thuộc vào phiên bản glibc mới, vì vậy nếu như tôi bạn lo lắng bạn sẽ phải liệt kê hàng trăm biểu tượng để xóa phụ thuộc, bạn sẽ không làm như vậy. – Malvineous
dietlibc cũng đáng xem. –
Hoặc nếu bạn có thể liên kết tĩnh (tức là mã của bạn không phải là plugin và sẽ không sử dụng plugin), bạn cũng có thể xem musl-libc. Tôi đã tìm thấy đôi khi các chương trình liên kết tĩnh với musl-libc nhỏ hơn so với các đối tác glibc được liên kết động của chúng. – 0xC0000022L