ELF 的最新规范列出了许多可以与其一起使用的架构,但是一些自我分配是在野外进行的(例如中国的 LoongArch)。
有没有人负责协调这些任务?LANANA 好像没有这样的列表,还是我遗漏了什么?
ELF 的最新规范列出了许多可以与其一起使用的架构,但是一些自我分配是在野外进行的(例如中国的 LoongArch)。
有没有人负责协调这些任务?LANANA 好像没有这样的列表,还是我遗漏了什么?
我正在阅读 Rust 不稳定的书,我看到了一个新功能emit-stack-sizes
,
rustc 标志
-Z emit-stack-sizes
使 LLVM 发出堆栈大小的元数据。
它继续说
注意:此 LLVM 功能仅支持 LLVM 8.0 起的 ELF 对象格式。将此标志与使用其他对象格式(例如 macOS 和 Windows)的目标一起使用将导致它被忽略。
它似乎正在使用的 LLVM 功能是EmitStackSizeSection
选项。知道堆栈大小的目的是什么?工具使用这个吗?这是 ELF 的官方功能吗?如果是,内核是否会使用它?这似乎记录在ELF 元数据中的部分.stack_sizes
、、.rel.stack_sizes
和.rela.stack_sizes
我目前正在做一个nm
类似的程序,以打印 ELF 文件的符号及其地址和类型。
典型的输出类似于:
$ nm ./my_exec
0000000000003d28 d _DYNAMIC
0000000000003f28 d _GLOBAL_OFFSET_TABLE_
0000000000002000 R _IO_stdin_used
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
第一列是符号地址,第二列是符号类型,第三列是符号名称。
man 表示每个字符的含义,大写是全局符号,小写是局部符号等...
但我不明白它如何选择使用哪个字符。
我正在使用该Gelf
库,但没有看到可以确定角色的字段。
我正在尝试转储由 ELF 文件 ( /usr/bin/ls
)导入的共享库的完整路径
使用readelf --dyn-syms /usr/bin/ls
我得到库的名称,但不是它们在文件系统上的位置:
101: 0000000000000000 0 FUNC GLOBAL DEFAULT UND [...]@LIBSELINUX_1.0 (4)
使用objdump -T /usr/bin/ls
我可以获得更多信息(包括函数名称):
0000000000000000 DF *UND* 0000000000000000 (LIBSELINUX_1.0) getfilecon
这是有用的信息,但我怎样才能在磁盘上提取库的位置?我可以运行该文件并查看它通过 . 打开的内容lsof
,但是有什么方法可以在不运行该文件的情况下执行此操作吗?
我试图通过读取程序头来定位 libc 程序段在程序内存中的位置。
在 Centos 6 上,当我在 libc.so.6 文件上使用 readelf 时,VirtAddr 包含程序段在进程内存中加载的正确地址:
[user@centos6 src]$ readelf -l /lib64/libc.so.6 --wide
Elf file type is DYN (Shared object file)
Entry point 0x3032c1ee30
There are 10 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000040 0x0000003032c00040 0x0000003032c00040 0x000230 0x000230 R E 0x8
INTERP 0x15aab0 0x0000003032d5aab0 0x0000003032d5aab0 0x00001c 0x00001c R 0x10
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x000000 0x0000003032c00000 0x0000003032c00000 0x18a00c 0x18a00c R E 0x200000
LOAD 0x18a700 0x0000003032f8a700 0x0000003032f8a700 0x004f58 0x009228 RW 0x200000
DYNAMIC 0x18db40 0x0000003032f8db40 0x0000003032f8db40 0x0001f0 0x0001f0 RW 0x8
NOTE 0x000270 0x0000003032c00270 0x0000003032c00270 0x000044 0x000044 R 0x4
TLS 0x18a700 0x0000003032f8a700 0x0000003032f8a700 0x000010 0x000068 R 0x8
GNU_EH_FRAME 0x15aacc 0x0000003032d5aacc 0x0000003032d5aacc 0x0065ec 0x0065ec R 0x4
GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x8
GNU_RELRO 0x18a700 0x0000003032f8a700 0x0000003032f8a700 0x003900 0x003900 R 0x1
所以在这种情况下,DYNAMIC 段位于 0x0000003032f8db40
但是在 Centos 7 上, VirtAddr 包含一个偏移量,我必须将 libc 基地址添加到该偏移量中才能找到该段在内存中的位置:
[user@centos7 src]$ readelf -l /usr/lib64/libc.so.6 --wide
Elf file type is DYN (Shared object file)
Entry point 0x22660
There are 10 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000040 0x0000000000000040 0x0000000000000040 0x000230 0x000230 R E 0x8
INTERP 0x18eb00 0x000000000018eb00 0x000000000018eb00 0x00001c 0x00001c R 0x10
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x1c3170 0x1c3170 R E 0x200000
LOAD 0x1c36f0 0x00000000003c36f0 0x00000000003c36f0 0x0051b0 0x009b10 RW 0x200000
DYNAMIC 0x1c6b60 0x00000000003c6b60 0x00000000003c6b60 0x0001f0 0x0001f0 RW 0x8
NOTE 0x000270 0x0000000000000270 0x0000000000000270 0x000044 0x000044 R 0x4
TLS 0x1c36f0 0x00000000003c36f0 0x00000000003c36f0 0x000010 0x0000a0 R 0x10
GNU_EH_FRAME 0x18eb1c 0x000000000018eb1c 0x000000000018eb1c 0x006aec 0x006aec R 0x4
GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x10
GNU_RELRO 0x1c36f0 0x00000000003c36f0 0x00000000003c36f0 0x003910 0x003910 R 0x1
在这种情况下,DYNAMIC 段将位于 0x00000000003c6b60 + libc 基地址。
我猜这可能是由于 Centos 7 上的 ASLR 导致 libc 库每次加载到不同的地址。在 Centos 6 上,似乎 libc 总是加载到相同的地址。
有没有办法仅通过读取 ELF 标头来确定我是否需要将 libc 基地址添加到 VirtAddr 以获取程序段在内存中的实际位置?
Executable and Linkable Format (ELF)至少有两个标准,其中之一
较旧的 TIS ELF 标准 1.2 为 106 页,而 SysV ABI 为 157 页,但仅在第 63-86 页(23 页)中涵盖 ELF。
这两个标准如何相互关联?Linux 和 GNU Linker 使用哪一个?什么是工具接口标准?
有两个文件,一个编译并链接,gcc
另一个手动使用nasm
,ld
我得到
这两件事有什么区别?我可以看到readelf -h
那个是
DYN (Shared object file)
EXEC (Executable file)
我可以在WikipediaET_DYN
ET_EXEC
上看到这些记录为和. 这两者之间有什么实际区别?
我有一个局部静态变量,如下所示:
void function(void) {
static unsigned char myVariable = 0;
...
我使用 readelf 转储符号表,如下所示:
readelf -s myprogram.elf
我得到了符号表,其中包含myVariable
以下内容:
...
409: 00412668 1 NOTYPE LOCAL DEFAULT 16 myVariable.9751
...
我的问题是:变量名称和点后面的数字是什么意思?有没有关于readelf输出格式的详细文档?手册页不包含有关符号表格式的信息,我找不到任何关于此的信息。(我正在使用 Xilinx 的 ARM GNU 工具,但我想,这对于其他平台也是一样的)谢谢!