-t ld linux
Linux LD
2016-10-18 08:40:00 weixin_33770878 阅读数 4
ldconfig: /usr/local/lib/../lib64/libstdc++.so.6.0.22-gdb.py is not an ELF file - it has the wrong magic bytes at the start.

----------------------------------------------------------------------
Libraries have been installed in:
   /usr/local/lib/../lib64

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
   - add LIBDIR to the `LD_LIBRARY_PATH' environment variable
     during execution
   - add LIBDIR to the `LD_RUN_PATH' environment variable
     during linking
   - use the `-Wl,-rpath -Wl,LIBDIR' linker flag
   - have your system administrator add LIBDIR to `/etc/ld.so.conf'

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------
make[4]: Nothing to be done for `install-data-am'.

转载于:https://my.oschina.net/innovation/blog/759813

2012-07-11 17:05:26 Lcz_Ptr 阅读数 780
ld,即GNU的连接工具,用于将各目标文件合并在一起,并重新安排他们的数据以及符号的引用,常常是程序编译的最后一步。
ld scripts 即ld脚本。ld 脚本的主要目的是要描述怎样将输入文件的各段印象到输出文件中去。它控制输出文件在内存的布局情况。
--------------------------------------------------------------------------------
关于VMA ,LMA
每一个可装载的输出段都有两个地址:VMA(Virtual memory address) 和 LMA(Load mem
ory
address)VMA 是输出段运行时的地址,LMA
则是输出段被装载的地址。而这2个地址常常是相同的。在某些情况下二者是有区别的。比如,一个data段被装载到ROM中,然后在程序启动的时候被拷贝到
了RAM中去。(这种技术常常用在以ROM 为基础的系统中,用来初始化全局变量,而我们的系统的处理方法可能与此类似?)

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

关于SECTIONS命令的使用
SECTIONS告诉LD怎样将输入的段印象到输出的段,以及怎样将输出的段装载到内存中去。这是我们在内存布局中常常要用到的命令。段的基本结构如下:
SECTIONS
{
sections- command
sections- command
...

其中的sections-command 可作如下选择:
* 程序入口点设置命令ENTRY。
* 符号赋值
* 输出段描述(下面会提到)
* 覆盖描述。(overlay description)
1.输出段描述(Output Section Description):
输出段描述的完整格式如下:
SECTION [ address] [( type)] : [AT( LMA)]
{
output-sections-command
output-sections-command
...
} [> region] [: phdr : phdr ...] [=fillexp]
一般对于以上的描述不会全部用到,对于这些描述的用法,后面将会讲述到。
(1).关于段名
对于不同的输出格式,段名应该满足相应的约定。比如a.out格式的文件就应该只能
使用这些段名:.text .data .bss
(3).输出段地址
输出段地址 address 是输出段的VMA地址。例:
.text [address] :{ *(.text)}
如果没有指定 address 则将按照 region 或者是当前地址记数值"."来分配地址。注意,这里分配的是VMA地址(见VMA的说明)。
另外,在分配地址的时候还有地址对齐操作,这里就不赘述了。
2.输入段描述:
输出段描述告诉连接器怎样在内存中安排你的程序布局,而输入段描述则告诉连接器怎样将各输入文件映射到你的内存布局中去。
(1).输入段的基本语法如下:
输入文件名(段名)
例: file1(.text)
表示将文件 file1的.text 段放于此处。
也支持通配符,如:
*(.text)
将所有的文件的.text段放置到此处。
又例:
a.out
直接将a.out的所有段放置此处。
(2).输入段的通配符使用,就是一般的通配符语法,这里就不赘述了。
3.COMMON 段的设置
在很多的目标文件格式中,对于common symbols(什么是common symbols?)都没有专门的段来存放。
所以在连接时,连接器专门指定了一个COMMON段来包含这些common symbols.
而COMMON段一般放于输出文件的.bss段中。
例:
.bss { *(.bss) *(COMMON) }
在.bss段中放置所有输入文件的.bss段 和 所有输入文件的 common symbols
4.输入段描述的示例:
SECTIONS {
outputa 0x10000 :
{
all.o all.o的所有段
foo.o (.input1) foo.o的所有.input1 段
}
outputb :
{
foo.o (.input2) foo.o的所有.input2 段
foo1.o (.input1) foo1.o的所有.input1段
}
outputc :
{
*(.input1) 所有文件的余下的.input1段
*(.input2) 所有文件的余下的.input2段 
}
}
5.在输出段中装填数据。
(1). BYTE, SHORT, LONG, and QUAD
如:BYTE(1)
在当前位置装填1字节的1
(2). FILL 的使用,可以从当前位置开始装填本SECTION。
6.两个输出段关键字。
CREATE_OBJECT_SYMBOLS 和 CONSTRUCTORS
CREATE_OBJECT_SYMBOLS:
每一个输入的文件将对应一个同名的symbol.而这些symbol将被放置在CREATE_OBJECT_SYMBOLS
命令出现的段中。
CONSTRUCTORS:

此命令出现的地方放置C++全局构造和析构函数信息。对于a.out
格式,它使用其专有的方法来支持C++构造与析构函数。对于不能使用任意段名的文件格式如:XCOFF 和ECOFF
则需要一个CONSTRUCTORS 命令来在输出文件中记录C++全局构造函数和析构函数的信息。对于能使用任意段名的文件格式如COFF 和
ELF 。则连接器将自动生成名为.ctors 和 .dtors 的段来记录相应信息。我们可能暂时用不到这个东西。
7.丢弃段。
命名为 /DISCARD/ 的段的内容将不被包含到输出文件中。
8.输出段描述的其它特性,输出段描述的基本结构正如前边所提到的如下所示:
SECTION [ address] [( type)] : [AT( LMA)]
{
output-sections-command
output-sections-command
...
} [> region] [: phdr : phdr ...] [=fillexp]
下面对其各个特性做一个比较详细的说明:
(1). Output Section Type (即输出段的type属性)
此属性可以赋值为:
NOLOAD 此段的内容将不被装载到内存中去,比如直接在ROM中运行程序。
DSECT
COPY
INFO
OVERLAY
以上4个代表运行时不另外为改段分配内存空间,这样可以一定的节省程序
空间。 
(2). 输出段LMA
使用AT 命令来设置段的LMA
这样的话可以使用这个特性很方便的建立ROM image.
例如:
SECTIONS
{
.text 0x1000 : { *(.text) _etext = . ; } //.text 的VMA为0x1000
.mdata 0x2000 : //.mdata 的VMA为0x2000
AT ( ADDR (.text) + SIZEOF (.text) ) //.mdata 的LMA为紧随.text
//段之后。
{ _data = . ; *(.data); _edata = . ; }
.bss 0x3000 : //.bss的VMA为0x3000
{ _bstart = . ; *(.bss) *(COMMON) ; _bend = . ;}
}
与之配合的初始化代码示例如下(可能是由ld自动生成):
extern char _etext, _data, _edata, _bstart, _bend;
char *src = &_etext; //从这里可以看出,"_etext=."的意思实际上是令_etext的地址
//等于当前的VMA
char *dst = &_data;
/* ROM has data at end of text; copy it. */
while (dst region 属性可以将某个段定位到预定义好的内存位置去。
例:
MEMORY { rom : ORIGIN = 0x1000, LENGTH = 0x1000 }
SECTIONS { ROM : { *(.text) } >rom }
(4). Output Section Segmentation
程序段的定义。
例: 
PHDRS { text PT_LOAD ; }
SECTIONS { .text : { *(.text) } :text }
后面将提到PHDRS
(5).输出段填充
例:采用如下的方法来填充段
SECTIONS { .text : { *(.text) } =0x9090 }
9.覆盖描述:(Overlay Description)
定义如下:
OVERLAY [ start] : [NOCROSSREFS] [AT ( ldaddr )]
{
secname1
{
output-section-command
output-section-command
...
} [:PHDR...] [=FILL]
secname2
{
output-section-command
output-section-command
...
} [: phdr...] [= fill]
...
} [> region] [: phdr...] [= fill]
OVERLAY 命令应该定义于SECTIONS 命令之内。
--------------------------------------------------------------------------------
------------ 
10.MEMORY 命令
分配内存区域
MEMORY
{
name [( attr)] : ORIGIN = origin, LENGTH = len
...
}
atrr 为段的匹配特性,如果一个段没有明确指定将其放置到某一个region中去,那么如果
其属性匹配该region的atrr属性,将被加入到该region中去。
有以下属性:
R 只读段 
W 只写段
X 执行段
A 可分配段
I 已初始化段
L 与I相同。
! 非特性 
例子:
MEMORY
{
rom (rx) : ORIGIN = 0, LENGTH = 256K
ram (!rx) : org = 0x40000000, l = 4M
}
一旦完成了region的定义,就可以使用 >region 的方法将某段指定添加到某个region中去
2013-12-30 17:22:09 bytxl 阅读数 656

http://blog.csdn.net/fisher_jiang/article/details/4193368

描述 (DESCRIPTION)

ld 合并 一组 目标文件(object) 和 库文件(archive), 重定位 数据部分, 构建 符号引用(symbol reference). 一般说来, 编译 生成 可执行文件 的 最后步骤 就是 调用 ld.

ld 可以读取 用 连接器命令语言(Linker Command Language) 编写的 脚本文件, 它能够 对 连接过程 提供 精确 和 全面 的 控制. 本 手册页 不讨论 命令语言; 可参看 `info' 的 `ld' 项, 或者 手册 ld: the GNU linker , 里面有 命令语言 的 细节和 其他 GNU linker 的 内容.

