linux可执行文件的装载

  1. 什么是库? 《linux中的动态链接库,和静态链接库是干什么的?——郭无心的回答》

    库是写好的现有的,成熟的,可以复用的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。

    本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。库有两种:静态库(.a、.lib)和动态库(.so、.dll)。 windows上对应的是.lib .dll linux上对应的是.a .so

  2. 什么叫做.so?

    .so file is a compiled library file. It stands for “Shared Object”

  3. 什么是动态链接 《Linux 动态库剖析》

    动态链接的共享库是 GNU/Linux® 的一个重要方面。

    该种库允许可执行文件在运行时动态访问外部函数

    ,从而(通过在需要时才会引入函数的方式)减少它们对内存的总体占用。

    库用于将相似函数打包在一个单元中。然后这些单元就可为其他开发人员所共享,并因此有了

    模块化编程

    这种说法 — 即,从模块中构建程序。

    Linux 支持两种类型的库:1.动态库

    2.静态库

    静态库包含在编译时静态绑定到一个程序的函数。动态库则不同,它是在加载应用程序时被加载的,而且它与应用程序是在运行时绑定的。


    动态使用共享库的方法有两种:您既可以在运行时动态链接库,也可以动态加载库并在程序控制之下使用它们。

    对于需要多个库的应用程序来说,则适合使用共享库,因为它们可以减少应用程序对内存(包括运行时中的磁盘占用和内存占用)的占用。这是因为多个应用程序可以同时使用一个共享库;因此,每次只需要在内存上复制一个库。要是静态库的话,每一个运行的程序都要有一份库的副本。

  4. 什么是静态链接

    在链接阶段,会将汇编生成的目标文件与引用到的库一起链接打包到可执行文件中。因此对应的链接方式称为静态链接。

    静态库较适宜于较小的应用程序,因为它们只需要最小限度的函数。

  5. 动态与静态的关系
  6. 目标文件格式 《目标文件的格式》

    目标文件从结构上讲,它是已经编译后的可执行文件格式,只是还没有经过链接的过程,其中可能有些符号或有些地址还没有被调整。其实它本身就是按照可执行文件格式存储的,只是跟真正的可执行文件在结构上稍有不同。

    可执行文件格式涵盖了程序的编译、链接、装载和执行的各个方面。

    现在PC平台流行的可执行文件格式(Executable)主要是:

    Windows下的PE(Portable Executable) Linux的ELF(Executable Linkable Format)

    目标文件就是源代码编译后但未进行链接的那些中间文件(Windows的.obj和Linux下的.o)。从广义上看,目标文件与可执行文件的格式其实几乎是一样的。

    立马编写一个hello world


    用file命令来查看相应的文件格式

    用nm查看ELF信息


    目标文件有三种类型:

    1. 可重定位文件(Relocatable File) 包含适合于与其他目标文件链接来创建可执行文件或者共享目标文件的代码和数据。 (Linux的*.o 文件 Windows的 *.obj文件)

    2. 可执行文件(Executable File) 包含适合于执行的一个程序,此文件规定了 exec() 如何创建一个程序的进程映像。(比如/bin/bash文件;Windows的*.exe)

    3. 共享目标文件(Shared Object File) 包含可在两种上下文中链接的代码和数据。首先链接编辑器可以将它和其它可重定位文件和共享目标文件一起处理,生成另外一个目标文件。其次,动态链接器(Dynamic Linker)可能将它与某个可执行文件以及其它共享目标一起组合,创建进程映像。

    目标文件全部是程序的二进制表示,目的是直接在某种处理器上直接执行(Linux的.so,如/lib/ glibc-2.5.so;Windows的DLL)

    《linux,windows 可执行文件(ELF、PE)》

  7. 什么是ABI

    ABI(application binary interface)描述了应用程序(或者其他类型)和操作系统之间或其他应用程序的低级接口。 一个BINARY(EXEC, LIB)必需符合ABI才能在相应的系统上运行.

  8. ABI和目标文件格式是什么关系

    目标文件格式要符合ABI才能运行。

  9. 装载可执行程序之前的工作

    1. 可执行程序的文件格式

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

    模拟实验:

准备.so文件

shlibexample.h (1.3 KB) – Interface of Shared Lib Example

shlibexample.c (1.2 KB) – Implement of Shared Lib Example

编译成libshlibexample.so文件

$ gcc -shared shlibexample.c -o libshlibexample.so -m32


dllibexample.h (1.3 KB) – Interface of Dynamical Loading Lib Example

dllibexample.c (1.3 KB) – Implement of Dynamical Loading Lib Example

编译成libdllibexample.so文件

$ gcc -shared dllibexample.c -o libdllibexample.so -m32


分别以共享库和动态加载共享库的方式使用libshlibexample.so文件和libdllibexample.so文件

main.c  (1.9 KB) – Main program

编译main,注意这里只提供shlibexample的-L(库对应的接口头文件所在目录)和-l(库名,如libshlibexample.so去掉lib和.so的部分),并没有提供dllibexample的相关信息,只是指明了-ldl

$ gcc main.c -o main -L /home/muggle/SharedLibDynamicLink/ -lshlibexample -ldl -m32

$ export LD_LIBRARY_PATH=$PWD #将当前目录加入默认路径,否则main找不到依赖的库文件,当然也可以将库文件copy到默认路径下。


跟新menu

新的menu增加了exec代码

make rootfs


gdb调试

还是有些地方模模糊糊的~

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

发表评论

电子邮件地址不会被公开。 必填项已用*标注