linux内核之_attribute_,练习使用 __attribute__ 属性(仿照内核)

上一篇文章分析了内核中各种 initcall 的调用过程,在这个基础上大概掌握了内核中使用的这种方法,于是参考内核及网友的文章自己动手写了下,记录在这个随笔中。

源代码如下:

#include

#include

#include

typedef void (*myown_call)(void);

/* 引用 LDS 文件中的标识 */

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 func1(void)

{

write(1, "function one!\n", 14);

}

static void func2(void)

{

write(1, "function two!\n", 14);

}

static void func3(void)

{

write(1, "function three!\n", 16);

}

/* 定义函数函数指针 */

func_init(func1);

func_init(func2);

func_init(func3);

/* 定义的展开:

static myown_call _fn_func1 __attribute__((unused, section(".myown"))) = func1;

*/

/* 依次调用段内的函数 */

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;

}

其中 __attribute__((unused)) 表示该函数或变量可能不使用,这个属性可以避免编译器产生警告信息。

OK,源代码如上所示,接下来就要编译。

我们需要修改默认的 LDS 文件,通过

ld -verbose > demo.lds

命令导出链接器脚本文件。

修改 LDS,添加如下代码:

_myown_start = .;

.myown : { *(.myown) }

_myown_end = .;

aaff5171db4c0d201a97f28586447513.png

然后编译即可:

gcc -o test -Tdemo.lds test.c

成功生成 test 可执行文件后运行。

运行结果如下:

008bec5b1afc5df3c0e2f7ba7fb2f080.png

我们也可以能过如下命令来查看自定义段内的数据信息:

objdump -d -j .myown test

数据信息如下:

3df9d694597df13e1c66a8e3412c3eba.png

OK,这篇文章到此结束,成功仿照内核完成了函数的调用。其实这也或许是在练习 C 语言中 attribute 属性的用法。

感谢您的浏览!

0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值