GNU链接器(LD):设置入口点(ENTRY命令)的用法及实例解析

0 参考资料

c 复制代码
GNU-LD-v2.30-中文手册.pdf
GNU linker.pdf

1 前言

一个完整的编译工具链应该包含以下4个部分:

(1)编译器

(2)汇编器

(3)链接器

(4)lib库

在GNU工具链中,对应的是:

(1)编译器:GCC(GNU Compiler Collection,GNU编译器套件)

(2)汇编器:GAS(GNU Assembler,GNU汇编器)

(3)链接器:LD(GNU Linker,GNU链接器)

(4)lib库:glibc(GNU C Library,GNU C 库)

本文介绍GNU链接器脚本中设置入口点(ENTRY命令)的用法及实例解析。

2 GNU linker(链接器,LD):设置入口点(ENTRY命令)的用法及实例解析

2.1 设置入口点官方释义及ENTRY命令的用法

CPU需要执行的第一条指令被称为入口点(Entry Point)。可以使用链接器脚本命令ENTRY设置入口点,不过ENTRY命令设置的入口点是elf loader加载程序的入口点,而不是CPU需要执行的第一条指令。使用ENTRY命令会影响elf文件的entry_address 字段。ENTRY命令格式如下:

c 复制代码
ENTRY(symbol)
symbol:符号名称,可以是函数名、地址

LD支持几种方法设置入口点,链接器将按照以下顺序设置入口点,直到找到成功的入口点为止:

(1)添加entry命令行选项:'-e'

(2)在链接器脚本使用ENTRY(symbol)命令

(3)目标指定符号的值(如果已经定义):大部分情况下如果定义了start符号则使用start符号,但基于PE和BeOS的系统会检查其它可行的入口符号,直到找到第一个符合的

(4)代码段(.text段)首地址

(5)地址0

2.2 ENTRY命令实例解析

很多链接脚本将复位中断服务函数作为入口点,配置SECTION内.text段的输出分区存储区域就可以将复位中断服务函数放置到代码段首地址。如下是stm32MP135的链接器脚本ENTRY的定义:

c 复制代码
/* Entry Point */
ENTRY(Reset_Handler)

text段定义如下:

c 复制代码
.RESET . : {
        __TEXT_START__ = .;
        *(.text.Reset_Handler)
        * (RESET)
        *(.text*)

        /* .init is used by libc_nano */
        KEEP (*(.init))
        KEEP (*(.fini))

        __TEXT_END_UNALIGNED__ = .;

        /*
         * Memory page(s) mapped to this section will be marked as
         * read-only, executable.  No non-executable data from the next section must
         * creep in.  Ensure the rest of the current memory page is unused.
         */
        __TEXT_END__ = .;

        . = NEXT(4096);

        __RO_START__ = .;
        *(.rodata*)

        __RO_END_UNALIGNED__ = .;
        /*
         * Memory page(s) mapped to this section will be marked as
         * read-only, non-executable.  No RW data from the next section must
         * creep in.  Ensure the rest of the current memory page is unused.
         */
        . = NEXT(4096);
        __RO_END__ = .;
    } >RAM :text

这样操作之后代码段首地址就是Reset_Handler函数,查看编译生成的.map文件如下:

可以看到Reset_Handler函数被定义在代码段首地址。

stm32MP135的SYSRAM起始地址定义如下:

2 总结

(1)ENTRY命令不能指定CPU执行的第一条指令,只会影响到elf文件的entry_address 字段

(2)ENTRY命令通常使用复位中断服务函数作为符号,通过修改.text段的输出分区,将复位中断服务函数分配在镜像的起始地址

相关推荐
时光飞逝的日子1 天前
GNU链接器(LD):什么是符号?符号定义及实例解析
符号·gcc·链接脚本·gnu链接器·符号定义
mzhan01723 天前
Gnu: binutils: ld: .gnu.warning.链接时的主动警告 glibc
gnu·glibc·ld
进击的铁甲小宝2 个月前
ld,GNU 链接器介绍以及命令行参数详解
gnu·ld
凉、介1 年前
动态链接那些事
linux·链接·got·ld·装载