Linux可执行文件程序载入和执行过程
今天分析下Linux下一个可执行文件是怎么载入和执行的。
Linux下标准的可执行文件格式是ELF。
ELF(ExecutableandLinkingFormat)是一种对象文件的格式。
在linux系统中,一个ELF文件主要用来表示3种类型的文件
可执行文件:被操作系统中的加载器从硬盘中读取,加载到内存中去执行。目标文件(。o):被链接器读取,用来产生一个可执行文件或者共享文件。共享文件(。so):在动态链接的时候,由ldlinux。so来读取。
今天分析一下可执行文件类型。
当我们在Linux下的bash下输入一个命令执行可执行程序时,bash进程会调用fork()创建一个新的进程,然后新的进程调用execve()系统调用来执行指定的可执行程序。
原先的bash进程继续返回等待刚才启动的新进程结束,然后继续等待用户的输入。
execve()系统调用原型如下:intexecve(constcharfilename,charconstargv〔〕,charconstenvp〔〕);
他们的三个参数分别是被执行的程序文件名、执行参数和环境变量。
当调用execve()系统调用时,进入内核调用过程如下sysexecve()doexecve()主要根据可执行文件进行构造linuxbinprm内核结构,该结构记录可执行文件信息,然后从formats链表中找到执行该执行文件的方法loadelfbinary
doexecve主要完成linuxbinprm内核结构的初始化,该结构定义如下:
structlinuxbinprm{charbuf〔128〕;与可执行文件路径名的处理一样,每个参数的最大长度定为一个物理页,所以设置为一个页面指针数组,最大个数为32unsignedlongpage〔MAXARGPAGES〕;unsignedlongp;intshbang;可执行文件的性质,当时shell脚本时为1structinodeinode;可执行文件的inodeinteuid,egid;可执行文件的属性intargc,envc;命令行参数和环境变量数目charfilename;可执行文件的路径名};
该结构主要记录了执行可执行文件所有需要的信息。
其中page表示的是存放参数的页面数组,而p表示的是在这些数组的顶部,因为这些字符串是按照栈的方式存放的,也就是说,先分配地址更高的数组,向低地址方向增长,p就指向栈顶部。
结构如下图
最终执行可执行文件的接口为loadelfbinary。
具体实现如下:
staticintloadelfbinary(structlinuxbinprmbprm,structptregsregs){structelfhdrelfex;structelfhdrinterpelfex;structfilefile;。。。status0;loadaddr0;elfex((structelfhdr)bprmbuf);execheader比对四个字符,必须是0x7f、‘E’、‘L’、和‘F’if(elfex。eident〔0〕!0x7fstrncmp(elfex。eident〔1〕,ELF,3)!0)returnENOEXEC;映像类型必须是ETEXECif(elfex。etype!ETEXEC(elfex。emachine!EM386elfex。emachine!EM486)(!bprminodeiop!bprminodeiopdefaultfileops!bprminodeiopdefaultfileopsmmap)){returnENOEXEC;};elfphdata(structelfphdr)kmalloc(elfex。ephentsizeelfex。ephnum,GFPKERNEL);oldfsgetfs();setfs(getds());获取所有程序头表信息retvalreadexec(bprminode,elfex。ephoff,(char)elfphdata,elfex。ephentsizeelfex。ephnum);setfs(oldfs);elfppntelfphdata;elfbss0;elfbrk0;elfexecfilenoopeninode(bprminode,ORDONLY);filecurrentfilesfd〔elfexecfileno〕;elfstack0xffffffff;elfinterpreterNULL;startcode0;endcode0;enddata0;oldfsgetfs();setfs(getds());处理解释器段,通过遍历每个段,找到PTINTERP类型段,也即是解释器段,找到说明需要运行过程中的动态链接。解释器段实际上只是一个字符串,即解释器的文件名,如libldlinux。so。2,或者64位机器上对应的叫做lib64ldlinuxx8664。so。2通过命令readelfl可执行文件获取解释器段信息type类型为INTERPfor(i0;ielfex。ephnum;i){检查是否有需要加载的解释器if(elfppntptypePTINTERP){该类型表示动态连接器elfinterpreter(char)kmalloc(elfppntpfilesz,GFPKERNEL);根据其位置的poffset和大小pfilesz把整个解释器段的内容读入缓冲区;从用户程序的programheader中读取动态链接器的路径,比如lib64ldlinuxx8664。soretvalreadexec(bprminode,elfppntpoffset,elfinterpreter,elfppntpfilesz);if(retval0)获取连接器的inodretvalnamei(elfinterpreter,interpreterinode);if(retval0)解释器也是一个elf格式的程序,读入解释器的前128个字节,即解释器映像的头部retvalreadexec(interpreterinode,0,bprmbuf,128);if(retval0){interpex((structexec)bprmbuf);execheaderinterpelfex((structelfhdr)bprmbuf);execheader};};elfppnt;};setfs(oldfs);检查并读取解释器(也可以叫动态链接器)的程序头表if(elfinterpreter){。。。}if(!bprmshbang){。。。}在此清除掉了父进程的所有相关代码flusholdexec(bprm);currentmmenddata0;currentmmendcode0;currentmmstartmmapELFSTARTMMAP;currentmmmmapNULL;elfentry(unsignedint)elfex。eentry;currentmmrss0;建立环境变量参数的页表映射,从虚拟地址0xC0000000UL处开始bprmpsetupargpages(0,bprmpage);currentmmstartstackbprmp;oldfsgetfs();setfs(getds());elfppntelfphdata;for(i0;ielfex。ephnum;i){if(elfppntptypePTINTERP){setfs(oldfs);不装入解释器,那么这个入口地址就是目标映像本身的入口地址if(interpretertype1)elfentryloadaoutinterp(interpex,interpreterinode);加载textdatabss段如果需要装入解释器,就通过loadelfinterp装入其映像,并把将来进入用户空间的入口地址设置成loadelfinterp()的返回值,即解释器映像的入口地址if(interpretertype2)elfentryloadelfinterp(interpelfex,interpreterinode);oldfsgetfs();setfs(getds());iput(interpreterinode);kfree(elfinterpreter);if(elfentry0xffffffff){。。。};};类型为PTLOAD需要映射到进程的地址虚拟空间的if(elfppntptypePTLOAD){errordommap(file,elfppntpvaddr0xfffff000,elfppntpfilesz(elfppntpvaddr0xfff),PROTREADPROTWRITEPROTEXEC,MAPFIXEDMAPPRIVATE,elfppntpoffset0xfffff000);ifdefLOWELFSTACKif(elfppntpvaddr0xfffff000elfstack)elfstackelfppntpvaddr0xfffff000;endifif(!loadaddr)loadaddrelfppntpvaddrelfppntpoffset;kelfppntpvaddr;if(kstartcode)startcodek;kelfppntpvaddrelfppntpfilesz;if(kelfbss)elfbssk;if((elfppntpflagsPROTWRITE)endcodek)endcodek;if(enddatak)enddatak;kelfppntpvaddrelfppntpmemsz;if(kelfbrk)elfbrkk;};elfppnt;};setfs(oldfs);kfree(elfphdata);if(interpretertype!INTERPRETERAOUT)sysclose(elfexecfileno);。。。currentexecutablebprminode;bprminodeicount;ifdefLOWELFSTACKcurrentstartstackpelfstack4;endifbprmpMAXARGPAGESPAGESIZE;createelftables填写目标文件的参数环境变量等必要信息在完成装入,启动用户空间的映像运行之前,还需要为目标映像和解释器准备好一些有关的信息,这些信息包括常规的argc、envc等等,还有一些辅助向量(AuxiliaryVector)。这些信息需要复制到用户空间,使它们在CPU进入解释器或目标映像的程序入口时出现在用户空间堆栈上。这里的createelftables()就起着这个作用。bprmp(unsignedlong)createelftables((char)bprmp,bprmargc,bprmenvc,(interpretertypeINTERPRETERELF?elfex:NULL),loadaddr,(interpretertypeINTERPRETERAOUT?0:1));if(interpretertypeINTERPRETERAOUT)currentmmargstartstrlen(passedfileno)1;调整内存映射内容currentmmstartbrkcurrentmmbrkelfbrk;currentmmendcodeendcode;currentmmstartcodestartcode;currentmmenddataenddata;currentmmstartstackbprmp;currentsuidcurrenteuidbprmeuid;currentsgidcurrentegidbprmegid;currentmmbrk(elfbss0xfff)0xfffff000;sysbrk((elfbrk0xfff)0xfffff000);padzero(elfbss);eip和esp改成新的地址,就使得CPU在返回用户空间时就进入新的程序入口startthread(regs,elfentry,bprmp);if(currentflagsPFPTRACED)sendsig(SIGTRAP,current,0);MODDECUSECOUNT;return0;}staticinlinevoidstartthread(structptregsregs,unsignedlongeip,unsignedlongesp){regscsUSERCS;regsdsregsesregsssregsfsregsgsUSERDS;regseipeip;regsespesp;}
该函数主要完成的功能如下:检查ELF可执行文件的有效性,比如魔数、程序头表中段的数量。寻找动态链接的。interp段,设置动态链接器路径。根据ELF可执行文件的程序头表的描述,对ELF文件进行映射,比如代码段,数据段等。初始化ELF进程环境。将系统调用的返回地址修改为ELF可执行文件的入口点,这个入口点取决于程序的链接方式,若是静态链接,则入口地址为ELF文件的文件头中eentry所指的地址;对于动态链接的ELF可执行文件,程序入口点是动态链接器。
当loadelfbinary()执行完毕,返回至doexecve()再返回至sysexecve()时,由于上述步骤已经把系统调用的返回地址改成了被装载的ELF可执行程序的入口地址,所以当sysexecve()系统调用从内核态返回到用户态时,EIP寄存器直接跳转到了LF程序的入口地址,于是新的程序开始执行,ELF可执行文件装载完成。
八路军团长煽动2000人叛变,解放后混入军校被认出,结局如何?1950年初的一天,时任西南军政大学政治教育科科长王玮在工作中意外了解到,该校高级研究班有一个学员的情况与其在抗战时期认识的八路军老团长的情况有些相似。王玮让人把该学员叫到办公室了
突然火起来的裸靴既洋气显高,又舒适不累脚,小个子都喜欢颜值有保质期,但气质是没有的,一个人如果想要一辈子都活得潇洒,活得漂亮,那一定要维持自身的好气质,并且去培养个人审美,所以在秋日里大家也仍然要注意穿搭,或许我们没有令人惊艳的外表,
古代将军武器动不动几十上百斤,真打得动?看出土的文物就知道了上下五千年孕育了中华民族璀璨的文化,同时也留下了很多优秀文物,到现在我国还在不断出土各种文物,其中刀剑等武器就十分多样。不过大家经常看电视剧会产生一种错觉,误以为所有的兵器很轻!但
全球都在抛,今年最大的风暴来了随着加息风暴席卷全球,继瑞典周二领衔加息后,美国英国瑞士等多国央行相继宣布加息。伴随而来的是,全球主要市场股市债市汇市原油贵金属纷纷上演大逃杀。全球都在抛!这可能是2008年美国金
风暴来袭美国登月火箭第三次推迟发射新华社北京9月25日电美国新一代登月火箭太空发射系统原定27日的发射任务取消,因为当天可能有热带风暴经过发射基地。这是太空发射系统发射任务一个月内第三次延期。美国国家航空航天局24
热带风暴逼近NASA推迟发射探月火箭中新社旧金山9月24日电受热带风暴伊恩威胁,美国国家航空航天局(NASA)当地时间24日宣布,取消原定于27日在佛罗里达州肯尼迪航天中心进行的巨型探月火箭太空发射系统发射计划。美联
我的编程能力从什么时候开始突飞猛进?作者扶余城里小老二链接httpswww。zhihu。comquestion356351510answer1595886454这可能是一个长篇。会陆续更新30天。先上图,证明自己学过
顺丰发布声明来源江阴日报江阴网寄鱼干到货只剩头尾?顺丰正在调查9月23日,顺丰集团发布声明表示,针对9月以来连续的热搜事件,集团高度重视,即时责令专职团队检视现有相关流程是否满足客户的期望,同
华为使用骁龙8处理器,为什么不能用高通的5g基带华为被制裁的是5g相关的技术,所以即使华为用了骁龙8,也不代表能用5g相关芯片,mate50全系还都是4g手机就知道华为是多么难受华为麒麟芯片设计是牛逼,可是不给没有代工厂敢给华为
区块链,定义元宇宙感谢今日头条邀请参与媒体人周刊第五期热点观察局主题征文活动,也欢迎大家一同参与活动投稿,和我一起记录生活,分享自己的真知灼见当元宇宙的发展开始逐渐变得深入与完善,区块链在其中所发挥
这次,进腾讯了Heyguys,这里是程序员cxuan,欢迎你收看我最新一期的文章,今天这篇文章源自于我一个忠实读者的亲身经历,这篇文章写了他从大一开始到进入腾讯的一系列感悟和总结,希望能够帮到你
如果硕士毕业去高校当老师一个月一般多少工资?如果,你是想问硕士去高校当专业教师的话,那就不用想太多了。除非是办学层次比较低的专科院校,而且是相对较为偏僻的地方,还可能有机会之外,其他学校都不太可能了。现在,连民办本科都需要博
名爵6使用感如何?目前国内自主品牌最火的三款车型,一是名爵6二是长安睿骋CC,三是18款帝豪GL,名爵6更是在刚上市阶段网络刷屏,可谓关注度极高,这车我在12月份试驾过一次,恰巧就是6速手动车型,由
痛风能喝酒吗,痛风和白酒有没有关系?你好,我是风湿免疫科乔方医生,原四川省人民医院全科医生。这个问题我来回答。根据中华医学会内分泌学分会最新发布(2020年1月)的中国高尿酸血症与痛风诊疗指南2019建议所有高尿酸血
王子酱香经典和红郎十五哪个好喝?偶尔和朋友聊酒说酒,我会开玩笑说最低限度红15,再低就别说你有诚意。当然,农村米酒我也能喝,我的意思是,低过红15的酒,那就基本是很一般的酒了。茅台名气大,搞出一大堆私生子,呵呵,
为什么很多凌晨航班的机票钱都很便宜呢?机票是不分贵贱的,而大众的选择却导致了红眼航班的便宜。其实同一航空公司同一航段的价格都是一样的,都是不分时间段来定价的。看完相信对此刨根问题的你,也能知道其中的原理奥秘。首先明确一
实体店寒冬已至,春天还会远吗?除非国家出台相关政策约制电商,就像国外一样,不然实体店一样是死我真的为实体店的经营担忧,实体店的经营已经是勉力维持,主要是现在出来消费的人很少,我们的实体经营笮么就成了这个样子?一
家居开关插座应该怎么布局?每天阅读三分钟,装修,再也不发愁,关于新房装修开关插座的位置,这个非常关键,今天我们来聊一下室内空间开关插座如何布置?客厅首先考虑入户双控开关。在入户门的旁边,强烈建议,虽然前期多
全国农业类大学前20强有哪些,各有哪些擅长的领域?上图为中国农林类大学排行榜前20名,从榜单中我们可以看出,中国农林类大学排名第一的是中国农业大学,排名第二的是南京农业大学,排名第三的是华中农业大学。1。中国农业大学。中国农业大学
为什么要严查独立署名的论文?一更新个前提我是理工类,具体说是生命科学,以下观点仅代表本学科以下为原答案独立署名的文章多少会有猫腻,因为首先一篇文章独立完成的概率不大,这是因为一篇文章从选题,到分析,到写作到审
补钙的水果有哪些?你好很高兴回答你的问题1柑橘类水果。如脐橙等。一个脐橙中大约含有60毫克的钙。2山楂。山楂含钙量在秋季水果中最高,每百克果肉中含钙量大约有52毫克。3柚子。柚子是含钙量非常多的水果
男生想转行,有哪些高收入行业推荐?要问哪里挣钱多,保险银行互联网就中国目前的情况来说,最挣钱的三个行业当属互联网,银行和保险,我们来看一组数据一目了然,最赚钱的公司大部分也都是在这些行业。哥哥我是在互联网行业呆了很