转自:https://my.oschina.net/u/180497/blog/177206

  1. gcc__attribute__编译属性有很多子项,用于改变作用对象的特性。这里讨论section子项的作用。
  2.  
  3. __attribute__section子项使用方式为:
  4.  
  5. __attribute__((section("section_name")))
  6.  
  7. 其作用是将作用的函数或数据放入指定名为"section_name"的段。
  8.  
  9. 看以下程序片段:
  10.  
  11. #include <unistd.h>
  12. #include <stdint.h>
  13. #include <stdio.h>
  14.  
  15. typedef void (*myown_call)(void);
  16.  
  17. extern myown_call _myown_start;
  18. extern myown_call _myown_end;
  19.  
  20. #define _init __attribute__((unused, section(".myown")))
  21. #define func_init(func) myown_call _fn_##func _init = func
  22.  
  23. static void mspec1(void)
  24. {
  25. write(, "aha!\n", );
  26. }
  27.  
  28. static void mspec2(void)
  29. {
  30. write(, "aloha!\n", );
  31. }
  32.  
  33. static void mspec3(void)
  34. {
  35. write(, "hello!\n", );
  36. }
  37.  
  38. func_init(mspec1);
  39. func_init(mspec2);
  40. func_init(mspec3);
  41.  
  42. /* exactly like below:
  43. static myown_call mc1 __attribute__((unused, section(".myown"))) = mspec1;
  44. static myown_call mc2 __attribute__((unused, section(".myown"))) = mspec2;
  45. static myown_call mc3 __attribute__((unused, section(".myown"))) = mspec3;
  46. */
  47.  
  48. void do_initcalls(void)
  49. {
  50. myown_call *call_ptr = &_myown_start;
  51. do {
  52. fprintf (stderr, "call_ptr: %p\n", call_ptr);
  53. (*call_ptr)();
  54. ++call_ptr;
  55. } while (call_ptr < &_myown_end);
  56.  
  57. }
  58.  
  59. int main(void)
  60. {
  61. do_initcalls();
  62. return ;
  63. }
  64.  
  65. 在自定义的.myown段依次填入mspec1/mspec2/mspec3的函数指针,并在do_initcalls中依次调用,从而达到构造并调用初始化函数列表的目的。
  66.  
  67. 两个extern变量:
  68.  
  69. extern myown_call _myown_start;
  70. extern myown_call _myown_end;
  71.  
  72. 来自ld的链接脚本,可以使用:
  73.  
  74. ld --verbose
  75.  
  76. 获取内置lds脚本,并在:
  77.  
  78. __bss_start = .;
  79.  
  80. 之前添加以下内容:
  81.  
  82. _myown_start = .;
  83. .myown : { *(.myown) } = 0x90000000
  84. _myown_end = .;
  85. code_segment : { *(code_segment) }
  86.  
  87. 即定义了.myown段及_myown_start/_myown_end变量(0x90000000这个数值可能需要调整)。
  88.  
  89. 保存修改后的链接器脚本,假设程序为s.c,链接器脚本保存为s.lds,使用以下命令编译:
  90.  
  91. gcc s.c -Wl,-Ts.lds
  92.  
  93. 执行结果:
  94.  
  95. [root@localhost ]# ./a.out
  96. call_ptr: 0x8049768
  97. aha!
  98. call_ptr: 0x804976c
  99. aloha!
  100. call_ptr: 0x8049770
  101. hello!
  102.  
  103. Have Fun!
  104. © 著作权归作者所有

