`
isiqi
  • 浏览: 16499553 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

Linux操作系统--显示运行时链接

阅读更多

1,显示运行时链接的优点

使得模块组织更加灵活,可以在使用的时候再进行加载,不需要的时候进行释放。

另外,模块可以进行更新而不需要停止程序的运行。这对诸如Web服务器等需要长时间运行的程序非常重要。例如Web服务器的某个模块更新了,则仅仅需要通知Web服务器对该模块进行重新动态加载就可以了。

2,动态库与共享对象的区别

共享对象是动态链接器在程序开启的时候进行加载和链接的,这一系列的步骤都是对程序本身透明的。动态库则是通过一系列的动态链接器提供的API,具体有4个:dlopen,dlsym,dlerror,dlclose,程序可以通过这几个API对动态库进行操作。

它们的实现在/lib/libdl.so.2里边,相关声明和常量在<dlfcn.h>。

2,dlopen

void * dlopen(const char *filename ,int flag);

如果传入的文件参数是0,那么dlopen返回的是全局符号表的句柄。也就是说可以运行时找到全局符号表的任何符号,执行它们。

这有些类似高级语言(比如Java,嘿嘿还好我学过)的反射机制。全局符号表包含程序的可执行文件、动态加载的共享模块和dlopen打开的共享库并且使用了RTLD_GLOBAL方式的模块中的符号。

第二个是符号解析方式。RTLD_LAZY表示使用延迟绑定(PLT);RTLD_NOW模块加载时进行绑定,如果有绑定失败,则dlopen返回错误。上边两种必选一个。另外可以使用RTLD_GLOBAL来与上述两个“或”,表示被加载的模块的全局符号合并到进程的全局符号表,使得以后加载的模块可以使用这些符号。

dlopen返回加载的模块的句柄,在dlsym和dlclose时需要。加载失败返回NULL。如果模块已经加载,返回同一个句柄。如果依赖于其他模块,程序员需要手工加载依赖模块。

另外dlopen会执行.init段的代码以进行模块初始化。

3,dlsym()

核心部分,用以找到符号。

void *dlsym(void *handle.char *symbol);

一个是模块句柄,一个是符号名称。没找到返回NULL,否则返回符号的值。

值的意义:函数则是函数地址,变量则是变量地址,常量则是常量值。如果常量本就是NULL或者0.则需要通过dlerror判断是找到符号而符号值是NULL还是没有找到符号返回了NULL。dlerror返回NULL表示没有发生错误。

常量符号一般是编译链接器产生的,对外不可见。比如编译单元文件名。使用objdump -t查看,常量在符号表中类型是 *ABS*。

4,符号查找优先序列

对于ld加载的模块,符号如果存在冲突,则先装入的优先。dlopen装入的符号也可能与之前的模块重复。进行符号解析和重定位时,ld同样采取了装载序列。dlsym()对符号查找分为两种: 传入的文件参数是NULL的时候,此时使用的是全局符号表;dlsym是使用装载序列的;如果不是NULL,则以打开对象的符号表为根节点,进行依赖文件的广度优先遍历。

dlerror判断dlopen、dlsym和dlclose的上次调用是否成功。返回是char *,如果是NULL则无错;否则是错误信息的指针。

5,dlclose()

系统维持一个模块的加载计数,dlclose使得计数-1,如果为0,就真正被卸载。卸载先执行.finit代码,然后将符号从符号表去除,取消进程地址空间和模块的映射关系,关闭模块文件。

6,gcc中的-ldl

gcc -o RuntimeSimple RuntimeSimple.c -ldl

-ldl表示使用 DL(动态加载)库,位于/lib/libdl.so.2。

7,函数的执行

知道函数的地址,还必须知道函数签名才能执行该函数(签名中有返回值、参数的信息)。Java等中的反射机制,可以获取函数的额外信息,包括函数的参数、返回值。但是C/C++没有保存这些信息到可执行、共享库或者目标文件(当然从符号修饰中可以知道)。所以,一般开发人员必须知道函数的原型。

8,程序员自我修养288页有个程序,可以根据传入参数和符号,执行该符号的函数。

由于预先不知道要执行的函数的参数的个数和各个参数类型,所以使用了汇编,根据输入的参数顺序依次压栈,然后跳转到函数符号地址处执行。 这种方式就伪造了函数调用的堆栈,然后使用无参数的该函数的指针,调用该函数。

分享到:
评论

相关推荐

    aarch64-linux-android-4.9.rar

    在这个场景中,我们的目标平台是Android设备,运行的是aarch64架构的处理器,而编译环境则是Linux操作系统。aarch64是ARM公司推出的一种64位指令集架构,广泛应用于现代高性能的Android设备中,如智能手机和平板电脑...

    linux-0.11-devel-040809.rar

    另一方面,"bochs-2.1.1"则是一个x86兼容的PC硬件模拟器,它可以运行在多种操作系统上,包括Linux。Bochs允许开发者在软件层面模拟一个完整的PC系统,包括CPU、内存、硬盘、网络接口等硬件设备,使得开发者能够在不...

    eclipse-jee-2023-09-R-linux-gtk-x86-64.tar.gz

    "eclipse-jee-2023-09-R-linux-gtk-x86_64.tar.gz" 文件是Eclipse专为Java企业版(Java EE)开发者设计的2023年9月版本,适用于64位的Linux操作系统。这个版本包含了对Java EE开发所需的全部工具和功能,如Web服务器...

    arm-none-linux-gnueabi-linux.zip

    例如,"arm-none-linux-gnueabi-"中的"arm"表示目标架构是ARM,"none"表示没有操作系统,"linux"则表明目标系统基于Linux内核。 四、使用步骤 1. **解压安装**:首先,我们需要解压下载的"arm-none-linux-gnueabi-...

    aarch64-linux-android-4.9(windows-64位)

    标题 "aarch64-linux-android-4.9(windows-64位)" 指的是一个特定版本的Android NDK工具链,适用于64位Windows操作系统,用于编译针对AArch64架构(也称为ARM64)的Linux Android应用程序。NDK(Native ...

    arm-linux-gcc-4.3.2.rar

    2. Linux操作系统:Linux是一种开源、自由的操作系统内核,被广泛用于各种设备,从手机到超级计算机。在嵌入式系统中,Linux提供了稳定、可定制的环境,便于开发者构建和管理软件。 3. GCC 4.3.2:这是GCC的一个...

    xilinx-gcc-arm-linux-gnueabi-201801 WINDOWS下ZYNQ LINUX交叉编译器

    这个工具链使得开发者能够在Windows环境下为ZYNQ板卡上的Linux操作系统编写和编译代码。 ZYNQ(Zynq-7000 All Programmable SoC)是Xilinx推出的一种片上系统(System on Chip),集成了FPGA(Field-Programmable ...

    arm-xilinx-linux-gnueabi-2011.09-50

    标题中的"arm-xilinx-linux-gnueabi-2011.09-50"是一个特定版本的交叉编译工具链,专为基于ARM架构的设备设计,用于构建在Linux操作系统上的应用程序。这个工具链是由Xilinx公司提供的,Xilinx是著名的 FPGA(现场可...

    arm-linux-gcc-4.4.3.tar.gz

    3. **组合**:ARM Linux意味着在基于ARM架构的硬件上运行Linux操作系统,需要特定的驱动程序和工具链来支持开发和运行。 **嵌入式硬件**: 1. **嵌入式系统**:嵌入式系统是将计算能力整合到设备中的专用系统,它们...

    aarch64-linux-android-4.9

    “Android”标签明确了这个工具与Android操作系统及其生态系统紧密相关。Android是一个开源的操作系统,广泛应用于智能手机、平板电脑等移动设备。在Android平台上开发应用时,开发者可以选择使用Java或Kotlin等高级...

    arm-fsl-linux-gnueabi-交叉编译工具链

    - "linux" 表明它是为Linux操作系统编译的。 - "gnueabi" 指的是GNU/Linux的嵌入式应用二进制接口(EABI),定义了应用程序如何与操作系统交互的规则。 使用交叉编译工具链的过程通常包括以下步骤: 1. **配置**: ...

    Qt交叉编译后aarch64-linux-gnu-成功运行在Zynq UltraScale+MPSoC上

    在本文中,我们将深入探讨如何将Qt交叉编译为aarch64-linux-gnu架构,并成功在Zynq UltraScale+ MPSoC平台上运行。这个过程适用于公司项目,特别是在Zynq UltraScale+ MPSoC(ZU9EG)处理器上运行具有软键盘功能的Qt...

    gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_windows.zip

    这个工具链允许在Windows操作系统上构建和调试适用于ARM/Linux系统的应用程序。 GCC是GNU项目的核心组成部分,它是一个开源的编译器套件,支持多种编程语言,包括C、C++、Fortran、Objective-C、Ada等。在这个版本...

    mips64el-linux-android-4.9

    Linux操作系统广泛应用在各种设备上,包括服务器、路由器、嵌入式设备等,而MIPS64el作为其中的一种处理器架构,有着广泛的应用场景。 从压缩包子文件的文件名称列表"mips64el-linux-android-4.9"来看,这个压缩包...

    secoclient-linux-32-64-7.0.2.26.zip

    这个压缩包"secoclient-linux-32-64-7.0.2.26.zip"包含了适用于Linux操作系统的SecoClient的32位和64位版本,版本号为7.0.2.26。这意味着它可以安装在各种基于Linux的系统上,无论是32位还是64位架构,为用户提供...

    mariadb-10.11.2-linux-systemd-x86-64.tar.gz

    这个名为“mariadb-10.11.2-linux-systemd-x86_64.tar.gz”的压缩包文件,显然是针对Linux操作系统,采用Systemd作为初始化系统的x86_64架构的MariaDB 10.11.2版本。 MariaDB的核心特点包括: 1. 兼容性:MariaDB...

    x86_64-unknown-linux-gnu-9.2.0.tar.gz

    描述中提到的"compile linux from windows"表明了用户打算在Windows操作系统下编译Linux平台的代码。为了实现这一目标,他们需要一个能够理解并生成Linux可执行文件的编译器,这就是x86_64-unknown-linux-gnu交叉...

    Linux -lglib-2.0 缺失时要用的 arm64下的链接库

    在Linux系统中,`-lglib-2.0` 是一个链接器选项,用于指示编译器在构建可执行程序时链接GLib库版本2.0。GLib是GObject系统的基础,它提供了核心数据类型、低级内存管理、线程支持、事件循环和定时器等关键功能,广泛...

Global site tag (gtag.js) - Google Analytics