标签: symbol-table

什么是符号表?

有人能描述符号表在C和C++的上下文中是什么吗?

c c++ symbol-table

81
推荐指数
4
解决办法
6万
查看次数

变量名如何存储在C的内存中?

在C中,假设您有一个名为的变量variable_name.假设它位于0xaaaaaaaa,并且在该内存地址,您有整数123.换句话说,variable_name包含123.

我正在寻找关于措词" variable_name位于0xaaaaaaaa"的澄清.编译器如何识别字符串"variable_name"与该特定内存地址相关联?字符串"variable_name"是否存储在内存中?该编译器只是替代variable_name0xaaaaaaaa,只要自己认为呢,如果是这样,是不是必须使用的内存,以使该替换吗?

c memory variables symbol-table

43
推荐指数
4
解决办法
1万
查看次数

如何从另一个模块调用导出的内核模块函数?

我正在编写一个API作为内核模块,为设备驱动程序提供各种功能.我在mycode.c中写了三个函数.然后我构建并加载了模块,然后将mycode.h复制到<kernel>/include/linux中.在设备驱动程序中,我有一个#include <linux/mycode.h>并调用这三个函数.但是当我构建驱动程序模块时,我得到三个链接器警告,说明这些函数是未定义的.

笔记:

  • 函数在mycode.h 中声明为extern
  • 使用mycode.c中的EXPORT_SYMBOL(func_name)导出函数
  • 运行命令nm mycode.ko显示符号表中可用的所有三个函数(它们旁边的大写字母T,表示符号在文本(代码)部分中找到)
  • 加载模块后,命令grep func_name/proc/kallsyms将所有三个函数显示为已加载

很明显,函数正在正确导出,内核知道它们的位置和位置.那么为什么司机不能看到他们的定义呢?知道我错过了什么吗?


编辑:我在这里找到了一些相关的信息: http ://www.kernel.org/doc/Documentation/kbuild/modules.txt

有时,外部模块使用来自另一个外部模块的导出符号.kbuild需要完全了解所有符号,以避免吐出有关未定义符号的警告.这种情况存在三种解决方案.

注意:建议使用顶级kbuild文件的方法,但在某些情况下可能不切实际.

使用顶级kbuild文件如果你有两个模块,foo.ko和bar.ko,其中foo.ko需要来自bar.ko的符号,你可以使用一个通用的顶级kbuild文件,所以这两个模块都是用同一个编译的建立.请考虑以下目录布局:

  ./foo/ <= contains foo.ko       ./bar/ <= contains bar.ko

  The top-level kbuild file would then look like:

  #./Kbuild (or ./Makefile):          obj-y := foo/ bar/

  And executing

      $ make -C $KDIR M=$PWD

  will then do the expected and compile both modules with         full
Run Code Online (Sandbox Code Playgroud)

任何一个模块的符号知识.

使用额外的Module.symvers文件构建外部模块时,会生成Module.symvers文件,其中包含未在内核中定义的所有导出符号.要从bar.ko访问符号,请将module.symvers文件从bar.ko的编译复制到构建foo.ko的目录.在模块构建期间,kbuild将读取外部模块目录中的Module.symvers文件,并且在构建完成时,将创建一个新的Module.symvers文件,其中包含已定义的所有符号的总和,而不是内核的一部分.

使用"make"变量KBUILD_EXTRA_SYMBOLS如果从另一个模块复制Module.symvers是不切实际的,则可以在构建文件中将空格分隔的文件列表分配给KBUILD_EXTRA_SYMBOLS.这些文件将在其符号表初始化期间由modpost加载.

但是对于所有这三种解决方案,为了让任何驱动程序使用我的API,它必须创建一个新的Makefile或直接访问我的Module.symvers文件?这看起来有点不方便.我希望他们能够#include我的头文件并且好好去.不存在其他替代方案吗?

c kernel module symbol-table

25
推荐指数
1
解决办法
2万
查看次数

处理ELF重定位 - 了解重定位,符号,节数据以及它们如何协同工作

TL; DR

我试图将这个问题作为一个简短的问题,但这是一个复杂的问题所以它最终会变长.如果您可以回答这方面的任何部分或提供任何建议或提示或资源或任何内容,那将非常有帮助(即使您没有直接解决我的所有问题).我现在正撞在墙上.:)

以下是我遇到的具体问题.请阅读下面的更多信息.

  • 我正在寻找有关如何处理重定位条目和更新节数据中未解析的符号的指导.我根本不明白如何处理我从重定位和部分等中提取的所有信息.
  • 我也希望了解链接器遇到重定位时发生了什么.试图正确实现重定位方程并以正确的方式使用所有正确的值是非常具有挑战性的.
  • 当我遇到操作码,地址和符号等时,我需要了解如何处理它们.我觉得我错过了一些步骤.
  • 我觉得我没有很好地掌握符号表条目如何与重定位进行交互.我应该如何使用符号的绑定,可见性,值和大小信息?
  • 最后,当我使用已解析的数据和可执行文件使用的新重定位条目输出我的文件时,数据都是不正确的.我不确定如何遵循所有重新安置并提供所需的所有信息.可执行文件对我有什么期望?

