利用gcc的__attribute__編譯屬性section子項構建初始化函數表,gcc__attribute_

來源:互聯網
上載者:User

利用gcc的__attribute__編譯屬性section子項構建初始化函數表,gcc__attribute_

本文轉寄自:https://my.oschina.net/u/180497/blog/177206

它解決宋寶華上次在《C語言的物件導向(面向較大型軟體)》ppt分享和ppt註解中提到的多模組軟體的初始化的問題

gcc的__attribute__編譯屬性有很多子項,用於改變作用對象的特性。這裡討論section子項的作用。

__attribute__的section子項使用方式為:

__attribute__((section("section_name")))

其作用是將作用的函數或資料放入指定名為"section_name"的段。

看以下程式片段:

#include <unistd.h>

#include <stdint.h>

#include <stdio.h>


typedef void (*myown_call)(void);


extern myown_call _myown_start;

extern myown_call _myown_end;


#define _init __attribute__((unused, section(".myown")))

#define func_init(func) myown_call _fn_##func _init = func


static void mspec1(void)

{

        write(1, "aha!\n", 5);

}


static void mspec2(void)

{

        write(1, "aloha!\n", 7);

}


static void mspec3(void)

{

        write(1, "hello!\n", 7);

}


func_init(mspec1);

func_init(mspec2);

func_init(mspec3);


/* exactly like below:

static myown_call mc1  __attribute__((unused, section(".myown"))) = mspec1;

static myown_call mc2  __attribute__((unused, section(".myown"))) = mspec2;

static myown_call mc3  __attribute__((unused, section(".myown"))) = mspec3;

*/


void do_initcalls(void)

{

        myown_call *call_ptr = &_myown_start;

        do {

                fprintf (stderr, "call_ptr: %p\n", call_ptr);

                (*call_ptr)();

                ++call_ptr;

        } while (call_ptr < &_myown_end);


}


int main(void)

{

        do_initcalls();

        return 0;

}


在自訂的.myown段依次填入mspec1/mspec2/mspec3的函數指標,並在do_initcalls中依次調用,從而達到構造並調用初始化函數列表的目的。

兩個extern變數:

extern myown_call _myown_start;

extern myown_call _myown_end;

來自ld的連結指令碼,可以使用:

ld --verbose

擷取內建lds指令碼,並在:


__bss_start = .;

之前添加以下內容:


_myown_start = .;

  .myown           : { *(.myown) } = 0x90000000

  _myown_end = .;

  code_segment    : { *(code_segment) }


即定義了.myown段及_myown_start/_myown_end變數(0x90000000這個數值可能需要調整)。

儲存修改後的連結器指令碼,假設程式為s.c,連結器指令碼儲存為s.lds,使用以下命令編譯:

gcc s.c -Wl,-Ts.lds


執行結果:


[root@localhost ]# ./a.out 

call_ptr: 0x8049768

aha!

call_ptr: 0x804976c

aloha!

call_ptr: 0x8049770

hello!


Have Fun!


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.