
编译链接
文章平均质量分 68
Virtual_Func
小风扇吹风好吵
展开
-
动态链接过程延迟绑定的实现(PLT)
动态链接比静态链接要慢1%~5%,根据动态链接中PIC(与地址无关代码)的原理PIC,可以知道造成该情况的原因如下:1.动态链接下对于全局和静态数据的访问都要进行复杂的GOT(全局偏移表)定位,然后间接寻址;对于模块间的调用也要先定位GOT,然后再进行跳转2.动态链接的链接工作是在运行时完成,即程序开始运行时,动态链接器都要进行一次链接工作,而链接工作需要复杂的重定位等工作,减慢了启动速度原创 2015-09-28 21:18:21 · 5051 阅读 · 0 评论 -
Window创建并使用动态链接库
1.关于导出符号动态链接库给外部文件提供一些函数或变量,将这种提供函数或变量的行为称为导出符号。而外部文件使用这些函数或变量的行为则称为导入符号。在Linux 的ELF文件中,默认导出共享对象中的所有全局符号,而在 Windows 中的 DLL 中,则默认所有符号都不导出;因此,在 DLL 中需要显示的指定哪些符号是导出的符号,有以下两种方式指定一个符号是否导出:1).__decl原创 2015-10-07 23:14:05 · 545 阅读 · 0 评论 -
详解LMA(装载内存地址)与VMA(虚拟内存地址)
关于LMA和VMA,这个问题,有点点小复杂,不过,此处,我会把我的理解,尽量通过通俗的方式解释出来,以方便理解。当然,鄙人水平有限,难免有错,希望各位批评指正。一般提及LMA和VMA,多数情况都是和ld,链接器相关的。在了解这两个名词的详细含义之前,有些基本知识和前提要说一下:[基础知识]1。从你写的源代码到执行你的程序,一般经历了这几个过程:源代码编辑 -> 编译 ->转载 2015-09-20 21:55:03 · 908 阅读 · 0 评论 -
进程虚拟空间分布中特殊的VMA
进程虚拟地址空间分布中,有几个特殊的区域,它们并不会映射到可执行文件内,分别为:堆、栈、vdso1.堆堆是由系统库进行管理的,我们通过C语言的 malloc() 内存分配函数分配到的空间就是在堆中分配的;2.栈也称堆栈,每个线程都有属于自己的堆栈。3.vdso事实上,“vdso”的地址已经位于内核空间了(即大于0xC0000000),它是一个内核的模块,进程可以通过它来与内原创 2015-09-20 22:13:25 · 748 阅读 · 0 评论 -
malloc 与 alloca 与 calloc 的区别
C语言跟内存分配方式(1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。(2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。(3)从堆上分配,亦称动态内存分配。程序在运行的时候转载 2015-10-25 19:52:18 · 1479 阅读 · 0 评论 -
可执行文件从装载到运行的全过程描述
我们的源代码通过预处理,编译,汇编,链接后形成可执行文件,(关于源代码到可执行文件的介绍见我的另一篇博客:程序从代码到可执行文件的过程简述)那么当我们在cmd窗口敲出指令$test argv1 argv2\n 后,操作系统是怎么将我们的可执行文件加载并运行的呢?首先知道,计算机的操作系统的启动程序是写死在硬件上的,每次计算机上电时,都将自动加载启动程序,之后的每一个程序,每一个应用,都原创 2015-09-21 21:53:36 · 3590 阅读 · 0 评论 -
动态链接知识点
1.基本思想:动态链接的基本思想是:将链接的过程推迟到运行时再执行。2.动态链接文件的格式:在LINUX 中,ELF的动态链接文件被称为动态共享对象(DSO,dynamic shared object),以.so为扩展名的文件在WINDOWS中,EP的动态链接文件被称为动态链接库(DLL,dynamic link library),以 .dll 为扩展名的文件3原创 2015-09-22 23:23:59 · 888 阅读 · 1 评论 -
Windows 下实现线程局部存储
以下叙述的仅是Windows NT,XP 等系统下实现线程局部存储的一个思路,并不是绝对的实现方法。线程局部存储(Thread Local Storage,TLS),是多线程普及的情况下一个很有用的机制,该机制使得线程可以使用属于自己的全局变量。只需要在一个全局变量的定义前加上相应的关键字,即可指定一个全局变量为TLS属性的。GCC:__thread int number;Window原创 2015-10-26 23:23:44 · 1325 阅读 · 0 评论 -
动态链接库中与地址无关代码(PIC)对于地址引用的处理
动态链接库希望所有进程共享指令段而各自拥有数据段的私有副本,为了实现这个目标,就要采用与地址无关代码(PIC: Position Independent code)的技术。该实现的基本思想是:把指令中需要修改的部分分离出来,跟数据部分放在一起,这样指令部分就可以保持不变,而数据部分则在每个进程拥有一个副本。与地址无关的代码,也就是需要考虑代码中会对地址进行引用的情况,共享对象(GCC中原创 2015-09-23 22:54:22 · 3965 阅读 · 0 评论 -
弱符号与强符号,弱引用与强引用
1.弱符号与强符号对C/C++而言,编译器默认函数和初始化了的全局变量为强符号。未初始化的全局变量为弱符号。此处弱符号与强符号均是针对定义来说的,不是针对符号的引用。也可以通过GCC的 “__attribute__((weak))”来定义任何一个强符号为弱符号。extern in ext;int weak;int strong = 1;__attribute__((weak)) in原创 2015-09-18 22:07:08 · 1863 阅读 · 0 评论 -
目标文件ELF中的内容
1.目标文件格式简述源文件经过编译器后生成目标文件,目标文件按照可执行文件的格式来存储,最初的可执行文件的格式为COFF,经过演变,现在的 windows下的可执行文件的格式为PE-COFF格式,而linux下的可执行文件的格式为ELF 格式。两种格式很类似。2.目标文件内容简述目标文件是以段的形式存储的。目标文件中包含了很多段,其中,程序源代码编译后的机器指令被放置在代码段(原创 2015-09-18 21:36:10 · 704 阅读 · 0 评论 -
Windows与Linux动态链接库技术的对比
Windows与Linux动态链接库区别概述Windows与Linux对动态链接库的实现虽然思想相同,但是使用方式却有些不同。下表总结了这一区别。linux gccwindows vc生成静态库gcc -c calc.c -o calc.oar rcs libcalc.a calc.o转载 2015-10-07 22:19:48 · 675 阅读 · 0 评论 -
ELF中与动态链接相关的段
在Linux 下,动态链接器 ld.so 是一个共享对象,操作系统同样通过映射的方式将其加载到进程的地址空间中。操作系统在加载完动态链接后,将控制权交给动态链接器的入口地址,动态链接器执行一系列自身的初始化操作,而后根据当前的环境参数,对可执行文件进行动态链接工作,完成后将操作系统的控制权交给可执行文件的入口地址。动态链接使用了很多的段信息,以下简述这些段:1 .interp 段动态链原创 2015-09-28 23:05:14 · 3186 阅读 · 0 评论 -
程序入口函数与初始化
1.概述程序执行过程:1)操作系统在创建进程后,将控制权交给了程序的入口,这个入口通常是运行库的某个入口函数2)入口函数对运行库和程序运行环境进行初始化,包括堆,IO,线程,全局变量的构成3)入口函数完成初始化后,调用 main 函数,正式执行程序主题4)main函数执行完毕后,返回到入口函数,入口函数进行清理,包括全局变量析构,堆销毁,关闭I/O等,然后进行系统调用结束进程。原创 2015-10-19 23:02:37 · 1296 阅读 · 0 评论 -
显示运行时链接的函数与例子,dlopen,dlsym,dlerror,dlclose
Linux提供一组函数用来支持显示运行时链接,具体来说,有四个函数:打开动态链接库(dlopen),查找符号(dlsym),错误处理(dlerror),以及关闭动态库(dlclose)。这几个函数的声明与相关常量定义在系统标准头文件中。1. void * dlopen(const char * filename,int flag);该函数用来打开动态库,并将其加载到进程的地址空间,原创 2015-10-04 23:11:05 · 2400 阅读 · 0 评论 -
动态链接的步骤与实现
动态链接器本身也是一个共享对象,但事实上其本身具有一些特殊性。动态链接器要能完成对普通共享对象的链接与装载,那对链接器本身,其重定位工作又该由谁来完成?1.对动态链接器的要求: 为了解决上述的问题,对动态链接器有以下两个要求:1.动态链接器本身不可以依赖于其他共享对象2.动态链接器本身所需要的全局与静态变量的重定位工作要由其自身完成2.满足要求的办法:对于动态链接器的原创 2015-10-04 20:30:53 · 1327 阅读 · 0 评论 -
程序从代码到可执行文件的过程简述
代码编写结束后,使用IDE(集成开发环境)直接编译就可以得到可执行文件。在这个过程中,IDE进行了很多内部操作。分别为:预处理,编译,汇编,链接。之后按序简述每一个步骤的执行1.预处理GCC预编译的指令为:$gcc -E hello.c -o hello.i ,C++文件预编译后的扩展名为:hello.ii预编译步骤主要操作源代码文件中以“#” 开始的预编译指令。主要处理规则如原创 2015-09-16 22:30:59 · 2406 阅读 · 0 评论 -
将目标文件分为程序段与数据段两大类的原因
目标文件中有很多段,根据其性质进行分类可分为两类,一类是程序段,代码段即属于程序段;另一类是数据段,.bss段和.data 段均属于数据段。这样划分的原因如下:1.可以防止程序的指令被有意或无意的改写:程序段中的指令通常都是不可写的,而数据段中的信息通常是可读写的。因此,将数据与指令分别映射到两个虚拟区域,并将这两个区域的权限分别设置为可读和读写,能够有效的防止程序指令被破坏原创 2015-09-17 23:10:20 · 847 阅读 · 0 评论 -
Linux 创建共享对象,共享库并安装使用共享库
linux的共享对象与Window下的动态链接文件是一个等价的概念,但是不同的操作系统对共享对象的存储方式不同。而Linux 的共享库也是共享对象的形式,是将多个源文件编译为一个共享对象的方式,这个共享对象就是共享库,现在共享对象与共享库的概念已经不再着重区分。1. Linux 编译共享对象假设现有源文件 a.c ,将其编译为共享对象的语句为:gcc -shared -fPIC a.c原创 2015-10-06 23:09:44 · 1145 阅读 · 0 评论 -
关于BSS段的大小
1.BSS段中的内容先明确 BSS 段存放的是未初始化的全局变量与局部静态变量,此处指的存放是指为其预留空间(占位符)。但BSS段在磁盘上不占用任何空间,它仅是记录所有未初始化全局变量与局部静态变量的大小总和。2.BSS段在加载运行前的处理当可执行文件加载运行前,会为BSS段中的变量分配足够的空间并全部自动清理(因此,才有未初始化的全局变量的值为0的说法)。3.BS原创 2015-09-17 21:44:20 · 4174 阅读 · 0 评论 -
系统调用与中断
在操作系统中,程序运行的时候,其本身是没有权利访问多少系统资源的,这是为了避免系统有限的资源可能被多个应用同时访问。为了让程序有能力访问系统资源,也为了让程序借助操作系统做一些必须由操作系统支持的行为,每个操作系统都会提供一套接口,供应用程序调用,这些接口通常通过中断来实现。现代操作系统中,CPU可以在多种不同的特权级别下执行指令,通常有用户模式与内核模式,也被称为用户态与内核态。应用程序原创 2015-10-27 22:16:19 · 6566 阅读 · 1 评论