第七周:可执行程序的装载

吕松鸿 原创做品转载请注明出处 《Linux内核分析》MOOC课程 http://mooc.study.163.com/course/USTC-1000029000shell

1、预处理,编译,连接和目标文件格式

1.可执行程序是怎么得来的

 

c代码->预处理->汇编代码->汇编器->目标代码->连接成可执行文件->加载到内核执行
函数

2.目标文件的格式ELF

      符号修饰标准、变量内层布局、函数调用方式等这些跟可执行代码二进制兼容性相关的内容称为ABI(Application Binary Interface)布局

常见的ABI格式:spa

3.静态连接的ELF可执行文件和进程的地址空间

 

通常静态连接将会把全部代码放在同一个代码段。命令行

动态链接的进程会有多个代码段。3d

2、可执行程序、共享库和动态连接

1.可执行程序的执行环境

命令行参数和shell环境,通常咱们执行一个程序的Shell环境,咱们的实验直接使用execve系统调用。

Shell自己不限制命令行参数的个数, 命令行参数的个数受限于命令自身。

shell会调用execve将命令行参数和环境参数传递给可执行程序的main函数。

命令行参数和环境串都放在用户态堆栈中。

 

2.装载时动态连接和运行时动态连接应用举例

动态连接分为可执行程序装载时动态连接和运行时动态连接

3、可执行程序的装载

1. sys_execve内核处理过程

(1)新的可执行程序起点

通常是地址空间为0x8048000或0x8048300

(2)execve与fork

execve和fork都是特殊一点的系统调用:通常的都是陷入到内核态再返回到用户态。
  • fork两次返回,第一次返回到父进程继续向下执行,第二次是子进程返回到ret_from_fork而后正常返回到用户态。code

  • execve执行的时候陷入到内核态,用execve中加载的程序把当前正在执行的程序覆盖掉,当系统调用返回的时候也就返回到新的可执行程序起点。blog

execve
- 执行到可执行程序 -> 陷入内核
- 构造新的可执行文件 -> 覆盖掉原可执行程序
- 返回到新的可执行程序,做为起点(也就是main函数)
- 须要构造其执行环境;
  • Shell会调用execve将命令行参数和环境参数传递给可执行程序的main函数,先函数调用参数传递,再系统调用参数传递。

(3)静态连接的可执行程序和动态连接的可执行程序execve系统调用返回时不一样

  • 静态连接:elf_entry指向可执行文件的头部,通常是main函数,是新程序执行的起点。

2.动态连接的可执行程序的装载

  • 动态连接库的依赖关系会造成一个图。
  • load_elf_interp实际加载动态连接器,entry返回的是动态连接器的入口,根据需求加载动态连接库,根据库的须要再加载更多的库。

4、实验 Linux内核如何装载和启动一个可执行程序

1.下载新的代码文件

2.运行和gdb跟踪断点

相关文章
相关标签/搜索