77范文网 - 专业文章范例文档资料分享平台

ld中文使用手册完全版(9)

来源:网络收集 时间:2020-05-05 下载这篇文档 手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:或QQ: 处理(尽可能给您提供完整文档),感谢您的支持与谅解。点击这里给我发消息

有些目标文件格式具有多于一个的普通符号。比如,MIPS ELF目标文件格式区分标准普通符号和小普通符号。

在这种情况下,连接器会为其他类型的普通符号使用一个不同的特殊节名。 在MIPS ELF的情况中, 连接器

为标准普通符号使用'COMMON',并且为小普通符号使用'.common'。这就允许你把不同类型的普通符号映射到 内存的不同位置。

在一些老的连接脚本上,你有时会看到'[COMMON]'。这个符号现在已经过时了, 它等效于'*(COMMON)'。

输入节和垃圾收集

---------------------------------------

当连接时垃圾收集正在使用中时('--gc-sections'),这在标识那些不应该被排除在外的节时非常有用。这

是通过在输入节的通配符入口外面加上'KEEP()'实现的,比如'KEEP(*(.init))'或者'KEEP(SORT(*)(.sorts)) '。

输入节示例

---------------------

接下来的例子是一个完整的连接脚本。它告诉连接器去读取文件'all.o'中的所有节,并把它们放到输出节

'outputa'的开始位置处, 该输出节是从位置'0x10000'处开始的。 从文件'foo.o'中来的所有节'.input1'

在同一个输出节中紧密排列。 从文件'foo.o'中来的所有节'.input2'全部放入到输出节'outputb'中,后面

跟上从'foo1.o'中来的节'.input1'。来自所有文件的所有余下的'.input1'和'.input2'节被写入到输出节 'outputc'中。

SECTIONS {

outputa 0x10000 : {

all.o

foo.o (.input1) }

outputb : {

foo.o (.input2) foo1.o (.input1) }

outputc :

{

*(.input1) *(.input2) } }

输出节数据

-------------------

你可以通过使用输出节命令'BYTE','SHORT','LONG','QUAD',或者'SQUAD'在输出节中显式包含几个字节的数据

每一个关键字后面都跟上一个圆括号中的要存入的值。表达式的值被存在当前的定位计数器的值处。

‘BYTE’,‘SHORT’,‘LONG’‘QUAD’命令分别存储一个,两个,四个,八个字节。存入字节后,定位计 数器的值加上被存入的字节数。

比如,下面的命令会存入一字节的内容1,后面跟上四字节,其内容是符号'addr'的值。 BYTE(1) LONG(addr)

当使用64位系统时,‘QUAD’和‘SQUAD’是相同的;它们都会存储8字节,或者说是64位的值。而如果软硬件

系统都是32位的,一个表达式就会被作为32位计算。在这种情况下,‘QUAD’存储一个32位值,并把它零扩展

到64位, 而‘SQUAD’会把32位值符号扩展到64位。

如果输出文件的目标文件格式有一个显式的endianness,它在正常的情况下,值就会被以这种endianness存储

当一个目标文件格式没有一个显式的endianness时, 值就会被以第一个输入目标文件的endianness存储。

注意, 这些命令只在一个节描述内部才有效,而不是在它们之间, 所以,下面的代码会使连接器产生一个错 误信息:

SECTIONS { .text : { *(.text) } LONG(1) .data : { *(.data) } } 而这个才是有效的:

SECTIONS { .text : { *(.text) ; LONG(1) } .data : { *(.data) } }

你可能使用‘FILL’命令来为当前节设置填充样式。它后面跟有一个括号中的表达式。任何未指定的节内内存

区域(比如,因为输入节的对齐要求而造成的裂缝)会以这个表达式的值进行填充。一个'FILL'语句会覆盖到

它本身在节定义中出现的位置后面的所有内存区域;通过引入多个‘FILL’语句,你可以在输出节的不同位置 拥有不同的填充样式。

这个例子显示如何在未被指定的内存区域填充'0x90': FILL(0x90909090)

‘FILL’命令跟输出节的‘=FILLEXP’属性相似,但它只影响到节内跟在‘FILL’命令后面的部分,而不是

整个节。如果两个都用到了,那‘FILL’命令优先。 输出节关键字

-----------------------

有两个关键字作为输出节命令的形式出现。

`CREATE_OBJECT_SYMBOLS'

这个命令告诉连接器为每一个输入文件创建一个符号。而符号的名字正好就是相关输入文件的名字。

而每一个符号的节就是`CREATE_OBJECT_SYMBOLS'命令出现的那个节。 这个命令一直是a.out目标文件格式特有的。 它一般不为其它的目标文件格式所使用。

