2009-08-28 40 views
19

Tôi đang viết một trình tải ELF không gian người dùng đơn giản trong Linux (tại sao? Cho 'vui'). Trình tải của tôi tại thời điểm này khá đơn giản và được thiết kế để chỉ tải các tệp ELF được liên kết tĩnh có chứa mã vị trí độc lập.tải lại thời gian ELF di dời

Thông thường, khi một chương trình được tải bởi trình nạp ELF của hạt nhân, nó được nạp vào không gian địa chỉ riêng của nó. Như vậy, phân đoạn dữ liệu và đoạn mã có thể được tải tại địa chỉ ảo chính xác như được chỉ định trong các phân đoạn ELF.

Trong trường hợp của tôi, tuy nhiên, tôi yêu cầu địa chỉ từ hạt nhân qua mmap và có thể hoặc không thể nhận được các địa chỉ được yêu cầu trong các phân đoạn ELF. Đây không phải là vấn đề đối với đoạn mã vì nó là vị trí độc lập. Tuy nhiên, nếu phân đoạn dữ liệu không được tải tại địa chỉ dự kiến, mã sẽ không thể tham chiếu chính xác mọi thứ được lưu trữ trong phân đoạn dữ liệu.

Thật vậy, trình tải của tôi có vẻ hoạt động tốt với một tệp thực thi lắp ráp đơn giản không chứa bất kỳ dữ liệu nào. Nhưng ngay sau khi tôi thêm một phân đoạn dữ liệu và tham chiếu nó, tệp thực thi không chạy đúng hoặc SEGFAULT.

Làm cách nào, nếu có thể, tôi có thể sửa bất kỳ tham chiếu nào đến phân đoạn dữ liệu để trỏ đến đúng địa điểm không? Có một phần di dời được lưu trữ trong tệp ELF (tĩnh) cho mục đích này không?

+1

Lý do mmap() không thành công khi đưa ra các địa chỉ được yêu cầu do quá trình 'đang gọi mmap đã có các trang được phân bổ trong không gian địa chỉ của nó? –

+0

Vâng, đây có lẽ là lý do. Tôi nghĩ về việc yêu cầu 'ld' để đặt mã/dữ liệu của tôi ở đâu đó" ngoài đường ", nhưng tôi đã tự hỏi nếu một giải pháp chung có thể được đầu tiên. Nếu tôi không nhận được bất kỳ phản ứng nào ở đây, tôi có thể tiếp tục và thử điều đó. –

Trả lời

8

Nếu bạn sửa đổi các địa chỉ tuyệt đối có sẵn trong phần .got, (bảng bù toàn cục), chương trình của bạn sẽ hoạt động. Hãy chắc chắn để sửa đổi tính toán địa chỉ tuyệt đối để phục vụ cho khoảng cách mới giữa .text và .data, tôi sợ bạn cần phải tìm ra nơi thông tin này đến từ, cho kiến ​​trúc của bạn.

Xem nội dung này: Global Offset Table (Processor-Specific)

Chúc may mắn.

+0

Không nên cố tính toán khoảng cách mới. Một số hướng dẫn có thể tham chiếu nội dung của phân đoạn dữ liệu bằng cách sử dụng địa chỉ tương đối và việc di chuyển phân đoạn sẽ đơn giản là phá vỡ nó. Để ánh xạ phân đoạn đúng cách, bạn nên sử dụng 'MAP_FIXED' để cuộc gọi' mmap' không thành công nếu khu vực bắt buộc không có sẵn và/hoặc ánh xạ khu vực lớn cho cả hai phân đoạn một cách nguyên tử, sau đó unmap các phần của nó và ánh xạ các phân đoạn riêng lẻ tại chỗ lỗ. –

4

Tôi không thấy bất kỳ cách nào bạn có thể làm điều đó, trừ khi bạn mô phỏng hoàn toàn không gian địa chỉ ảo do hạt nhân cung cấp và chạy mã bên trong không gian ảo đó. Khi bạn mmap phần dữ liệu từ tập tin, bạn đang bản địa di dời nó đến một địa chỉ không rõ của không gian địa chỉ ảo của trình thông dịch ELF của bạn, và mã của bạn sẽ không thể tham chiếu đến nó theo bất kỳ cách nào.

Rất vui được chứng minh là sai. Có điều gì đó rất hay để học ở đây.

+0

Hoặc có mục tiêu ELF và chức năng tải trong các quy trình khác nhau, với một phần tối thiểu cần phải được trong quá trình nhắm mục tiêu trên một địa chỉ freaky. Bằng cách này, bạn có thể sử dụng các công cụ và thủ tục tiêu chuẩn cho hầu hết bộ nạp –

Các vấn đề liên quan