zoukankan      html  css  js  c++  java
  • Linux下的lds链接脚本简介(四)

    十一、 表达式
    lds中表达式的文法与C语言的表达式文法一致,表达式的值都是整型,如果ld的运行主机和生成文件的目标机都是32位,则表达式是32位数据,否则是64位数据
    以下是一些常用的表达式:
    _fourk_1 = 4K; /* K、M单位 */
    _fourk_2 = 4096; /* 整数 */
    _fourk_3 = 0×1000; /* 16 进位 */
    _fourk_4 = 01000; /* 8 进位 */
    注意:1K=1024 1M=1024*1024
    11.1、符号名
    没有被引号”"包围的符号,以字母、下划线或’.'开头,可包含字母、下划线、’.'和’-'。当符号名被引号包围时,符号名可以与关键字相同。如,
    “SECTION”=9;
    “with a space” = “also with a space” + 10;
    11.2、定位符号’.'
    只在SECTIONS命令内有效,代表一个程序地址空间内的地址。
    注意:在连接时,当定位符用在SECTIONS命令的输出section描述内时,它代表的是该section的当前**偏移**,而不是程序地址空间的绝对地址。当然当程序载入后,符号最后的地址还是程序地址空间的绝对地址。
    示例11.2_1:
    SECTIONS
    {
    output :
    {
    file1(.text)
    . + 1000;
    file2(.text)
    += 1000;
    file3(.text)
    } = 0×1234;
    }
    其中由于对定位符的赋值而产生的空隙由0×1234填充。其他的内容应该容易理解吧。
    示例11.2_2:
    SECTIONS
    {
    . = 0×100
    .text: {
    *(.text)
    = 0×200
    }
    = 0×500
    .data: {
    *(.data)
    . += 0×600
    }
    .text section在程序地址空间的开始位置是0x100
    示例11.2_3
    文件srca.c
    #include <stdio.h>
    int a = 100;
    int b=0;
    int c=0;
    int d=1;
    int main()
    {
    printf( "&a=%p ", &a );
    printf( "&b=%p ", &b );
    printf( "&c=%p ", &c );
    printf( "&d=%p ", &d );
    return 0;
    }
    文件ldsa.lds
    a = 10; /* 全局位置 */
    SECTIONS
    {
    b = 11;
    .text :
    {
    *(.text)
    c = .; /* section描述内 */
    . = 10000;
    d = .;
    }
    _bdata = (. + 3) & ~ 4; /* SECTIONS命令内 */
    .data : { *(.data) }
    }
    在没有使用a.lds情况下编译
    gcc -Wall -o a-without-lds.exe ./src/a.c
    运行./a-without-lds.exe
    结果:
    &a=0x601020
    &b=0x601038
    &c=0x60103c
    &d=0x601024
    在使用a.lds情况下编译
    gcc -Wall -o a-with-lds.exe ./src/a.c ./lds/a.lds
    运行./a-with-lds.exe
    结果:
    &a=0xa
    &b=0xb
    &c=0x400638
    &d=0x402b20
    10.3、表达式的操作符
    在lds中,表达式的操作符与C语言一致。
    优先级 结合顺序 操作符
    1 left ! – ~ (1)
    2 left * / %
    3 left + -
    4 left >>  =
    5 left &
    6 left |
    7 left &&
    8 left ||
    9 right ? :
    10 right &= += -= *= /= (2)
    (1)表示前缀符,(2)表示赋值符。
    10.4、表达式的计算
    连接器延迟计算大部分表达式的值。
    但是,对待与连接过程紧密相关的表达式,连接器会立即计算表达式,如果不能计算则报错。比如,对于section的VMA地址、内存区域块的开始地址和大小,与其相关的表达式应该立即被计算。
    例子,
    SECTIONS
    {
    .text 9+this_isnt_constant :
    { *(.text) }
    }
    这个例子中,9+this_isnt_constant表达式的值用于设置.text section的VMA地址,因此需要立即运算,但是由于this_isnt_constant变量的值不确定,所以此时连接器无法确立表达式的值,此时连接器会报错。
    10.5、相对值与绝对值
    在输出section描述内的表达式,连接器取其相对值,相对与该section的开始位置的偏移
    SECTIONS命令内且非输出section描述内的表达式,连接器取其绝对值
    通过ABSOLUTE关键字可以将相对值转化成绝对值,即在原来值的基础上加上表达式所在section的VMA值。
    示例
    SECTIONS
    {
    .data : { *(.data) ;_edata = ABSOLUTE(.); }
    }
    该例子中,_edata符号的值是.data section的末尾位置(绝对值,在程序地址空间内)。
    10.6、内建函数
    lds中有以下一些内建函数:
    ABSOLUTE(EXP) :转换成绝对值
    ADDR(SECTION) :返回某section的VMA值。
    ALIGN(EXP) :返回定位符’.'的按照EXP进行对齐后的修调值,对齐后的修调值算法为:(. + EXP – 1) & ~(EXP – 1)
    BLOCK(EXP) :如同ALIGN(EXP),为了向前兼容。
    DEFINED(SYMBOL) :如果符号SYMBOL在全局符号表内,且被定义了,那么返回1,否则返回0。
    示例:
    SECTIONS { …
    .text : {
    begin = DEFINED(begin) ? begin : . ;
    }
    }
    LOADADDR(SECTION) :返回三SECTION的LMA
    MAX(EXP1,EXP2) :返回大者
    MIN(EXP1,EXP2) :返回小者
    NEXT(EXP) :返回下一个能被使用的地址,该地址是EXP的倍数,类似于ALIGN(EXP)。除非使用了MEMORY命令定义了一些非连续的内存块,否则NEXT(EXP)与ALIGH(EXP)一定相同。
    SIZEOF(SECTION) :返回SECTION的大小。当SECTION没有被分配时,即此时SECTION的大小还不能确定时,连接器会报错。
    SIZEOF_HEADERS :返回输出文件头部的字节数。这些信息出现在输出文件的开始处。当设置第一个段的开始地址时,你可以使用这个数字。如果你选择了加速分页,当产生一个ELF输出文件时,如果链接器脚本使用SIZEOF_HEADERS内建函数,连接器必须在它
    算出所有段地址和长度之前计算程序头部的数值。如果连接器后来发现它需要附加程序头,它将报告一个“not enough room for 
    program headers”错误。为了避免这样的错误,你必须避免使用SIZEOF_HEADERS函数,或者你必须修改你的连接器脚本去避免强制
    连接器去使用附加程序头,或者你必须使用PHDRS命令去定义你自己的程序头
    十二、 暗含的连接脚本
    输入文件可以是目标文件,也可以是连接脚本,此时的连接脚本被称为 暗含的连接脚本
    如果连接器不认识某个输入文件,那么该文件被当作连接脚本被解析。更进一步,如果发现它的格式又不是连接脚本的格式,那么连接器报错。
    一个暗含的连接脚本不会替换默认的连接脚本,仅仅是增加新的连接而已。
    一般来说,暗含的连接脚本符号分配命令,或INPUT、GROUP、VERSION命令。
    在连接命令行中,每个输入文件的顺序都被固定好了,暗含的连接脚本在连接命令行内占住一个位置,这个位置决定了由该连接脚本指定的输入文件在连接过程中的顺序
    典型的暗含的连接脚本是libc.so文件,在GNU/linux内一般存在/usr/lib目录下。
  • 相关阅读:
    Nuget常用命令(转)
    Core使用SAP Web Service
    jquery.dataTables动态列--转
    jqGrid随窗口大小变化自适应大小-转
    30个值得推荐的数据可视化工具--转
    Automapper问题记录
    MVC及MVC Core在filter中如何获取控制器名称和Action名称
    .Net Core使用 MiniProfiler 进行性能分析(转)
    Core中使用Hangfire
    ASP.NET 多环境下配置文件web.config的灵活配置---转
  • 原文地址:https://www.cnblogs.com/Zyf2016/p/6337816.html
Copyright © 2011-2022 走看看