这个版本 的 ld 使用 通用BFD库操作 目标文件, ld 能够 以 多种格式 读入, 连接和 输出 目标文件 ---例如 COFF 或 a.out, 能够 把 不同的格式 连接 在一起, 产生 各种 有效 的 目标文件. 用 `objdump -i' 可以 列出 各种 体系结构 支持 的 格式 列表; 另见 objdump(1).

GNU linker 不仅 灵活 强大, 还能够 比 其他 linker 提供 更多 的 诊断信息. 很多 linker 只要 碰上 一个错误 就 立刻停止 执行; 而 ld 一有可能 仍然 继续执行, 这样 容易 定位出 其他错误 (某些情况下, 尽管出了错, 仍然 生成 输出文件).

GNU linker ld 期望 实现 更广泛 的 适用范围, 尽可能 兼容 其他 linker. 通过 命令行 和 环境变量, 用户 可以 用 ld 执行 多种 操作.

 

选项 (OPTIONS)

过于丰富的 命令行选项 使人 感到 压抑, 好在 实际使用 中, 多数情况下只需要掌握 其中 一小部分. 例如, 在 一个 标准的, 提供 相应支持 的 Unix 系统 中, 常常 用 ld 连接标准的 Unix 目标文件. 如果要 连接 hello.o:


$ ld -o output /lib/crt0.o hello.o -lc

它 告诉 ld 生成 一个 叫做 output 的 文件 , 其中 连接了 文件 /lib/crt0.ohello.o 以及库文件 libc.a (在 标准搜索目录下).

ld 的 命令行选项 可以 任意顺序出现, 甚至 重复出现. 多数 情况 下, 如果 用 不同的 参数 重复 同一种 选项, ld 不会 出现 更多的变化, 也不会 覆盖 以前的 参数. (指 命令行 中 左边的参数)

例外情况 --- 某些选项 有 反复使用 的 需要 --- 如 -A, -b (或等同的 -format), -defsym, -L, -l, -R, 和 -u.

待连接的 目标文件 列表, 即 总览中的 objfile, 可以 放在 命令行选项 的 前面, 后面, 或者 混杂其中; 但是 不能 把 objfile 放置于 某个 选项开关 和 它的参数 中间.

一般说来 linker 要求 至少 输入 一个 目标文件, 但是 可以 用 -l, -R 输入 其他格式 的 二进制文件, 或者 用 命令语言 编写的 脚本文件. 如果 没有 指定二进制格式 的 输入文件, linker 就不能 产生 输出文件, 而是显示 `No input files'.

选项的参数 必须 出现在 代表 选项的 字母 后面, 可以有 空白符, 也可以 没有.

-Aarchitecture

在 目前版本 的 ld 中, 这个 选项 仅适用于 Intel 960 体系系列. 在 ld 的 设置 中, architecture 参数 是 960 系列 的 成员 识别名称 之一, 由 两个字母 组成; 这个选项 指出 期望的 输出目标, 对 输入文件 的 不兼容指令 作出警告. 它 能够 改变 linker 对 库文件 的 搜索策略, 以便于 支持 体系相关库, 方法是把 体系识别名称 添加在 待搜索 的文件名 尾部.

例如, 如果 ld 命令行 有 `-ACA' 和 `-ltry', linker 将 搜索 (根据 内置的路径和 -L 指定的路径) 以下 名称 的 库文件


try
libtry.a
tryca
libtryca.a