到目前为止我的方法

我正在尝试以特定的[未记录的]专有格式创建一个重定位文件,该格式主要基于ELF.我编写了一个工具,它接受一个ELF文件和一个部分链接文件(PLF)并处理它们以输出完全解析的rel文件.此rel文件用于根据需要加载/卸载数据以节省内存.该平台是一个32位PPC.一个问题是该工具是用c#编写的,但数据是针对PPC的,因此需要注意有趣的endian问题等.

我一直试图了解在用于解析未解析的符号等时如何处理重定位.到目前为止我所做的是从PLF复制相关部分,然后对于每个相应的.rela部分,我解析条目并尝试修复部分数据并根据需要生成新的重定位条目.但这就是我的困难所在.我离开了我的元素,这种事情似乎通常是由链接器和加载器完成的,所以没有很多好的例子可以借鉴.但是我发现了一些有帮助的东西,包括这一个.

所以发生的事情是:

  1. 从PLF复制部分数据以用于rel文件.我只对.init(无数据),.text,.ctors,.dtors,.rodata,.data,.bss(无数据)和我们正在使用的另一个自定义部分感兴趣.
  2. 迭代PLF中的.rela部分并读入Elf32_Rela条目.
  3. 对于每个条目,我提取r_offset,r_info和r_addend字段,并从r_info(符号和reloc类型)中提取相关信息.
  4. 从PLF的符号表中,我可以得到symbolOffset,symbolSection和symbolValue.
  5. 从ELF,我得到symbolSection的加载地址.
  6. 我计算int localAddress =(.relaSection.Offset + r_offset).
  7. 我从r_offset的symbolSection的内容中获取了uint relocValue.
  8. 现在我拥有了我需要的所有信息,因此我对reloc类型进行了切换并处理数据.这些是我支持的类型:
    R_PPC_NONE
    R_PPC_ADDR32
    R_PPC_ADDR24
    R_PPC_ADDR16
    R_PPC_ADDR16_LO
    R_PPC_ADDR16_HI
    R_PPC_ADDR16_HA
    R_PPC_ADDR14
    R_PPC_ADDR14_BRTAKEN
    R_PPC_ADDR14_BRNTAKEN
    R_PPC_REL24
    R_PPC_REL14
    R_PPC_REL14_BRTAKEN
    R_PPC_REL14_BRNTAKEN
  9. 怎么办??我需要更新节数据并构建随播重定位条目.但我不明白该做什么以及如何做.

我这样做的全部原因是因为有一个旧的过时不支持的工具不支持使用自定义部分,这是该项目的关键要求(出于内存原因).我们有一个自定义部分,其中包含一堆我们想要在启动后卸载的初始化代码(总计大约一兆).现有工具只是忽略该部分中的所有数据.

因此,虽然制作支持自定义部分的自己的工具是理想的,但如果有任何明智的想法以实现这一目标的另一种方式,我全都耳朵!我们已经提出了将.dtor部分用于我们的数据的想法,因为它几乎是空的.但这很麻烦,如果它阻止干净关闭,可能无论如何都无法工作.


重定位加示例代码

当我处理搬迁,我工作过的公式和信息在ABI文档中发现的HERE(约4.13节,第80ish),以及一些我已经挖出了其他代码示例和博客文章.但是这一切都让人感到困惑,并没有真正拼写出来,而且我发现的所有代码都有所不同.

例如,

  • R_PPC_ADDR16_LO - > half16:#lo(S + A)
  • R_PPC_ADDR14_BRTAKEN - > low14*:( S + A)>> 2
  • 等等

所以,当我看到这种代码时,我该如何解读呢?

这是一个例子(来自这个来源)

