zoukankan      html  css  js  c++  java
  • 练习使用 __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!
    ", 14);
    }
    
    static void func2(void)
    {
    	write(1, "function two!
    ", 14);
    }
    
    static void func3(void)
    {
    	write(1, "function three!
    ", 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
    ", 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 = .;
    

    然后编译即可:

    gcc -o test -Tdemo.lds test.c
    

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

    运行结果如下:

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

    objdump -d -j .myown test
    

    数据信息如下:

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

    感谢您的浏览!

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

    原文中的代码是

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

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

  • 相关阅读:
    SpringBoot-整合Shiro和JWT时关于JWT部分的内容
    springboot常用注解分类整理
    ubuntu18.04 安装tomcat9
    Ubuntu 18.04 安装Tomcat9 遇到的问题Tomcat9 Error: Could not find or load main class org.apache.catalina.startup.Bootstrap
    Ubuntu 18.04 上安装水下网络仿真器Aqua-Sim NG
    用gorm向mysql插入的时间数据和实际时间不一致问题
    Ubuntu18.04上安装NS-3
    Java集合用法
    Spring Boot 自动装配原理
    深入理解select、poll和epoll及区别
  • 原文地址:https://www.cnblogs.com/GyForever1004/p/10419527.html
Copyright © 2011-2022 走看看