ENTRY(symbol)命令是否总是将指令放在.text节开头的符号处?

时间:2019-05-04 10:58:45

标签: linker ld

根据Using ld doc

  

链接器命令语言包括专门用于   在输出文件(其条目)中定义 first 可执行指令   点)。

如何在这里理解第一?是逻辑上要跳转的第一条指令吗?还是物理上放置在.text节中的第一条指令?

我将here中的以下链接描述文件用作实验:

ENTRY(__entry)  /* <=============== HERE, the __entry  */

/*kernel will be loaded at this address after boot*/
INCLUDE linker.ld

SECTIONS
{
    /*kernel will be compiled with virtual address base at 2GB*/
    . = 0x80000000 + start_address; /*2GB + start_address = (0x80010000)*/
    PROVIDE(_kernel_start = .); /*defined at kernel/include/kernel.h, set to 0x80010000*/

 .text : AT(start_address) 
    {
        *(.text)
    }

    .data : 
    { 
        *(.data) 
    }

    .bss : 
    { 
        *(.bss COMMON)
    }
    . = ALIGN(8);
    PROVIDE(_fb_start = .); 
    . += framebuffer_size;

    PROVIDE(_kernel_end = .); /*defined at kernel/include/kernel.h*/
}

我试图在最终构建的二进制文件的__entry中搜索指令字节。并发现这些说明确实位于.text部分的开头。

那么这是否意味着ENTRY()命令总是将入口点放置在最终二进制文件的.text部分的开头?

2 个答案:

答案 0 :(得分:1)

可执行文件中的第一机器指令是指先执行的指令。它不一定是 .text 段中所有指令的有序列表中的第一个(偏移量最小)。

许多程序都是以自然的 top-down 风格编写的,它们的 entry 实际上指向物理上的第一条指令(偏移量为零)。但是,在这种情况下,程序代码也可能以helper子例程开头,并且其进入点将在代码中更深地移位。

答案 1 :(得分:0)

ENTRY(__entry)将在最终目标文件中记录__entry符号的VMA位置。例如,在ELF标头中。加载程序将目标文件的每个 section 加载到内存中后,加载程序或运行时将仅跳转到入口点。

但是在我的情况下,ENTRY(__entry)实际上不必要。因为EwokOS在裸机上运行,​​所以没有加载程序。在尝试时,如果我注释掉ENTRY(__entry),EwokOS仍然可以在裸机上启动。

__entry的第一条指令恰好是最终EwokOS.bin文件的第一条指令的原因,是两个因素的组合:

  • 目标文件到链接器ld

  • 的输入顺序
  • boot.S文件中的编码顺序。

有3个文件以ld的顺序馈入boot.o system.o context.o。因此,我们可以看到boot.o是要链接的第一个对象文件。

组装成boot.S的{​​{1}}文件包含boot.o作为第一行代码。

这两个因素导致__entry位于最后一个__entry的开头,而这是从EwokOS.bin的{​​{1}}部分提取的。

在我的场景中,我需要.text出现在EwokOS.elf文件的开头,因为bin文件加载在0x10000地址上,该地址是QEMU ARM通用pb的起始地址虚拟机。