Linux, GNU GCC, ld, script script và định dạng nhị phân ELF - Nó hoạt động như thế nào?


13

Tôi đang cố gắng tìm hiểu thêm về phiên bản thư viện trong Linux và cách làm cho tất cả hoạt động. Đây là bối cảnh:

- Tôi có hai phiên bản của một thư viện động hiển thị cùng một bộ giao diện, nói libsome1.solibsome2.so.

- Một ứng dụng được liên kết với libsome1.so.

- Ứng dụng này sử dụng libdl.sođể tải động một mô-đun khác, nói libmagic.so.

- Bây giờ libmagic.sođược liên kết với libsome2.so. Rõ ràng, không sử dụng tập lệnh liên kết để ẩn biểu tượng libmagic.so, trong thời gian chạy, tất cả các lệnh gọi đến giao diện libsome2.sođược giải quyết libsome1.so. Điều này có thể được xác nhận bằng cách kiểm tra giá trị được trả về bằng libVersion()giá trị của macro LIB_VERSION.

- Vì vậy, tôi cố gắng bên cạnh biên dịch và liên kết libmagic.sovới một tập lệnh liên kết ẩn tất cả các ký hiệu trừ 3 được xác định libmagic.sovà được xuất bởi nó. Điều này hoạt động ... Hoặc ít nhất libVersion()LIB_VERSIONcác giá trị khớp với nhau (và nó báo cáo phiên bản 2 chứ không phải 1).

- Tuy nhiên, khi một số cấu trúc dữ liệu được tuần tự hóa vào đĩa, tôi nhận thấy một số tham nhũng. Trong thư mục của ứng dụng nếu tôi xóa libsome1.sovà tạo một liên kết mềm ở vị trí của nó để trỏ đến libsome2.so, mọi thứ sẽ hoạt động như mong đợi và tham nhũng tương tự không xảy ra.

Tôi không thể không nghĩ rằng điều này có thể được gây ra do một số xung đột trong độ phân giải biểu tượng của trình liên kết thời gian chạy. Tôi đã thử nhiều thứ, như cố gắng liên kết libsome2.sođể tất cả các biểu tượng được chỉnh sửa symbol@@VER_2(điều mà tôi vẫn bối rối vì lệnh nm -CD libsome2.sovẫn liệt kê các biểu tượng là symbolvà không symbol@@VER_2) ... Dường như không có gì hoạt động !!! Cứu giúp!!!!!!


Cách tiếp cận cuối cùng của bạn là cách tôi sẽ bắt đầu với. Và tôi đồng ý rằng tham nhũng có lẽ là một sự nhầm lẫn biểu tượng. Đáng buồn thay, tôi không có câu trả lời cho bạn.
RobotHumans

điều này có thể làm tốt hơn trên SO, mặc dù tôi không hiểu nó đủ để nói chắc chắn. gắn cờ nếu bạn muốn chúng tôi di chuyển nó.
xenoterracide

1
Hãy thử các cờ RTLD_LOCALRTLD_DEEPBINDdlopen trong ứng dụng của bạn. Tôi không có thời gian để kiểm tra điều này ngay bây giờ nhưng nó sẽ hoạt động dựa trên trang chủ.
stribika

Câu trả lời:


13

Điều này không trả lời chính xác câu hỏi của bạn, nhưng ...

Trước hết, ELF là đặc tả được Linux sử dụng cho các tệp thực thi (chương trình), thư viện dùng chung và cả các tệp đối tượng là các tệp trung gian được tìm thấy khi biên dịch phần mềm. Các tệp đối tượng kết thúc bằng .o, các thư viện dùng chung kết thúc bằng .so theo sau là 0 hoặc nhiều chữ số được phân tách bằng dấu chấm và các tệp thực thi không có bất kỳ tiện ích mở rộng thông thường.

Thông thường có ba biểu mẫu để đặt tên cho thư viện dùng chung, biểu mẫu đầu tiên chỉ đơn giản kết thúc bằng .so. Ví dụ: thư viện có tên là readline được lưu trữ trong một tệp có tên libreadline.so và được đặt dưới một trong / lib, / usr / lib hoặc / usr / local / lib thông thường. Tập tin đó được định vị khi biên dịch phần mềm với tùy chọn như -lreadline. -l báo cho trình biên dịch liên kết với thư viện sau. Bởi vì các thư viện thay đổi theo thời gian, nó có thể trở nên lỗi thời nên các thư viện nhúng một thứ gọi là SONAME. SONAME cho readline có thể trông giống như libreadline.so.2 cho phiên bản chính thứ hai của libreadline. Cũng có thể có nhiều phiên bản nhỏ của đường đọc tương thích và không yêu cầu phải biên dịch lại phần mềm. Một phiên bản nhỏ của readline có thể được đặt tên là libreadline.so.2.14. Bình thường libreadline. vì vậy chỉ là một liên kết tượng trưng cho phiên bản chính gần đây nhất của readline, libreadline.so.2 trong trường hợp này. libreadline.so.2 cũng là một liên kết tượng trưng đến libreadline.so.2.14 thực sự là tập tin đang được sử dụng.

SONAME của thư viện được nhúng bên trong tệp thư viện. Một nơi nào đó bên trong tệp libreadline.so.2.14 là chuỗi libreadline.so.2. Khi một chương trình được biên dịch và liên kết với readline, nó sẽ tìm tệp libreadline.so và đọc SONAME được nhúng trong đó. Sau đó, khi chương trình thực sự được thực thi, nó sẽ tải libreadline.so.2, không chỉ libreadline.so, vì đó là SONAME được đọc khi lần đầu tiên được liên kết. Điều này cho phép một hệ thống có nhiều phiên bản đọc không tương thích được cài đặt và mỗi chương trình sẽ tải phiên bản chính phù hợp mà nó được liên kết. Ngoài ra, khi nâng cấp readline, giả sử lên 2.17, tôi chỉ có thể cài đặt libreadline.so.2.17 cùng với thư viện hiện có và một khi tôi di chuyển liên kết tượng trưng libreadline.so.2 từ libreadline.so.2.13 sang libreadline.so.2.17,

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.