利用gcc的__attribute__编译属性section子项构建初始化函数表【转】
转自:https://my.oschina.net/u/180497/blog/177206
- 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(, "aha!\n", );
- }
- static void mspec2(void)
- {
- write(, "aloha!\n", );
- }
- static void mspec3(void)
- {
- write(, "hello!\n", );
- }
- 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 ;
- }
- 在自定义的.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!
- © 著作权归作者所有
利用gcc的__attribute__编译属性section子项构建初始化函数表【转】的更多相关文章
- 利用gcc的__attribute__编译属性section子项构建初始化函数表
参考链接 : https://my.oschina.net/u/180497/blog/177206
- 利用__attribute__((section()))构建初始化函数表【转】
转自: https://mp.weixin.qq.com/s?__biz=MzAwMDUwNDgxOA==&mid=2652663356&idx=1&sn=7797629530 ...
- 廖威雄: 思维导图:利用__attribute__((section()))构建初始化函数表与Linux内核init的实现
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/juS3Ve/article/details/79049404 本文具体解说了利用__attribut ...
- GCC的__attribute__ ((constructor))和__attribute__ ((destructor))
通过一个简单的例子介绍一下gcc的__attribute__ ((constructor))属性的作用.gcc允许为函数设置__attribute__ ((constructor))和__attrib ...
- [转]GCC系列: __attribute__((visibility("")))
在 objc-api.h 里面有很多关于__attribute__ 的定义. 例如 #if !defined(OBJC_VISIBLE) # if TARGET_OS_WIN32 # if defin ...
- 利用GCC编译器生成动态链接库和静态链接库
转载请标明:http://www.cnblogs.com/winifred-tang94/ 1.编译过程 gcc –fPIC –c xxx.c 其中-fPIC是通知gcc编译器产生位置独立的目标代码. ...
- 利用@property实现可控的属性操作
利用@property实现可控的属性操作 Python中没有访问控制符, 不像java之类的 public class Person{ private int x public int getAge( ...
- gcc与makefile编译 BY 四喜三顺
gcc编译控制过程:(假设源代码为a.c)(1)源文件到预处理文件: gcc -E -o a.cxx a.c a.cxx显示调用哪些头文件(2)生成汇编代码: g ...
- java利用反射获取类的属性及类型
java利用反射获取类的属性及类型. import java.lang.reflect.Field; import java.math.BigDecimal; import java.util.Map ...
随机推荐
- 【前端】JS截取字符串常用方法详细整理
函数:split() 功能:使用一个指定的分隔符把一个字符串分割存储到数组 例子: str=”jpg|bmp|gif|ico|png”; arr=theString.split(”|”); //arr ...
- 使用Xpath定位元素
1.xpath较复杂的定位方法: 现在要引用id为“J_password”的input元素,可以像下面这样写: WebElement password = driver.findElement(By. ...
- (转)Java GC基本算法
http://blog.csdn.net/heyutao007/article/details/38151581 1.引用计数(reference counting) 原理:此对象有一个引用,则 ...
- 【BZOJ1143】祭祀(网络流)
[BZOJ1143]祭祀(网络流) 题面 BZOJ 洛谷 Description 在遥远的东方,有一个神秘的民族,自称Y族.他们世代居住在水面上,奉龙王为神.每逢重大庆典, Y族都 会在水面上举办盛大 ...
- bzoj2956: 模积和(数论)
先算出无限制的情况,再减去i==j的情况. 无限制的情况很好算,有限制的情况需要将式子拆开. 注意最后的地方要用平方和公式,模数+1是6的倍数,于是逆元就是(模数+1)/6 #include<i ...
- python基础----文件处理
一.文件处理流程 打开文件,得到文件句柄并赋值给一个变量 通过句柄对文件进行操作 关闭文件 正趣果上果 Interesting fruit fruit 词:郭婞 曲:陈粒 编曲/混音/和声:燕池 萧: ...
- python 之 strip()--(转载)
原博地址:http://www.jb51.net/article/37287.htm 函数原型 声明:s为字符串,rm为要删除的字符序列 s.strip(rm) 删除s字符串中开头.结尾 ...
- 树莓派apt-get下载网速太慢
因为学校有ipv6的原因,当我想用ipv4的时候用apt-get发现特别慢.找了很久终于找到了解决方案: Add -o Acquire::ForceIPv4=true when running apt ...
- signal和sigaction 分析
1:signal 函数 原型: sighandler_t signal(int signum, sighandler_t handler) typedef void (*sighandler ...
- 1.Android JUnit Runner(使用AndroidStudio)
一.Android JUnit Runner介绍 1.Android JUnit Runner 1)是一个测试运行器,用于运行Junit3和Junit4的Android测试包 2)替换Instrume ...