2011-06-02 468 views
6

objdump如何计算elf段的物理地址(LMA)?据我所知,精灵节头只包含节[1]的虚拟地址(VMA)。elf文件中段的虚拟地址和物理地址

通常,VMA和LMA是相同的。但对于初始化数据段(.data),VMA是变量的RAM位置,LMA是初始值所在的ROM位置。在main()被调用之前,Crt0负责将初始值复制到RAM中。例如:

$ objdump -h my.elf 
Sections: 
Idx Name   Size  VMA  LMA  File off Algn 
    0 .text   0003c3d0 00080000 00080000 00010000 2**2 
        CONTENTS, ALLOC, LOAD, READONLY, CODE 
    5 .data   000008d0 40000000 000d08d4 00060000 2**3 
        CONTENTS, ALLOC, LOAD, DATA 

- 汤姆

[1] http://www.ouah.org/RevEng/x430.htm

+0

我不知道关于这个主题的anython,但它似乎LMA是由[链接器脚本](https://sourceware.org/binutils/docs-2.18/ld/Output-Section-LMA.html)给出的(使用'AT')。 – ysdx 2015-08-20 21:27:51

回答

0

物理地址是ELF文件段的属性。 ELF文件部分没有这样的属性。尽管将部分映射到相应的段的内存是可能的。

物理地址的含义取决于体系结构,可能因不同的操作系统和硬件平台而异。

从这个link

p_paddr - 在系统这 物理寻址相关的,这 成员保留该事业部 物理地址。由于系统V 忽略了 应用程序的物理地址,因此该成员具有 未指定内容的可执行 文件和共享对象。

看起来你的Crt0对位于ELF文件中的物理地址的含义做了一些假设。这个假设对于特定的系统可能是正确的,但是在另一个系统中并不保证。

6

查找此有关LMA: http://www-zeuthen.desy.de/dv/documentation/unixguide/infohtml/binutils/docs/ld/Basic-Script-Concepts.html#Basic-Script-Concepts

重要的是以下几点:

每个可加载或分配的输出段都具有两个地址。第一个是VMA或虚拟内存地址。这是输出文件运行时该部分的地址。第二个是LMA或装载存储器地址。这是该部分将被加载的地址。在大多数情况下,这两个地址将是相同的。例如,当数据部分加载到ROM中,然后在程序启动时复制到RAM中(这种技术通常用于初始化基于ROM的系统中的全局变量)。在这种情况下,ROM地址将是LMA,RAM地址将是VMA

+0

什么是文件关闭? – electro 2017-06-05 08:24:21

4

部分标题包含一个地址。它看起来像在部分标题中的地址是VMA。程序标题包含VMA到LMA的映射。

例如,这里有一个片段是什么 “objdump的-x” 显示我的ELF文件:

Program Header: 
<a few lines removed> 
    LOAD off 0x00000240 vaddr 0x00000048 paddr 0x0000018c align 2**0 
     filesz 0x00000000 memsz 0x00000004 flags rw- 

Sections: 
Idx Name   Size  VMA  LMA  File off Algn 
<a few lines removed> 
    3 .bss   00000004 00000048 0000018c 00000240 2**1 
        ALLOC 

所以,拥有的.bss的0x48一个VMA。如果你查看程序头文件,一个条目有一个0x48的“vaddr”和一个0x18c的paddr,这是LMA。

+0

我认为你的猜测是正确的。这里有一个相关的问题:作者说:https://stackoverflow.com/questions/39888381/elf-loading-when-vma-lma它有助于认识到“VMA”和“LMA”是GNU实用程序术语,而不是在ELF规范中....有些环境不使用p_paddr作为物理地址,而是使用加载地址(因此称为“LMA”).... – 2018-02-09 14:52:43