天天看點

__attribute__前言__attribute__介紹參考

前言

本文介紹__attribute__ 的使用方法

__attribute__介紹

要了解Linux Kernel代碼的分段資訊,需要了解一下gcc的__attribute__的編繹屬性,__attribute__主要用于改變所聲明或定義的函數或 資料的特性,它有很多子項,用于改變作用對象的特性。比如對函數,noline将禁止進行内聯擴充、noreturn表示沒有傳回值、pure表明函數除 傳回值外,不會通過其它(如全局變量、指針)對函數外部産生任何影響。

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

section

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

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

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

輸入段和輸出段是相對于要生成最終的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);

           

注意事項

在.init_array或者constructor中使内聯彙編彙編的時候,需要使用pusha和popa指令儲存指令上下文,不否會報錯

參考

attribute 用法 section 部分

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

繼續閱讀