`CONSTRUCTORS'

当使用a.out目标文件格式进行连接的时候, 连接器使用一组不常用的结构以支持C++的全局构造函

数和析构函数。当连接不支持专有节的目标文件格式时, 比如ECOFF和XCOFF,连接器会自动辩识C++

全局构造函数和析构函数的名字。对于这些目标文件格式,‘CONSTRUCTORS’命令告诉连接器把构造

函数信息放到‘CONSTRUCTORS’命令出现的那个输出节中。对于其它目标文件格式,‘CONSTRUCTORS’ 命令被忽略。

符号`__CTOR_LIST__'标识全局构造函数的开始,而符号`__DTOR_LIST'标识结束。这个列表的第一个

WORD是入口的数量,紧跟在后面的是每一个构造函数和析构函数的地址,再然后是一个零WORD。编译

器必须安排如何实际运行代码。对于这些目标文件格式,GNU C++通常从一个`_

_main'子程序中调用

构造函数,而对`__main'的调用自动被插入到`main'的启动代码中。GNU C++通常使用'atexit'运行

析构函数,或者直接从函数'exit'中运行。

对于像‘COFF’或‘ELF’这样支持专有节名的目标文件格式,GNU C++通常会把全局构造函数与析构

函数的地址值放到'.ctors'和'.dtors'节中。把下面的代码序列放到你的连接脚本中去,这样会构建

出GNU C++运行时代码希望见到的表类型。

__CTOR_LIST__ = .;

LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) *(.ctors) LONG(0)

__CTOR_END__ = .; __DTOR_LIST__ = .;

LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) *(.dtors) LONG(0)

__DTOR_END__ = .;

如果你正使用GNU C++支持来进行优先初始化,那它提供一些可以控制全局构造函数运行顺序的功能,

你必须在连接时给构造函数排好序以保证它们以正确的顺序被执行。当使用'CONSTRUCTORS'命令时,

替代为`SORT(CONSTRUCTORS)'。当使用'.ctors'和'dtors'节时,使用`*(SORT(.ctors))'和

`*(SORT(.dtors))' 而不是`*(.ctors)'和`*(.dtors)'。

通常,编译器和连接器会自动处理这些事情,并且你不必亲自关心这些事情。但是,当你正在使用

C++,并自己编写连接脚本时,你可能就要考虑这些事情了。 输出节的丢弃。

-------------------------

连接器不会创建那些不含有任何内容的输出节。这是为了引用那些可能出现或不出现在任何输入文件中的输入 节时方便。比如: .foo { *(.foo) }

如果至少在一个输入文件中有'.foo'节,它才会在输出文件中创建一个'.foo'节

如果你使用了其它的而不是一个输入节描述作为一个输出节命令,比如一个符号赋值,那这个输出节总是被

创建,即使没有匹配的输入节也会被创建。

一个特殊的输出节名`/DISCARD/'可以被用来丢弃输入节。任何被分配到名为`/DISCARD/'的输出节中的输入 节不包含在输出文件中。 输出节属性

-------------------------

上面,我们已经展示了一个完整的输出节描述,看下去就象这样: SECTION [ADDRESS] [(TYPE)] : [AT(LMA)] {

OUTPUT-SECTION-COMMAND OUTPUT-SECTION-COMMAND ...

} [>REGION] [AT>LMA_REGION] [:PHDR :PHDR ...] [=FILLEXP] 我们已经介绍了SECTION, ADDRESS, 和OUTPUT-SECTION-COMMAND. 在这一节中,我们将介绍余下的节属性。 输出节类型

...................

每一个输出节可以有一个类型。类型是一个放在括号中的关键字,已定义的类型如下所示:

`NOLOAD'

这个节应当被标式讵不可载入,所以当程序运行时,它不会被载入到内存中。 `DSECT' `COPY' `INFO' `OVERLAY'

支持这些类型名只是为了向下兼容,它们很少使用。它们都具有相同的效果:这个节应当被标式讵不

可分配,所以当程序运行时,没有内存为这个节分配。

连接器通常基于映射到输出节的输入节来设置输出节的属性。你可以通过使用节类型来重设这个属性,

比如,在下面的脚本例子中,‘ROM’节被定址在内存地址零处,并且在程序运行时不需要被载入。

‘ROM’节的内容会正常出现在连接输出文件中。

百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说教育文库ld中文使用手册完全版(9)在线全文阅读。

ld中文使用手册完全版(9).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印 下载失败或者文档不完整,请联系客服人员解决!
本文链接:https://www.77cn.com.cn/wenku/jiaoyu/1024691.html(转载请注明文章来源)
Copyright © 2008-2022 免费范文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ: 邮箱:tiandhx2@hotmail.com
苏ICP备16052595号-18
× 注册会员免费下载(下载后可以自由复制和排版)
注册会员下载
全站内容免费自由复制
注册会员下载
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: