How do you get the start and end addresses of a custom ELF section?

前端 未结 5 583
粉色の甜心
粉色の甜心 2020-12-05 02:57

I\'m working in C on Linux. I\'ve seen the usage of of the gcc __section__ attribute (especially in the Linux kernel) to collect data (usually function pointers) into custom

5条回答
  •  醉酒成梦
    2020-12-05 03:52

    Collecting the information together from various answers, here is a working example of how to collect information into a custom linker section and then read the information from that section using the magic variables __start_SECTION and __stop_SECTION in your C program, where SECTION is the name of the section in the link map.

    The __start_SECTION and __stop_SECTION variables are made available by the linker so explicit extern references need to be created for these variables when they are used from C code.

    There are also some problems if the alignment used by the compiler for calculating pointer/array offsets is different than the alignment of the objects packed in each section by the linker. One solution (used in this example) is to store only a pointer to the data in the linker section.

    #include 
    
    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;
    }
    

提交回复
热议问题