簡體   English   中英

如何獲得自定義ELF部分的起始和結束地址?

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

我在Linux上使用C語言。 我已經看到使用gcc __section__屬性 (特別是在Linux內核中)將數據(通常是函數指針)收集到自定義ELF部分中。 如何檢索和使用這些自定義部分中的“東西”?

只要節名稱產生有效的C變量名稱, gccld ,而不是)就會生成兩個魔術變量: __start_SECTION__stop_SECTION 這些可用於檢索節的開始和結束地址,如下所示:

/**
 * 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 */
}

我找不到任何關於此功能的正式文檔,只有一些不明確的郵件列表引用。 如果您知道文檔的位置,請發表評論!

如果你使用自己的鏈接器腳本(就像Linux內核那樣),你必須自己添加魔術變量(參見vmlinux.lds.[Sh]這個SO答案 )。

有關使用自定義ELF節的另一個示例,請參見此處

從各種答案中收集信息,這里是一個工作示例,說明如何將信息收集到自定義鏈接器部分,然后使用C程序中的魔術變量__start_SECTION__stop_SECTION從該部分讀取信息,其中SECTION是鏈接圖中的部分。

鏈接器可以使用__start_SECTION__stop_SECTION變量,因此在從C代碼中使用這些變量時,需要為這些變量創建顯式的extern引用。

如果編譯器用於計算指針/數組偏移的對齊不同於鏈接器在每個部分中打包的對象的對齊,則還存在一些問題。 一個解決方案(在此示例中使用)是僅存儲指向鏈接器部分中的數據的指針。

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

鏈接器可以使用代碼中定義的符號,如果在鏈接描述文件中使用確切的名稱,則可以分配它們的初始值:

_smysection = .;
*(.mysection)
*(.mysection*)
_emysection = .;

只需在C代碼中定義一個變量:

const void * _smysection;

然后您可以將其作為常規變量進行訪問。

u32 someVar = (u32)&_smysection;

所以上面的答案, __start_SECTION__stop_SECTION將起作用,但是為了使程序能夠使用鏈接器中的信息,您需要將這些變量聲明為extern char* __start_SECTION 請享用!

extern char * __start_blobby;

...
printf("This section starts at %p\n", (unsigned int)&__start_blobby);
...

HI:喜歡這個。

extern const struct pseudo_ta_head __start_ta_head_section;
extern const struct pseudo_ta_head __stop_ta_head_section;    

const struct pseudo_ta_head *start = &__start_ta_head_section;
const struct pseudo_ta_head *end = &__stop_ta_head_section;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM