__attribute__之ction详解

更新时间:2023-08-03 11:44:10 阅读: 评论:0

__attribute__之ction详解
__attribute__之ction详解
置顶  2019-07-15 12:19:53  9793
分类专栏:
版权
前⾔
第⼀次接触 “ction” 是在公司的⼀个STM32的项⽬代码中,前⼯程师将所有的初始化函数都使⽤的“ction”进⾏设定了属性。当时知道其⽬的,但是不知道原因。然后到后来在接触了Linux的驱动程序的时候,发现linux的驱动注册的宏定义层层解析以后,也是使⽤
的“ction”进⾏修饰,但是当时看教程以为必须限定到内存的特定位置中,以及经验不⾜,所以没有深究。然现在在写Linux应⽤程序的的时候,发现在SDK中也有使⽤“ction”进⾏⼀类程序的修饰,然后我就专门花了⼏个⼩时时间去查阅各种论坛,进⾏了⼀次算还算⽐较深⼊的学习吧。
使⽤ction可以使我们如在初始化函数时,不⽤在主函数中去添加⼀个新的初始化程序,只需要在⾃⼰的函数模块内注册就好了。或者在实现某些命令时,添加或删除该命令的⽀持,会⽅便很多。
使⽤⽅法
"ction"关键字会将被修饰的变量或函数编译到特定的⼀块位置,不是物理存储器上的特定位置,⽽是在可执⾏⽂件的特定段内。在编译好的程序中我们可以使⽤命令:
1. ven@root:~/ction/$ readelf -S a.out
2. There are 37 ction headers, starting at offt 0x201c:
3.
4. Section Headers:
5. [Nr] Name Type Addr Off Size ES Flg Lk Inf Al
6. [ 0] NULL 00000000 000000 000000 00 0 0 0
7. [ 1] .interp PROGBITS 08048154 000154 000013 00 A 0 0 1
8. [ 2] .note.ABI-tag NOTE 08048168 000168 000020 00 A 0 0 4
9. [ 3] .u.build-i NOTE 08048188 000188 000024 00 A 0 0 4
0. [ 4] .gnu.hash GNU_HASH 080481ac 0001ac 00002c 04 A 5 0 4
1. [ 5] .dynsym DYNSYM 080481d8 0001d8 000050 10 A 6 1 4
2. [ 6] .dynstr STRTAB 08048228 000228 00004c 00 A 0 0 1
3. [ 7] .gnu.version VERSYM 08048274 000274 00000a 02 A 5 0 2
4. [ 8] .gnu.version_r VERNEED 08048280 000280 000020 00 A 6 1 4
5. [ 9] .rel.dyn REL 080482a0 0002a0 000018 08 A 5 0 4
6. [10] .init PROGBITS 080482b8 0002b8 000023 00 AX 0 0 4
7. [11] .plt PROGBITS 080482e0 0002e0 000010 04 AX 0 0 16
8. [12] . PROGBITS 080482f0 0002f0 000018 00 AX 0 0 8
9. [13] .text PROGBITS 08048310 000310 000212 00 AX 0 0 16
0. [14] .fini PROGBITS 08048524 000524 000014 00 AX 0 0 4
1. [15] .rodata PROGBITS 08048538 000538 00007f 00 A 0 0 4
2. [16] .eh_frame_hdr PROGBITS 080485b8 0005b8 000044 00 A 0 0 4
3. [17] .eh_frame PROGBITS 080485fc 0005fc 00012c 00 A 0 0 4
4. [18] .init_array INIT_ARRAY 08049f08 000f08 000004 00 WA 0 0 4
5. [19] .fini_array FINI_ARRAY 08049f0c 000f0c 000004 00 WA 0 0 4
6. [20] .jcr PROGBITS 08049f10 000f10 000004 00 WA 0 0 4
7. [21] .dynamic DYNAMIC 08049f14 000f14 0000e0 08 WA 6 0 4
8. [22] .got PROGBITS 08049ff4 000ff4 00000c 04 WA 0 0 4
9. [23] .got.plt PROGBITS 0804a000 001000 00000c 04 WA 0 0 4
0. [24] .data PROGBITS 0804a00c 00100c 000008 00 WA 0 0 4
1. [25] .application_init PROGBITS 0804a014 001014 00000c 00 WA 0 0 4
2. [26] .bss NOBITS 0804a020 001020 000004 00 WA 0 0 1
3. [27] .comment PROGBITS 00000000 001020 000035 01 MS 0 0 1
4. [28] .debug_aranges PROGBITS 00000000 001055 000020 00 0 0 1
5. [29] .debug_info PROGBITS 00000000 001075 000200 00 0 0 1
椰汁西米露的做法
6. [30] .debug_abbrev PROGBITS 00000000 001275 0000e3 00 0 0 1
7. [31] .debug_line PROGBITS 00000000 001358 000079 00 0 0 1
8. [32] .debug_str PROGBITS 00000000 0013d1 0001c9 01 MS 0 0 1
9. [33] .debug_loc PROGBITS 00000000 00159a 0000f1 00 0 0 1
0. [34] .shstrtab STRTAB 00000000 001ebd 00015e 00 0 0 1
1. [35] .symtab SYMTAB 00000000 00168c 000560 10 36 59 4
2. [36] .strtab STRTAB 00000000 001bec 0002d1 00 0 0 1
3. Key to Flags:
4. W (write), A (alloc), X (execute), M (merge), S (strings)
5. I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
黄豆酱蒸鱼6. O (extra OS processing required) o (OS specific), p (processor specific)
如上,可以看到程序被分成了很多的段,其中“.application_init”为稍后步骤中⾃定义的⼀个段。测试源代码如下:
1. #include <stdio.h>
2. #include <string.h>
3.
4. struct _s_application_init {
5. int(*function)(void);
6. };
7.
8. struct _s_application_init _init_start;//段".application_init"的起始地址,在*.lds⽂件中定义
9. struct _s_application_init _init_end;//段".application_init"的末尾地址,在*.lds⽂件中定义
0. #define __app_init_ction __attribute__((ction(".application_init")))
1. #define __application_init(function) \
2. struct _s_application_init _s_a_init_##function __app_init_ction = {function}
13.
14.
5. static int application_init_a(void)
6. {
7. printf("execute funtion : %s\n", __FUNCTION__);
8. return 0;会计核算期
9. }
0. __application_init(application_init_a);
21.
2. static int application_init_b(void)
3. {
4. printf("execute funtion : %s\n", __FUNCTION__);
5. return 0;
6. }
7. __application_init(application_init_b);
情感散文精选28.
9. static int application_init_c(void)
0. {
1. printf("execute funtion : %s\n", __FUNCTION__);貂多少钱一只
2. return 0;
3. }
4. __application_init(application_init_c);
35.
6. int main(int argc, char **argv)
7. {
8. /*
9. * 从段的起始地址开始获取数据,直到末尾地址
0. */
1. struct _s_application_init *pf_init = &_init_start;
2. do {
3. printf("Load init function from address %p\n", pf_init);
4. pf_init->function();
5. ++pf_init;
6. } while (pf_init < &_init_end);
7. return 0;
8. }
然后我们还需要编写lds⽂件,⾸先使⽤命令⽣成默认的⽂件:
1. ven@root:~/ction/$ ld --verbo > main.lds
2. ven@root:~/ction/$ cat main.lds
3. GNU ld (GNU Binutils for Ubuntu) 2.26.1
4. Supported emulations:
5. elf_i386
6. i386linux
7. elf_iamcu
8. elf32_x86_64
9. elf_x86_64
0. elf_l1om
1. elf_k1om
2. i386pep
五指毛桃的作用与功效
3. i386pe
4. using internal linker script:
5. ==================================================
6. /* Script for -z combreloc: combine and sort reloc ctions */
7. /* Copyright (C) 2014-2015 Free Software Foundation, Inc.
8. Copying and distribution of this script, with or without modification,
9. are permitted in any medium without royalty provided the copyright
0. notice and this notice are prerved. */
1. OUTPUT_FORMAT("elf32-i386", "elf32-i386",
2. "elf32-i386")
3. OUTPUT_ARCH(i386)
4. ENTRY(_start)
家访照片
5. SEARCH_DIR("=/usr/local/lib/i386-linux-gnu"); SEARCH_DIR("=/lib/i386-linux-gnu"); SEARCH_DIR("=/usr/lib/i386-linux-gnu");
SEARCH_DIR("=/usr/local/lib32"); SEARCH_DIR("=/lib32"); SEARCH_DIR("=/usr/lib32"); SEARCH_DIR("=/usr/local/lib");
SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib"); SEARCH_DIR("=/usr/i686-linux-gnu/lib32"); SEARCH_DIR("=/usr/i686-linux-gnu/lib");
6. SECTIONS
7. {
8. /* Read-only ctions, merged into text gment: */
9. PROVIDE (__executable_start = SEGMENT_START("text-gment", 0x08048000)); . = SEGMENT_START("text-gment",
0x08048000) + SIZEOF_HEADERS;
0. .interp : { *(.interp) }
1. .u.build-id : { *(.u.build-id) }
2. .hash : { *(.hash) }
3. .gnu.hash : { *(.gnu.hash) }
4. .dynsym : { *(.dynsym) }
5. .dynstr : { *(.dynstr) }
6. .gnu.version : { *(.gnu.version) }
7. .gnu.version_d : { *(.gnu.version_d) }
8. .gnu.version_r : { *(.gnu.version_r) }
9. .rel.dyn :
0. {
1. *(.rel.init)
2. *(. .* .*)
3. *(.rel.fini)
4. *(.data .data.* .*)
5. *(.l.ro .l.ro.* .u.l.ro.*)
6. *(.rel.data .rel.data.* .u.linkonce.d.*)
7. *(.rel.tdata .rel.tdata.* .u.linkonce.td.*)
8. *(.rel.tbss .rel.tbss.* .u.linkonce.tb.*)
9. *(.s)
>大熊猫的生活习性

本文发布于:2023-08-03 11:44:10,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1106518.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:程序   位置   定义   命令   函数   注册   发现   地址
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图