Tôi đã thấy việc sử dụng gcc __section__
attribute (đặc biệt là trong hạt nhân Linux) để thu thập dữ liệu (thường là con trỏ hàm) vào các phần tùy chỉnh ELF. Làm thế nào là "công cụ" được đưa vào các phần tùy chỉnh được truy xuất và sử dụng?Làm thế nào để bạn có được địa chỉ bắt đầu và kết thúc của phần ELF tùy chỉnh trong C (gcc)?
Trả lời
Miễn là tên phần dẫn đến tên biến C hợp lệ, gcc
(ld
, đúng hơn) tạo hai biến ma thuật: __start_SECTION
và __stop_SECTION
. Những có thể được sử dụng để lấy các địa chỉ bắt đầu và kết thúc của một bộ phận, như vậy:
/**
* Assuming you've tagged some stuff earlier with:
* __attribute((__section__("my_custom_section")))
*/
struct thing *iter = &__start_my_custom_section;
for (; iter < &__stop_my_custom_section; ++iter) {
/* do something with *iter */
}
tôi không thể tìm thấy bất kỳ tài liệu chính thức cho tính năng này, chỉ có một mơ hồ vài mailing list tài liệu tham khảo. Nếu bạn biết tài liệu ở đâu, hãy viết nhận xét!
Nếu bạn đang sử dụng tập lệnh trình liên kết của riêng mình (như hạt nhân Linux), bạn sẽ phải tự thêm các biến ma thuật (xem vmlinux.lds.[Sh]
và this SO answer).
Xem here để biết ví dụ khác về cách sử dụng các phần tùy chỉnh ELF.
Linker có thể sử dụng những biểu tượng được xác định trong các mã, và có thể gán giá trị ban đầu của họ nếu bạn sử dụng tên chính xác trong kịch bản mối liên kết:
_smysection = .;
*(.mysection)
*(.mysection*)
_emysection = .;
Chỉ cần xác định một biến trong mã C:
const void * _smysection;
Và sau đó bạn có thể truy cập đó dưới dạng biến thông thường.
u32 someVar = (u32)&_smysection;
Vì vậy, câu trả lời ở trên, __start_SECTION
và __stop_SECTION
sẽ làm việc, tuy nhiên đối với các chương trình để có thể sử dụng thông tin từ các mối liên kết bạn cần phải khai báo các biến như extern char* __start_SECTION
. Thưởng thức!
extern char * __start_blobby;
...
printf("This section starts at %p\n", (unsigned int)&__start_blobby);
...
Thu thập các thông tin với nhau từ những câu trả lời khác nhau, đây là một ví dụ làm việc như thế nào để thu thập thông tin vào một phần tùy chỉnh mối liên kết và sau đó đọc các thông tin từ phần đó bằng cách sử dụng các biến kỳ diệu __start_SECTION
và __stop_SECTION
trong chương trình C, trong đó SECTION
là tên của phần trong bản đồ liên kết.
Các biến số __start_SECTION
và __stop_SECTION
được tạo sẵn bởi trình liên kết vì vậy cần phải tạo tham chiếu rõ ràng cho các biến này khi chúng được sử dụng từ mã C.
Ngoài ra còn có một số vấn đề nếu sự liên kết được sử dụng bởi trình biên dịch để tính toán con trỏ/mảng bù đắp là khác với sự liên kết của các đối tượng được đóng gói trong từng phần của trình liên kết. Một giải pháp (được sử dụng trong ví dụ này) là lưu trữ chỉ một con trỏ tới dữ liệu trong phần trình liên kết.
#include <stdio.h>
struct thing {
int val;
const char* str;
int another_val;
};
struct thing data1 = {1, "one"};
struct thing data2 = {2, "two"};
/* The following two pointers will be placed in "my_custom_section".
* Store pointers (instead of structs) in "my_custom_section" to ensure
* matching alignment when accessed using iterator in main(). */
struct thing *p_one __attribute__((section("my_custom_section"))) = &data1;
struct thing *p_two __attribute__((section("my_custom_section"))) = &data2;
/* The linker automatically creates these symbols for "my_custom_section". */
extern struct thing *__start_my_custom_section;
extern struct thing *__stop_my_custom_section;
int main(void) {
struct thing **iter = &__start_my_custom_section;
for (; iter < &__stop_my_custom_section; ++iter) {
printf("Have thing %d: '%s'\n", (*iter)->val, (*iter)->str);
}
return 0;
}
- 1. Làm thế nào để tìm địa chỉ kết thúc của một hàm trong một prog C?
- 2. Làm cách nào để tôi có thể bắt đầu và kết thúc trong regex của Python?
- 3. Làm cách nào để chuyển đến phần bắt đầu/kết thúc của lựa chọn trực quan?
- 4. làm thế nào để bạn chỉ đẩy một số cam kết git địa phương của bạn?
- 5. Làm thế nào để có được địa chỉ MAC của máy client trong C# và vb.net
- 6. Làm thế nào để có được đầu của bạn xung quanh C + + liên kết/phụ thuộc?
- 7. Chỉ định tùy tiện bắt đầu và kết thúc thời gian cho công việc định kỳ
- 8. Làm cách nào để bắt đầu và kết thúc trong ngày bằng Javascript?
- 9. Lấy một phần của Danh sách <Item> theo chỉ mục bắt đầu và kết thúc
- 10. Địa chỉ phụ thuộc thành phần tùy chỉnh
- 11. Làm cách nào để có thể bắt đầu và kết thúc trên toàn bộ lịch biểu?
- 12. Bắt đầu và kết thúc tệp trong python với regex
- 13. Làm thế nào để bạn có được "ngày bắt đầu tuần" và "ngày kết thúc tuần" từ số tuần trong SQL Server?
- 14. Tìm bắt đầu và kết thúc chỉ số của sublist trong danh sách
- 15. Làm thế nào để có được thành phần RGB của một màu tùy chỉnh trong ios
- 16. Làm thế nào để sử dụng giải cứu trong Ruby mà không có khối bắt đầu và kết thúc
- 17. Làm thế nào để chạy truy vấn Oracle với bắt đầu/kết thúc trong SQL * Plus?
- 18. Làm thế nào để nắm bắt kết quả đầu ra của Shell trong C#?
- 19. làm thế nào để cắt chuỗi địa chỉ IP để có được 3 phần đầu tiên của nó?
- 20. Làm thế nào để có được địa chỉ của std :: vector buffer bắt đầu một cách tao nhã nhất?
- 21. Làm cách nào để chỉ định các phần đầu ra trong các tệp C được biên dịch bằng GCC?
- 22. Vẽ hình elip với góc bắt đầu và kết thúc trong Mục tiêu-C
- 23. Làm cách nào để bạn phát hiện khi hoạt ảnh CSS bắt đầu và kết thúc bằng JavaScript?
- 24. UITableView bắt đầu/kết thúc cập nhật
- 25. Kết hợp Regex bắt đầu và kết thúc chuỗi
- 26. Làm thế nào để bắt đầu hoạt ảnh trong deleteRowsAtIndexPaths
- 27. PHP có ngày bắt đầu và ngày kết thúc của tuần theo số tuần
- 28. Bạn có nên gọi kết thúc() sau khi bắt đầu Hoạt động mới trong Android không?
- 29. cách lấy địa chỉ bắt đầu của cấu trúc từ địa chỉ thành viên
- 30. python regex lấy phần đầu tiên của địa chỉ email
Có thể quan tâm: http://stackoverflow.com/questions/4152018/initialize-global-array-of-function-pointers-at-either-compile-time-or-run-time/4152185# 4152185 –