2019-2020-1 20199314 《Linux内核原理与分析》 第八周作业
可执行程序工作原理、
1、ELF(Executable and Linkable Format)可执行和可链接文件,其包含了以下三类:
- 可重定位文件(Relocatable File):保存着代码和适当的数据,用来和其它的目标文件一起来创建一个可执行文件、静态库文件或者是一个共享目标文件(主要是.o文件)
- 可执行文件(Executable File):保存着一个用来执行的程序,一般由多个可重定位文件结合生成,是完成了所有重定位工作和符号解析(除了运行时解析的共享库符号)的文件。
- 共享目标文件(Shared Object File):保存着代码和合适的数据,用来被两个链接器链接。第一个是链接编辑器(静态链接),可以和其它的可重定位和共享目标文件来创建其它的object。第二个是动态链接器,联合一个可执行文件和其它的共享目标文件来创建一个进程映象。
2、ELF文件格式:
ELF文件的主体是各种节,以及描述这些节属性的信息(Program header table和 Section header table),以及ELF文件的整体性信息(ELF header),如下图。
3、程序编译
程序从源代码到可执行文件的步骤:预处理、编译、汇编、衔接--以hello.c为例。
预处理: gcc -E hello.c -o hello.i -m32
编译:gcc -S hello.i -o hello.s -m32
汇编:gcc -c hello.s -o hello.o -m32
默认衔接(动态库):gcc hello.o -o hello -m32
衔接静态库:gcc hello.o -o hello.static -m32 -static
最后得到的hello和hello-static文件就是可执行文件。可执行文件中的内容包括有编译后的机器指令代码、数据还包括了链接时所须要的一些信息,比如符号表、调试信息、字符串等。
其文件格式,如下图。
4、静态衔接和动态衔接
静态链接:在编译链接时直接将需要的执行代码复制到最终可执行文件中,优点是代码的装载速度快,执行速度也比较快,对外部环境依赖度低。缺点是如果多个应用程序使用同一库函数,会被装载多次,浪费内存。
动态链接:编译时不直接复制可执行代码,而是通过记录一系列符号和参数,在程序运行或加载时将这些信息传递给操作系统。操作系统负责将需要的动态库加载到内存中,在程序运行到指定的代码时,去共享执行内存中已经加载的动态库去执行代码,最终达到运行时链接的目的。优点是多个程序可以共享同一段代码,而不需要在磁盘上存储多个复制。缺点是在运行时加载可能会影响程序的前期执行性能,而且对使用的库依赖性较高。(分为装载时动态链接和运行时动态链接)
使用gcc hello.o -o hello.static -static进行静态链接,发现得到的可执行程序文件大小可达到动态链接的100倍,如图。
5、动态衔接
动态衔接分为以下两种;
- 可执行程序装载时动态衔接
2.运行时动态衔接。
装载时动态衔接意味着在程序一开始启动的时候其所调用的库需要在一开始就提供,而运行时动态衔接只有程序运行到相关语句才会访问dllibexample。
6、fork和execve区别与联系
对于fork():
1、子进程复制父进程的所有进程内存到其内存地址空间中。父、子进程的
“数据段”,“堆栈段”和“代码段”完全相同,即子进程中的每一个字节都
和父进程一样。
2、子进程的当前工作目录、umask掩码值和父进程相同,fork()之前父进程
打开的文件描述符,在子进程中同样打开,并且都指向相同的文件表项。
3、子进程拥有自己的进程ID。
对于exec():
1、进程调用exec()后,将在同一块进程内存里用一个新程序来代替调用
exec()的那个进程,新程序代替当前进程映像,当前进程的“数据段”,
“堆栈段”和“代码段”背新程序改写。
2、新程序会保持调用exec()进程的ID不变。
3、调用exec()之前打开打开的描述字继续打开(好像有什么参数可以令打开
的描述字在新程序中关闭)
实验1:
编程使用exec* 库函数加载一个可执行文件,动态链接分为可执行程序装载时动态链接和运行时动态链接,编程练习动态链接库的这两种使用方式。
1、实验楼上说要从某个网站上下载下面两个源码:
shlibexample.h (1.3 KB) - Interface of Shared Lib Example
shlibexample.c (1.2 KB) - Implement of Shared Lib Example
但是后来查到是网易云付费课的附件,为了两个代码没必要花这么多钱,再说书上已经有源码了,可以自己写一遍,但是书上的代码有一个大坑,直接影响了我后面做实验的进度,之后来我会说明。
shlibexample.h
#ifndef _SH_LTB_EXAMPLE_H_
#define _SH_LTB_EXAMPLE_H_
#define SUCCESS 0
#define FAILURE (-1)
#ifdef __cplusplus
extern "C" {
#endif
int SharedLibApi();
#ifdef __cplusplus
}
#endif
#endif
dllibexample.h
#ifndef _DL_LTB_EXAMPLE_H_
#define _DL_LTB_EXAMPLE_H_
#ifdef _cplusplus
extern "C"{
#endif
int DynamicalLoadingLibApi();
#ifdef _cplusplus
}
#endif
#endif
shlibexample.c
#include <stdio.h>
#include "shlibexample.h"
int SharedLibApi()
{
printf("This is a shared libary!\n");
return SUCCESS;
}
dllibexample.c
#include <stdio.h>
#include "dllibexample.h"
#define SUCCESS 0
#define FAILURE(-1)
int DynamicalLoadingLibApi()
{
printf(“This is a Dynamical Loading library”!\n”);
return SUCCESS;
}
2、编译成libshlibexample.so文件
$ gcc -shared shlibexample.c -o libshlibexample.so -m32
$ gcc -shared dllibexample.c -o libdllibexample.so -m32
错误到这里就显现出来了,为什么会报错我在网上查了很多答案,什么需要更新gcc啊,什么C文件头名字冲突啊,反正各种答案,耗费了很久时间就是依旧会报错,于是我重新打了好几遍代码,直到发现有一个贼细小的地方,书上很容易误导。
**注意看!这分明看着是就是LIB对吧,我在vim编辑器中敲的时候也和书上的样子差不多,然而我仔细看了一下I的上横和下横还是有点长短不一的,这货该不会是T吧!!,结果事实验证了我的判断,这货就是T,LTB。终于找到原因了 **
3、mian函数中分别以共享库和动态加载共享库的方式使用libshlibexample.so文件和libdllibexample.so文件
main.c
#include <stdio.h>
#include "shlibexample.h"
#include <dlfcn.h>
int main()
{
printf("This is a Main program!\n");
/* Use Shared Lib */
printf("Calling SharedLibApi() function of libshlibexample.so!\n");
SharedLibApi(); //直接调用共享库
/* Use Dynamical Loading Lib */
void * handle = dlopen("libdllibexample.so",RTLD_NOW);//打开动态库并将其加载到内存
if(handle == NULL)
{
printf("Open Lib libdllibexample.so Error:%s\n",dlerror());
return FAILURE;
}
int (*func)(void);
char * error;
func = dlsym(handle,"DynamicalLoadingLibApi");
if((error = dlerror()) != NULL)
{
printf("DynamicalLoadingLibApi not found:%s\n",error);
return FAILURE;
}
printf("Calling DynamicalLoadingLibApi() function of libdllibexample.so!\n");
func();
dlclose(handle); //卸载库
return SUCCESS;
}
4、动态衔接运行测试
因为shilibexample在衔接时就需要提供路径,对应的头文件shilibexample.h也需要在编译器能找到位置。使用参数-L表明文件路径,-l表示库文件名。
dllibexample只有在程序运行到相关语句才会访问,在编译时不需要任何的相关信息,使用-ldl指明其所需要的共享库dlopen,同时修改LD_LIBRARY_PATH确保dllibexample.so可以查到。
gcc main.c -o main -L./ -l shlibexample -ldl -m32
export LD_LIBRARY_PATH=$PWD
./main
实验2:
使用gdb跟踪分析一个execve系统调用内核处理函数sys_execve ,验证您对Linux系统加载可执行程序所需处理过程的理解。
实验二就只能在实验楼环境做了,毕竟本地虚拟机没有配好的环境。
1、首先从github上下载包含test_exec.c文件的文件夹,进行编译。
ls
cd ~/LinuxKernel
rm menu -rf
git clone https://github.com/mengning/menu.git
cd menu
mv test_exec.c test.c
make rootfs
2、在qemu界面使用help和exec命令查看是否编译成功。
3、随后重新启动qemu。
4、加载内核和端口。
5、设置三个断点。
6、调试运行程序。
2019-2020-1 20199314 《Linux内核原理与分析》 第八周作业的更多相关文章
- 2019-2020-1 20199329《Linux内核原理与分析》第九周作业
<Linux内核原理与分析>第九周作业 一.本周内容概述: 阐释linux操作系统的整体构架 理解linux系统的一般执行过程和进程调度的时机 理解linux系统的中断和进程上下文切换 二 ...
- 2019-2020-1 20199329《Linux内核原理与分析》第二周作业
<Linux内核原理与分析>第二周作业 一.上周问题总结: 未能及时整理笔记 Linux还需要多用 markdown格式不熟练 发布博客时间超过规定期限 二.本周学习内容: <庖丁解 ...
- 20169212《Linux内核原理与分析》第二周作业
<Linux内核原理与分析>第二周作业 这一周学习了MOOCLinux内核分析的第一讲,计算机是如何工作的?由于本科对相关知识的不熟悉,所以感觉有的知识理解起来了有一定的难度,不过多查查资 ...
- 20169210《Linux内核原理与分析》第二周作业
<Linux内核原理与分析>第二周作业 本周作业分为两部分:第一部分为观看学习视频并完成实验楼实验一:第二部分为看<Linux内核设计与实现>1.2.18章并安装配置内核. 第 ...
- 2018-2019-1 20189221 《Linux内核原理与分析》第九周作业
2018-2019-1 20189221 <Linux内核原理与分析>第九周作业 实验八 理理解进程调度时机跟踪分析进程调度与进程切换的过程 进程调度 进度调度时机: 1.中断处理过程(包 ...
- 2017-2018-1 20179215《Linux内核原理与分析》第二周作业
20179215<Linux内核原理与分析>第二周作业 这一周主要了解了计算机是如何工作的,包括现在存储程序计算机的工作模型.X86汇编指令包括几种内存地址的寻址方式和push.pop.c ...
- 2019-2020-1 20209313《Linux内核原理与分析》第二周作业
2019-2020-1 20209313<Linux内核原理与分析>第二周作业 零.总结 阐明自己对"计算机是如何工作的"理解. 一.myod 步骤 复习c文件处理内容 ...
- 2018-2019-1 20189221《Linux内核原理与分析》第一周作业
Linux内核原理与分析 - 第一周作业 实验1 Linux系统简介 Linux历史 1991 年 10 月,Linus Torvalds想在自己的电脑上运行UNIX,可是 UNIX 的商业版本非常昂 ...
- 《Linux内核原理与分析》第一周作业 20189210
实验一 Linux系统简介 这一节主要学习了Linux的历史,Linux有关的重要人物以及学习Linux的方法,Linux和Windows的区别.其中学到了LInux中的应用程序大都为开源自由的软件, ...
- 2018-2019-1 20189221《Linux内核原理与分析》第二周作业
读书报告 <庖丁解牛Linux内核分析> 第 1 章 计算工作原理 1.1 存储程序计算机工作模型 1.2 x86-32汇编基础 1.3汇编一个简单的C语言程序并分析其汇编指令执行过程 因 ...
随机推荐
- ES6学习总结之Set和Map数据结构的理解
前言 当我们需要存储一些数据的时候,首先想到的是定义一个变量用来存储,之后我们可能学了数组,发现数组比变量可以存储更多的数据,接着可能有其它的存储数据的方法等等,然而我今天需要介绍的是在ES6中比较常 ...
- python 关于excel弹窗——请注意,您的文档的部分内容可能包含了文档检查器无法删除的个人信息解决方法
参考https://www.cnblogs.com/Jacklovely/p/6582732.html 这个问题的原因是由于工作簿包含宏.ActiveX控件等内容, 而Excel被设置为在保存文件时自 ...
- Python入门系列【附】进阶教程
如题,本篇将讲解Python提升之路:Python作为语法简单易学的语言,入门容易精通却很难,这是共识,那么为什么会有这样的共识?精通Python的难度在哪里? Python拥有简单.形象.直观的语法 ...
- java并发之内存模型
java内存模型知识导图 一 并发问题及含义 并发编程存在原子性.可见性.有序性问题. 原子性即一系列操作要么都执行,要么都不执行. 可见性,一个线程对共享变量的修改,另一个线程可能不会马上看到. ...
- C#使用GUID作为随机数种子
使用C#默认的Random无参构造的next生成的随机数,在快速生成随机数的时候,会出现大批量的重复.使用guid作为随机数种子,效果会好很多 Guid temp = Guid.NewGuid(); ...
- Window下的VScode快捷键
转载自4ark 全局 Ctrl + Shift + P, F1 显示命令面板 Ctrl + P 快速打开Ctrl + Shift + N 打开新窗口Ctrl + Shift + W 关闭窗口 基本 C ...
- CSS3新单位vw、vh、vmin、vmax使用详解
像 px.em 这样的长度单位大家肯定都很熟悉,前者为绝对单位,后者为相对单位.CSS3 又引入了新单位:vw.vh.vmin.vmax.下面对它们做个详细介绍. 新单位也成为视窗单位,视窗(View ...
- Stock Charts
Description You're in the middle of writing your newspaper's end-of-year economics summary, and you' ...
- Python flask 构建微电影视频网站☝☝☝
Python flask 构建微电影视频网站☝☝☝ 1.安装数据库连接依赖包 pip install flask-sqlalchemy 2.创建movie数据库 在CentOS虚拟机,进入MaridD ...
- iOS RGBA转YV12
引言 因为项目中要做画面共享,所以需要学一点图像相关的知识,首当其冲就是RGB转YUV了,因为图像处理压缩这一块是由专业对口的同事做的,所以呢,我这就是写一下自己的理解,如有不对的地方,还望指正,谢谢 ...