2011-07-08 23 views
7

Khi chạy, tôi cần in một địa chỉ và sau đó tìm địa chỉ mà địa chỉ đó là một phần của. Các chức năng nằm trong một thư viện được chia sẻ nên không có địa chỉ cố định. Tập tin bản đồ của tôi rõ ràng chỉ hiển thị các offset tương đối cho mỗi thư viện được chia sẻ func. Có thể tại thời gian chạy để truy vấn nơi một thư viện đã được tải, để tôi có thể trừ giá trị đó khỏi địa chỉ của tôi để có được sự bù đắp tập tin bản đồ đúng không?Tìm địa chỉ tải của một thư viện được chia sẻ trong Linux

Hiện tại tôi đang thực hiện một thỏa thuận hơi hacky theo đó tôi cũng in địa chỉ của một hàm trong thư viện, sau đó tìm hàm đó trong tệp bản đồ để tìm ra địa chỉ tải phải ở đâu. Tôi thà có một phương pháp chung mà không yêu cầu bạn phải đặt tên một hàm tham chiếu.

(GDB không có trong thiết lập của tôi). Cảm ơn.

Trả lời

4

Trên Linux gần đây, bạn có thể sử dụng dl_iterate_phdr để tìm hiểu địa chỉ của thư mục được chia sẻ.

1

GNU backtrace thư viện?

Tôi sẽ không dựa vào phương pháp tiếp cận hacky cho một thứ như thế này. Tôi không nghĩ rằng có bất kỳ đảm bảo rằng nội dung của thư viện được nạp vào bộ nhớ tiếp giáp.

3

Hãy thử xem/proc/[PID]/tệp bản đồ. Điều này sẽ chứa địa chỉ của ánh xạ thư viện trong không gian địa chỉ bộ nhớ quá trình.

Nếu bạn muốn tiếp cận phần thực thi, hãy sử dụng chính sách đọc trên thư viện của bạn và tìm phần bù đắp của phần .text.

7

dladdr thực hiện việc này, kết thúc. :-)

Dễ hiểu hơn, dladdr sẽ lấy địa chỉ và tìm ra thư viện và ký hiệu tương ứng với ... và sau đó nó sẽ cho bạn tên thư viện, tên biểu tượng và cơ sở địa chỉ của mỗi địa chỉ. Cá nhân tôi nghĩ rằng đó là tiện lợi, nó cũng làm cho công việc gỡ lỗi hiện tại của tôi một ánh sáng dễ dàng hơn.

Hy vọng điều này sẽ hữu ích!

1

Kiểm tra System V ABI, chapter 5. Đối với những người lười biếng trên mạng, đây là cách tiêu chuẩn để làm điều này cho các hệ thống hỗ trợ các định dạng nhị phân ELF:

#include <link.h> 

off_t load_offset; 
for (Elf64_Dyn *dyn = _DYNAMIC; dyn->d_tag != DT_NULL; ++dyn) { 
    if (dyn->d_tag == DT_DEBUG) { 
     struct r_debug *r_debug = (struct r_debug *) dyn->d_un.d_ptr; 
     struct link_map *link_map = r_debug->r_map; 
     while (link_map) { 
      if (strcmp(link_map->l_name, libname) == 0) { 
       load_offset = (off_t)link_map->l_addr; 
       break; 
      } 
      link_map = link_map->l_next; 
     } 
     break; 
    } 
} 

này không dựa trên bất kỳ phần mở rộng GNU.

Trên hệ thống GNU, macro ElfW (Dyn) sẽ trả về hoặc là Elf64_Dyn hoặc Elf32_Dyn thuận tiện.

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