首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

是什么导致一个变量出现在链接器映射文件中,而不是ELF符号表中?

一个变量出现在链接器映射文件(linker map file)中而不是ELF符号表(ELF symbol table)中,通常是由于以下几种情况导致的:

  1. 变量被声明为静态变量:静态变量在编译时就分配了内存空间,并且具有全局作用域,但是它们的可见性仅限于定义它们的源文件中。因此,静态变量不会出现在ELF符号表中,但会在链接器映射文件中出现。
  2. 变量被定义为内联(inline):内联变量是一种特殊的变量,其定义和声明通常出现在头文件中,并且在编译时会被直接插入到调用它的函数中,而不会生成独立的符号表项。因此,内联变量通常不会出现在ELF符号表中,但会在链接器映射文件中出现。
  3. 变量被优化掉:编译器在优化代码时可能会删除未被使用的变量,即使它们在源代码中有定义和声明。这种情况下,变量可能不会被包含在ELF符号表中,但在链接器映射文件中可能会有相应的提及。
  4. 变量定义位于动态链接库中:当变量定义位于动态链接库(dynamic link library)中时,它们通常不会直接出现在ELF符号表中,而是在链接器映射文件中被列出。这是因为动态链接库的符号表是在运行时加载的,并且在链接时不会被链接器直接处理。

需要注意的是,链接器映射文件(linker map file)是链接器生成的一种文本文件,用于描述链接过程中生成的符号、地址和大小等信息。ELF符号表(ELF symbol table)是一种特殊的数据结构,用于存储可执行文件或共享库中的符号信息。两者在功能和用途上略有不同,因此某些情况下,一个变量可能会出现在链接器映射文件中而不是ELF符号表中。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

ELF文件及android hook原理

链接视图和执行视图 ELF文件在磁盘中和被加载到内存不是完全一样的,ELF文件提供了两种视图来反映这两种情况:链接视图和执行视图。...符号表(.symtab) 在链接的过程需要把多个不同的目标文件合并在一起,不同的目标文件相互之间会引用变量和函数。在链接过程,我们将函数和变量统称为符号,函数名和变量名就是符号名。...每个变量都对应一个4字节的地址,链接在装载模块的时候会查找每个变量所在的地址,然后填充GOT的各个项,以确保每个指针所指向的地址正确。...动态链接的相关结构 .interp段 在动态链接ELF可执行文件,有一个专门的段叫做”.interp”段。里面保存的是一个字符串,记录所需动态链接的路径。...如果该符号表不是所需要的,那么chain[y]则给出了具有相同哈希值的下一个符号表项。

3.8K81

【C进阶】——我们写的代码是如何一步步变成可执行程序(.EXE)的?

每个目标文件链接(linker)捆绑在一起,形成一个单一完整的可执行程序。 3....我们上面提到过生成的目标文件test.o其实也是elf格式的,按照这个格式呢,会把文件分成一个一个的段,分别用来存放表示不同用途的数据。...最终链接之后生成的可执行文件不是也是elf格式的啊,那这个时候,它们就会把这些相同段的内容都放在一起,最终生成一个可执行程序: 这就是合并段表。...2.3.2 符号表的合并和重定位 那符号表的合并和重定位又是什么呢? 我们已经知道了在汇编阶段会生成符号表,这些符号往往是一些全局变量,函数名等和它们对应地址的映射。...当然如果add.c没有定义add函数,或者函数名我们写错的情况下,是不是也会因为符号表没有有效的信息报错。

