Có, bằng cách kiểm tra tệp thực thi của riêng nó (/proc/self/exe
) bằng cách sử dụng ví dụ: libbfd
hoặc thư viện phân tích tệp ELF, để phân tích cú pháp các ký hiệu thực tế. Về cơ bản, bạn muốn viết mã C mà không tương đương với một cái gì đó giống như
env LANG=C LC_ALL=C readelf -s executable | awk '($5 == "LOCAL" && $8 ~ /^[^_]/ && $8 !~ /\./)'
Theo như tôi biết, giao diện mối liên kết động trong Linux (<dlfcn.h>
) không trả lại địa chỉ cho (địa phương) những biểu tượng tĩnh.
Cách tiếp cận đơn giản và mạnh mẽ là thực hiện readelf
hoặc objdump
từ chương trình của bạn. Lưu ý rằng bạn không thể cung cấp đường dẫn tệp giả /proc/self/exe
cho các tệp đó vì nó luôn đề cập đến quá trình thực thi của chính quy trình đó. Thay vào đó, bạn phải sử dụng ví dụ. realpath("/proc/self/exe", NULL)
để có được đường dẫn tuyệt đối được cấp phát động cho tệp thi hành hiện tại mà bạn có thể cung cấp cho lệnh. Bạn cũng chắc chắn muốn đảm bảo môi trường chứa LANG=C
và LC_ALL=C
, sao cho đầu ra của lệnh dễ dàng phân tích cú pháp (và không được bản địa hóa cho bất kỳ ngôn ngữ nào mà người dùng hiện tại thích). Điều này có thể cảm thấy một chút kludgy, nhưng nó chỉ yêu cầu gói binutils
được cài đặt để hoạt động và bạn không cần phải cập nhật chương trình hoặc thư viện của mình để theo kịp những phát triển mới nhất, vì vậy tôi nghĩ rằng đó là một cách tiếp cận khá tốt .
Bạn có muốn một ví dụ không?
Một cách để dễ dàng hơn, là tạo các mảng riêng biệt với thông tin ký hiệu tại thời gian biên dịch. Về cơ bản, sau khi các tập tin đối tượng được tạo ra, một file nguồn riêng biệt được tạo động bằng cách chạy objdump
hoặc readelf
qua các tập tin đối tượng liên quan, tạo ra một loạt các tên và con trỏ tương tự như
const struct {
const char *const name;
const void *const addr;
} local_symbol_names[] = {
/* Filled in using objdump or readelf and awk, for example */
{ NULL, NULL }
};
có lẽ với một chức năng tìm kiếm đơn giản xuất khẩu trong một tệp tiêu đề, để khi tệp thực thi cuối cùng được liên kết, nó có thể truy cập dễ dàng và hiệu quả mảng các ký hiệu cục bộ.
Sao chép một số dữ liệu, vì cùng một thông tin đã có trong tệp thi hành và nếu tôi nhớ chính xác, trước tiên bạn phải liên kết tệp thực thi cuối cùng với mảng sơ khai để có được địa chỉ thực tế cho biểu tượng, sau đó liên kết lại với mảng biểu tượng, làm cho nó hơi phức tạp trong một thời gian biên dịch .. Nhưng nó tránh được sự phụ thuộc vào thời gian chạy trên binutils
.