博客
关于我
Linux下的lds链接脚本详解
阅读量:54 次
发布时间:2019-02-25

本文共 2252 字,大约阅读时间需要 7 分钟。

链接脚本(ld脚本)详解

概述

链接脚本(Linker Script)是用于控制链接过程的文件,主要用于指定如何将输入文件的section合并到输出文件中,以及输出文件中各section在程序地址空间中的布局。链接脚本能够执行静态链接和动态链接任务,还能完成一些高级操作,如符号赋值和内存区域管理。


基本概念

输入文件与输出文件

  • 输入文件:通常是目标文件(如可执行文件或共享库),也可以是链接脚本文件。
  • 输出文件:通常是可执行文件或共享库。

目标文件的格式通常为ELF格式,包含多个section,如.text(代码)、.data(数据)、.bss(未初始化的全局变量)、.sym(符号表)、.note(注释信息)等。


链接脚本格式

结构

链接脚本由一系列命令组成,每个命令由关键字(后接参数)或对符号的赋值语句组成,命令由分号;分隔。文件名或格式名中若包含分号;或其他分隔符,需用引号"引用。注释用/* */之间的内容表示。

命令类型

  • 赋值语句SYMBOL = EXPRESSION

    用于对目标文件中的符号赋值,符号为全局符号,可用于设置入口地址、函数地址等。

  • 输入文件引用

    • INPUT(files):将括号内文件作为链接输入文件。
    • GROUP(files):指定需要重复搜索的文件组,常用于处理共享库的依赖。
  • 输出文件定义OUTPUT(FILENAME)

    定义输出文件的名字,优先级高于命令行的-o选项。

  • 搜索路径SEARCH_DIR(PATH)

    定义搜索路径,路径内文件优先被搜索。

  • 启动文件STARTUP(filename)

    指定第一个输入文件。

  • 目标文件格式OUTPUT_FORMAT(BFDNAME)

    设置输出文件的BFD格式。

  • 字节顺序设置OUTPUT_FORMAT(DEFAULT,BIG,LITTLE)

    设置输出文件的字节顺序(默认为BIG)。

  • 输入文件的BFD格式TARGET(BFDNAME)

    设置输入文件的BFD格式。

  • 断言ASSERT(EXP, MESSAGE)

    在表达式EXP不为真时终止连接过程。

  • 符号处理

    • EXTERN(SYMBOL ...):在输出文件中增加未定义的符号。
    • FORCE_COMMON_ALLOCATION:为通用符号分配空间。
  • 内存区域管理MEMORY

    定义内存区域,用于限制未引用section的分配范围。

  • 覆盖图描述OVERLAY

    实现多个section共享同一内存区域。

  • 程序头描述PHDRS

    定义ELF目标文件的程序头信息。

  • 版本控制VERSION

    定义符号的版本信息,适用于共享库。


  • 符号赋值

    示例

    a = 3;  /* 全局位置 */.text : { *(.text) }_bdata = (. + 3) & ~4;  /* SECTIONS命令内 */.data : { *(.data) }

    注意事项

    • 符号赋值只对全局变量起作用。
    • 赋值语句需包含四个部分:符号名、操作符、表达式、分号。

    SECTIONS命令

    格式

    SECTIONS {  SECTION-NAME [ADDRESS] [(TYPE)] : [AT(LMA)]  {    OUTPUT-SECTION-COMMAND    ...  }  ...}

    参数说明

    • SECTION-NAME:输出section的名字,需符合目标文件格式要求。
    • ADDRESS:section的VMA地址,可用表达式表示。
    • TYPE:section的类型(如NOLOAD)。
    • AT(LMA):section的LMA地址。

    示例

    SECTIONS {  .text : { *(.text) }  .data : { *(.data) }  .bss : { *(.bss) *(COMMON) }}

    特殊说明

    • 如果没有在SECTIONS命令中提到某section,该section会被直接拷贝到输出文件中。
    • 通用符号COMMON用于存储输入文件的通用符号。

    输入section与垃圾回收

    示例

    SECTIONS {  outputa : 0x10000 : { all.o }  foo.o(.input1)}

    处理方式

    • 如果某输入section未在SECTIONS命令中引用,链接器会将其直接拷贝到输出section中。
    • 使用KEEP()命令可强制保留特定section。

    内存区域命令

    示例

    MEMORY {  rom (rx) : ORIGIN = 0, LENGTH = 256K  ram (!rx) : org = 0x40000000, l = 4M}

    说明

    • rom区域用于只读section,ram区域用于可读写section。
    • 未引用section的section会被放置在指定区域内,若超出区域大小,连接器会报错。

    PHDRS命令

    示例

    PHDRS {  headers PT_PHDR PHDRS  interp PT_INTERP  text PT_LOAD FILEHDR PHDRS  data PT_LOAD  dynamic PT_DYNAMIC}

    说明

    • PHDRS命令用于定义ELF目标文件的程序头信息。
    • 每个PT_类型对应一个程序段,FILEHDRPHDRS可选。

    结论

    链接脚本是链接过程中的核心文件,通过合理配置可以实现对目标文件section的精确控制,完成高级链接任务。理解链接脚本的语法和用法是高级程序员的必备技能。

    转载地址:http://tve.baihongyu.com/

    你可能感兴趣的文章
    nodejs开发公众号报错 40164,白名单配置找不到,竟然是这个原因
    查看>>
    Nodejs异步回调的处理方法总结
    查看>>
    NodeJS报错 Fatal error: ENOSPC: System limit for number of file watchers reached, watch ‘...path...‘
    查看>>
    nodejs支持ssi实现include shtml页面
    查看>>
    Nodejs教程09:实现一个带接口请求的简单服务器
    查看>>
    nodejs服务端实现post请求
    查看>>
    nodejs框架,原理,组件,核心,跟npm和vue的关系
    查看>>
    Nodejs概览: 思维导图、核心技术、应用场景
    查看>>
    nodejs模块——fs模块
    查看>>
    Nodejs模块、自定义模块、CommonJs的概念和使用
    查看>>
    nodejs生成多层目录和生成文件的通用方法
    查看>>
    nodejs端口被占用原因及解决方案
    查看>>
    Nodejs简介以及Windows上安装Nodejs
    查看>>
    nodejs系列之express
    查看>>
    nodejs系列之Koa2
    查看>>
    Nodejs连接mysql
    查看>>
    nodejs连接mysql
    查看>>
    NodeJs连接Oracle数据库
    查看>>
    nodejs配置express服务器,运行自动打开浏览器
    查看>>
    NodeMCU教程 http请求获取Json中文乱码解决方案
    查看>>