Linux内核如何装载和启动一个可执行程序
一.实验要求
1.理解编译链接的过程和 ELF 可执行文件格式
2.编程使用 exec*库函数加载一个可执行文件,动态链接分为可执行程序装载时动态链接和运行时动态链接,编程练习动态链接库的这两种使用方式
3.使用 gdb 跟踪分析一个 execve 系统调用内核处理函数 sys_execve ,验证您对 Linux 系统加载可执行程序所需处理过程的理解
4.特别关注新的可执行程序是从哪里开始执行的?为什么 execve 系统调用返回后新的可执行程序能顺利执行?对于静态链接的可执行程序和动态链接的可执行程序 execve 系统调用返回时会有什么不同?
二.实验步骤
1.编译链接命令:
gcc -E hello.c -o hello.i //预处理
gcc -S hello.i -o hello.s //编译
gcc -c hello.s -o hello.o //汇编
gcc hello.o -o hello //链接

预处理和编译完的文件均为文本文件,汇编和链接完的文件均为ELF文件。
"gcc -o hello.static hello.o -static"静态编译出来的hello.static把C库里需要的东西也放到可执行文件里了.
2.ELF文件:
ELF(Excutable and Linking Format)是一个文件格式的标准。输入redelf -h hello可以查看hello的EIF头部,可以看到定义的入口地址与“new_ip”所指向的地址一致。

ELF的头保存的是元数据,也就是路线图,描述了文件的组织情况。比如程序头表(program header table)告诉系统如何来创建一个进程的内存映像。section头表(section header table)包含描述文件sections的信息。每个section在这个表中有一个入口;每个入口给出了该section的名字,大小等等信息。ELF的剩余部分是sections,包括代码段,数据段。这些在程序变成进程映像时加载到内存的虚拟地址空间中,从ELF头开始加载。
ELF可执行文件中有三种主要的目标文件:
1.可重定位文件:这种文件一般是中间文件,还需要继续处理。文件中保存着代码和适当的数据,用来和其他的object文件一起创建一个可执行文件或者是一个共享文件。主要是.o文件。
2.可执行文件:文件中保存着一个用来执行的程序;该文件指出了exec如何创建程序进程映像。
3.共享目标文件:共享库,是指可以被可执行文件或者其他库文件使用的目标文件。
3、静态链接和动态链接
静态链接:
在编译链接时直接讲=将需要的执行代码复制到最终可执行文件中,优点是代码的装载速度快,执行速度也快,对外部环境依赖度低。编译时她会把所有需要的代码都链接进去,应用程序相对比较大。缺点是如果多个应用程序使用同一库函数,会被装载多次,浪费内存。
动态链接:
在装入或运行时进行链接。通常被链接的共享代码称为动态链接库或共享库。
动态链接分为可执行程序装载时动态链接和运行时动态链接。
dllibexample.h代码如下:
#ifndef _DL_LIB_EXAMPLE_H_
#define _DL_LIB_EXAMPLE_H_
#ifdef __cplusplus
extern

本文详细探讨了Linux内核如何装载和启动一个可执行程序,涉及实验要求和步骤,包括编译链接、ELF文件格式、静态与动态链接、exec函数的使用,以及sys_execve系统调用在程序执行过程中的作用。通过实验,读者能够理解Linux系统加载可执行程序的全过程。
最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



