__attribute__

youngseaz發表於2020-11-12

前言

本文介紹__attribute__ 的使用方法

__attribute__介紹

要了解Linux Kernel程式碼的分段資訊,需要了解一下gcc的__attribute__的編繹屬性,__attribute__主要用於改變所宣告或定義的函式或 資料的特性,它有很多子項,用於改變作用物件的特性。比如對函式,noline將禁止進行內聯擴充套件、noreturn表示沒有返回值、pure表明函式除 返回值外,不會通過其它(如全域性變數、指標)對函式外部產生任何影響。

子項描述
section將變數(整數變數、字串和函式等)放入指定的節區段

section

子項section對程式碼段起作用。其作用是將作用的函式或資料放入指定名為"section_name"輸入段。

__attribute__的section子項的使用格式為:

__attribute__((section("section_name")))

這裡還要注意一下兩個概念:輸入段和輸出段

輸入段和輸出段是相對於要生成最終的elf或binary時的連結過程說的

輸入段
連結過程的輸入大都是由原始碼編繹生成的目標檔案.o,那麼這些.o 檔案中包含的段相對連結過程來說就是輸入段
輸出段
連結過程的輸出一般是可執行檔案elf或庫等,這些輸出檔案中也包含有段,這些輸出檔案中的段就叫做輸出段。

輸入段和輸出段本來沒有什麼必然的聯絡,是互相獨立,只是在連結過程中,Link程式會根據一定的規則(這些規則來源於Link Script),將不同的輸入段重新組合到不同的輸出段中,即使是段的名字,輸入段和輸出段可以完全不同。

使用方法實踐

  • 將整型變數var存放到.text段
    int var __attribute__((section(".text"))) = 0;

  • 將字串str存放到.data段
    char str[] __attribute__((section(".data"))) = "hello world";

  • 將函式存放到.mysection段(這個是自定義的段)

void __attribute__((section(".mysection"))) myfunc()
{
	printf("ohhh!");
}

-------------------------------------

typedef void (*funcptr)();
funcptr func  __attribute__((section(".mysection"))) = myfunc;
void myfunc()
{
	printf("ohhh!");
}

---------------------------------------------

typedef void (*funcptr)();
#define init __attribute__((section(".mysection")))
#define init_func(func) funcptr _fn_##func init=func

void myfunc()
{
	printf("ohhh!");
}
init_func(myfunc);

參考

attribute 用法 section 部分
gcc attribute((section(“section_name”))) 使用方法