前两项 是 常规做法; 后两项 源于 `-ACA'.

将来发布的 ld 可能 对 其他 体系结构提供 类似功能.

可以 在 命令行上 使用 多个 -A 选项, 只要 该 体系 允许 和 目标体系 相连, 其选项 使 ld 在 搜索 -l 指定的库中, 增加 和 体系结构名称 对应的库.

-b input-format

指定 输入目标文件 的 二进制格式, 目标文件 在 命令行 上 给出, 放在这个选项 的 后面. 一般 不需要 指定 这个选项, ld 的 缺省输入格式 配置为各个机器 上 最常用 的 格式. input-format 是 字符串, BFD 库 支持的 格式 名称. 选项 -format input-format 起 相同的 作用, 脚本命令 TARGET 也是 一样.

连接 某些 不寻常的 二进制文件 时 需要 这个选项. 或者 使用 -b 选项 强调 格式切换 (连接不同格式 的 目标文件), 比如说, 在 每组 特定格式 的 目标文件前面 使用 -b input-format 选项.

环境变量 GNUTARGET 用于 指定缺省格式. 也可以 在 脚本文件 中 用 TARGET 命令 定义 输入格式.

-Bstatic

禁止 连接 共享库. 这个选项只在 支持 共享库 的 平台 上 有意义.

-Bdynamic

连接 动态库. 这个选项只在 支持 共享库 的 平台 上 有意义, 一般说来 它是 缺省选项.

-Bsymbolic

当 创建 共享库 的 时候, 只要有可能, 在 共享库 内 编联(bind reference) 全局符号和 定义(definition). 一般说来, 允许 连接了 某个共享库 的 程序覆盖 共享库内 的 定义. 这个选项 只在 支持 共享库 的 ELF 平台 上 有意义.

-c commandfile

告诉 ld 从 文件 commandfile 中 读取 连接 命令. 这些 命令 彻底的 覆盖 ld 的 缺省 连接 格式 (而不是添加); commandfile 必须 详尽的 描述 目标格式 的 所有细节.

你 也可以 在 命令行 上 直接嵌入 连接命令, 把 脚本 嵌在 大括弧 `{' 和 `}' 中间.

--cref

输出 交叉引用表(cross reference). 如果 创建了 连接映像(linker map) 文件, 交叉引用表 就 输出到 映像文件 中, 否则 送往 标准输出.

-d

-dc

-dp

这 三个选项 是 一回事, 为了兼容 其他 linker 而 同时提供. 即使 已经 指定 ld 生成 可重定位文件 (-r), 它们 能为 公共符号(common symbol) 分配 空间. 脚本命令 FORCE_COMMON_ALLOCATION 起 同样作用.

-defsym symbol = expression

在 输出文件 中 创建 一个 全局符号, 它 含有 expression 给出的 绝对地址. 可以 在 命令行 使用 多个 这样的 选项. 这个 expression 只能 使用 有限的 数学形式: 十六进制常数, 已经存在 的 符号名字. 或者 使用 +- 加减 十六进制常数 或 符号. 如果 需要 更复杂的 表达式, 考虑 使用命令语言脚本.

--demangle

--no-demangle

这些选项 控制 是否在 出错信息 和 其他信息 中, 输出 可读的(demangle) 符号名称. 如果 使用了 demangle 选项, linker 尽量使 符号名称 容易理解: 去掉 领头的 下划线 (如果 被 目标文件格式 采用); 把 C++ 难懂的 符号名称 (symbol name) 转换成 可读的 名称. 缺省情况下 linker 输出 可读的 符号名称, 除非 设置了 环境变量 COLLECT_NO_DEMANGLE . 这些选项 能够 覆盖 缺省行为.

-e entry

使用 entry (入口) 标识符 作为 程序 执行 的 开始端, 而不是 缺省入口. 关于 缺省入口 和 其他设置 入口 的 方法 参见 `info' 的 ld' 项.

-embedded-relocs

这个选项 仅用于 连接 MIPS上嵌入的 PIC 代码, GNU 的 编译器 和 汇编器 用 -membedded-pic 选项 能够 生成 这种代码. 它使 linker 创建 一张 表格, 用于 在 运行的时候, 重定位 任何 被 静态初始化 为 指针值 的 数据. 详见 testsuite/ld-empic 的 代码.

-E

-export-dynamic

当 创建 ELF 文件时, 把 所有 符号 加入 动态符号表. 一般说来, 动态符号表 只包含 动态目标库(dynamic object) 需要的符号. 用 dlopen 的 时候 需要 这个 选项.

-f name

--auxiliary name

创建 ELF 共享目标库时, 把 内部的 DT_AUXILIARY 字段 设置为 name. 它 告诉 动态linker, 把 该 共享目标库 的 符号表 用做 共享目标 name 的 符号表 的 辅助过滤器.

-F name

--filter name

创建 ELF 共享目标库时, 把 内部的 DT_FILTER 字段 设置为 name. 它 告诉 动态linker, 把 该 共享目标库 的 符号表 用做 共享目标 name 的 符号表 的 辅助过滤器.

-format input-format

等同于 -b input-format.

-g

虚设项; 用于 兼容其他 工具.

-G size

把 使用 GP 寄存器优化的 目标(文件) 大小 限制为 size . 用于 MIPS ECOFF, 对 其他 目标文件格式 无效.

-h name

-soname name

创建 ELF 共享目标库时, 把 内部的 DT_SONAME 字段 设置为 name. 如果 某个 可执行文件 连接了 含有 DT_SONAME 字段的 共享目标库, 当 该程序 运行 时, 动态 linker 试图 根据 DT_SONAME 字段 调入 共享的 目标库, 而 不使用 提供给 linker 的 文件名.

--help

在 标准输出 显示 命令行选项 的 摘要, 然后 结束. 这个选项 和 --version 选项 使用了 两个 短横线, 不是 一个, 目的是 兼容 其他 GNU 程序. 只用一个 短横线 的 选项 是为了 兼容 其他 linker.

-i

执行 增量连接(incremental link), 等同于 -r 选项.

-lar

在 连接文件 列表 中 增加 归档库文件 ar. 可以 多次 使用 这个选项. 凡指定 一项 ar , ld 就会 在 路径列表 中 增加 一项 对 libar.a 的 搜索.

-Lsearchdir

这个选项 将 路径 searchdir 添加 到 路径列表 中去, ld 在 这个 列表 中 搜索归档库. 可以 多次 使用 这个选项.

缺省的 搜索路径集 (不使用 -L 时) 取决于 ld 使用的 模拟模式(emulation) 及其 配置. 在 连接脚本 中, 可以 用 SEARCH_DIR 命令 指定 路径.

-M

在 标准输出 显示 连接映像 --- 有关 ld 把 符号 映射到何处 的 诊断信息, 以及 全局公共存储器 的 分配 信息.

-Map mapfile

把 连接映像 输出到 mapfile 文件 中 --- 有关 ld 把 符号 映射到 何处 的 诊断信息, 以及 全局公共存储器 的 分配 信息.

-m emulation

模仿 emulation 连接器. 可以 用 --verbose-V 选项列出 有效的 模拟项. 这个选项 覆盖 编译 进去 的 缺省项.

-N

指定 可读写 的 正文 数据 节(section). 如果 输出格式 支持 Unix 风格的 幻数(magic number), 则 输出文件 标记为 OMAGIC.

当 使用 `-N' 选项 时, linker 不做数据段 的 页对齐(page-align).

-n

设置 正文段 为 只读, 如果有可能, NMAGIC 为 可写.

-noinhibit-exec

一般说来, 如果 连接的时候 发生 错误, linker 不会 产生 输出文件. 使用了这个 标志选项, 只要 不出 致命差错, 仍能够 产生 输出文件.

-no-keep-memory

linker 通常 牺牲 内存, 优化 速度, 它 把 输入文件 的符号表 缓冲在 内存中. 这个选项 使 linker 必要时 重复读取符号表, 以便 优化 内存使用. 连接 大型 可执行文件 的 时候, linker 有可能 内存 不够, 此时 可以 试试 这个选项.

-no-warn-mismatch

一般情况下, 如果试图 连接 某些 不匹配 的 输入文件, 比如说, 按 不同处理器编译 的, 或者 具有 不同的 字节顺序(endianness), linker 就会 报错. 这个选项 告诉 linker 默许这种 错误. 要 小心使用 这个选项, 除非 你正在做 某些 特殊操作, 而且 能够 确定 不需要 linker 报错.

-o output

output 用来 指定 ld 生成的 程序名; 如果 没有 使用 这个选项, 缺省名字 是 `a.out'. 脚本命令 OUTPUT 起 同样 作用.

-Olevel

生成 优化的 输出文件. 这个选项占用 比较多 的 时间, 因此 仅 常用于最终文件 的 生成. level 是 数值参数. 任何 大于零 的 参数 意味着 要求 优化.

-oformat output-format

指定 输出目标文件 的 二进制格式. 一般 不需要 指定 这个选项, ld 的 缺省 输出格式配置为 各个机器 上 最常用 的 格式. output-format 是 一个 字符串, BFD 库 支持的 格式 名称. 脚本命令 OUTPUT_FORMAT 也可以 指定 输出格式, 但是 这个选项 能够 覆盖 掉 它.

-R filename

从 文件 filename 中 读取 符号名称 及其 地址, 但是 不做 重定位, 不传送到 输出端. 它 可以 使 输出文件 符号引用 其他程序中 定义的绝对地址.

-relax

这个选项 的 效果 取决于 机器, 目前 只支持 H8/300.

在 某些 平台 上 可以 使用 这个选项 做 全局优化, 它 让 linker 解决 程序中的 地址处理, 例如 在 输出目标文件 中 缓和(relax) 地址模式 以及 合成 (synthesize) 新指令.

其他平台 也接受 `-relax' 选项, 但是不起作用.

-r

生成 可重定位 输出 --- 就是说, 生成的 输出文件 能够 依次 成为 ld 的 输入, 一般 称之为 不完全(partial) 连接. 它 有 一个 副效应, 在支持 标准 Unix 幻数(magic number) 的 环境中, 这个选项 把 输出文件 的 幻数 设置成 OMAGIC. 如果 没有 指定 这个选项, linker 生成 绝对定位 的 文件. 连接 C++ 程序时, 这个选项 不会 解析 出 对 构造子(constructor) 的 引用(reference); 不妨 改用 -Ur 选项.

这个选项 的 效果 和 -i 一样.

-rpath directory

增加 一条 对 运行时(runtime)库的 搜索路径. 这个选项 用于 连接 ELF 可执行文件 和 共享目标库. 所有 -rpath 选项的 参数 被 合并, 然后 一起 传递 给 运行时 linker, 运行时 linker 在运行 的 时候 使用 这些 路径 寻找 共享目标库. -rpath 也可以 用来 定位 共享目标库 引用的 共享目标库; 参见 对 -rpath-link 选项 的 叙述. 如果 连接 ELF 可执行文件 时 没有 指定 -rpath 选项, linker 就使用 环境变量 LD_RUN_PATH 的 内容 --- 只要 这个 环境变量 存在.

-rpath 选项 能够 用在 SunOS 上, 缺省状况下, linker 可以 根据 给出的 -L 选项 形成 运行时 搜索路径. 如果 使用了 -rpath 选项, 运行时搜索路径 从 -rpath 中 产生, 而 忽略 -L 选项. 这一点 有利于 使用 gcc, 在 NFS 文件系统 上, gcc 可能 产生 许多 -L 选项.

-rpath-link directory

使用 ELF 或 SunOS 的 时候, 某些 共享库 可能 需要 其他 共享库. 这种情况 一般 发生在 某个 ld -shared 连接 中, 输入文件 包含了 共享库.

如果 linker 遇到 这样的 依赖情况, 当 它执行 非共享, 不可重定位 的 连接时, linker 将 自动寻找 所需的 共享库, 如果 它们 没有 被 显明 包含, 就把它们 包含到 连接 中. 在 这种情况下, -rpath-link 选项 指定了 最先 搜索 的 目录集. -rpath-link 能够 指定 一批 目录, 目录 用 冒号 隔开. 也可以 用 这些 目录名 作为 参数, 重复 使用 这个 选项.

如果 没有 找到 需要的 共享库, linker 产生 一个 警告, 但是 继续 连接.

-S

去掉 输出文件 中的 调试符号信息 (但不是 所有符号).

-s

去掉 输出文件 中的 全部 符号信息.

-shared

创建 一个 共享库. 目前只支持 ELF 和 SunOS 平台 (在 SunOS 上, 这个选项不是必须的, 如果 没有 使用 -e 选项, 而且 存在 不确定 的 符号, linker 将 自动 创建 共享库).

-sort-common

ld 通常 把 全局公共符号 放到 适当的 输出节, 按照 大小 排序. 首先是 单字节符号, 然后是 双字节, 接下来是 四字节, 随后是 其他的. 它的 目的是 防止 符号间 因为 排布限制 出现 间隙. 使用 这个选项 可以 禁止 排序.

-split-by-reloc count

在 输出文件 中 创建 附加节(extra section), 使得 输出文件 中, 没有 某一个 输出节 包含 大于 count 个 重定位项. 它用于 产生 大型 可重定位 COFF 目标文件, 可以 插入到某些实时内核 中; 因为 COFF 不能 在 单一节内 存放 65535 以上的 重定位项. 注意, 有些 目标文件格式 不支持 任意 分节, 此时 这个选项 将会 操作 失败. 此外, linker 不能够 分割 输入节, 然后 重新分配, 因此 如果 某个 输入节 包含 count 以上的 重定位项, 相应的输出节 将 包含 同样多的 重定位项.

-split-by-file

类似于 -split-by-reloc , 但是 它为 每个 输入文件 建立一个 新的 输出节.

-Tbss org

-Tdata org

-Ttext org

org 作为 输出文件 的 段 起始地址 --- 特别是 --- bss, data, 或 text 段. org 必须是 十六进制整数.

-T commandfile

等同于 -c commandfile; 用于 兼容 其他工具.

-t

ld 处理 输入文件 的 时候 显示 文件名.

-u sym

sym 作为 未定义(undefined) 的 符号 送入 输出文件. 这样做 可以, 例如, 促使 linker 从 标准库 连接 某个 附加的模块. 允许 使用 多个 -u 选项 输入 多个 未定义 符号.

-Ur

对于 除 C++ 以外的任何 程序, 这个选项 等同于 -r: 生成 可重定位 的 输出 --- 就是说, 能够 依次 输入 ld 的 输出文件. 连接 C++ 程序 的 时候, -Ur 解析 对 构造子(constructor) 的引用(reference), 这一点 和 -r 不同.

--verbose

显示 ld 的 版本号, 列出 支持的 模拟项(emulation). 显示 哪些 输入文件 能够 打开, 哪些 不能,

-v, -V

显示 ld 的 版本号. 此外 -V 选项 能够 列出 支持的 模拟项.

--version

显示 ld 的 版本号 然后 结束.

-warn-common

当 公共符号 和 其他 公共符号 合并 时, 或者 和 某个 符号定义 合并 时, linker 就发出 警告. Unix 系统的 linker 允许 这种 有些 草率 的 做法, 其他操作系统 则 不行. 这个选项 帮助你 在 合并 全局符号 的 时候发现 潜在问题.

-warn-constructors

如果 使用了 全局构造子(global constructor), linker 就发出 警告. 它 只对 某些 目标文件结构 有用, 对于 如 COFF 或 ELF, 此 linker 不能够检测 全局构造子 的 使用情况.

-warn-multiple-gp

如果 输出文件 需要 多个 全局指针值, linker 就发出 警告. 这个选项 只能用于 某些 处理器, 如 Alpha.

-warn-once

对 每个 未定义符号 只 警告 一次, 而不是 每次 引用 这个符号 都 警告.

-warn-section-align

如果 某个 输出节(section) 的 地址 因为 边界对齐 而 发生 改变, linker 就发出 警告. 典型情况下 由 输入节 设置 边界, 只有 不做 明确指定的 时候 地址才会 改变; 就是说, SECTIONS 命令 没有 指出 该节的 开始地址.

--whole-archive

对于 命令行 上 --whole-archive 选项 提到的 每个 归档库, 连接时 连入 归档库 的 全部 目标文件, 而不是在 归档库 中 搜索 所需的 目标文件. 一般用于 把 归档库文件转变成 共享库文件, 迫使 全部 目标文件 进入 共享库.

--no-whole-archive

关闭 --whole-archive 选项 对 归档库 的 影响.

--wrap symbol

symbol 使用 包装函数(wrapper function). 任何 对 symbol 未定义 的 引用 (undefined reference) 将 解析为 __wrap_symbol. 任何 对 __real_symbol 未定义 的 引用 将 解析为 symbol.

-X

删除 全部 临时的 局部符号. 大多数目的文件 中, 这些 局部符号 的 名字 用 `L' 做开头.

-x

删除 全部 局部符号.

 

环境 (ENVIRONMENT)

通过 环境变量 GNUTARGET 可以改变 ld 的 行为.

如果 没有 使用 -b 选项 (或 相同的 -format), GNUTARGET 决定了输入文件 的 目标格式, 其值 应为 BFD的 名称之一. 如果 没有 GNUTARGET 环境变量, ld 就使用 主机的 本地格式. 如果 GNUTARGET 设置为 default, BFD 通过 检查 输入文件 的 二进制格式 判断输入格式; 这个方法 通常 有效, 但 隐含 歧义, 这是因为 没有 办法 保证 标志 目标文件格式的 幻数 是 唯一的. 不过, 各个系统 配置 BFD 的 时候, 会把系统 约定的格式 放在 搜索列表 的前面, 因此 能够 按照 约定 消除 歧义.

 

另见 (SEE ALSO)

objdump(1)
`ld'
和 `binutils' ( info)
ld: the GNU linker, Steve Chamberlain and Roland Pesch; The GNU Binary Utilities, Roland H. Pesch.

 

COPYING

Copyright (c) 1991, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.

Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.

Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.

Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be included in translations approved by the Free Software Foundation instead of in the original English.


2012-09-25 10:57:32 ninver2007 阅读数 751

描述 (DESCRIPTION)

ld 合并 一组 目标文件(object) 和 库文件(archive), 重定位 数据部分, 构建 符号引用(symbol reference). 一般说来, 编译 生成 可执行文件 的 最后步骤 就是 调用 ld.

ld 可以读取 用 连接器命令语言(Linker Command Language) 编写的 脚本文件, 它能够 对 连接过程 提供 精确 和 全面 的 控制. 本 手册页 不讨论 命令语言; 可参看 `info' `ld' , 或者 手册 ld: the GNU linker , 里面有 命令语言 的 细节和 其他 GNU linker 的 内容.

这个版本 的 ld 使用 通用BFD库操作 目标文件, ld 能够 以 多种格式 读入, 连接和 输出 目标文件 ---例如 COFF a.out, 能够 把 不同的格式 连接 在一起, 产生 各种 有效 的 目标文件. `objdump -i' 可以 列出 各种 体系结构 支持 的 格式 列表; 另见 objdump(1).

GNU linker 不仅 灵活 强大, 还能够 比 其他 linker 提供 更多 的 诊断信息. 很多 linker 只要 碰上 一个错误 就 立刻停止 执行; ld 一有可能 仍然 继续执行, 这样 容易 定位出 其他错误 (某些情况下, 尽管出了错, 仍然 生成 输出文件).

GNU linker ld 期望 实现 更广泛 的 适用范围, 尽可能 兼容 其他 linker. 通过 命令行 和 环境变量, 用户 可以 用 ld 执行 多种 操作.

 

选项 (OPTIONS)

过于丰富的 命令行选项 使人 感到 压抑, 好在 实际使用 中, 多数情况下只需要掌握 其中 一小部分. 例如, 在 一个 标准的, 提供 相应支持 的 Unix 系统 中, 常常 用 ld 连接标准的 Unix 目标文件. 如果要 连接 hello.o:


$ ld -o output /lib/crt0.o hello.o -lc

它 告诉 ld 生成 一个 叫做 output 的 文件 , 其中 连接了 文件 /lib/crt0.o hello.o 以及库文件 libc.a (在 标准搜索目录下).

ld 的 命令行选项 可以 任意顺序出现, 甚至 重复出现. 多数 情况 下, 如果 用 不同的 参数 重复 同一种 选项, ld 不会 出现 更多的变化, 也不会 覆盖 以前的 参数. (指 命令行 中 左边的参数)

例外情况 --- 某些选项 有 反复使用 的 需要 --- -A, -b (或等同的 -format), -defsym, -L, -l, -R, -u.

待连接的 目标文件 列表, 即 总览中的 objfile, 可以 放在 命令行选项 的 前面, 后面, 或者 混杂其中; 但是 不能 把 objfile 放置于 某个 选项开关 和 它的参数 中间.

一般说来 linker 要求 至少 输入 一个 目标文件, 但是 可以 用 -l, -R 输入 其他格式 的 二进制文件, 或者 用 命令语言 编写的 脚本文件. 如果 没有 指定二进制格式 的 输入文件, linker 就不能 产生 输出文件, 而是显示 `No input files'.

选项的参数 必须 出现在 代表 选项的 字母 后面, 可以有 空白符, 也可以 没有.

-Aarchitecture

在 目前版本 的 ld , 这个 选项 仅适用于 Intel 960 体系系列. ld 的 设置 中, architecture 参数 是 960 系列 的 成员 识别名称 之一, 由 两个字母 组成; 这个选项 指出 期望的 输出目标, 对 输入文件 的 不兼容指令 作出警告. 它 能够 改变 linker 对 库文件 的 搜索策略, 以便于 支持 体系相关库, 方法是把 体系识别名称 添加在 待搜索 的文件名 尾部.

例如, 如果 ld 命令行 有 `-ACA' `-ltry', linker 将 搜索 (根据 内置的路径和 -L 指定的路径) 以下 名称 的 库文件


try
libtry.a
tryca
libtryca.a

前两项 是 常规做法; 后两项 源于 `-ACA'.

将来发布的 ld 可能 对 其他 体系结构提供 类似功能.

可以 在 命令行上 使用 多个 -A 选项, 只要 该 体系 允许 和 目标体系 相连, 其选项 使 ld 在 搜索 -l 指定的库中, 增加 和 体系结构名称 对应的库.

-b input-format

指定 输入目标文件 的 二进制格式, 目标文件 在 命令行 上 给出, 放在这个选项 的 后面. 一般 不需要 指定 这个选项, ld 的 缺省输入格式 配置为各个机器 上 最常用 的 格式. input-format 是 字符串, BFD 库 支持的 格式 名称. 选项 -format input-format 起 相同的 作用, 脚本命令 TARGET 也是 一样.

连接 某些 不寻常的 二进制文件 时 需要 这个选项. 或者 使用 -b 选项 强调 格式切换 (连接不同格式 的 目标文件), 比如说, 在 每组 特定格式 的 目标文件前面 使用 -b input-format 选项.

环境变量 GNUTARGET 用于 指定缺省格式. 也可以 在 脚本文件 中 用 TARGET 命令 定义 输入格式.

-Bstatic

禁止 连接 共享库. 这个选项只在 支持 共享库 的 平台 上 有意义.

-Bdynamic

连接 动态库. 这个选项只在 支持 共享库 的 平台 上 有意义, 一般说来 它是 缺省选项.

-Bsymbolic

当 创建 共享库 的 时候, 只要有可能, 在 共享库 内 编联(bind reference) 全局符号和 定义(definition). 一般说来, 允许 连接了 某个共享库 的 程序覆盖 共享库内 的 定义. 这个选项 只在 支持 共享库 的 ELF 平台 上 有意义.

-c commandfile

告诉 ld 从 文件 commandfile 中 读取 连接 命令. 这些 命令 彻底的 覆盖 ld 的 缺省 连接 格式 (而不是添加); commandfile 必须 详尽的 描述 目标格式 的 所有细节.

你 也可以 在 命令行 上 直接嵌入 连接命令, 把 脚本 嵌在 大括弧 `{' `}' 中间.

--cref

输出 交叉引用表(cross reference). 如果 创建了 连接映像(linker map) 文件, 交叉引用表 就 输出到 映像文件 中, 否则 送往 标准输出.

-d

-dc

-dp

这 三个选项 是 一回事, 为了兼容 其他 linker 而 同时提供. 即使 已经 指定 ld 生成 可重定位文件 (-r), 它们 能为 公共符号(common symbol) 分配 空间. 脚本命令 FORCE_COMMON_ALLOCATION 起 同样作用.

-defsym symbol = expression

在 输出文件 中 创建 一个 全局符号, 它 含有 expression 给出的 绝对地址. 可以 在 命令行 使用 多个 这样的 选项. 这个 expression 只能 使用 有限的 数学形式: 十六进制常数, 已经存在 的 符号名字. 或者 使用 + - 加减 十六进制常数 或 符号. 如果 需要 更复杂的 表达式, 考虑 使用命令语言脚本.

--demangle

--no-demangle

这些选项 控制 是否在 出错信息 和 其他信息 中, 输出 可读的(demangle) 符号名称. 如果 使用了 demangle 选项, linker 尽量使 符号名称 容易理解: 去掉 领头的 下划线 (如果 被 目标文件格式 采用); C++ 难懂的 符号名称 (symbol name) 转换成 可读的 名称. 缺省情况下 linker 输出 可读的 符号名称, 除非 设置了 环境变量 COLLECT_NO_DEMANGLE . 这些选项 能够 覆盖 缺省行为.

-e entry

使用 entry (入口) 标识符 作为 程序 执行 的 开始端, 而不是 缺省入口. 关于 缺省入口 和 其他设置 入口 的 方法 参见 `info' ld' .

-embedded-relocs

这个选项 仅用于 连接 MIPS上嵌入的 PIC 代码, GNU 的 编译器 和 汇编器 用 -membedded-pic 选项 能够 生成 这种代码. 它使 linker 创建 一张 表格, 用于 在 运行的时候, 重定位 任何 被 静态初始化 为 指针值 的 数据. 详见 testsuite/ld-empic 的 代码.

-E

-export-dynamic

当 创建 ELF 文件时, 把 所有 符号 加入 动态符号表. 一般说来, 动态符号表 只包含 动态目标库(dynamic object) 需要的符号. dlopen 的 时候 需要 这个 选项.

-f name

--auxiliary name

创建 ELF 共享目标库时, 把 内部的 DT_AUXILIARY 字段 设置为 name. 它 告诉 动态linker, 把 该 共享目标库 的 符号表 用做 共享目标 name 的 符号表 的 辅助过滤器.

-F name

--filter name

创建 ELF 共享目标库时, 把 内部的 DT_FILTER 字段 设置为 name. 它 告诉 动态linker, 把 该 共享目标库 的 符号表 用做 共享目标 name 的 符号表 的 辅助过滤器.

-format input-format

等同于 -b input-format.

-g

虚设项; 用于 兼容其他 工具.

-G size

把 使用 GP 寄存器优化的 目标(文件) 大小 限制为 size . 用于 MIPS ECOFF, 对 其他 目标文件格式 无效.

-h name

-soname name

创建 ELF 共享目标库时, 把 内部的 DT_SONAME 字段 设置为 name. 如果 某个 可执行文件 连接了 含有 DT_SONAME 字段的 共享目标库, 当 该程序 运行 时, 动态 linker 试图 根据 DT_SONAME 字段 调入 共享的 目标库, 而 不使用 提供给 linker 的 文件名.

--help

在 标准输出 显示 命令行选项 的 摘要, 然后 结束. 这个选项 和 --version 选项 使用了 两个 短横线, 不是 一个, 目的是 兼容 其他 GNU 程序. 只用一个 短横线 的 选项 是为了 兼容 其他 linker.

-i

执行 增量连接(incremental link), 等同于 -r 选项.

-lar

在 连接文件 列表 中 增加 归档库文件 ar. 可以 多次 使用 这个选项. 凡指定 一项 ar , ld 就会 在 路径列表 中 增加 一项 对 libar.a 的 搜索.

-Lsearchdir

这个选项 将 路径 searchdir 添加 到 路径列表 中去, ld 在 这个 列表 中 搜索归档库. 可以 多次 使用 这个选项.

缺省的 搜索路径集 (不使用 -L ) 取决于 ld 使用的 模拟模式(emulation) 及其 配置. 在 连接脚本 中, 可以 用 SEARCH_DIR 命令 指定 路径.

-M

在 标准输出 显示 连接映像 --- 有关 ld 把 符号 映射到何处 的 诊断信息, 以及 全局公共存储器 的 分配 信息.

-Map mapfile

把 连接映像 输出到 mapfile 文件 中 --- 有关 ld 把 符号 映射到 何处 的 诊断信息, 以及 全局公共存储器 的 分配 信息.

-m emulation

模仿 emulation 连接器. 可以 用 --verbose -V 选项列出 有效的 模拟项. 这个选项 覆盖 编译 进去 的 缺省项.

-N

指定 可读写 的 正文数据(section). 如果 输出格式 支持 Unix 风格的 幻数(magic number), 则 输出文件 标记为 OMAGIC.

当 使用 `-N' 选项 时, linker 不做数据段 的 页对齐(page-align).

-n

设置 正文段 为 只读, 如果有可能, NMAGIC 为 可写.

-noinhibit-exec

一般说来, 如果 连接的时候 发生 错误, linker 不会 产生 输出文件. 使用了这个 标志选项, 只要 不出 致命差错, 仍能够 产生 输出文件.

-no-keep-memory

linker 通常 牺牲 内存, 优化 速度, 它 把 输入文件 的符号表 缓冲在 内存中. 这个选项 使 linker 必要时 重复读取符号表, 以便 优化 内存使用. 连接 大型 可执行文件 的 时候, linker 有可能 内存 不够, 此时 可以 试试 这个选项.

-no-warn-mismatch

一般情况下, 如果试图 连接 某些 不匹配 的 输入文件, 比如说, 按 不同处理器编译 的, 或者 具有 不同的 字节顺序(endianness), linker 就会 报错. 这个选项 告诉 linker 默许这种 错误. 要 小心使用 这个选项, 除非 你正在做 某些 特殊操作, 而且 能够 确定 不需要 linker 报错.

-o output

output 用来 指定 ld 生成的 程序名; 如果 没有 使用 这个选项, 缺省名字 是 `a.out'. 脚本命令 OUTPUT 起 同样 作用.

-Olevel

生成 优化的 输出文件. 这个选项占用 比较多 的 时间, 因此 仅 常用于最终文件 的 生成. level 是 数值参数. 任何 大于零 的 参数 意味着 要求 优化.

-oformat output-format

指定 输出目标文件 的 二进制格式. 一般 不需要 指定 这个选项, ld 的 缺省 输出格式配置为 各个机器 上 最常用 的 格式. output-format 是 一个 字符串, BFD 库 支持的 格式 名称. 脚本命令 OUTPUT_FORMAT 也可以 指定 输出格式, 但是 这个选项 能够 覆盖 掉 它.

-R filename

从 文件 filename 中 读取 符号名称 及其 地址, 但是 不做 重定位, 不传送到 输出端. 它 可以 使 输出文件 符号引用 其他程序中 定义的绝对地址.

-relax

这个选项 的 效果 取决于 机器, 目前 只支持 H8/300.

在 某些 平台 上 可以 使用 这个选项 做 全局优化, 它 让 linker 解决 程序中的 地址处理, 例如 在 输出目标文件 中 缓和(relax) 地址模式 以及 合成 (synthesize) 新指令.

其他平台 也接受 `-relax' 选项, 但是不起作用.

-r

生成 可重定位 输出 --- 就是说, 生成的 输出文件 能够 依次 成为 ld 的 输入, 一般 称之为 不完全(partial) 连接. 它 有 一个 副效应, 在支持 标准 Unix 幻数(magic number) 的 环境中, 这个选项 把 输出文件 的 幻数 设置成 OMAGIC. 如果 没有 指定 这个选项, linker 生成 绝对定位 的 文件. 连接 C++ 程序时, 这个选项 不会 解析 出 对 构造子(constructor) 的 引用(reference); 不妨 改用 -Ur 选项.

这个选项 的 效果 和 -i 一样.

-rpath directory

增加 一条 对 运行时(runtime)库的 搜索路径. 这个选项 用于 连接 ELF 可执行文件 和 共享目标库. 所有 -rpath 选项的 参数 被 合并, 然后 一起 传递 给 运行时 linker, 运行时 linker 在运行 的 时候 使用 这些 路径 寻找 共享目标库. -rpath 也可以 用来 定位 共享目标库 引用的 共享目标库; 参见 对 -rpath-link 选项 的 叙述. 如果 连接 ELF 可执行文件 时 没有 指定 -rpath 选项, linker 就使用 环境变量 LD_RUN_PATH 的 内容 --- 只要 这个 环境变量 存在.

-rpath 选项 能够 用在 SunOS , 缺省状况下, linker 可以 根据 给出的 -L 选项 形成 运行时 搜索路径. 如果 使用了 -rpath 选项, 运行时搜索路径 从 -rpath 中 产生, 而 忽略 -L 选项. 这一点 有利于 使用 gcc, NFS 文件系统 上, gcc 可能 产生 许多 -L 选项.

-rpath-link directory

使用 ELF SunOS 的 时候, 某些 共享库 可能 需要 其他 共享库. 这种情况 一般 发生在 某个 ld -shared 连接 中, 输入文件 包含了 共享库.

如果 linker 遇到 这样的 依赖情况, 当 它执行 非共享, 不可重定位 的 连接时, linker 将 自动寻找 所需的 共享库, 如果 它们 没有 被 显明 包含, 就把它们 包含到 连接 中. 在 这种情况下, -rpath-link 选项 指定了 最先 搜索 的 目录集. -rpath-link 能够 指定 一批 目录, 目录 用 冒号 隔开. 也可以 用 这些 目录名 作为 参数, 重复 使用 这个 选项.

如果 没有 找到 需要的 共享库, linker 产生 一个 警告, 但是 继续 连接.

-S

去掉 输出文件 中的 调试符号信息 (但不是 所有符号).

-s

去掉 输出文件 中的 全部 符号信息.

-shared

创建 一个 共享库. 目前只支持 ELF SunOS 平台 ( SunOS , 这个选项不是必须的, 如果 没有 使用 -e 选项, 而且 存在 不确定 的 符号, linker 将 自动 创建 共享库).

-sort-common

ld 通常 把 全局公共符号 放到 适当的 输出节, 按照 大小 排序. 首先是 单字节符号, 然后是 双字节, 接下来是 四字节, 随后是 其他的. 它的 目的是 防止 符号间 因为 排布限制 出现 间隙. 使用 这个选项 可以 禁止 排序.

-split-by-reloc count

在 输出文件 中 创建 附加节(extra section), 使得 输出文件 中, 没有 某一个 输出节 包含 大于 count 个 重定位项. 它用于 产生 大型 可重定位 COFF 目标文件, 可以 插入到某些实时内核 中; 因为 COFF 不能 在 单一节内 存放 65535 以上的 重定位项. 注意, 有些 目标文件格式 不支持 任意 分节, 此时 这个选项 将会 操作 失败. 此外, linker 不能够 分割 输入节, 然后 重新分配, 因此 如果 某个 输入节 包含 count 以上的 重定位项, 相应的输出节 将 包含 同样多的 重定位项.

-split-by-file

类似于 -split-by-reloc , 但是 它为 每个 输入文件 建立一个 新的 输出节.

-Tbss org

-Tdata org

-Ttext org

org 作为 输出文件 的 段 起始地址 --- 特别是 --- bss, data, text . org 必须是 十六进制整数.

-T commandfile

等同于 -c commandfile; 用于 兼容 其他工具.

-t

ld 处理 输入文件 的 时候 显示 文件名.

-u sym

sym 作为 未定义(undefined) 的 符号 送入 输出文件. 这样做 可以, 例如, 促使 linker 从 标准库 连接 某个 附加的模块. 允许 使用 多个 -u 选项 输入 多个 未定义 符号.

-Ur

对于 除 C++ 以外的任何 程序, 这个选项 等同于 -r: 生成 可重定位 的 输出 --- 就是说, 能够 依次 输入 ld 的 输出文件. 连接 C++ 程序 的 时候, -Ur 解析 对 构造子(constructor) 的引用(reference), 这一点 和 -r 不同.

--verbose

显示 ld 的 版本号, 列出 支持的 模拟项(emulation). 显示 哪些 输入文件 能够 打开, 哪些 不能,

-v, -V

显示 ld 的 版本号. 此外 -V 选项 能够 列出 支持的 模拟项.

--version

显示 ld 的 版本号 然后 结束.

-warn-common

当 公共符号 和 其他 公共符号 合并 时, 或者 和 某个 符号定义 合并 时, linker 就发出 警告. Unix 系统的 linker 允许 这种 有些 草率 的 做法, 其他操作系统 则 不行. 这个选项 帮助你 在 合并 全局符号 的 时候发现 潜在问题.

-warn-constructors

如果 使用了 全局构造子(global constructor), linker 就发出 警告. 它 只对 某些 目标文件结构 有用, 对于 如 COFF ELF, linker 不能够检测 全局构造子 的 使用情况.

-warn-multiple-gp

如果 输出文件 需要 多个 全局指针值, linker 就发出 警告. 这个选项 只能用于 某些 处理器, Alpha.

-warn-once

对 每个 未定义符号 只 警告 一次, 而不是 每次 引用 这个符号 都 警告.

-warn-section-align

如果 某个 输出节(section) 的 地址 因为 边界对齐 而 发生 改变, linker 就发出 警告. 典型情况下 由 输入节 设置 边界, 只有 不做 明确指定的 时候 地址才会 改变; 就是说, SECTIONS 命令 没有 指出 该节的 开始地址.

--whole-archive

对于 命令行 上 --whole-archive 选项 提到的 每个 归档库, 连接时 连入 归档库 的 全部 目标文件, 而不是在 归档库 中 搜索 所需的 目标文件. 一般用于 把 归档库文件转变成 共享库文件, 迫使 全部 目标文件 进入 共享库.

--no-whole-archive

关闭 --whole-archive 选项 对 归档库 的 影响.

--wrap symbol

symbol 使用 包装函数(wrapper function). 任何 对 symbol 未定义 的 引用 (undefined reference) 将 解析为 __wrap_symbol. 任何 对 __real_symbol 未定义 的 引用 将 解析为 symbol.

-X

删除 全部 临时的 局部符号. 大多数目的文件 中, 这些 局部符号 的 名字 用 `L' 做开头.

-x

删除 全部 局部符号.

 

环境 (ENVIRONMENT)

通过 环境变量 GNUTARGET 可以改变 ld 的 行为.

如果 没有 使用 -b 选项 (或 相同的 -format), GNUTARGET 决定了输入文件 的 目标格式, 其值 应为 BFD的 名称之一. 如果 没有 GNUTARGET 环境变量, ld 就使用 主机的 本地格式. 如果 GNUTARGET 设置为 default, BFD 通过 检查 输入文件 的 二进制格式 判断输入格式; 这个方法 通常 有效, 但 隐含 歧义, 这是因为 没有 办法 保证 标志 目标文件格式的 幻数 是 唯一的. 不过, 各个系统 配置 BFD 的 时候, 会把系统 约定的格式 放在 搜索列表 的前面, 因此 能够 按照 约定 消除 歧义.

 

另见 (SEE ALSO)

objdump(1)
`ld'
`binutils' ( info)
ld: the GNU linker, Steve Chamberlain and Roland Pesch; The GNU Binary Utilities, Roland H. Pesch.

 

COPYING

Copyright (c) 1991, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.

Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.

Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.

Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be included in translations approved by the Free Software Foundation instead of in the original English.

2012-10-17 14:27:29 prownd 阅读数 371

ld,即GNU的连接工具,用于将各目标文件合并在一起,并重新安排他们的数据以及符号的引用,常常是程序编译的最后一步。

ld scripts 即ld脚本。ld 脚本的主要目的是要描述怎样将输入文件的各段印象到输出文件中去。它控制输出文件在内存的布局情况。
--------------------------------------------------------------------------------
关于VMA ,LMA
每一个可装载的输出段都有两个地址:VMA(Virtual memory address) 和 LMA(Load mem
ory
address)VMA 是输出段运行时的地址,LMA
则是输出段被装载的地址。而这2个地址常常是相同的。在某些情况下二者是有区别的。比如,一个data段被装载到ROM中,然后在程序启动的时候被拷贝到
了RAM中去。(这种技术常常用在以ROM 为基础的系统中,用来初始化全局变量,而我们的系统的处理方法可能与此类似?)

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

关于SECTIONS命令的使用
SECTIONS告诉LD怎样将输入的段印象到输出的段,以及怎样将输出的段装载到内存中去。这是我们在内存布局中常常要用到的命令。段的基本结构如下:
SECTIONS
{
sections- command
sections- command
...

其中的sections-command 可作如下选择:
* 程序入口点设置命令ENTRY。
* 符号赋值
* 输出段描述(下面会提到)
* 覆盖描述。(overlay description)
1.输出段描述(Output Section Description):
输出段描述的完整格式如下:
SECTION [ address] [( type)] : [AT( LMA)]
{
output-sections-command
output-sections-command
...
} [> region] [: phdr : phdr ...] [=fillexp]
一般对于以上的描述不会全部用到,对于这些描述的用法,后面将会讲述到。
(1).关于段名
对于不同的输出格式,段名应该满足相应的约定。比如a.out格式的文件就应该只能
使用这些段名:.text .data .bss
(3).输出段地址
输出段地址 address 是输出段的VMA地址。例:
.text [address] :{ *(.text)}
如果没有指定 address 则将按照 region 或者是当前地址记数值"."来分配地址。注意,这里分配的是VMA地址(见VMA的说明)。
另外,在分配地址的时候还有地址对齐操作,这里就不赘述了。
2.输入段描述:
输出段描述告诉连接器怎样在内存中安排你的程序布局,而输入段描述则告诉连接器怎样将各输入文件映射到你的内存布局中去。
(1).输入段的基本语法如下:
输入文件名(段名)
例: file1(.text)
表示将文件 file1的.text 段放于此处。
也支持通配符,如:
*(.text)
将所有的文件的.text段放置到此处。
又例:
a.out
直接将a.out的所有段放置此处。
(2).输入段的通配符使用,就是一般的通配符语法,这里就不赘述了。
3.COMMON 段的设置
在很多的目标文件格式中,对于common symbols(什么是common symbols?)都没有专门的段来存放。
所以在连接时,连接器专门指定了一个COMMON段来包含这些common symbols.
而COMMON段一般放于输出文件的.bss段中。
例:
.bss { *(.bss) *(COMMON) }
在.bss段中放置所有输入文件的.bss段 和 所有输入文件的 common symbols
4.输入段描述的示例:
SECTIONS {
outputa 0x10000 :
{
all.o all.o的所有段
foo.o (.input1) foo.o的所有.input1 段
}
outputb :
{
foo.o (.input2) foo.o的所有.input2 段
foo1.o (.input1) foo1.o的所有.input1段
}
outputc :
{
*(.input1) 所有文件的余下的.input1段
*(.input2) 所有文件的余下的.input2段 
}
}
5.在输出段中装填数据。
(1). BYTE, SHORT, LONG, and QUAD
如:BYTE(1)
在当前位置装填1字节的1
(2). FILL 的使用,可以从当前位置开始装填本SECTION。
6.两个输出段关键字。
CREATE_OBJECT_SYMBOLS 和 CONSTRUCTORS
CREATE_OBJECT_SYMBOLS:
每一个输入的文件将对应一个同名的symbol.而这些symbol将被放置在CREATE_OBJECT_SYMBOLS
命令出现的段中。
CONSTRUCTORS:

此命令出现的地方放置C++全局构造和析构函数信息。对于a.out
格式,它使用其专有的方法来支持C++构造与析构函数。对于不能使用任意段名的文件格式如:XCOFF 和ECOFF
则需要一个CONSTRUCTORS 命令来在输出文件中记录C++全局构造函数和析构函数的信息。对于能使用任意段名的文件格式如COFF 和
ELF 。则连接器将自动生成名为.ctors 和 .dtors 的段来记录相应信息。我们可能暂时用不到这个东西。
7.丢弃段。
命名为 /DISCARD/ 的段的内容将不被包含到输出文件中。
8.输出段描述的其它特性,输出段描述的基本结构正如前边所提到的如下所示:
SECTION [ address] [( type)] : [AT( LMA)]
{
output-sections-command
output-sections-command
...
} [> region] [: phdr : phdr ...] [=fillexp]
下面对其各个特性做一个比较详细的说明:
(1). Output Section Type (即输出段的type属性)
此属性可以赋值为:
NOLOAD 此段的内容将不被装载到内存中去,比如直接在ROM中运行程序。
DSECT
COPY
INFO
OVERLAY
以上4个代表运行时不另外为改段分配内存空间,这样可以一定的节省程序
空间。 
(2). 输出段LMA
使用AT 命令来设置段的LMA
这样的话可以使用这个特性很方便的建立ROM image.
例如:
SECTIONS
{
.text 0x1000 : { *(.text) _etext = . ; } //.text 的VMA为0x1000
.mdata 0x2000 : //.mdata 的VMA为0x2000
AT ( ADDR (.text) + SIZEOF (.text) ) //.mdata 的LMA为紧随.text
//段之后。
{ _data = . ; *(.data); _edata = . ; }
.bss 0x3000 : //.bss的VMA为0x3000
{ _bstart = . ; *(.bss) *(COMMON) ; _bend = . ;}
}
与之配合的初始化代码示例如下(可能是由ld自动生成):
extern char _etext, _data, _edata, _bstart, _bend;
char *src = &_etext; //从这里可以看出,"_etext=."的意思实际上是令_etext的地址
//等于当前的VMA
char *dst = &_data;
/* ROM has data at end of text; copy it. */
while (dst region 属性可以将某个段定位到预定义好的内存位置去。
例:
MEMORY { rom : ORIGIN = 0x1000, LENGTH = 0x1000 }
SECTIONS { ROM : { *(.text) } >rom }
(4). Output Section Segmentation
程序段的定义。
例: 
PHDRS { text PT_LOAD ; }
SECTIONS { .text : { *(.text) } :text }
后面将提到PHDRS
(5).输出段填充
例:采用如下的方法来填充段
SECTIONS { .text : { *(.text) } =0x9090 }
9.覆盖描述:(Overlay Description)
定义如下:
OVERLAY [ start] : [NOCROSSREFS] [AT ( ldaddr )]
{
secname1
{
output-section-command
output-section-command
...
} [:PHDR...] [=FILL]
secname2
{
output-section-command
output-section-command
...
} [: phdr...] [= fill]
...
} [> region] [: phdr...] [= fill]
OVERLAY 命令应该定义于SECTIONS 命令之内。
--------------------------------------------------------------------------------
------------ 
10.MEMORY 命令
分配内存区域
MEMORY
{
name [( attr)] : ORIGIN = origin, LENGTH = len
...
}
atrr 为段的匹配特性,如果一个段没有明确指定将其放置到某一个region中去,那么如果
其属性匹配该region的atrr属性,将被加入到该region中去。
有以下属性:
R 只读段 
W 只写段
X 执行段
A 可分配段
I 已初始化段
L 与I相同。
! 非特性 
例子:
MEMORY
{
rom (rx) : ORIGIN = 0, LENGTH = 256K
ram (!rx) : org = 0x40000000, l = 4M
}
一旦完成了region的定义,就可以使用 >region 的方法将某段指定添加到某个region中去

原文地址:http://www.yuanma.org/data/2009/0921/article_3926.htm

Linux ld命令

阅读数 28

linux连接器ld

阅读数 218

linux连接器ld

阅读数 12076

Linux ld script用法

阅读数 1582

Linux ld链接问题

阅读数 115

没有更多推荐了,返回首页