利用gcc的__attribute__编译属性section子项构建初始化函数表【转】的更多相关文章

  1. 利用gcc的__attribute__编译属性section子项构建初始化函数表

    参考链接 :    https://my.oschina.net/u/180497/blog/177206

  2. 利用__attribute__((section()))构建初始化函数表【转】

    转自: https://mp.weixin.qq.com/s?__biz=MzAwMDUwNDgxOA==&mid=2652663356&idx=1&sn=7797629530 ...

  3. 廖威雄: 思维导图:利用__attribute__((section()))构建初始化函数表与Linux内核init的实现

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/juS3Ve/article/details/79049404 本文具体解说了利用__attribut ...

  4. GCC的__attribute__ ((constructor))和__attribute__ ((destructor))

    通过一个简单的例子介绍一下gcc的__attribute__ ((constructor))属性的作用.gcc允许为函数设置__attribute__ ((constructor))和__attrib ...

  5. [转]GCC系列: __attribute__((visibility("")))

    在 objc-api.h 里面有很多关于__attribute__ 的定义. 例如 #if !defined(OBJC_VISIBLE) # if TARGET_OS_WIN32 # if defin ...

  6. 利用GCC编译器生成动态链接库和静态链接库

    转载请标明:http://www.cnblogs.com/winifred-tang94/ 1.编译过程 gcc –fPIC –c xxx.c 其中-fPIC是通知gcc编译器产生位置独立的目标代码. ...

  7. 利用@property实现可控的属性操作

    利用@property实现可控的属性操作 Python中没有访问控制符, 不像java之类的 public class Person{ private int x public int getAge( ...

  8. gcc与makefile编译 BY 四喜三顺

    gcc编译控制过程:(假设源代码为a.c)(1)源文件到预处理文件:    gcc -E -o a.cxx a.c    a.cxx显示调用哪些头文件(2)生成汇编代码:              g ...

  9. java利用反射获取类的属性及类型

    java利用反射获取类的属性及类型. import java.lang.reflect.Field; import java.math.BigDecimal; import java.util.Map ...

随机推荐

  1. 【前端】JS截取字符串常用方法详细整理

    函数:split() 功能:使用一个指定的分隔符把一个字符串分割存储到数组 例子: str=”jpg|bmp|gif|ico|png”; arr=theString.split(”|”); //arr ...

  2. 使用Xpath定位元素

    1.xpath较复杂的定位方法: 现在要引用id为“J_password”的input元素,可以像下面这样写: WebElement password = driver.findElement(By. ...

  3. (转)Java GC基本算法

    http://blog.csdn.net/heyutao007/article/details/38151581 1.引用计数(reference counting)    原理:此对象有一个引用,则 ...

  4. 【BZOJ1143】祭祀(网络流)

    [BZOJ1143]祭祀(网络流) 题面 BZOJ 洛谷 Description 在遥远的东方,有一个神秘的民族,自称Y族.他们世代居住在水面上,奉龙王为神.每逢重大庆典, Y族都 会在水面上举办盛大 ...

  5. bzoj2956: 模积和(数论)

    先算出无限制的情况,再减去i==j的情况. 无限制的情况很好算,有限制的情况需要将式子拆开. 注意最后的地方要用平方和公式,模数+1是6的倍数,于是逆元就是(模数+1)/6 #include<i ...

  6. python基础----文件处理

    一.文件处理流程 打开文件,得到文件句柄并赋值给一个变量 通过句柄对文件进行操作 关闭文件 正趣果上果 Interesting fruit fruit 词:郭婞 曲:陈粒 编曲/混音/和声:燕池 萧: ...

  7. python 之 strip()--(转载)

    原博地址:http://www.jb51.net/article/37287.htm 函数原型 声明:s为字符串,rm为要删除的字符序列 s.strip(rm)        删除s字符串中开头.结尾 ...

  8. 树莓派apt-get下载网速太慢

    因为学校有ipv6的原因,当我想用ipv4的时候用apt-get发现特别慢.找了很久终于找到了解决方案: Add -o Acquire::ForceIPv4=true when running apt ...

  9. signal和sigaction 分析

    1:signal 函数 原型: sighandler_t signal(int signum, sighandler_t handler)      typedef void (*sighandler ...

  10. 1.Android JUnit Runner(使用AndroidStudio)

    一.Android JUnit Runner介绍 1.Android JUnit Runner 1)是一个测试运行器,用于运行Junit3和Junit4的Android测试包 2)替换Instrume ...