通过这个gcc提供的扩展机制,可以将特定的变量存放在自定义的段中。如下面的程序中,将t11、t12、t13放置在st1段中,并对t11、t13进行了初始化,将t2放置在st2段中,将t3放置在st3段中。
验证这些部分,可以使用下面例子提供的objdump命令,在操作过程中,注意objdump的参数和st1段中三个变量的位置和初始值的保存。
从下面的示例代码中可以发现,此时__attribute__修饰符的位置,对最终的目标文件来说,没有影响。
但是,自定义段中是否可以存放其他类型的数据,另外,若可以存放其他类型的数据,这个自定义段的长度是通过什么方法获得的?这两点还需要后续深入研究。但是,就目前情况来看,这两个问题不会困扰后面的代码分析。
1 #include <stdio.h>
2
3 struct test {
4 int a;
5 int b;
6 };
7
8 struct test t11 __attribute__((section(" st1"))) = {
9 .a = 0x00112233,
10 .b = 0xffeeddcc
11 };
12 struct test t12 __attribute__((section(" st1")));
13 struct test t13 __attribute__((section(" st1"))) = {
14 . a = 0x01234567,
15 .b = 0xfedcba98
16 };
17
18 struct test __attribute__((section("st2"))) t2;
19
20 __attribute__((section("st3"))) struct test t3;
21
22 extern struct test __start_st1;
23 extern struct test __stop_st1;
24
25 int main()
26 {
27 t11.a = 11; t11.b = 12;
28 t2.a = 21; t2.b = 22;
29 t3.a = 31; t3.b = 32;
30 int i = 0;
31 printf("__startt11: %p\n", &__start_st1);
32 printf("__stopt11: %p\n", &__stop_st1);
33 printf("size: %d\n", abs((long)& __start_st1- (long)& __stop_st1));
34
35 printf("t1.a:%d, t1.b: %d\n", t11.a, t11.b);
36 printf("t2.a:%d, t2.b: %d\n", t2.a, t2.b);
37 printf("t3.a:%d, t3.b: %d\n", t3.a, t3.b);
38 return 0;
39 }
$ gcc test_section.c
$ objdump -h a.out
a.out: file format elf64-x86-64
Sections:
Idx Name Size VMA LMA File off Algn
0 .interp 0000001c 0000000000400200 0000000000400200 00000200 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .note.ABI-tag 00000020 000000000040021c 000000000040021c 0000021c 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .note.gnu.build-id 00000024 000000000040023c 000000000040023c 0000023c 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .gnu.hash 0000001c 0000000000400260 0000000000400260 00000260 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .dynsym 00000060 0000000000400280 0000000000400280 00000280 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
5 .dynstr 0000003f 00000000004002e0 00000000004002e0 000002e0 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
6 .gnu.version 00000008 0000000000400320 0000000000400320 00000320 2**1
CONTENTS, ALLOC, LOAD, READONLY, DATA
7 .gnu.version_r 00000020 0000000000400328 0000000000400328 00000328 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
8 .rela.dyn 00000018 0000000000400348 0000000000400348 00000348 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
9 .rela.plt 00000030 0000000000400360 0000000000400360 00000360 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
10 .init 00000018 0000000000400390 0000000000400390 00000390 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
11 .plt 00000030 00000000004003a8 00000000004003a8 000003a8 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
12 .text 00000268 00000000004003e0 00000000004003e0 000003e0 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
13 .fini 0000000e 0000000000400648 0000000000400648 00000648 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
14 .rodata 00000049 0000000000400658 0000000000400658 00000658 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
15 .eh_frame_hdr 00000024 00000000004006a4 00000000004006a4 000006a4 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
16 .eh_frame 0000007c 00000000004006c8 00000000004006c8 000006c8 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
17 .ctors 00000010 0000000000600748 0000000000600748 00000748 2**3
CONTENTS, ALLOC, LOAD, DATA
18 .dtors 00000010 0000000000600758 0000000000600758 00000758 2**3
CONTENTS, ALLOC, LOAD, DATA
19 .jcr 00000008 0000000000600768 0000000000600768 00000768 2**3
CONTENTS, ALLOC, LOAD, DATA
20 .dynamic 00000190 0000000000600770 0000000000600770 00000770 2**3
CONTENTS, ALLOC, LOAD, DATA
21 .got 00000008 0000000000600900 0000000000600900 00000900 2**3
CONTENTS, ALLOC, LOAD, DATA
22 .got.plt 00000028 0000000000600908 0000000000600908 00000908 2**3
CONTENTS, ALLOC, LOAD, DATA
23 .data 00000004 0000000000600930 0000000000600930 00000930 2**2
CONTENTS, ALLOC, LOAD, DATA
24 st1 00000018 0000000000600934 0000000000600934 00000934 2**2
CONTENTS, ALLOC, LOAD, DATA
25 st2 00000008 000000000060094c 000000000060094c 0000094c 2**2
CONTENTS, ALLOC, LOAD, DATA
26 st3 00000008 0000000000600954 0000000000600954 00000954 2**2
CONTENTS, ALLOC, LOAD, DATA
27 .bss 00000010 0000000000600960 0000000000600960 0000095c 2**3
ALLOC
28 .comment 00000058 0000000000000000 0000000000000000 0000095c 2**0
CONTENTS, READONLY
$ objdump -d -s a.out
a.out: file format elf64-x86-64
Contents of section .interp:
400200 2f6c6962 36342f6c 642d6c69 6e75782d /lib64/ld-linux-
400210 7838362d 36342e73 6f2e3200 x86-64.so.2.
Contents of section .note.ABI-tag:
40021c 04000000 10000000 01000000 474e5500 ............GNU.
40022c 00000000 02000000 06000000 12000000 ................
……
Contents of section .data:
600930 00000000 ....
Contents of section st1:
600934 33221100 ccddeeff 00000000 00000000 3"..............
600944 67452301 98badcfe gE#.....
Contents of section st2:
60094c 00000000 00000000 ........
Contents of section st3:
600954 00000000 00000000 ........
Contents of section .comment:
0000 4743433a 2028474e 55292034 2e342e36 GCC: (GNU) 4.4.6
0010 20323031 32303330 35202852 65642048 20120305 (Red H
0020 61742034 2e342e36 2d342900 4743433a at 4.4.6-4).GCC:
0030 2028474e 55292034 2e342e37 20323031 (GNU) 4.4.7 201
0040 32303331 33202852 65642048 61742034 20313 (Red Hat 4
0050 2e342e37 2d332900 .4.7-3).
Disassembly of section .init:
0000000000400390 <_init>:
400390: 48 83 ec 08 sub $0x8,%rsp
400394: e8 73 00 00 00 callq 40040c <call_gmon_start>
400399: e8 02 01 00 00 callq 4004a0 <frame_dummy>
40039e: e8 6d 02 00 00 callq 400610 <__do_global_ctors_aux>
4003a3: 48 83 c4 08 add $0x8,%rsp
4003a7: c3 retq
……
400647: 90 nop
Disassembly of section .fini:
0000000000400648 <_fini>:
400648: 48 83 ec 08 sub $0x8,%rsp
40064c: e8 df fd ff ff callq 400430 <__do_global_dtors_aux>
400651: 48 83 c4 08 add $0x8,%rsp
400655: c3 retq
$ objdump --section=st1 -s -d a.out
a.out: file format elf64-x86-64
Contents of section st1:
600934 33221100 ccddeeff 00000000 00000000 3"..............
600944 67452301 98badcfe gE#.....
Disassembly of section st1:
0000000000600934 < t11>:
600934: 33 22 11 00 cc dd ee ff 3"......
000000000060093c < t12>:
...
0000000000600944 < t13>:
600944: 67 45 23 01 98 ba dc fe gE#.....
$ ./a.out
__startt11: 0x6009cc
__stopt11: 0x6009e4
size: 24
t1.a:11, t1.b: 12
t2.a:21, t2.b: 22
t3.a:31, t3.b: 32
$
验证这些部分,可以使用下面例子提供的objdump命令,在操作过程中,注意objdump的参数和st1段中三个变量的位置和初始值的保存。
现将该段测试使用的objdump的参数及含义整理如下:
objdump的参数 | 作用 |
-h | 显示段表 |
-d | 对包含机器指令的段进行反汇编 |
-s | 显示文件的所有内容 |
--section=NAME | 仅显示指定段的信息 |
对于自定义段的使用方法,可以参见下面的代码,实在没有找到具有针对性质的相关材料,就个人理解对下面的代码进行解释一下。
line 8、line 12、line 13将t11、t12和t13放置在了st1段中,通过后面的objdump的输出可以看出来。line 22引用了外部的针对段st1的开始处的结构体,line 23声明了段st1的结束位置,从这两行的代码可以猜测出,在设置段的区域,“__start_”字符串开始并且紧接着是目标段名(如这个示例中的段名称为st1,则st1段开始的变量为__start_st1)的变量记录了目标段的开始位置,“__stop_”字符串开始的变量记录了目标段的结束位置(对于本例,__stop_st1指向的地址是st1段后的第一个非本段的地址,即st2段的起始地址),它们之间的差值,就是当前段的长度。从下面的示例代码中可以发现,此时__attribute__修饰符的位置,对最终的目标文件来说,没有影响。
但是,自定义段中是否可以存放其他类型的数据,另外,若可以存放其他类型的数据,这个自定义段的长度是通过什么方法获得的?这两点还需要后续深入研究。但是,就目前情况来看,这两个问题不会困扰后面的代码分析。
1 #include <stdio.h>
2
3 struct test {
4 int a;
5 int b;
6 };
7
8 struct test t11 __attribute__((section(" st1"))) = {
9 .a = 0x00112233,
10 .b = 0xffeeddcc
11 };
12 struct test t12 __attribute__((section(" st1")));
13 struct test t13 __attribute__((section(" st1"))) = {
14 . a = 0x01234567,
15 .b = 0xfedcba98
16 };
17
18 struct test __attribute__((section("st2"))) t2;
19
20 __attribute__((section("st3"))) struct test t3;
21
22 extern struct test __start_st1;
23 extern struct test __stop_st1;
24
25 int main()
26 {
27 t11.a = 11; t11.b = 12;
28 t2.a = 21; t2.b = 22;
29 t3.a = 31; t3.b = 32;
30 int i = 0;
31 printf("__startt11: %p\n", &__start_st1);
32 printf("__stopt11: %p\n", &__stop_st1);
33 printf("size: %d\n", abs((long)& __start_st1- (long)& __stop_st1));
34
35 printf("t1.a:%d, t1.b: %d\n", t11.a, t11.b);
36 printf("t2.a:%d, t2.b: %d\n", t2.a, t2.b);
37 printf("t3.a:%d, t3.b: %d\n", t3.a, t3.b);
38 return 0;
39 }
$ gcc test_section.c
$ objdump -h a.out
a.out: file format elf64-x86-64
Sections:
Idx Name Size VMA LMA File off Algn
0 .interp 0000001c 0000000000400200 0000000000400200 00000200 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .note.ABI-tag 00000020 000000000040021c 000000000040021c 0000021c 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .note.gnu.build-id 00000024 000000000040023c 000000000040023c 0000023c 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .gnu.hash 0000001c 0000000000400260 0000000000400260 00000260 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .dynsym 00000060 0000000000400280 0000000000400280 00000280 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
5 .dynstr 0000003f 00000000004002e0 00000000004002e0 000002e0 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
6 .gnu.version 00000008 0000000000400320 0000000000400320 00000320 2**1
CONTENTS, ALLOC, LOAD, READONLY, DATA
7 .gnu.version_r 00000020 0000000000400328 0000000000400328 00000328 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
8 .rela.dyn 00000018 0000000000400348 0000000000400348 00000348 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
9 .rela.plt 00000030 0000000000400360 0000000000400360 00000360 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
10 .init 00000018 0000000000400390 0000000000400390 00000390 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
11 .plt 00000030 00000000004003a8 00000000004003a8 000003a8 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
12 .text 00000268 00000000004003e0 00000000004003e0 000003e0 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
13 .fini 0000000e 0000000000400648 0000000000400648 00000648 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
14 .rodata 00000049 0000000000400658 0000000000400658 00000658 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
15 .eh_frame_hdr 00000024 00000000004006a4 00000000004006a4 000006a4 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
16 .eh_frame 0000007c 00000000004006c8 00000000004006c8 000006c8 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
17 .ctors 00000010 0000000000600748 0000000000600748 00000748 2**3
CONTENTS, ALLOC, LOAD, DATA
18 .dtors 00000010 0000000000600758 0000000000600758 00000758 2**3
CONTENTS, ALLOC, LOAD, DATA
19 .jcr 00000008 0000000000600768 0000000000600768 00000768 2**3
CONTENTS, ALLOC, LOAD, DATA
20 .dynamic 00000190 0000000000600770 0000000000600770 00000770 2**3
CONTENTS, ALLOC, LOAD, DATA
21 .got 00000008 0000000000600900 0000000000600900 00000900 2**3
CONTENTS, ALLOC, LOAD, DATA
22 .got.plt 00000028 0000000000600908 0000000000600908 00000908 2**3
CONTENTS, ALLOC, LOAD, DATA
23 .data 00000004 0000000000600930 0000000000600930 00000930 2**2
CONTENTS, ALLOC, LOAD, DATA
24 st1 00000018 0000000000600934 0000000000600934 00000934 2**2
CONTENTS, ALLOC, LOAD, DATA
25 st2 00000008 000000000060094c 000000000060094c 0000094c 2**2
CONTENTS, ALLOC, LOAD, DATA
26 st3 00000008 0000000000600954 0000000000600954 00000954 2**2
CONTENTS, ALLOC, LOAD, DATA
27 .bss 00000010 0000000000600960 0000000000600960 0000095c 2**3
ALLOC
28 .comment 00000058 0000000000000000 0000000000000000 0000095c 2**0
CONTENTS, READONLY
$ objdump -d -s a.out
a.out: file format elf64-x86-64
Contents of section .interp:
400200 2f6c6962 36342f6c 642d6c69 6e75782d /lib64/ld-linux-
400210 7838362d 36342e73 6f2e3200 x86-64.so.2.
Contents of section .note.ABI-tag:
40021c 04000000 10000000 01000000 474e5500 ............GNU.
40022c 00000000 02000000 06000000 12000000 ................
……
Contents of section .data:
600930 00000000 ....
Contents of section st1:
600934 33221100 ccddeeff 00000000 00000000 3"..............
600944 67452301 98badcfe gE#.....
Contents of section st2:
60094c 00000000 00000000 ........
Contents of section st3:
600954 00000000 00000000 ........
Contents of section .comment:
0000 4743433a 2028474e 55292034 2e342e36 GCC: (GNU) 4.4.6
0010 20323031 32303330 35202852 65642048 20120305 (Red H
0020 61742034 2e342e36 2d342900 4743433a at 4.4.6-4).GCC:
0030 2028474e 55292034 2e342e37 20323031 (GNU) 4.4.7 201
0040 32303331 33202852 65642048 61742034 20313 (Red Hat 4
0050 2e342e37 2d332900 .4.7-3).
Disassembly of section .init:
0000000000400390 <_init>:
400390: 48 83 ec 08 sub $0x8,%rsp
400394: e8 73 00 00 00 callq 40040c <call_gmon_start>
400399: e8 02 01 00 00 callq 4004a0 <frame_dummy>
40039e: e8 6d 02 00 00 callq 400610 <__do_global_ctors_aux>
4003a3: 48 83 c4 08 add $0x8,%rsp
4003a7: c3 retq
……
400647: 90 nop
Disassembly of section .fini:
0000000000400648 <_fini>:
400648: 48 83 ec 08 sub $0x8,%rsp
40064c: e8 df fd ff ff callq 400430 <__do_global_dtors_aux>
400651: 48 83 c4 08 add $0x8,%rsp
400655: c3 retq
$ objdump --section=st1 -s -d a.out
a.out: file format elf64-x86-64
Contents of section st1:
600934 33221100 ccddeeff 00000000 00000000 3"..............
600944 67452301 98badcfe gE#.....
Disassembly of section st1:
0000000000600934 < t11>:
600934: 33 22 11 00 cc dd ee ff 3"......
000000000060093c < t12>:
...
0000000000600944 < t13>:
600944: 67 45 23 01 98 ba dc fe gE#.....
$ ./a.out
__startt11: 0x6009cc
__stopt11: 0x6009e4
size: 24
t1.a:11, t1.b: 12
t2.a:21, t2.b: 22
t3.a:31, t3.b: 32
$