89510
  • 动态链接的相关结构

    所以在映射完可执行文件之后,操作系统会先启动个动态链接( Dynamic Linker) 在 Linux下,动态链接ld.so实际上是一个共享对象,操作系统同样通过映射的方式将它加载到进程的地址空间中...是不是所有的*NX系统的动态链接都位于 /lib/ld.so呢?实际上,动态链接的位置既不是由系统配置指定,也不是由环境参数决定,而是由ELF可执行文件决定。...在动态链接ELF可执行文件,有一个专门的段叫做“ Interp”段(“ Interp”是“ Interpreter”(解释)的缩写)。...当系统的Glibc库更新或者安装其他版本的时候,/lib/ld-linux.so.2 这个软链接就会指向新的动态链接可执行文件本身不需要修改 ".interp" 的动态链接路径来适应系统的升级...类型多出了一个偏移为0x0000042c的入口,这个入口是什么呢?

    1.7K20

    《程序员的自我修养》笔记

    +符号的段偏移 在目标文件: 如果“符号所在段(st_shndx)”的值不是COMMON类型的,那么这个符号值代表的就是这个符号在文件的偏移,即符号所对应的函数或变量位于由st_shndx指定的段,...进程的虚拟空间 运行就是镜像,注意是映射不是加载(好像也没有区别吧,区别可能是一个不能修改一个可以修改吗),一面镜子映射着你的脸,他并没有真正拥有你的脸(加载到内存作为私有的数据可以修改)只是进行了映射...实体文件是真正加载到内存里面可以修改的,不是镜像只是模仿不可以修改 原文:映像(Image):因为PE文件在装载时被直接映射到进程的虚拟空间中运行,它是进程的虚拟空间的映像。...所以PE可执行文件很多时候被叫做映像文件(Image File)。 ELF静态链接 符号地址是什么 符号地址原来指定的是在段里面的偏移(我理解成偏移量就是 地址就行。...GOT实现地址无关(ELF格式采用) 因为数据段是可以修改的,因此got存放在数据段,那么自然got的偏移是知道的,然后*把这些外部链接的符号 统一放到got表里面(so记录的是共享库的导出符号表程序使用的是导入符号表不是所有共享库的符号陈序都药使用

    9010

    程序的编译、链接、装载与运行

    静态链接过程分为两步 扫描所有的目标文件,获取它们的每个段的长度、位置和属性,并将每个目标文件符号表的符号定义和符号引用收集起来放在一个全局符号表,建立起可执行文件到目标文件的段映射关系 读取目标文件的段数据...从上面的结果我们可以看到,链接过程确实是对目标文件的符号做了“粘合”操作。 问:重定位表和符号表之间是什么关系?...当使用到标准库的内容时,链接会对用户目标文件和标准库进行链接,得到最终的可执行文件链接过程的控制 链接默认情况下生成的是一个ELF文件,这在Linux操作系统上是符合我们的要求的。...每一个栈帧保存了一个函数的如下信息 函数的参数和返回地址 临时变量,包括非静态局部变量和编译生成的其它临时变量 保存的上下文 一个函数被调用时将会有如下操作 把所有的参数压入栈,有些参数也可以不压栈通过寄存进行传递...为了保存程序在运行时产生的全局变量 数据段:只能保存在编译时产生的变量 栈:只能在当前方法内部保存变量 系统调用的调用惯例和函数调用有些类似,但是系统调用使用寄存不是栈作为参数传递的载体 因为系统调用本质上也是函数

    1.3K10

    程序一定要从main函数开始运行吗?

    A: 这里涉及到程序链接的两个步骤: 空间与地址分配:扫描所有的输入目标文件,获得它们每个段的长度属性和位置,收集输入目标文件符号表的所有符号定义和符号引用,统一放到一个全局符号表,合并所有的段...,计算出输出文件各个段合并后的长度和位置,并建立映射关系。...,在链接扫描完所有的输入目标文件后,所有这种未定义的符号都应该能在全局符号表中找到,否则报符号未定义错误。...Tips: 现在的程序和库通常来讲都很大,一个目标文件可能包含成百上千个函数或变量,当需要用到某个目标文件的任意一个函数或变量时,就需要把它整个目标文件链接进来,也就是说那些没有用到的函数也会被链接进去...有一个编译选项叫函数级别链接,可以使得某个函数或变量单独保存在一个段里面,都链接需要用到某个函数时,就将它合并到输出文件,对于没用到的函数则将他们抛弃,减少空间浪费,但这会减慢编译和链接过程,GCC

    1.2K30

    动态链接的步骤与实现

    在编写动态链接时必须保证不使用任何系统库,运行库;对于第二个条件,动态链接必须在启动时有一段非常精巧的代码可以完成这项艰巨的工作同时又不能使用全局和静态变量。...从这一步开始,动态链接代码才可以使用自己的全局变量和静态变量。 实际上在动态链接的自举代码,除了不可以使用全局变量和静态变量之外,甚至不能调用函数,即动态链接本身的函数也不能调用。...装载共享对象 完成基本自举以后,动态链接将可执行文件链接本身的符号表都合并到一个符号表当中,我们可以称它为全局符号表( Global Symbol Table)。...然后链接开始从集合里取个所需要的共享对象的名字,找到相应的文件后打开该文件,读取相应的ELF文件头和“ .dynamic”段,然后将它相应的代码段和数据段映射到进程空间中。...所以整个进程,所有对于符合“a”的引用都会被解析到a1.so的函数a,这也是为什么main打印出的结果是两个“a1.c”不是理想的“alc”和“a2.c”。

    1.4K20

    从程序员角度看ELF

    链接然后通过指向程序符号表链接自己的符号表的若干指针来初始化一个符号   表链。从概念上讲,程序文件和所有加载到进程的库会共享一个符号表。...但实际链接   并不是在运行时创建一个合并后的符号表,而是将个个文件符号表组成一个符号表链。   ...在该过程结束时,所有的库都被映射进来了,加载拥有了一个由程序和所有映射进   来的库的符号表联合而成的逻辑上的全局符号表。   ...静态的初始化   如果一个程序存在对定义在一个的全局变量的引用,由于程序的数据地址必须在   链接时被绑定,因此链接不得不在程序创建一个变量的副本,如图4所示。...当链接创建一个使用共享库的程序时,它会列出程序所使用库的SONAME不是库   的真实名称。

    97940

    ELF文件格式解析

    链接视图只在链接起作用,执行视图只在加载并执行时起作用。   为什么需要区分两种不同视图?(即为什么要区分段和节?)内存分配和权限管理以页为单位,一节太小浪费空间,所以把相同权限的节放到一起管理。...SHT_DYNSYM 11 作为一个完整的符号表,它可能包含很多对动态链接而言不必要的符号。因此,目标文件也可以包含一个 SHT_DYNSYM 节区,其中保存动态链接符号的一个最小集合,以节省空间。...相关联的字符串表的节区头部索引 最后一个局部符号(绑定 STB_LOCAL)的符号表索引值加一 其它 SHN_UNDEF 0 Section 字符串表与符号表   一个ELF文件包含三张字符串表....dynstr .dynstr和.shstrtab一样存放的都是字符串,只不过字符串的用途不一样,后者是每个Section的名称,前者则是程序符号定义和引用的名称,通俗讲就是函数名和变量名,还有依赖的其他...ELF加载   经过测试,ELF文件被加载时会每个LOAD段的记录将文件进行加载,具体来说,就是将ELF文件从LOAD段的p_offset位置读取p_filesz大小的数据,映射到内存ELF基址+p_vaddr

    2.5K40

    【胖虎的逆向之路】——GOTPLT Hook详解&针对自定义so库的Hook实操

    ELF文件头又是什么西西?...其中Magic表示了这是一个ELF文件ELF 文件是以 7F 45 4C 46 开头 , 其中 7F 是一个二进制标志 , 45 4C 46 是 ELF 字符对应的 ASCII 码 ; 节头表...为了表示动态链接这些模块之间的符号导入导出关系,ELF一个叫做动态符号表(Dynamic Symbol Table)的段用来保存这些信息 .rel.dyn:实际上是对数据引用的修正,它所修正的位置位于...ELF文件在执行视图中是 以段(Segment)为单位来组织和管理各种信息 所有类型为 PT_LOAD 的段(segment)都会被动态链接(linker)映射(mmap)到内存 程序头表(program...~ 2、动态链接 动态链接的原理是让程序按照既定模块拆分成各个相对独立的部分,在程序运行的时候才将它们链接在一起,从而形成一个完整的程序,相当于Android的热拔插、组件化等,不是整体打包成一个dex

    98241

    CSAPP---第七章-链接

    汇编和编译生成可重定位目标文件(包括共享目标文件),链接生成可执行目标文件一个目标模块就是一个字节序列,一个目标文件就是一个文件形式存放在磁盘的目标模块。...为了防止局部静态变量a和b同名,编译还进行了重命名处理 局部变量在运行时的栈中被管理,链接对此类符号不感兴趣,所以不会出现在符号表。...全局符号解析: 当编译遇到一个不是在当前模块定义的符号(变量或函数名)时,编译会假设该符号在其他某个模块中进行的定义,生成一个链接符号表条目,并把它交给链接处理,如果链接在任何输入模块中都找不到这个被引用符号的定义...首先,在任何给定的文件系统,对于一个库只有一个. so 文件。所有引用该库的可执行目标文件共享这个 .so 文件的代码和数据,不是像静态库的内容那样被复制和嵌入到引用它们的可执行的文件。...当一个来自 Web 浏览的请求到达时,服务动态地加载和链接适当的函数,然后直接调用它,不是使用 fork 和 execve 在子进程的上下文中运行函数。

    85810

    《程序员的自我修养》第三章学习笔记

    4,Linux下命令: $: file   ***   显示出对应文件的类型 目标文件是什么样的 1,目标文件包含的内容:编译后的机器指令代码、数据,还有链接时要的一些信息(比如符号表、调试信息、字符串等...3.4.3 重定位表 1,一个叫”rel.text”的段,类型是”SHT_REL”,就是重定位表 2,链接在处理目标文件时,需要对目标文件的某些部位进行重定位(即代码段和数据段那些对绝对地址的引用的位置...3.4.3 字符串表 1,把ELF文件中用到的字符串(段名、变量名等)集中起来存放到一个。然后使用字符串在表的偏移来引用字符串。这个表就是字符串表。...3.5.1 ELF符号表结构 1,ELF文件符号表往往是文件一个段,y一般叫做 “.symtab”。是一个Elf32_Sym的数组,数组每个元素对应一个符号。...3,强弱符号都是针对定义来说的,不是针对符号的引用。 假如 extern int ext; ext不是强符号也不是弱符号,因为它是一个外部变量的引用。

    1.1K60

    Linux下,使用nm命令输出可执行文件符号表

    可执行文件符号表(symbol table)记录了某个可执行文件的函数名、全局变量、宏定义等符号信息,这些信息对于我们调试十分重要。...nm命令属于GNU binutils的功能,能够输出可执行文件符号表。它的用法是这样的: 用法:nm [选项] [文件] 列举 [文件] 的符号 (默认为 a.out)。...效果如下图: 图片 图片中所看到的就是DragonOS内核的符号表。最左侧一栏指的是符号在内核文件的地址,中间一栏表示符号类型,最右侧的表示符号的名称。...对于符号的类型的字母的含义,有下列的解释: -A, -o, --print-file-name 在找到的各个符号的名字前加上文件名,不是在此文件的所有符号前只出现文件名一次 -a, --debug-syms...合成符号是链接为各种目的创建的特殊符号,默认情况下不会显示它们,因为它们不是二进制文件源代码的一部分 --target=BFDNAME 指定系统默认格式以外的目标文件格式 以上就是nm命令的简单用法

    2.4K30

    认识目标文件结构

    这其实和不同语言与编译的实现有关,有些编译会将全局未初始化变量放在.bss段,有些则不放,只是预留一个未定义的全局变量符号,等到最终链接成可执行文件的时候再在.bss段分配空间。...为什么编译把未初始化的全局变量标记为一个COMMON符号,不直接把它当作未初始化的局部静态变量,为其在.bss段分配空间呢?...段表是 ELF 文件除了文件头以外最重要的结构,它描述了 ELF 各个段的信息,比如每个段的段名、类型、长度、在文件的偏移等,编译链接和装载都是通过访问段表来获取各个段的属性。...ELF 文件符号表往往是一个段,段名一般叫 .symtab。...比如 test.o 全局未初始化变量 gUninitVar; (c)在可执行文件,st_value 表示符号的虚拟地址,这个虚拟地址对动态链接十分有用。

    1.2K30

    深入浅出ELF

    这时候就需要一种可拓展(Portable)的文件标准,一方面让开发者(编译/链接)能够高效协作,另一方面也需要系统能够正确、安全地将文件加载到对应内存中去执行,这就是ELF的使命。...程序加载 在新版的ELF标准文档,将ELF的介绍分成了三部分,第一部分介绍ELF文件本身的结构,第二部分是处理相关的内容,第三部分是操作系统相关的内容。...如果把动态链接相关的代码也放到内核,就会导致内核执行功能过多,内核的理念一直是能不在内核执行的就不在内核处理,以避免出现问题时难以更新而且影响系统整体的稳定性。...我在自己解析动态链接文件的时候发现,实际上 .dynamic section的数据,和PT_DYNAMIC的数据指向的是文件的同一个地方,即这两个entry的s_offset和p_offset是相同...但这不是必须的,例如在Android中就通过ELF格式封装了特有的.odex 、 .oat文件来保存优化后的dex。

    76430

    Android Linker 与 SO 加壳技术

    2.2 装载 在 load_library , 首先初始化 elf_reader 对象, 第一个参数为 SO 的名字, 第二个参数为文件描述符 fd: ElfReader elf_reader(name...ReadElfHeader 使用 read 直接从 SO 文件中将 elfheader 读取 header ,header_ 为 ElfReader 的成员变量,类型为 Elf32_Ehdr,通过 header...关于loadbias: SO 可以指定加载基址,但是 SO 指定的加载基址可能不是页对齐的,这种情况会导致实际映射地址和指定的加载地址有一个偏差,这个偏差便是 load_bias_,之后在针对虚拟地址进行计算时需要使用...使用 mmap 将 segment 映射到内存,指定映射地址为 seg_page_start,长度为 file_length,文件偏移为 file_page_start。 ?...+ si_load_bias,相当于 偏移地址+基地址 符号表表项的结构为elf32_sym: ?

    3K61

    链接加载原理及ELF文件格式

    链接和加载(linker and loader): linker即链接,它负责将多个.c编译生成的.o文件链接一个可执行文件或者是库文件;loader即加载,它原本的功能很单一只是将可执行文件的段拷贝到编译确定的内存地址即可...这方面的资料乍一看起来非常晦涩难懂,其实根本的功能非常简单:链接和加载的最核心的内容就是重定位。链接负责将多个.o文件链接重定位成一个文件加载再将这个大文件重定位到一个进程空间当中去。...符号表的作用就是一个助记符,用一个字符串来标示某些抽象的地址,它能标示的地址有代码地址和数据地址,代码地址包括函数名、跳转标号,数据地址包括全局变量。...重定位表(Relocation): 有了符号表,就需要有人对符号表进行引用,在程序的执行过程对全局变量的引用、跳转、调用函数,这些都涉及到相应的符号引用。...同样加载的过程还需要重定位操作,需要将外部链接的函数和变量和本程序的引用链接起来,但是由于加载过程中代码已经处于运行状态,使用链接过程同样的重定位手段有些不合适。

    1.1K20

    符号解析与重定位

    我们可以看到0x27存放着并不是swap函数的地址,跟前面的“shared” 一样,“0xFFFFFFFC”只是一个临时的假地址,因为在编译的时候,编译并不知道“swap”的真正地址。...事实上在ELF文件,有一个叫重定位表( Relocation Table)的结构专门用来保存这些与重定位相关的信息,我们在前面介绍ELF文件结构时已经提到过了重定位表,它在ELF文件往往是个或多个段...对于每个要被重定位的ELF段都有一个对应的重定位表,一个重定位表往往就是ELF文件一个段,所以其实重定位表也可以叫重定位段,我们在这里统一称作重定位表。...这时候链接就会去查找由所有输入目标文件符号表组成的全局符号表,找到相应的符号后进行重定位。...所以在链接扫描完所有的输入目标文件之后,所有这些未定义的符号都应该能够在全局符号表中找到,否则链接就报符号未定义错误。

    1.2K10

    Linux命令(65)——ld命令

    -E,--export-dynamic:对于ELF格式文件,创建动态链接的可执行文件时,把所有符号添加到动态符号表 -f ,--auxiliary=:对于ELF格式共享对象,设置...这告诉动态链接,正在创建的共享对象的符号表应该用作共享对象名称的符号表的筛选。 -g:被忽略。...这仅在生成动态链接ELF可执行文件时才有意义。默认的动态链接通常是正确的,除非您知道正在做什么,否则不要使用该选项。...-M,--print-map:显示链接映射,用于诊断目的 -Map=: 将链接映射输出到指定的文件 -m : 模拟指定的链接 -N,--omagic: 指定读取...此脚本将替换ld的默认链接脚本(不是添加到其中),因此脚本必须指定输出文件所需的所有内容。

    17.4K13

    《操作系统导论》疑惑解答

    加载简化:操作系统的加载(loader)在加载可执行文件时,会根据文件的段信息来映射到内存的相应位置。使用段可以减少加载的复杂性。...在编译和链接过程,编译链接会生成符号表和重定位表。符号表存储了程序定义和引用的符号(如函数和变量)的信息,重定位表则记录了符号引用需要修正的地址信息。...在程序加载到内存后,操作系统会将虚拟地址映射到实际的物理地址,从而实现正确的内存访问。 符号表不是记录了符号的虚拟内存地址 在符号表,每个符号都有一个对应的标识符虚拟地址。...这个虚拟地址是符号在程序的位置信息,不是真实的内存地址。在程序运行时,动态链接会使用这个虚拟地址来找到符号的定义。 **一旦找到了符号的定义,动态链接就会将符号引用转换为真实的内存地址。...同样地,编译编译 utils.c 生成 utils.o ,并在符号表记录 add 函数的定义。 ****链接阶段 : 链接将 main.o 和 utils.o 链接一个可执行文件

    8210
    领券