kir*_*eos 2 linux emulation elf virtual-memory riscv
我正在构建一个 RISC-V 模拟器,它基本上将整个 ELF 文件加载到内存中。
到目前为止,我使用了 risc-v 基金会提供的预编译测试二进制文件,该二进制文件在本节的开头处方便地有一个入口点.text
。
例如:
> riscv32-unknown-elf-objdump ../riscv32i-emulator/tests/simple -d
../riscv32i-emulator/tests/simple: file format elf32-littleriscv
Disassembly of section .text.init:
80000000 <_start>:
80000000: 0480006f j 80000048 <reset_vector>
...
Run Code Online (Sandbox Code Playgroud)
进入这个项目时,我对 ELF 文件了解不多,所以我只是假设每个 ELF 的入口点与该部分的开头完全相同.text
。
当我编译自己的二进制文件时出现了问题,我发现实际的入口点并不总是与该部分的开头相同.text
,但它可能位于其中的任何位置,如下所示:
> riscv32-unknown-elf-objdump a.out -d
a.out: file format elf32-littleriscv
Disassembly of section .text:
00010074 <register_fini>:
10074: 00000793 li a5,0
10078: 00078863 beqz a5,10088 <register_fini+0x14>
1007c: 00010537 lui a0,0x10
10080: 43850513 addi a0,a0,1080 # 10438 <__libc_fini_array>
10084: 3a00006f j 10424 <atexit>
10088: 00008067 ret
0001008c <_start>:
1008c: 00002197 auipc gp,0x2
10090: cec18193 addi gp,gp,-788 # 11d78 <__global_pointer$>
...
Run Code Online (Sandbox Code Playgroud)
因此,在阅读了有关 ELF 文件的更多信息后,我发现实际的入口点地址是由Entry
ELF 标头上的条目提供的:
> riscv32-unknown-elf-readelf a.out -h | grep Entry
Entry point address: 0x1008c
Run Code Online (Sandbox Code Playgroud)
现在的问题是这个地址不是文件上的实际地址(从0开始的偏移量)而是一个虚拟地址,所以显然如果我将模拟器的程序计数器设置为这个地址,模拟器就会崩溃。
多读一点,我听到人们谈论有关程序头偏移量等的计算,但没有人给出具体的答案。
我的问题是:如何准确获取过程的入口点地址_start
作为距字节 0 的偏移量的实际“公式”是什么?
需要明确的是,我的模拟器不支持虚拟内存,并且二进制文件是加载到模拟器内存中的唯一内容,因此我没有使用虚拟内存的抽象。我只想将每个内存地址作为磁盘上的物理地址。
我的问题是:如何准确获取 _start 过程的入口点地址作为距字节 0 的偏移量的实际“公式”是什么?
首先,忘记sections。只有段 在运行时才重要。
其次,用readelf -Wl
来看细分。它们准确地告诉您文件的哪个块 ( [.p_offset, .p_offset + .p_filesz)
) 进入哪个内存区域 ( [.p_vaddr, .p_vaddr + .p_memsz)
)。
“文件中的偏移量所在的_start
位置”的精确计算是:
Elf32_Phdr
哪个“覆盖”了 中包含的地址Elf32_Ehdr.e_entry
。phdr
,文件偏移量_start
为:ehdr->e_entry - phdr->p_vaddr + phdr->p_offset
。更新:
那么,我总是在寻找第一个程序头吗?
不。
另外,“覆盖”是指第一个 phdr->p_vaddr 始终等于 e_entry?
不。
ehdr->e_entry
您正在寻找与内存重叠的程序头(描述内存中数据和文件数据之间的关系) 。也就是说,您正在寻找 的段phdr->p_vaddr <= ehdr->e_entry && ehdr->e_entry < phdr->p_vaddr + phdr->p_memsz
。该部分通常是第一个,但这并不能保证。另请参阅此答案。
归档时间: |
|
查看次数: |
886 次 |
最近记录: |