|
/* hello.c */
#include
#include
#define __copy_user(to,from,size) do
{ int __d0, __d1; __asm__ __volatile__
( "0: rep; movsl\n" " movl %3,%0\n" "1: rep; movsb\n"
"2:\n" ".section .fixup,\"ax\"\n"
"3: lea 0(%3,%0,4),%0\n" " jmp 2b\n"
".previous\n" ".section __ex_table,\"a\"\n"
" .align 4\n"
" .long 0b,3b\n" " .long 1b,2b\n"
".previous" : "=&c"(size), "=&D" (__d0),
"=&S" (__d1) : "r"(size & 3), "0"(size / 4), "1"(to),
"2"(from) : "memory"); } while (0)
int main(void)
{
const char *string = "Hello, world!";
char buf[20];
unsigned long n, m;
m = n = strlen(string);
__copy_user(buf, string, n);
buf[m] = '\0';
printf("%s\n", buf);
exit(0);
}
|
先看看本程序的执行结果:
$ gcc hello.c -o hello
$ ./hello
Hello, world!
|
显然,这就是一个简单的"hello world"程序,那为什么要写得这么复杂呢?程序中的一大段汇编代码在内核中才能体现出其价值,笔者把其加入到上面的程序中,是为了后面的分析而准备的。
系统在核心态运行的时候,参数是通过寄存器来传递的,由于寄存器所能够传递的信息有限,所以传递的参数大多数是指针。要使用指针所指向的更大块的数据,就需要把用户空间的数据拷贝到系统空间来。上面的__copy_user在内核中正是扮演着这样的一个拷贝数据的角色,当然,内核中这样的宏定义还很多,笔者也只是取其中的一个来讲解,读者如果感兴趣的话可以看完本文以后自行学习。
如果读者对于简单的嵌入式汇编还不是很了解的话,可以参考《Linux内核源代码情景分析》一书。
下面我们把程序编译成汇编程序来加以分析:
$ gcc -S hello.c
/* hello.s */
movl -60(%ebp), %eax
andl $3, %eax
movl -60(%ebp), %edx
movl %edx, %ecx
shrl $2, %ecx
leal -56(%ebp), %edi
movl -12(%ebp), %esi
#APP
0: rep; movsl
movl %eax,%ecx
1: rep; movsb
2:
.section .fixup,"ax"
3: lea 0(%eax,%ecx,4),%ecx
jmp 2b
.previous
.section __ex_table,"a"
.align 4
.long 0b,3b
.long 1b,2b
.previous
#NO_APP
movl %ecx, %eax
|
从上面通过gcc生成的汇编程序中,我们可以很容易的找到访问用户地址空间的指令,也就是程序中的标号为0和1的两条语句。而程序中伪操作.section的作用就是定义了.fixup和__ex_table这样的两个段,那么这两段在可执行程序中又是怎么样安排的呢?下面就通过objdump给读者一个直观的概念:
$ objdump --section-headers hello
hello: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .interp 00000013 080480f4 080480f4 000000f4 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
………………………………
9 .init 00000018 080482e0 080482e0 000002e0 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
10 .plt 00000070 080482f8 080482f8 000002f8 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
11 .text 000001c0 08048370 08048370 00000370 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
12 .fixup 00000009 08048530 08048530 00000530 2**0
CONTENTS, ALLOC, LOAD, READONLY, CODE
13 .fini 0000001e 0804853c 0804853c 0000053c 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
14 .rodata 00000019 0804855c 0804855c 0000055c 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
15 __ex_table 00000010 08048578 08048578 00000578 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
16 .data 00000010 08049588 08049588 00000588 2**2
CONTENTS, ALLOC, LOAD, DATA
CONTENTS, READONLY
………………………………
26 .note 00000078 00000000 00000000 0000290d 2**0
CONTENTS, READONLY
|
共6页: 上一页 [1] [2] 3 [4] [5] [6] 下一页
|