case ELF::R_PPC64_ADDR14 : {
    assert(((Value + Addend) & 3) == 0); …
Run Code Online (Sandbox Code Playgroud)

reverse-engineering elf opcode relocation symbol-table

18
推荐指数
1
解决办法
7029
查看次数

动态加载和弱符号分辨率

分析这个问题,dlopen在Linux上的动态加载()上下文中发现了一些关于弱符号解析行为的事情.现在我正在寻找管理这个的规范.

我们来举个例子吧.假设有一个程序a可以动态加载库b.so,并c.so按此顺序.如果c.so依赖于另外两个库foo.so(实际上libgcc.so在该示例中)和bar.so(实际上libpthread.so),则通常bar.so可以使用导出的符号来满足弱符号链接foo.so.但是,如果b.so还依赖foo.so但不依赖bar.so,那么这些弱的符号显然不会被联系起来bar.so.看起来好像foo.so墨水只是从ab.so它们的所有依赖项中寻找符号.

这在某种程度上是有道理的,因为否则加载c.so可能会改变已经使用库的foo.so某些点的行为b.so.另一方面,在让我开始的问题中,这引起了相当多的麻烦,所以我想知道是否有办法解决这个问题.为了找到解决方法,我首先需要很好地理解在这些情况下如何指定符号解析的非常精确的细节.

在这些场景中定义正确行为的规范或其他技术文档是什么?

linux dynamic-linking dynamic-loading weak-linking symbol-table

17
推荐指数
1
解决办法
6112
查看次数

如何解释ELF可执行文件中的动态符号表?

我正在寻找解释.dynsymELF可执行文件的动态符号表().我可以.symtab使用该value属性成功解释符号表(每个符号16个字节),以表示符号和name属性的地址,以表示.strtab段中字符串开头的偏移量.但是我无法.dynsym使用相同的方法解释动态符号表().我用阿里的博客[1]作为参考.

我查看了Ali的另一个博客[2],但我不明白如何使用哈希表来解释动态符号表.显然,它与符号表使用的映射不同.我该如何解释动态符号表(.dynsym)?

另外,我正在查看的ELF可执行文件有两个部分,即.hash.gnu.hash.我在哪个部分引用哈希值?

[1] http://blogs.oracle.com/ali/entry/inside_elf_symbol_tables
[2] http://blogs.oracle.com/ali/entry/gnu_hash_elf_sections

dynamic elf symbol-table

11
推荐指数
2
解决办法
8056
查看次数

Python中的符号表

我们怎样才能看到python源代码的符号表?

我的意思是,Python在实际运行之前为每个程序创建一个符号表.所以我的问题是如何将符号表作为输出?

python symbol-table

11
推荐指数
3
解决办法
1万
查看次数

为什么 exec() 中的符号定义语句有时对本地符号表没有影响?

以下代码片段按预期工作:

def test():
    print(f'local symbol table before exec : {locals()}')
    exec('a = 0')
    print(f'local symbol table after exec  : {locals()}')

test()
# printed result:
# local symbol table before exec : {}
# local symbol table after exec  : {'a': 0}
Run Code Online (Sandbox Code Playgroud)

但是,一旦我a = 1test函数末尾添加了符号定义语句,该exec语句似乎对本地符号表没有影响:

def test():
    print(f'local symbol table before exec : {locals()}')
    exec('a = 0')
    print(f'local symbol table after exec  : {locals()}')
    a = 1

test()
# printed result:
# local symbol table …
Run Code Online (Sandbox Code Playgroud)

python exec local-variables symbol-table python-3.x

10
推荐指数
1
解决办法
167
查看次数

符号查找错误:./ executableName:未定义符号:_ZN18QXmlDefaultHandlerC2Ev

我试图在Linux Mint 16 x64上运行可执行文件,这是为Ubuntu 12 x64编译的.可执行文件在运行时动态使用Qt 5.1.1.我收到错误:

loaded the dummy plugin 
loaded the Linux plugin 
updating server status 
./executableName: symbol lookup error: ./executableName: undefined symbol: _ZN18QXmlDefaultHandlerC2Ev
Run Code Online (Sandbox Code Playgroud)

我跑的时候

ldd executableName | grep "not found"
Run Code Online (Sandbox Code Playgroud)

搜索缺少的依赖项我没有得到任何结果; 似乎找到了所有动态依赖关系,但上面的未定义符号错误仍然存​​在.

思考?

linux linker qt shared-libraries symbol-table

9
推荐指数
1
解决办法
2万
查看次数

目标文件中的符号表和重定位表

据我所知,目标文件中的指令和数据都有地址.第一个数据项从地址0开始,第一个指令也从地址0开始.

重定位表包含有关在文件中的地址更改时需要更新的指令的信息,例如,如果文件与另一个文件链接在一起.在下面的示例中,行A将位于重定位表中.我不认为B会在重定位表中,因为标签"相等"的地址是相对于B.这些正确的假设是什么?

我知道符号表显示文件的标签以及尚未解析的标签.但是符号表包含哪些其他信息?

此外,当汇编程序将指令转换为二进制时,那些具有未解析引用的指令中放置了什么?B在这个例子中.

.data
TEXT: .asciiz "Foo"

.text
.global main
main:
     li t0, 1
     beq t0, 1, equal #B

equal:
    la a0, TEXT
    jal printf #A
Run Code Online (Sandbox Code Playgroud)

assembly compilation object-files symbol-table

8
推荐指数
1
解决办法
1万
查看次数