变量属性扩展

来源:互联网 发布:windows加载驱动失败 编辑:程序博客网 时间:2024/05/07 05:45

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指令的第二个操作数也都替换成了链接脚本中指定的地址了。