练习使用 __attribute__ 属性(仿照内核)

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

源代码如下:
#include <unistd.h>
#include <stdint.h>
#include <stdio.h>

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 = .;

1319058-20190222171031604-1082195074.png

然后编译即可:

gcc -o test -Tdemo.lds test.c

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

运行结果如下:

1319058-20190222171042745-3257463.png

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

objdump -d -j .myown test

数据信息如下:

1319058-20190222171053802-1241486228.png

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

感谢您的浏览!

参考网友:my.oschina.net/u/180497/blog/177206

原文中的代码是

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

后面的 0x90000000 真心不知道是什么意思,哪位网友帮忙解读下,谢谢。

转载于:https://www.cnblogs.com/GyForever1004/p/10419527.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值