1、__attribute__((section(“section_name ”)))
(参考:http://bigbluesmth.bokee.com/5590910.html)
通常,编译器会把它生成的目标文件放置在data和bss段。然而有时候你需要其他的段,或者你需要把特定的变量放在特定的段中。section属性用于指定一个变量或者一个函数所在的特定段。如下例:
//file test.c
#include <stdio.h>
#include <stdlib.h>
int a __attribute__(section("section_a"));
int b __attribute __(section("section_b"));
int main(int argc, char *argv[])
{
a = 1;
b = 2;
return (a+b);
}
执行命令gcc -c -o test.o test.c。其中-c选项告诉编译器只编译和汇编,但是不进行链接。然后执行命令objdump -s test.o,得到如下输出:
test.o: file format elf32-i386
Contents of section .text:
0000 5589e5c7 05000000 00010000 00c70500
0010 00000001 000000b8 00000000 5dc3
Contents of section section_a:
0000 00000000
Contents of section section_b:
0000 00000000
Contents of section .comment:
0000 00474343 3a202855 62756e74 7520342e
0010 342e312d 34756275 6e747538 2920342e
0020 342e3100
可见,目标文件中已经指定了段section_a和section_b。由于段section_a和section_b此时并没有分配,所以它们的起始地址都为0。接着运行命令objdump -S test.o,得到如下输出:
test.o: file format elf32-i386
Disassembly of section .text:
00000000 <main>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: c7 05 00 00 00 00 01 movl $0x1,0x0
a: 00 00 00
d: c7 05 00 00 00 00 01 movl $0x1,0x0
14: 00 00 00
17: b8 00 00 00 00 mov $0x0,%eax
1c: 5d pop %ebp
1d: c3 ret
两条movl语句正好对应到程序中的两条赋值语句。同样由于section_a和section_b尚未被分配,变量a和b的地址均为0,即两条movl语句各自的第二个操作数均为0。为了分配section_a和section_b,首先创建一个链接脚本文件,如下:
/* file test.lds */
SECTIONS
{
.text :
{
*(.text)
}
section_a 0x1f0000 :
{
*(section_a)
}
section_b 0xff0000 :
{
*(section_b)
}
}
最后我们将目标文件test.o使用该链接脚本进行链接。执行命令:ld -o test.elf -T test.lds test.o。然后执行命令objdump -s test.elf,得到如下输出:
test.elf: file format elf32-i386
Contents of section .text:
0000 5589e5c7 0500001f 00010000 00c70500
0010 00ff0001 000000b8 00000000 5dc3
Contents of section section_a:
1f0000 00000000
Contents of section section_b:
ff0000 00000000
Contents of section .comment:
0000 4743433a 20285562 756e7475 20342e34
0010 2e312d34 7562756e 74753829 20342e34
0020 2e3100
从上述输出,我们发现段section_a和section_b的起始地址变成了链接脚本中指定的地址。接着执行命令objdump -S test.elf,得到如下输出:
test.elf: file format elf32-i386
Disassembly of section .text:
00000000 <main>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: c7 05 00 00 1f 00 01 movl $0x1,0x1f0000
a: 00 00 00
d: c7 05 00 00 ff 00 01 movl $0x1,0xff0000
14: 00 00 00
17: b8 00 00 00 00 mov $0x0,%eax
1c: 5d pop %ebp
1d: c3 ret
同样发现,两个movl指令的第二个操作数也都替换成了链接脚本中指定的地址了。