精华内容
下载资源
问答
  • 目录 1.实验说明 1.1 DSE简介 符号执行 (Symbolic Execution)是一种程序分析技术,它可以通过分析程序来得到让特定代码区域执行的输入。顾名思义,使用符号执行分析一个程序时...动态符号执行是以具体数值作为输入来

    目录

    1.实验说明

    1.1 DSE简介

    符号执行 (Symbolic Execution)是一种程序分析技术,它可以通过分析程序来得到让特定代码区域执行的输入。顾名思义,使用符号执行分析一个程序时,该程序会使用符号值作为输入,而非一般执行程序时使用的具体值。在达到目标代码时,分析器可以得到相应的路径约束,然后通过约束求解器来得到可以触发目标代码的具体值。

    符号执行在发展过程中出现了一种叫做动态符号执行的方法(concrete and symbolic, concolic)。动态符号执行是以具体数值作为输入来模拟执行程序代码,与传统静态符号执行相比,其输入值的表示形式不同。动态符号执行使用具体值作为输入,同时启动代码模拟执行器,并从当前路径的分支语句的谓词中搜集所有符号约束。然后修改该符号约束内容构造出一条新的可行的路径约束,并用约束求解器求解出一个可行的新的具体输入,接着符号执行引擎对新输入值进行一轮新的分析。通过使用这种输入迭代产生变种输入的方法,理论上所有可行的路径都可以被计算并分析一遍。

    1.2 实验要求

    • 基于llvm和Z3求解器实现基本的动态符号执行工具
    • 设计路径搜索策略,发现测试程序中的ERROR
    • 分析不可达路径的测试用例执行情况

    2.实验环境

    2.1 软件环境

    软件/系统 版本
    Ubuntu(虚拟机) 18.01
    Clion 2020.02.1
    llvm 8.0.1
    Z3 4.8.8

    2.2 实验环境配置

    1. 本次实验原本是在MacOs上进行的,但是由于最终在运行程序时,需要加载动态库libruntime.在Ubuntu下是需要导入环境变量LD_LIBRARY_PATH,这基本等同于在MAC下配置DYLD+LIBRARY_PATH的环境路径,但是运行时的动态库加载却一时无法加载。因此,我直接选择了在Ubuntu下对环境进行重新的配置。
    2. 安装LLVM。
      本次实验推荐安装的LLVM版本为8.0.1,直接在github代码库中下载,进行源码编译即可(首次编译时间可能过长,可以开启多线程编译,缩短时间)。同时设置好LLVM的环境变量。
    3. 安装Z3。
      Z3可以选择对应系统的已编译完成的二进制源码即可,同样可以再gtthub release中下载对应4.8.8版本。(ubuntu18.04选择ubuntu16.0.4版本下载即可)。同时设置好Z3_DIR的环境变量。
    4. Clion
      作为代码的编辑器,同时管理CMakeFile文件。

    3.实验步骤

    3.1 整体流程

    ./dse ./branch0 N
    循环次数小于N
    从input.txt 中读符号变量的值
    符号执行
    测试程序是否崩溃
    程序执行结束
    应用搜索策略
    Z3求解
    产生新的input.txt
    1. 在流程图中,N决定尝试找寻有效路径的次数。
    2. input.txt没有初值时,会根据符号化的变量产生对应符号的随机值。
    3. 每次测试程序执行时,如果成功执行,会将路径约束记录下来。
    4. 根据路径约束和搜索策略可以得到另外一条可满足的约束路径(本次实验所采用的就是DFS搜索策略)

    3.2 插装函数

    我们插装的目的是为了进行符号运算。只有通过插装函数,才能跟踪程序执行过程中符号关系以及赋值的变化。

    1. 初始化
      在LLVM main函数执行之初插装
      __DSE__Init__
      __DSE_Init__插装位置

    2. LLVM-IR alloc
      __DSE_Alloc__插装位置

    3. LLVM_IR Stroe
      当Store指令的第一个操作数为常数时,需要先调用__DSE_Const__将常数压入DSE栈中。
      __DSE_Store__指令插装位置1
      当Store指令的第一个操作数为寄存器时,需要先调用__DSE_Register__将寄存器压入DSE栈中。
      __DSE_Store__指令插装位置2

    4. LLVM_IR Load

    __DSE_Load__指令插装位置

    1. LLVM_IR BinarryOperator
      BinOp插装之前需要先将BinOp的两个操作数首先压如到DSE栈中,然后插装BinOp指令。
      插装两个操作数是首先需要判断操作数的类别是寄存器还是常数,调用不同的入栈函数。

    __DSE_BinOp指令插装位置

    上图表示的第一个操作数是寄存器,第二个操作数是常数的情况。

    1. LLVM-IR Icmp
      Icmp指令插装是首先需要把两个操作数调用指令压入DSE栈中,类似于DSE_BinOp的插装.
      __DSE_Icmp__指令插装位置
      上图表示两个操作数都是寄存器。

    2. LLVM-IR Branch
      br指令在LLVM指令集中有两种形式,一种是无条件跳转,这种指令不需要进行任何插装。对于条件指令,需要在运行路径上插装,不能简单地插装在现有的任何一个代码块中。

    对于条件语句的插装位置一种简单的实现方式就是在跳转的代码块之间建立一个新的代码块,在新的代码块中插入跳转指令的插装函数。

    ; 原llvm
    br i1 %cmp, label %for.body, label %for.end
    
    for.body:      
    xxx
    
    for.end:  
    xxx
    
    
    ; 插装后llvm
    br i1 %cmp, label %for.body_temp, label %for.end_temp
    
    for.body:      
    xxx
    
    for.end:  
    xxx
    
    for.body_temp:                                    ; preds = %for.cond
    call void @__DSE_Branch__(i32 0, i32 7, i32 1)
    br label %for.body
    
    for.end_temp:                                     ; preds = %for.cond
    call void @__DSE_Branch__(i32 0, i32 7, i32 0)
    br label %for.end
    
    

    3.3 运行时函数

    插装函数是作为钩子函数嵌入在代码中,当程序运行时,会调用外部动态库中相应名称的函数方法。
    在所给的程序代码框架中已经对如下LLVM函数实现了插装函数的运行时函数:

    LLVM函数 对应插装函数 功能
    XX __DSE_Input__
    br __DSE_Branch__ 在对应需要跳转的路径上记录跳转条件
    xx __DSE_Const__ 将常量压入DSE栈中
    xx __DSE_Register__ 将寄存器压入DSE栈中
    xx __DSE_Init__ 初始化新的DSE栈和DSE内存
    xx __DSE_Exit__ 将执行路径条件打印到日志中
    1. DSE_Alloca
      在DSE内存中存储分配变量的地址。
    2. DSE_Store
      从栈中取值,赋值给传过来的寄存器(该寄存器已经在DSE内存中)。
    3. DSE_Load
      从DSE内存中将一个值赋值另一个寄存器。
    4. DSE_ICmp
      从DSE栈中取出两个操作数,并且根据操作符进行比较,将结果分配给传入的寄存器。
    5. DSE_BinOp
      从DSE栈中取出两个操作数,并且根据操作符进行运算,将结果分配给传入的寄存器。

    3.4 搜索策略

    本次实验采用的是DSE的深度优先搜索的策略。
    大致过程如下:

    1. 首先构造一个二叉树根节点,(值为空,左右节点为空)
    2. 当前一次条件过来时执行如下步骤(条件顺序就是路径顺序):
    3. 以根节点作为当前节点。
    4. 如果左节点为空,将该条件加入左节点(新建节点),左节点作为当前节点。
    5. 如果左节点条件与该条件等价,那么左节点作为当前左节点。
    6. 如果右节点为空,那么将条件加入到右节点(新建右节点)。
    7. 如果右节点与当前条件等价,那么右节点作为当前节点。
    8. 跳至第四步操作,直至条件循环。
    9. 得到最新的当前节点
    10. 如果当前节点为左节点,同时它的邻居右节点为空,那么将该节点的值取反加入到右节点,右节点成为当前节点。
    11. 如果当前节点为右节点,需要向上取其父母,直到有邻居右节点为空,执行第10步的操作。如果找不到这样的节点,说明条件搜索完毕。

    4.实验结果

    4.1 测试用例1分析(branch0)-崩溃测试

    // branch0.c
    int main() {
      int x;
      DSE_Input(x);
      int y;
      DSE_Input(y);
      int z;
      DSE_Input(z);
    
      if (x == 0) {
    	 if (y == z) {
    		x = x / (y-z);
    	 }
      }
    
      return 0;
    }
    

    该程序对x、y、z进行了符号化。

    dse程序对该程序执行的结果如下:
    结果1

    同时log.txt中的内容如下:

    === Inputs ===
    X0 : 0
    X1 : 1035168130
    X2 : 180465486
    
    === Symbolic Memory ===
    140733207362528 : X2
    140733207362532 : X1
    140733207362536 : X0
    140733207362540 : 0
    R0 : |140733207362540|
    R1 : |140733207362536|
    R2 : |140733207362532|
    R3 : |140733207362528|
    R4 : X0
    R5 : (= 0 X0)
    R6 : X1
    R7 : X2
    R8 : (= X2 X1)
    
    === Path Condition ===
    B0 : (= (= 0 X0) true)
    B1 : (= (= X2 X1) false)
    
    === New Path Condition ===
    (= (= 0 X0) true)
    (not (= (= X2 X1) false))
    
    

    对比运行结果,我们发现,即使程序设置是5次迭代,但是在第2次时,由于最新的路径条件
    (=(=0X0)true) (= (= 0 X0) true)
    (not(=(=X2X1)false)) (not (= (= X2 X1) false))
    ,使得程序崩溃。

    同时发现,搜索策略对第二条路径直接取反,成为了新的路径条件。

    4.2 测试用例2分析(branch0-1)-分支测试

    //branch0-1.c
    int main() {
      int x;
      DSE_Input(x);
      int y;
      DSE_Input(y);
      int z;
      DSE_Input(z);
    
      if (x > 0) {
    	 if (y > 0) {
    	     if (z > 0)
    		x = x;
    	 }
      }
    
      return 0;
    }
    

    观察该程序,发现该程序的路径有4条。

    运行结果如下:
    结果2

    结合上面的输出,可以画出执行路径:
    路径1
    路径2
    路径3
    路径4

    4.3 测试用例3分析(infeseable)-不可达测试

    int main() {
      int x;
      DSE_Input(x);
    
      //c is a product of two primes 
      int c = 181 * 191;
    
      int y = 1;
    
      for(int i=0; i<x; i++){
    	y *= 2;
      }
    
      if (y % c == 17) {
      	x = x / (c-c);
      }
      return 0;
    }
    

    该函数的路径数取决于x。x越大路径数越多。由于该原型设计的深度优先搜索策略,以第一次输入的路径为基础。
    当x固定输入10时:
    结果
    在for循环内执行10次,接着是一次不满足的for循环条件,接下来是一个没有被符号化的条件。
    第二次条件为:
    结果
    根据深度优先搜索,之后的条件都会与(=(<0X0)true)(= (< 0 X0) true)矛盾,因此,直接产生第三次的可满足的条件:
    结果
    此时该次DFS搜索全部结束。
    由于我在程序中加入了break语句,在搜索完毕后直接退出,但是如果继续重置搜索二叉树,生成随机的x,从而产生y,满足非符号化的条件,生成这样的随机x的概率很小。
    x=log2(17+181191r),rN,s.t.xN x=\log_2{(17+181*191*r)},r\in\N,s.t. x\in\N

    代码资源下载

    展开全文
  • 链接选项 -rdynamic与动态符号

    千次阅读 2018-04-10 22:01:46
    注意,这是链接选项,而不是编译选项。在将c文件编译成.o的过程中,使用rdynamic是没有任何...一个验证方法显示可执行程序文件内的动态符号(注意,仅仅是动态符号):readelf -Ds a.out默认情况下,可执行程序(...
    注意,这是链接选项,而不是编译选项。
    在将c文件编译成.o的过程中,使用rdynamic是没有任何效果的。
    只有将.o链接成elf时,才有效果。

    这主要是对可执行程序而言的,而编译动态库时,即使没有rdynamic选项,默认也会将非静态函数放入动态符号表中(刻意隐藏的函数除外)。

    一个验证方法
    显示可执行程序文件内的动态符号(注意,仅仅是动态符号):
    readelf -Ds a.out

    默认情况下,可执行程序(非动态库)文件内我们定义的非静态函数,是不放到动态符号表中的,链接时只有加上-rdynamic才能将所有非静态函数加到动态符号表中。
    但qin_dev中编译生成的resource_manager,不加rdynamic的情况下,里面依然会有大量动态符号,why?什么情况下,即使没有-rdynamic选项,可执行程序内的很多函数也放到动态符号表中???

    一个猜想(待验证):
    resourcemanage中为何不加rdynamic也会有大量动态符号,我猜这可能和编译器对寻址模式的优化有关。helloworld小程序,不加rdynamic就没有动态符号,这是因为程序太小了,使用短距离的寻址指令完全够用了。但resourcemanager太大,很多跨文件的调用,不得不采用动态符号表作为跳板来进行远距离寻址。
    展开全文
  • 选项 -rdynamic 用来通知链接器将所有符号添加到动态符号表中  (目的是能够通过使用 dlopen 来实现向后跟踪)  -rdynamic  Pass the flag ‘-export-dynamic’ to the ELF linker, on targets that support ...
    选项 -rdynamic 用来通知链接器将所有符号添加到动态符号表中 
    (目的是能够通过使用 dlopen 来实现向后跟踪) 
    -rdynamic 
    Pass the flag ‘-export-dynamic’ to the ELF linker, on targets that support 
    it. This instructs the linker to add all symbols, not only used ones, to the 
    dynamic symbol table. This option is needed for some uses of dlopen or to 
    allow obtaining backtraces from within a program. 
      
    比如日志系统,主程序里使用一套日志系统,dlopen方式打开的libso里无法使用。编译时加上这个参数,不需要增加任何代码就可以使代码通用。 
      
    网上搜到上面的说法 
    没看太明白 
    是不是可以理解为 
    我现在有 A.o  B.so 
    然后我可以g++ -rdynamic A.o B.so -shared -o C.so 
    然后我用C.so的时候 可以不必依赖B.so了? 
    我试了试 貌似这个选项不生效啊 
    还是说 对B.so有什么限制? 
      
    还是说 只是将符号表全部添加进去 而不是只添加实现的那部分符号表? 这有什么好处? 
      
    其实我的需求是这样的 
    我原来用了开源的ACE  我本机编译时没问题 
    现在一发布时  我都要写个脚本去创建libACE.conf 指明ACE的路径 
    我嫌麻烦(自己到是不麻烦,主要是公司实施员工水平不行,经常连脚本都不会运行) 
    所以我现在期望能程序启动时 直接运行 
    我代码里有一部分需要使用到ACE 具体的说 就是继承并实现了ACE_Task 
    这导致我的工程必须在编译时需要 -lACE 
    有什么办法  能让我运行时 不修改系统任何配置就能加载libACE.so? 
    我在stackoverflow上问了下  有个回帖的说用-rdynamic  但我试了试  好像只导入符号表  没有把实现链接进去 
    展开全文
  • 关于动态符号表及“全局符号表”

    千次阅读 2018-04-10 21:54:15
    elf.h中对符号表的类型定义如下:#define DT_STRTAB 5 /* Address of string table */#define DT_SYMTAB 6 /* Address of symbol table */这里DT_SYMTAB与DT_STRTAB对应的section其实是.dynsym和.dynstr,而非....
    elf.h中对符号表的类型定义如下:
    #define DT_STRTAB 5 /* Address of string table */
    #define DT_SYMTAB 6 /* Address of symbol table */

    这里DT_SYMTAB与DT_STRTAB对应的section其实是.dynsym和.dynstr,而非.symtab和.symstr!

    .symtab和.dynsym两个不同的symbol table, 它们有什么区别?
    .dynsym是.symtab的一个子集, 为什么要两个信息重合的结构?
    需要先了解allocable/non-allocable ELF section, ELF文件包含一些sections(如code和data)是在运行时需要的, 这些sections被称为allocable; 而其他一些sections仅仅是linker,debugger等工具需要, 在运行时并不需要, 这些sections被称为non-allocable的. 当linker构建ELF文件时, 它把allocable的数据放到一个地方, 将non-allocable的数据放到其他地方. 当OS加载ELF文件时, 仅仅allocable的数据被映射到内存, non-allocable的数据仍静静地呆在文件里不被处理. strip就是用来移除某些non-allocable sections的.
    .symtab包含大量linker,debugger需要的数据, 但并不为runtime必需, 它是non-allocable的; .dynsym包含.symtab的一个子集, 比如共享库所需要在runtime加载的函数对应的symbols, 它世allocable的.
    因此, 得到答案:
    1. strip移除的应是.symtab.
    2. nm读取的应是.symtab: 上面发现的libattr等nm结果为空, libpthread nm结果非空应是正常的. 3. 共享库包含的.dynsym是runtime必需的, 是allocable的.

    另外,很多资料上经常用到的一个概念是“全局符号表“,其实这是一个伪概念,内存中并不存在这样一个表,libdl中会将所有已加载到内存中的可执行模块(主程序或动态库)的相关指针放入一个全局的链表中,通过这个全局链表可以访问到所有可执行模块的动态符号表,仅此而以。我们可以假定这个全局链表是一个“全局符号表“,但其存储的内容远远不止符号表这么简单,而是可执行模块的所有相关信息,如重定位信息、代码段地址、got段地址等。

    例子:
    [lubo@localhost src]$ mipsel-linux-readelf -S main.elf
    There are 42 section headers, starting at offset 0xef4:
    Section Headers:
    [Nr] Name Type Addr Off Size ES Flg Lk Inf Al
    [ 0] NULL 00000000 000000 000000 00 0 0 0
    [ 1] .interp PROGBITS 00400154 000154 000014 00 A 0 0 1
    [ 2] .reginfo MIPS_REGINFO 00400168 000168 000018 18 A 0 0 4
    [ 3] .dynamic DYNAMIC 00400180 000180 000110 08 A 6 0 4
    [ 4] .hash HASH 00400290 000290 0000a4 04 A 5 0 4
    [ 5] .dynsym DYNSYM 00400334 000334 000160 10 A 6 1 4
    [ 6] .dynstr STRTAB 00400494 000494 00010a 00 A 0 0 1
    [ 7] .gnu.version VERSYM 0040059e 00059e 00002c 02 A 5 0 2
    [ 8] .gnu.version_r VERNEED 004005cc 0005cc 000020 00 A 6 1 4
    [ 9] .rel.plt REL 004005ec 0005ec 000018 08 A 5 11 4
    [10] .init PROGBITS 00400604 000604 000048 00 AX 0 0 4
    [11] .plt PROGBITS 00400660 000660 000050 00 AX 0 0 32
    [12] .text PROGBITS 004006b0 0006b0 000240 00 AX 0 0 16
    [13] .MIPS.stubs PROGBITS 004008f0 0008f0 000020 00 AX 0 0 4
    [14] .fini PROGBITS 00400910 000910 000038 00 AX 0 0 4
    [15] .eh_frame_hdr PROGBITS 00400948 000948 000014 00 A 0 0 4
    [16] .eh_frame PROGBITS 0041095c 00095c 000030 00 WA 0 0 4
    [17] .ctors PROGBITS 0041098c 00098c 000008 00 WA 0 0 4
    [18] .dtors PROGBITS 00410994 000994 000008 00 WA 0 0 4
    [19] .jcr PROGBITS 0041099c 00099c 000004 00 WA 0 0 4
    [20] .data PROGBITS 004109a0 0009a0 000010 00 WA 0 0 16
    [21] .rld_map PROGBITS 004109b0 0009b0 000004 00 WA 0 0 4
    [22] .got.plt PROGBITS 004109b4 0009b4 000014 00 WA 0 0 4
    [23] .got PROGBITS 004109d0 0009d0 00000c 04 WAp 0 0 16
    [24] .sdata PROGBITS 004109dc 0009dc 000004 00 WAp 0 0 4
    [25] .bss NOBITS 004109e0 0009e0 000020 00 WA 0 0 16
    [26] .pdr PROGBITS 00000000 0009e0 000080 00 0 0 4
    [27] .comment PROGBITS 00000000 000a60 000038 01 MS 0 0 1
    [28] .debug_aranges MIPS_DWARF 00000000 000a98 000020 00 0 0 1
    [29] .debug_pubnames MIPS_DWARF 00000000 000ab8 00001b 00 0 0 1
    [30] .debug_info MIPS_DWARF 00000000 000ad3 0000cc 00 0 0 1
    [31] .debug_abbrev MIPS_DWARF 00000000 000b9f 00006a 00 0 0 1
    [32] .debug_line MIPS_DWARF 00000000 000c09 000040 00 0 0 1
    [33] .debug_frame MIPS_DWARF 00000000 000c4c 00002c 00 0 0 4
    [34] .debug_str MIPS_DWARF 00000000 000c78 0000a5 01 MS 0 0 1
    [35] .debug_loc MIPS_DWARF 00000000 000d1d 00002c 00 0 0 1
    [36] .debug_pubtypes MIPS_DWARF 00000000 000d49 000012 00 0 0 1
    [37] .gnu.attributes LOOS+ffffff5 00000000 000d5b 000010 00 0 0 1
    [38] .mdebug.abi32 PROGBITS 00000030 000d6b 000000 00 0 0 1
    [39] .shstrtab STRTAB 00000000 000d6b 000186 00 0 0 1
    [40] .symtab SYMTAB 00000000 001584 000540 10 41 63 4
    [41] .strtab STRTAB 00000000 001ac4 00022c 00 0 0 1
    Key to Flags:
    W (write), A (alloc), X (execute), M (merge), S (strings)
    I (info), L (link order), G (group), x (unknown)
    O (extra OS processing required) o (OS specific), p (processor specific)
    从此处看出,symtab和strtab并没有被加载到内存中。
    展开全文
  • [授权发表]动态符号链接的细节

    千次阅读 2015-04-12 17:39:14
    而常规符号除了动态符号以外,还包含有一些静态符号,比如说本地函数,这个信息主要是调试器会用,对于正常部署的系统,一般会用strip工具删除掉。 关于 nm 与 readelf -s 的详细比较,可参考: nm vs “readelf -...
  • 导读: by falcon2008-02-26 Linux支持动态连接库,不仅节省了磁盘、内存空间,...这里主要讨论符号动态链接过程,即程序在执行过程中,对其中包含的一些未确定地址的符号进行重定位的过程[3][8]。 本篇主要参考
  • Linux动态链接库同名符号装载问题

    千次阅读 2012-09-03 16:02:48
    如果在创建动态链接的可执行文件不加–export-dynamic选项,则它所export的动态符号仅仅包括在链接时动态对象所用到的,因为dlopen是自行加载动态库,并不存在与可执行文件动态符号解析的过程,所以如果dlope
  • linux静态库 动态库 去符号 符号恢复

    千次阅读 2018-04-17 00:45:08
    最近遇到了一题去除符号的题目,需要进行符号修复。为此学习了一波,顺便补了补其它的一下知识。 准备知识 命名方式: 动态库libxxx.so.major.minor .so .dll 静态库:libxxx.a .a .lib 生成动态库 gcc -...
  • Linux的nm查看动态和静态库中的符号

    万次阅读 2016-07-10 20:58:13
    功能 列出.o .a .so中的符号信息,包括诸如符号的值,符号类型及符号名称等。所谓符号,通常指定义出的函数,全局变量等等。 ...-D 打印动态符号;-l 使用对象文件中的调试信息打印出所在
  • 调用动态库导致符号无法解析错误

    千次阅读 2016-10-16 10:20:41
    调用动态库的情况下,跨工程引入头文件导致的符号解析错误 对第三种情况进行详细说明  较为大型的项目常常会设置较多个工程,以其中一个工程为主工程(包含main函数),且该主工程通过调用其他子工程的静态库或...
  • Mac系统动态符号表分析

    千次阅读 2019-04-29 09:07:23
    查看符号表 # 查看 nm *.dylib nm -C *.dylib nm -P *.dylib nm -nm *.dylib -n,按照数字而不是默认的字符排序。 -r,符号按照反序显示 -C,以原代码显示 -P,以简单格式显示每一个符号 符号表分析 符号类型 ...
  • 找到了当时发生同名符号冲突的原因。当程序A调用.so模块B时,为了让被调用的B模块能够使用A模块中的一些函数,在编译A程序时...如果在创建动态链接的可执行文件不加–export-dynamic选项,则它所export的动态符号仅仅包
  • 解决动态库的符号冲突

    千次阅读 2019-05-24 11:28:33
    解决动态库的符号冲突 一次debug遇到的疑惑 动态库和符号表 和符号有关的编译器选项和环境变量选项 一次debug遇到的疑惑 某天发现一个程序有点问题。祭上print大法,在关键的 lib_func() 函数里添加 print ...
  • Linux动态链接(5)动态符号搜索顺序

    千次阅读 2016-08-03 21:25:32
    这里的动态搜索是指通过dlopen+dlsym来搜索动态符号的过程,而静态搜索则是指程序在运行的过程中的惰性链接实现。这里其实又是一个比较边界的问题,但是也是可能存在的,另外这些问题可以促使感兴趣的同学看一下...
  • 本文分析了linux环境下动态库和静态库导出相同符号所导致的符号冲突问题,通过构建问题模型并进行情景分析,提出解决方案,最后验证解决方案。
  • GCC制作动态库导出符号

    千次阅读 2017-08-09 13:48:57
    GCC制作动态链接库时默认会将所有的函数及变量都导出到符号表,正常情况下所有符号均导出是不会有问题的,但是有时会有问题。为了避免这种情况,就需要定制符号表,即仅仅将需要提供给其他模块使用的接口或变量导出...
  • 动态库、可执行文件符号表分析

    千次阅读 2020-04-20 12:21:19
    分析最后的可执行文件和动态库文件的符号表; 1.1 第一个C文件:basic.c 这个C文件只定义并实现了四个不同形参的函数、五个静态变量、一个全局变量。由于只关心符号表或者其他二进制内容,因此不具体实现特定功能....
  • 浅谈动态符号的私有化与全局化

    千次阅读 2013-05-12 01:13:57
    之前一篇《记一个链接库导出函数被覆盖的问题》中,描述了这样一个问题:动态库若想使用自己的符号,不受可执行程序(或其他动态库的影响),可以使用-Wl,-Bsymbolic链接参数或version_script来让动态库的符号自我...
  • 动态链接库符号表问题

    千次阅读 2020-02-25 17:37:21
    当链接动态库时出现下面这样的错误时,一般是动态库生成的编译选项问题 found local symbol '__bss_start' in global part of symbol table found local symbol '_edata' in global part of symbol table found ...
  • linux命令之查看动态符号-nm

    千次阅读 2017-11-22 16:46:36
    在调用动态库的时候,由于动态库接口修改或者版本不匹配出现调用动态库找不到函数接口符号的情况。 原因可能有如下几种: 1.由于c++动态库编译没有加extern c导致函数编译时加了c++的前缀的; 2.系统中有多个库,...
  • 动态库的符号隐藏

    千次阅读 2017-11-28 13:29:27
    • 通过版本控制脚本--version-script= libc.map 传送到gcc并用-Wl 链接,便会隐藏不需要对外公开的函数符号.-Wl 是用來隔開兩參數反傳送到連接器上的選項. – 庫的利用者不能看到非公開的API – 共享庫的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 351,411
精华内容 140,564
关键字:

动态符号