命令行手册

Man » ld 手册在线 - ld 手册页的详细在线文档

🌍
ld - The GNU linker

概要

ld [选项] objfile ...

描述

ld 组合多个对象文件和存档文件,重定位它们的数据,并连接符号引用。 通常,编译程序的最后一步是运行 ld。

ld 接受用 AT&T 链接器命令语言的超集编写的链接器命令语言文件,以提供对链接过程的显式和完全控制。

此手册页不描述命令语言;有关命令语言和 GNU 链接器的其他方面的完整详细信息,请参阅“info”中的 ld 条目。

此版本的 ld 使用通用 BFD 库来操作对象文件。 这使得 ld 能够读取、组合和写入多种不同格式的对象文件——例如,COFF 或“a.out”。 可以链接不同的格式以生成任何可用的对象文件类型。

除了其灵活性之外,GNU 链接器比其他链接器更有用,因为它能提供诊断信息。 许多链接器在遇到错误时立即停止执行;只要可能,ld 会继续执行,从而允许您识别其他错误(或者,在某些情况下,即使发生错误也能获得输出文件)。

GNU 链接器 ld 旨在涵盖广泛的情况,并尽可能与其他链接器兼容。 因此,您拥有许多选择来控制其行为。

选项

链接器支持大量的命令行选项,但在实际应用中,很少有选项在任何特定情况下被使用。 例如,ld 的常见用法是链接标准 Unix 对象文件,在标准的受支持的 Unix 系统上。 在这样的系统中,要链接文件“hello.o”:

ld -o <输出> /lib/crt0.o hello.o -lc

这告诉 ld 将文件“/lib/crt0.o”与“hello.o”和库“libc.a”链接起来,结果将生成一个名为“输出”的文件,该库将来自标准搜索目录。(请参见下面关于 -l 选项的讨论。)

命令行选项中的某些选项可以在命令行的任何位置指定。 但是,引用文件的选项,例如 -l 或 -T,会导致该文件在该选项在命令行中出现时相对于对象文件和其他文件选项进行读取。 重复使用带有不同参数的非文件选项,要么不会产生进一步的影响,要么会覆盖先前出现的该选项(即,在命令行中靠左边的选项)。 可以在下面的描述中明确说明哪些选项可以有意义地多次指定。

非选项参数是要链接在一起的对象文件或存档。 它们可以位于命令行选项的前面、后面或与命令行选项混合使用,但对象文件参数不能位于选项及其参数之间。

通常链接器会至少带有一个目标文件,但你可以使用 -l、-R 和脚本命令语言来指定其他形式的二进制输入文件。如果没有指定任何二进制输入文件,链接器将不会产生任何输出,并显示消息“No input files”。

如果链接器无法识别目标文件的格式,它将假定该文件是一个链接器脚本。以这种方式指定的脚本会增强用于链接的主链接器脚本(可以是默认链接器脚本,也可以是使用 -T 选项指定的脚本)。此功能允许链接器链接到一个文件,该文件看起来像是一个目标文件或一个存档,但实际上只是定义了一些符号值,或者使用“INPUT”或“GROUP”来加载其他目标文件。以这种方式指定脚本只是增强主链接器脚本,额外的命令将放置在主脚本之后;使用 -T 选项可以完全替换默认链接器脚本,但请注意“INSERT”命令的效果。

对于名称为单个字母的选项,选项参数必须要么紧跟在选项字母后面,中间没有空格,要么作为单独的参数立即跟在需要它们的选项之后。

对于名称为多个字母的选项,可以使用一个或两个连字符作为选项名称的前缀;例如,-trace-symbol 和 --trace-symbol 是等效的。请注意,这里有一个例外。以小写字母“o”开头的多个字母选项只能使用两个连字符作为前缀。这是为了减少与 -o 选项混淆。因此,例如 -omagic 将输出文件名设置为 magic,而 --omagic 会在输出上设置 NMAGIC 标志。

多字母选项的参数必须要么通过等号与选项名称分隔,要么作为单独的参数立即跟在需要它们的选项之后。例如,--trace-symbol foo 和 --trace-symbol=foo 是等效的。多字母选项的名称可以使用唯一的缩写。

请注意,如果链接器是通过编译器驱动程序(例如 gcc)间接调用的,则所有链接器命令行选项都应以 -Wl 为前缀(或者使用适用于特定编译器驱动程序的任何其他前缀),如下所示:

gcc -Wl,--start-group foo.o bar.o -Wl,--end-group

这一点很重要,因为否则编译器驱动程序程序可能会静默地丢弃链接器选项,导致链接失败。在通过驱动程序传递需要值的选项时,也可能会出现混淆,因为选项和参数之间的空格充当分隔符,并且导致驱动程序仅将选项传递给链接器,并将参数传递给编译器。在这种情况下,最好使用单字母和多字母选项的连接形式,例如:


gcc foo.o bar.o -Wl,-eENTRY -Wl,-Map=a.map

以下是 GNU 链接器接受的通用命令行开关的表格:

@file

从文件中读取命令行选项。读取的选项将替换原始的 @file 选项。如果文件不存在或无法读取,则该选项将按字面意思处理,并且不会删除。

文件中的选项由空格分隔。可以通过用单引号或双引号将整个选项括起来,从而在选项中包含空格字符。可以通过在要包含的字符前加上反斜杠,来包含任何字符(包括反斜杠)。该文件本身可以包含其他 @file 选项;任何此类选项都将递归处理。

-a keyword

此选项支持 HP/UX 兼容性。keyword 参数必须是字符串 archiveshareddefault-aarchive 在功能上等同于 -Bstatic,而其他两个关键字在功能上等同于 -Bdynamic。此选项可以多次使用。

--audit AUDITLIB

AUDITLIB 添加到动态节的 "DT_AUDIT" 条目中。AUDITLIB 不会检查其是否存在,也不会使用库中指定的 DT_SONAME。如果多次指定,则 "DT_AUDIT" 将包含一个用冒号分隔的审核接口列表。如果链接器在搜索共享库时找到一个带有审核条目的对象,它将会在输出文件中添加一个相应的 "DT_DEPAUDIT" 条目。此选项仅在支持 rtld-audit 接口的 ELF 平台上才有意义。

-b input-format
--format=input-format

^ d 可以配置为支持多种对象文件。如果您的 ld 配置为此,则可以使用 -b 选项来指定输入对象文件的二进制格式,ld 之后在命令行中出现。即使 ld 配置为支持替代对象格式,通常也不需要指定此选项,因为 ld 应该配置为期望默认输入格式为每台机器上最常用的格式。input-format 是一个文本字符串,是 BFD 库支持的特定格式的名称。(您可以使用 objdump -i 列出可用的二进制格式。)

如果您要链接具有非标准二进制格式的文件,则可能需要使用此选项。您还可以使用 -b 来显式切换格式(在链接具有不同格式的对象文件时),方法是在特定格式的每个对象文件组之前包含 -b input-format

默认格式是从环境变量 "GNUTARGET" 中获取的。

您还可以从脚本中定义输入格式,使用命令 TARGET

-c MRI-commandfile
--mri-script=MRI-commandfile

为了与 MRI 产生的链接器兼容,ld 接受用替代的、受限制的命令语言编写的脚本文件,具体说明请参见 GNU ld 文档的“MRI 兼容脚本文件”部分。使用 -c 选项引入 MRI 脚本文件;使用 -T 选项来运行用通用 ld 脚本语言编写的链接器脚本。如果 MRI-cmdfile 不存在,则 ld 会在任何 -L 选项指定的目录中查找它。


-d
-dc
-dp 这三个选项是等效的;支持多种形式是为了与其他链接器兼容。它们为公共符号分配空间,即使指定了可重定位输出文件(使用 -r)。脚本命令“FORCE_COMMON_ALLOCATION”具有相同的效果。

--depaudit AUDITLIB
-P AUDITLIB
将 AUDITLIB 添加到动态部分的“DT\_DEPAUDIT”条目中。AUDITLIB 不会被检查是否存在,也不会使用库中指定的 DT_SONAME。如果多次指定,则“DT_DEPAUDIT”将包含一个以冒号分隔的要使用的审计接口列表。此选项仅在支持 rtld-audit 接口的 ELF 平台上才有意义。-P 选项是为了与 Solaris 兼容。

--enable-linker-version
启用“LINKER\_VERSION”链接器脚本指令,如“输出节数据”中所述。如果链接器脚本中使用此指令并且已启用此选项,则将插入一个包含链接器版本的字符串到当前位置。

请注意 - 此选项在链接器命令行中的位置非常重要。它只会影响命令行中此选项之后的链接器脚本,或者内置到链接器中的脚本。

--disable-linker-version
禁用“LINKER\_VERSION”链接器脚本指令,使其不插入版本字符串。这是默认设置。

--enable-non-contiguous-regions
此选项避免生成错误,如果输入节无法匹配到输出节。链接器尝试将输入节分配到后续匹配的输出节,并且仅在没有输出节足够大时才生成错误。当有几个不连续的内存区域可用,并且输入节不需要位于特定的区域时,这很有用。输入节的评估顺序不会改变,例如:

MEMORY {
MEM1 (rwx) : ORIGIN = 0x1000, LENGTH = 0x14
MEM2 (rwx) : ORIGIN = 0x1000, LENGTH = 0x40
MEM3 (rwx) : ORIGIN = 0x2000, LENGTH = 0x40
}
SECTIONS {
mem1 : { *(.data.*); } > MEM1
mem2 : { *(.data.*); } > MEM2
mem3 : { *(.data.*); } > MEM3
}

带有输入节:
.data.1: 大小 8
.data.2: 大小 0x10
.data.3: 大小 4

结果是 .data.1 映射到 mem1,.data.2 和 .data.3 映射到 mem2,即使 .data.3 可以匹配到 mem3。

此选项与 INSERT 语句不兼容,因为它会改变输入节与输出节的映射方式。

--enable-non-contiguous-regions-warnings
此选项启用警告,当“--enable-non-contiguous-regions”允许节映射中可能出现意外匹配时,可能会导致静默地丢弃一个节,而不是因为该节无法匹配到任何输出区域而失败。

-e entry
--entry=entry

使用 entry 作为程序开始执行的显式符号,而不是默认的入口点。如果不存在名为 entry 的符号,链接器将尝试将 entry 解析为一个数字,并将其用作入口地址(该数字将以十进制形式解释;您可以使用前导 0x 表示十六进制,或使用前导 0 表示八进制)。对于 i386 PE,entry 也可以是原始函数名称(无需前导下划线和/或尾随 stdcall @number)。

--exclude-libs lib,lib,...

指定一个要从其中排除符号以进行自动导出的存档库列表。库名可以用逗号或冒号分隔。指定“--exclude-libs ALL”会将所有存档库中的符号从自动导出中排除。此选项仅适用于针对 i386 PE 的链接器端口和针对 ELF 的链接器端口。对于 i386 PE,即使使用此选项,显式列在 .def 文件中的符号仍会被导出。对于针对 ELF 的链接器端口,受此选项影响的符号将被视为隐藏的。

--exclude-modules-for-implib module,module,...

指定一个对象文件或存档成员列表,其符号不应进行自动导出,但应将其全部复制到在链接期间生成导入库中。模块名可以用逗号或冒号分隔,并且必须完全匹配 ld 用于打开文件的文件名;对于存档成员,这只是成员名称,但对于对象文件,列出的名称必须包括并完全匹配用于在链接器的命令行中指定输入文件的任何路径。此选项仅适用于针对 i386 PE 的链接器端口。即使使用此选项,显式列在 .def 文件中的符号仍会被导出。

-E
--export-dynamic
--no-export-dynamic

在创建动态链接的可执行文件时,使用 -E 选项或 --export-dynamic 选项会导致链接器将所有符号添加到动态符号表中。动态符号表是在运行时动态对象可见的符号集合。

如果您不使用这两个选项中的任何一个(或使用 --no-export-dynamic 选项以恢复默认行为),则动态符号表通常仅包含由链接中提到的某个动态对象引用的符号。

如果您使用“dlopen”加载需要引用程序中定义的符号(而不是其他动态对象)的动态对象,那么在链接程序本身时,您可能需要使用此选项。

您还可以使用动态列表来控制如果输出格式支持,应将哪些符号添加到动态符号表。请参阅 --dynamic-list 的描述。


请注意,此选项仅适用于 ELF 目标端口。PE 目标支持一个类似的功能,用于导出 DLL 或 EXE 中的所有符号;请参见下面的 `--export-all-symbols` 说明。

--export-dynamic-symbol=glob
在创建动态链接的可执行文件时,与 `glob` 匹配的符号将被添加到动态符号表中。在创建共享库时,与 `glob` 匹配的符号的引用将不会绑定到共享库内的定义。当创建共享库且未指定 `-Bsymbolic` 或 `--dynamic-list` 时,此选项不起作用。此选项仅在支持共享库的 ELF 平台上才有意义。

--export-dynamic-symbol-list=file
为文件中的每个模式指定一个 `--export-dynamic-symbol`。文件的格式与不带作用域和节点名称的版本节点相同。有关更多信息,请参见 VERSION。

-EB 链接大端对象。这会影响默认输出格式。

-EL 链接小端对象。这会影响默认输出格式。

-f name
--auxiliary=name
在创建 ELF 共享对象时,将内部 `DT_AUXILIARY` 字段设置为指定的 `name`。这告诉动态链接器,共享对象的符号表应作为共享对象 `name` 的符号表的辅助过滤器。

如果您稍后将程序链接到此过滤器对象,那么当您运行程序时,动态链接器将看到 `DT_AUXILIARY` 字段。如果动态链接器解析来自过滤器对象的任何符号,它将首先检查共享对象 `name` 中是否存在定义。如果存在,则将使用它而不是过滤器对象中的定义。共享对象 `name` 不需要存在。因此,共享对象 `name` 可用于提供某些函数的替代实现,可能用于调试或用于特定于机器的性能。

此选项可以多次指定。`DT_AUXILIARY` 条目将按照它们在命令行中出现的顺序创建。

-F name
--filter=name
在创建 ELF 共享对象时,将内部 `DT_FILTER` 字段设置为指定的 `name`。这告诉动态链接器,正在创建的共享对象的符号表应作为共享对象 `name` 的符号表的过滤器。

如果您稍后将程序链接到此过滤器对象,那么当您运行程序时,动态链接器将看到 `DT_FILTER` 字段。动态链接器将根据过滤器对象的符号表解析符号,但它实际上将链接到在共享对象 `name` 中找到的定义。因此,过滤器对象可用于选择对象 `name` 提供的符号子集。

一些较旧的链接器在整个编译工具链中使用 `-F` 选项来指定输入和输出对象文件的对象文件格式。GNU 链接器使用其他机制来实现此目的:`-b`、`--format`、`--oformat` 选项、链接器脚本中的 `TARGET` 命令以及 `GNUTARGET` 环境变量。当不创建 ELF 共享对象时,GNU 链接器将忽略 `-F` 选项。

-fini=name

在创建 ELF 可执行文件或共享对象时,在卸载可执行文件或共享对象时调用 NAME,方法是将 DT_FINI 设置为该函数的地址。默认情况下,链接器使用 "_fini" 作为要调用的函数。

-g  忽略。为了与其它工具兼容而提供。

-G value
--gpsize=value

设置使用 GP 寄存器进行优化的对象的最大大小。这仅对支持将大型和小型对象放入不同部分的 ELF 等对象文件格式有意义。对于其他对象文件格式,此选项将被忽略。

-h name
-soname=name

在创建 ELF 共享对象时,将内部 DT_SONAME 字段设置为指定的名称。当可执行文件链接到具有 DT_SONAME 字段的共享对象时,当可执行文件运行时,动态链接器将尝试加载 DT_SONAME 字段中指定的共享对象,而不是使用链接器提供的文件名。

-i  执行增量链接(与选项 -r 相同)。

-init=name

在创建 ELF 可执行文件或共享对象时,在加载可执行文件或共享对象时调用 NAME,方法是将 DT_INIT 设置为该函数的地址。默认情况下,链接器使用 "_init" 作为要调用的函数。

-l namespec
--library=namespec

将由 namespec 指定的存档或对象文件添加到要链接的文件列表中。此选项可以多次使用。如果 namespec 的形式为 :filename,则 ld 将在库路径中搜索名为 filename 的文件,否则它将在库路径中搜索名为 libnamespec.a 的文件。

在支持共享库的系统上,ld 还可以搜索其他文件,而不仅仅是 libnamespec.a。具体来说,在 ELF 和 SunOS 系统上,ld 将在目录中搜索名为 libnamespec.so 的库,然后再搜索名为 libnamespec.a 的库。(按照惯例,“.so”扩展名表示共享库。)请注意,此行为不适用于 :filename,后者始终指定名为 filename 的文件。

链接器仅搜索一次存档,即在命令行中指定的存档位置。如果存档定义了一个符号,并且在存档之前的一些对象文件中该符号未定义,则链接器将包含来自存档的适当文件。但是,如果稍后出现在命令行中的对象文件中存在未定义的符号,则链接器将不再搜索存档。

请参阅 -( 选项,以了解如何强制链接器多次搜索存档。

您可以在命令行中多次列出相同的存档。

这种存档搜索对于 Unix 链接器来说是标准的。但是,如果您在 AIX 上使用 ld,请注意,这与 AIX 链接器的行为不同。


-L searchdir
--library-path=searchdir

将路径 searchdir 添加到 ld 将搜索存档库和 ld 控制脚本的路径列表中。您可以多次使用此选项。这些目录按在命令行中指定的顺序进行搜索。命令行中指定的目录在默认目录之前搜索。所有 -L 选项都适用于所有 -l 选项,无论选项出现的顺序如何。-L 选项不会影响 ld 搜索链接器脚本的方式,除非指定了 -T 选项。

如果 searchdir 以“=”或 $SYSROOT 开头,则会用 --sysroot 选项控制的或在配置链接器时指定的 sysroot 前缀替换此前缀。

在不使用 -L 选项显式指定的情况下,默认搜索的路径集取决于 ld 使用的仿真模式,并且在某些情况下还取决于链接器的配置方式。

路径也可以在链接脚本中使用“SEARCH_DIR”命令进行指定。以这种方式指定的目录在链接器脚本在命令行中出现时进行搜索。

-m emulation

模拟指定的链接器。您可以使用 --verbose 或 -V 选项列出可用的仿真。

如果未使用 -m 选项,则从“LDEMULATION”环境变量中获取仿真(如果已定义)。

否则,默认仿真取决于链接器的配置方式。

--remap-inputs=pattern=filename
--remap-inputs-file=file

这些选项允许在链接器尝试打开输入文件之前更改输入文件的名称。选项 --remap-inputs=foo.o=bar.o 将导致任何尝试加载名为 foo.o 的文件都会尝试加载一个名为 bar.o 的文件。第一个文件名中允许使用通配符模式,因此 --remap-inputs=foo*.o=bar.o 将重命名任何匹配 foo*.o 的输入文件,并将其重命名为 bar.o。

另一种形式的选项 --remap-inputs-file=filename 允许从文件中读取重映射。文件中的每一行可以包含一个重映射。空行将被忽略。从井号 (#) 到行尾的所有内容都将被视为注释,也会被忽略。映射模式可以使用空格或等号 (=) 字符与文件名分隔。

可以多次指定这些选项。它们的内容会累积。重映射将按照它们在命令行中出现的顺序进行处理,如果来自文件,则按照它们在文件中出现的顺序进行处理。如果找到匹配项,则不会对该文件名执行进一步的检查。

如果替换文件名是 /dev/null 或仅为 NUL,则重映射实际上会导致输入文件被忽略。这是一种方便的方法,可以用来试验从复杂的构建环境中删除输入文件。


请注意,此选项依赖于位置,并且仅影响命令行中其后的文件名。因此:

ld foo.o --remap-inputs=foo.o=bar.o

不会产生任何效果,而:

ld --remap-inputs=foo.o=bar.o foo.o

会将输入文件 foo.o 重命名为 bar.o。

请注意,这些选项还会影响链接器脚本中 INPUT 语句引用的文件。但是,由于链接器脚本是在读取完整个命令行之后才处理的,因此命令行中重映射选项的位置并不重要。

如果启用了详细模式选项,则任何匹配的映射都将被报告,但同样,必须在命令行中启用详细模式选项,然后才会显示重映射的文件名。

如果启用了 -Map 或 --print-map 选项,则重映射列表将包含在映射输出中。

-M
--print-map

将链接映射打印到标准输出。链接映射提供有关链接的信息,包括以下内容:

对象文件在内存中映射的位置。

公共符号的分配方式。

包含在链接中的所有归档成员,以及导致将归档成员引入的符号。

分配给符号的值。

请注意,如果符号的值由涉及对同一符号的先前值的引用表达式计算得出,则链接映射中可能不会显示正确的符号值。这是因为链接器会丢弃中间结果,并且仅保留表达式的最终值。在这种情况下,链接器将以方括号括起来显示最终值。因此,例如,如果链接器脚本包含:

foo = 1
foo = foo * 4
foo = foo + 8

如果使用 -M 选项,则将在链接映射中生成以下输出:

000000001                foo = 0x1
[0x0000000c]                foo = (foo * 0x4)
[0x0000000c]                foo = (foo + 0x8)

有关链接器脚本中表达式的更多信息,请参阅表达式。

GNU 属性的合并方式。

当链接器将输入 .note.gnu.property 节合并为一个输出 .note.gnu.property 节时,某些属性将被删除或更新。这些操作将在链接映射中报告。例如:

Removed property 0xc0000002 to merge foo.o (0x1) and bar.o (not found)

这表示在合并 foo.o(其属性 0xc0000002 的值为 0x1)和 bar.o(它没有属性 0xc0000002)中的属性时,属性 0xc0000002 已从输出中删除。

Updated property 0xc0010001 (0x1) to merge foo.o (0x1) and bar.o (0x1)

这表示在合并 foo.o(其属性 0xc0010001 的值为 0x1)和 bar.o(其属性 0xc0010001 的值为 0x1)中的属性时,属性 0xc0010001 的值已更新为 0x1。

在某些 ELF 目标上,显示由 --relax 插入的修复列表

foo.o: Adjusting branch at 0x00000008 towards "far" in section .text

这表示在 foo.o 中,指向位于 .text 节中的“far”符号的位于 0x00000008 的分支已被一个跳转指令替换。


--print-map-discarded
--no-print-map-discarded

打印(或不打印)链接映射中丢弃的和垃圾回收的部分列表。默认启用。

--print-map-locals
--no-print-map-locals

打印(或不打印)链接映射中的本地符号。本地符号会在其名称前打印“(local)”文本,并且会在给定部分中的所有全局符号之后列出。通常以.L开头的临时本地符号不会包含在输出中。默认禁用。

-n
--nmagic

关闭节的页面对齐,并禁用与共享库的链接。如果输出格式支持Unix样式的魔数,则将输出标记为“NMAGIC”。

-N
--omagic

将文本和数据段设置为可读和可写。此外,不执行数据段的页面对齐,并禁用与共享库的链接。如果输出格式支持Unix样式的魔数,则将输出标记为“OMAGIC”。请注意:虽然对于PE-COFF目标,允许使用可写的文本段,但这不符合Microsoft发布的格式规范。

--no-omagic

此选项否定了-N选项的大部分效果。它将文本段设置为只读,并强制数据段进行页面对齐。请注意,此选项不会启用与共享库的链接。为此,请使用-Bdynamic

-o output
--output=output

使用output作为ld生成的程序的名称;如果未指定此选项,则默认使用a.out。脚本命令“OUTPUT”也可以指定输出文件名。

请注意,链接器将在开始写入之前删除输出文件。即使最终由于错误而无法完成链接,它也会这样做。

请注意,链接器会检查输出文件名是否与任何输入文件的名称匹配,但这仅此而已。特别是,如果输出文件可能会覆盖源代码或其他重要文件,它不会发出任何警告。因此,在构建系统中,建议将-o选项用作链接器命令行中的最后一个选项。例如,请考虑以下情况:

ld -o $(EXE) $(OBJS)
ld $(OBJS) -o $(EXE)

如果由于某种原因未定义EXE变量,则第一个链接器命令可能会删除对象文件(OBJS列表中的第一个文件),而第二个链接器命令将生成错误消息并且不会删除任何内容。

--dependency-file=depfile

将依赖项文件写入depfile。此文件包含适用于“make”的规则,描述了输出文件以及用于生成它的所有输入文件。输出类似于编译器使用-M -MP时的输出。请注意,没有像编译器中-MM那样的选项,以排除“系统文件”(这与编译器中的“系统头文件”不同,在链接器中不是一个明确定义的概念)。因此,--dependency-file的输出始终是针对在其中生成它的安装的确切状态,因此不应在不进行仔细编辑的情况下将其复制到分发makefile中。


-O level

如果 level 是一个大于零的数值,ld 将优化输出。这可能需要更长的时间,因此可能只应在生成最终二进制文件时启用。目前,此选项仅影响 ELF 共享库的生成。未来版本的链接器可能会更多地使用此选项。此外,目前对于此选项的不同非零值,链接器的行为没有区别。这可能会在未来的版本中发生变化。

-plugin name

在链接过程中使用插件。name 参数是插件的绝对文件名。通常,当使用链接时优化时,编译器会自动添加此参数,但用户也可以添加自己的插件。

请注意,编译器生成的插件的位置与 ar、nm 和 ranlib 程序搜索插件的位置不同。为了使这些命令能够使用基于编译器的插件,必须首先将其复制到 ${libdir}/bfd-plugins 目录中。所有基于 gcc 的链接器插件都具有向后兼容性,因此只需复制最新的插件即可。

--push-state

--push-state 允许保存当前控制输入文件处理的标志的状态,以便可以使用相应的 --pop-state 选项恢复它们。

受影响的选项是:-Bdynamic、-Bstatic、-dn、-dy、-call_shared、-non_shared、-static、-N、-n、--whole-archive、--no-whole-archive、-r、-Ur、--copy-dt-needed-entries、--no-copy-dt-needed-entries、--as-needed、--no-as-needed 和 -a。

此选项的一个目标是 pkg-config 规范。当与 --libs 选项一起使用时,将列出所有可能需要的库,然后可能始终将它们链接在一起。最好返回如下内容:

-Wl,--push-state,--as-needed -libone -libtwo -Wl,--pop-state

--pop-state

撤消 --push-state 的效果,恢复控制输入文件处理的标志的先前值。

-q
--emit-relocs

在完全链接的可执行文件中保留重定位节和内容。后期链接分析和优化工具可能需要此信息才能正确修改可执行文件。这将导致可执行文件变大。

此选项当前仅支持 ELF 平台。

--force-dynamic

强制输出文件具有动态节。此选项特定于 VxWorks 目标。

-r
--relocatable

生成可重定位的输出,即生成可以作为 ld 的输入使用的输出文件。这通常称为部分链接。作为副作用,在支持标准 Unix 魔法数字的环境中,此选项还将输出文件的魔法数字设置为 "OMAGIC"。如果未指定此选项,则将生成绝对文件。当链接 C++ 程序时,此选项不会解析对构造函数的引用;要执行此操作,请使用 -Ur。

当输入文件与输出文件格式不同时,仅当该输入文件不包含任何重定位时,才支持部分链接。不同的输出格式可能具有进一步的限制;例如,某些基于“a.out”的格式根本不支持与其他格式的输入文件进行部分链接。

当可重定位的输出包含既需要链接时优化 (LTO) 又不需要 LTO 的内容时,将创建一个 .gnu_object_only 部分,以包含一个可重定位的目标文件,就像对所有不需要 LTO 的可重定位输入应用了 -r 一样。处理包含 .gnu_object_only 部分的可重定位输入时,链接器会将该 .gnu_object_only 部分作为单独的输入进行提取。

请注意,由于 -r 选项会将来自不同输入文件的某些部分组合在一起,因此可能会对最终可执行文件或共享库的代码大小和局部性产生不利影响。

此选项与 -i 选项执行相同的操作。

-R filename
--just-symbols=filename

从文件名中读取符号名称及其地址,但不进行重定位或将其包含在输出中。这允许您的输出文件以符号方式引用其他程序中内存的绝对位置。您可以多次使用此选项。

为了与其他的 ELF 链接器兼容,如果 -R 选项后跟一个目录名而不是文件名,则它将被视为 -rpath 选项。

--rosegment
--no-rosegment

尝试确保仅创建一个只读、非代码段。仅在与 -z separate-code 选项一起使用时才有用。生成的二进制文件应该比仅使用 -z separate-code 选项时更小。如果没有指定此选项,或者如果指定了 --no-rosegment,则 -z separate-code 选项将创建两个只读段,一个在代码段之前,一个在代码段之后。

这些选项的名称具有误导性,但它们是为了使链接器与 LLD 和 GOLD 链接器兼容而选择的。

这些选项仅受 ELF 目标的支持。

-s
--strip-all

从输出文件中省略所有符号信息。

-S
--strip-debug

从输出文件中省略调试器符号信息(但不是所有符号)。

--strip-discarded
--no-strip-discarded

省略(或不省略)在已丢弃部分中定义的全局符号。默认情况下启用。

-plugin-save-temps

永久存储插件的“临时”中间文件。

-t
--trace

在 ld 处理输入文件时,打印输入文件的名称。如果提供 -t 两次,则还会打印存档中的成员。-t 输出对于生成所有参与链接的对象文件和脚本的列表非常有用,例如,在打包用于链接器错误报告的文件时。


-T scriptfile
--script=scriptfile
使用 scriptfile 作为链接器脚本。此脚本会替换 ld 的默认链接器脚本(而不是添加到其中),除非脚本包含“INSERT”,因此 commandfile 必须指定描述输出文件所需的一切内容。

如果 scriptfile 不存在于当前目录中,则“ld”会在任何先前的 -L 选项指定的目录中查找它。

在 -T 选项之前的命令行选项可能会影响脚本,但在其之后的命令行选项则不会。

如果它们是增强当前脚本,则多个 -T 选项将累积;否则,将使用最后一个非增强的 -T 选项。

还有其他指定链接器脚本的方法。请参阅:

-dT scriptfile
--default-script=scriptfile
使用 scriptfile 作为默认链接器脚本。

此选项类似于 --script 选项,不同之处在于脚本的处理会延迟到处理完其余命令行之后。这使得放置在 --default-script 选项之后的命令行选项能够影响链接器脚本的行为,这在无法直接由用户控制命令行时非常重要(例如,因为命令行是由另一个工具(如 gcc)构建的)。

-u symbol
--undefined=symbol
强制将 symbol 作为未定义的符号添加到输出文件中。这样做可能会触发从标准库中链接其他模块。-u 可以重复使用,并带有不同的选项参数以输入其他未定义的符号。此选项等效于链接器脚本命令“EXTERN”。

如果此选项用于强制将其他模块拉入链接,并且如果符号仍然未定义会出错,则应使用 --require-defined 选项。

--require-defined=symbol
要求在输出文件中定义 symbol。此选项与 --undefined 选项相同,但如果 symbol 在输出文件中未定义,则链接器将发出错误并退出。可以通过在链接器脚本中使用“EXTERN”、“ASSERT”和“DEFINED”来实现相同的效果。此选项可以多次使用以要求其他符号。

-Ur 对于不使用构造函数或析构函数的程序,或者对于基于 ELF 的系统,此选项等效于 -r:它生成可重定位输出——即,一个可以作为 ld 的输入的输出文件。但是,对于其他二进制文件,-Ur 选项类似于 -r,但它还会解析对构造函数和析构函数的引用。

对于 -r 和 -Ur 行为不同的系统,对已使用 -Ur 链接的文件使用 -Ur 是不可行的;一旦构造函数表构建完成,就无法添加到其中。仅对最后一个部分链接使用 -Ur,对于其他链接使用 -r。


--orphan-handling=MODE
控制如何处理孤立节。孤立节是指未在链接器脚本中明确提及的节。

MODE 可以具有以下任何值:

"place"
孤立节将被放置在合适的输出节中,其策略如“孤立节”中所述。`--unique` 选项也会影响节的放置方式。

"discard"
所有孤立节都将被丢弃,通过将它们放置在 `/DISCARD/` 节中。

"warn"
链接器将像 `“place”` 一样放置孤立节,并发出警告。

"error"
如果找到任何孤立节,链接器将退出并显示错误。

如果未提供 `--orphan-handling`,则默认值为“place”。

--unique[=SECTION]
为每个与 SECTION 匹配的输入节创建一个单独的输出节,或者如果省略了可选的通配符 SECTION 参数,则为每个孤立输入节创建一个单独的输出节。孤立节是指未在链接器脚本中明确提及的节。可以在命令行中多次使用此选项;它会阻止具有相同名称的输入节的正常合并,并覆盖链接器脚本中的输出节分配。

-v
--version
-V  显示 ld 的版本号。`-V` 选项还会列出支持的模拟。另请参见“选项,命令行选项”中 `--enable-linker-version` 的描述,该选项可用于将链接器版本字符串插入到二进制文件中。

-x
--discard-all
删除所有本地符号。

-X
--discard-locals
删除所有临时本地符号。(这些符号以特定于系统的本地标签前缀开头,通常对于 ELF 系统为 .L,对于传统的 a.out 系统为 L。)

-y symbol
--trace-symbol=symbol
打印每个链接文件中出现该符号的文件名。此选项可以多次使用。在许多系统中,有必要添加一个下划线作为前缀。

当你在链接中有一个未定义的符号但不知道引用来自哪里时,此选项很有用。

-Y path
将路径添加到默认库搜索路径中。此选项用于 Solaris 兼容性。

-z keyword
已知的关键字是:

call-nop=prefix-addr
call-nop=suffix-nop
call-nop=prefix-byte
call-nop=suffix-byte
指定在将对本地定义的函数 foo 的间接调用转换为其 GOT 插槽时,使用的 1 字节“NOP”填充。`call-nop=prefix-addr` 生成“0x67 call foo”。`call-nop=suffix-nop` 生成“call foo 0x90”。`call-nop=prefix-byte` 生成“byte call foo”。`call-nop=suffix-byte` 生成“call foo byte”。支持 i386 和 x86_64。

cet-report=none
cet-report=warning
cet-report=error
指定如何报告输入 `.note.gnu.property` 节中缺少 GNU\_PROPERTY\_X86\_FEATURE\_1\_IBT 和 GNU\_PROPERTY\_X86\_FEATURE\_1\_SHSTK 属性。`cet-report=none`,这是默认值,将使链接器不会报告输入文件中的缺失属性。`cet-report=warning` 将使链接器对输入文件中的缺失属性发出警告。`cet-report=error` 将使链接器对输入文件中的缺失属性发出错误。请注意,ibt 将关闭缺失 GNU\_PROPERTY\_X86\_FEATURE\_1\_IBT 属性的报告,shstk 将关闭缺失 GNU\_PROPERTY\_X86\_FEATURE\_1\_SHSTK 属性的报告。支持 Linux/i386 和 Linux/x86\_64。

combreloc
nocombreloc

合并多个动态重定位节,并进行排序以改进动态符号查找缓存。 如果指定了 nocombreloc,则不执行此操作。

common
nocommon

在可重定位链接期间生成具有 STT_COMMON 类型的公共符号。 如果指定了 nocommon,则使用 STT_OBJECT 类型。

common-page-size=value

将最常用的页面大小设置为 value。 如果系统使用此大小的页面,则将优化内存映像布局以最小化内存页面。

defs

报告来自常规目标文件的未解析符号引用。 即使链接器正在创建非符号共享库,也会执行此操作。 此选项是 -z undefs 的反向选项。

dynamic-undefined-weak
nodynamic-undefined-weak

在构建动态对象时,如果未通过符号可见性或版本控制强制为本地,并且这些未定义的弱符号来自常规目标文件,则使其成为动态符号。 如果指定了 nodynamic-undefined-weak,则不使其成为动态符号。 如果未指定任何选项,则目标可能会默认强制执行其中一个选项,或者对某些未定义的弱符号进行不同的动态选择。 并非所有目标都支持这些选项。

execstack

将对象标记为需要可执行堆栈。

global

此选项仅在构建共享对象时才有意义。 它使共享对象中定义的符号可用于后续加载的库的符号解析。

globalaudit

此选项仅在构建动态可执行文件时才有意义。 此选项通过在 DT_FLAGS_1 动态标记中设置“DF_1_GLOBAUDIT”位,将可执行文件标记为需要全局审核。 全局审核要求运行通过 --depaudit 或 -P 命令行选项定义的任何审核库,以对应用程序加载的所有动态对象进行审核。

ibtplt

生成启用 Intel 间接分支跟踪 (IBT) 的 PLT 条目。 支持 Linux/i386 和 Linux/x86_64。

ibt 在 .note.gnu.property 节中生成 GNU_PROPERTY_X86_FEATURE_1_IBT,以指示与 IBT 的兼容性。 这也意味着 ibtplt。 支持 Linux/i386 和 Linux/x86_64。

indirect-extern-access
noindirect-extern-access

在 .note.gnu.property 节中生成 GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS,以指示目标文件需要规范函数指针,并且不能与复制重定位一起使用。 此选项还意味着 noextern-protected-data 和 nocopyreloc。 支持 i386 和 x86-64。


noindirect-extern-access   移除   GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS    从
.note.gnu.property 部分。

initfirst
此选项只有在构建共享对象时才有意义。它将对象标记为,使其在运行时初始化时,先于同时加载到进程中的任何其他对象的运行时初始化。同样,该对象的运行时最终化将发生在任何其他对象的运行时最终化之后。

interpose
指定动态加载器应修改其符号搜索顺序,以便此共享库中的符号替换其他未如此标记的共享库中的所有符号。

unique
nounique
在生成共享库或其他可动态加载的 ELF 对象时,将其标记为应(默认情况下)只加载一次,并且仅加载到主命名空间中(在使用“dlmopen”时)。这主要用于标记基本库,例如 libc、libpthread 等,这些库通常如果不是它们自身的唯一实例,则无法正常工作。可以通过“dlmopen”调用者覆盖此行为,并且它不适用于某些加载机制(例如审核库)。

lam-u48
在 .note.gnu.property 部分中生成 GNU\_PROPERTY\_X86\_FEATURE\_1\_LAM\_U48,以指示与 Intel LAM_U48 兼容。支持 Linux/x86_64。

lam-u57
在 .note.gnu.property 部分中生成 GNU\_PROPERTY\_X86\_FEATURE\_1\_LAM\_U57,以指示与 Intel LAM_U57 兼容。支持 Linux/x86_64。

lam-u48-report=none
lam-u48-report=warning
lam-u48-report=error
指定如何报告输入 .note.gnu.property 部分中缺少的 GNU\_PROPERTY\_X86\_FEATURE\_1\_LAM\_U48 属性。lam-u48-report=none,这是默认设置,链接器将不会报告输入文件中的缺失属性。lam-u48-report=warning 将使链接器为输入文件中的缺失属性发出警告。lam-u48-report=error 将使链接器为输入文件中的缺失属性发出错误。支持 Linux/x86_64。

lam-u57-report=none
lam-u57-report=warning
lam-u57-report=error
指定如何报告输入 .note.gnu.property 部分中缺少的 GNU\_PROPERTY\_X86\_FEATURE\_1\_LAM\_U57 属性。lam-u57-report=none,这是默认设置,链接器将不会报告输入文件中的缺失属性。lam-u57-report=warning 将使链接器为输入文件中的缺失属性发出警告。lam-u57-report=error 将使链接器为输入文件中的缺失属性发出错误。支持 Linux/x86_64。

lam-report=none
lam-report=warning
lam-report=error
指定如何报告输入 .note.gnu.property 部分中缺少的 GNU\_PROPERTY\_X86\_FEATURE\_1\_LAM\_U48 和 GNU\_PROPERTY\_X86\_FEATURE\_1\_LAM\_U57 属性。lam-report=none,这是默认设置,链接器将不会报告输入文件中的缺失属性。lam-report=warning 将使链接器为输入文件中的缺失属性发出警告。lam-report=error 将使链接器为输入文件中的缺失属性发出错误。支持 Linux/x86_64。

lazy
在生成可执行文件或共享库时,标记它以指示动态链接器将函数调用解析推迟到函数被调用时(延迟绑定),而不是在加载时。延迟绑定是默认设置。

loadfltr
指定对象的过滤器应在运行时立即处理。

max-page-size=value
将支持的最大内存页大小设置为 value。

mark-plt
nomark-plt
使用动态标签 DT\_X86\_64\_PLT、DT\_X86\_64\_PLTSZ 和 DT\_X86\_64\_PLTENT 标记 PLT 条目。由于此选项在 R\_X86\_64\_JUMP\_SLOT 重定位的 r\_addend 字段中存储一个非零值,因此生成的可执行文件和共享库与动态链接器不兼容,例如较旧版本的 glibc 中的动态链接器,这些动态链接器没有忽略 r\_addend 的更改,即 R\_X86\_64\_GLOB\_DAT 和 R\_X86\_64\_JUMP\_SLOT 重定位,这些动态链接器不忽略 R\_X86\_64\_JUMP\_SLOT 重定位的 r\_addend 字段。支持 x86\_64。

muldefs
允许多个定义。

nocopyreloc
禁用链接器生成的 .dynbss 变量,这些变量用于替代在共享库中定义的变量。这可能会导致动态文本重定位。

nodefaultlib
指定动态加载器在搜索此对象的依赖项时应忽略任何默认库搜索路径。

nodelete
指定该对象在运行时不应被卸载。

nodlopen
指定该对象不可用于“dlopen”。

nodump
指定该对象不能被“dldump”转储。

noexecstack
将对象标记为不需要可执行堆栈。

noextern-protected-data
在构建共享库时,不要将受保护的数据符号视为外部符号。此选项会覆盖链接器后端的默认设置。它可以用于解决编译器生成的针对受保护的数据符号的错误重定位问题。对受保护的数据符号的更新,由另一个模块进行时,对生成的共享库不可见。支持 i386 和 x86-64。

noreloc-overflow
禁用重定位溢出检查。如果运行时不会发生动态重定位溢出,则可以使用此选项来禁用重定位溢出检查。支持 x86\_64。

memory-seal
nomemory-seal
指示可执行文件或共享库,所有 PT\_LOAD 节都应被密封,以避免进一步的操作(例如更改保护标志、节大小或删除映射)。这是一个安全加固措施,需要系统支持。这会在 .note.gnu.property 节中生成 GNU\_PROPERTY\_MEMORY\_SEAL。

now
在生成可执行文件或共享库时,标记它以指示动态链接器在程序启动时或共享库通过 dlopen 加载时,解析所有符号,而不是将函数调用解析推迟到函数第一次被调用时。

origin

指定对象需要对路径进行 $ORIGIN 处理。

pack-relative-relocs
nopack-relative-relocs

为位置无关的可执行文件和共享库生成紧凑的相对重定位。它会在动态节中添加“DT_RELR”、“DT_RELRSZ”和“DT_RELRENT”条目。 在构建位置相关的可执行文件和可重定位输出时,它将被忽略。 nopack-relative-relocs 是默认值,它会禁用紧凑的相对重定位。当链接到 GNU C 库时,它会在输出中添加一个针对共享 C 库的 GLIBC_ABI_DT_RELR 符号版本依赖项。支持 i386 和 x86-64。

relro
norelro

在对象中创建一个 ELF “PT_GNU_RELRO” 段头。这指定了一个内存段,如果支持,该段应该在重定位后变为只读。指定小于系统页面大小的 commonpage-size 会使这种保护无效。 如果使用 norelro,则不要创建 ELF “PT_GNU_RELRO” 段。

report-relative-reloc

报告链接器生成的动态相对重定位。支持 Linux/i386 和 Linux/x86_64。

sectionheader
nosectionheader

生成节头。如果使用 nosectionheader,则不要生成节头。 sectionheader 是默认值。

separate-code
noseparate-code

在对象中创建一个单独的代码“PT_LOAD”段头。这指定了一个内存段,该段应该只包含指令,并且必须与任何其他数据位于完全不同的页面中。如果使用 noseparate-code,则不要创建单独的代码“PT_LOAD”段。

shstk

在 .note.gnu.property 节中生成 GNU_PROPERTY_X86_FEATURE_1_SHSTK,以指示与 Intel Shadow Stack 的兼容性。支持 Linux/i386 和 Linux/x86_64。

stack-size=value

为 ELF “PT_GNU_STACK” 段指定堆栈大小。指定零会覆盖任何默认的非零大小的“PT_GNU_STACK”段的创建。

start-stop-gc
nostart-stop-gc

当使用 --gc-sections 时,如果保留的节引用了“__start_SECNAME”或“__stop_SECNAME”,并且“SECNAME”可以表示为 C 标识符,并且链接器通过合成“__start_SECNAME”或“__stop_SECNAME”,则所有名为“SECNAME”的输入节也将被保留。-z start-stop-gc 禁用此效果,允许像没有定义特殊合成符号一样进行垃圾回收。-z start-stop-gc 对对象文件或链接器脚本中“__start_SECNAME”或“__stop_SECNAME”的定义没有影响。这样的定义将阻止链接器提供合成的“__start_SECNAME”或“__stop_SECNAME”,因此垃圾回收对这些引用的特殊处理将不会发生。

start-stop-visibility=value

指定合成的“__start_SECNAME”和“__stop_SECNAME”符号的 ELF 符号可见性。value 必须是 default、internal、hidden 或 protected。如果未提供 -z start-stop-visibility 选项,则将使用 protected 以与历史做法兼容。但是,强烈建议在新程序和共享库中使用 -z start-stop-visibility=hidden,以便这些符号不会在共享对象之间导出,这通常不是预期的。


text
notext
textoff

如果设置了 DT_TEXTREL,则报告错误,即如果位置无关或共享对象在只读部分中具有动态重定位。 如果未设置 notext 或 textoff,则不报告错误。

undefs

不要报告来自普通目标文件的未解析符号引用,无论是在创建可执行文件时,还是在创建共享库时。 此选项是 -z defs 的反向选项。

unique-symbol
nounique-symbol

避免在符号字符串表中出现重复的局部符号名称。 如果使用 unique-symbol,则将“.”number”附加到重复的局部符号名称。 默认情况下使用 nounique-symbol。

x86-64-baseline
x86-64-v2
x86-64-v3
x86-64-v4

指定 .note.gnu.property 部分中所需的 x86-64 ISA 级别。 x86-64-baseline 生成“GNU_PROPERTY_X86_ISA_1_BASELINE”。 x86-64-v2 生成“GNU_PROPERTY_X86_ISA_1_V2”。 x86-64-v3 生成“GNU_PROPERTY_X86_ISA_1_V3”。 x86-64-v4 生成“GNU_PROPERTY_X86_ISA_1_V4”。 适用于 Linux/i386 和 Linux/x86_64。

isa-level-report=none
isa-level-report=all
isa-level-report=needed
isa-level-report=used

指定如何在输入可重定位文件中报告 x86-64 ISA 级别。 isa-level-report=none,这是默认设置,将使链接器不报告输入文件中的 x86-64 ISA 级别。 isa-level-report=all 将使链接器报告输入文件中的所需和使用的 x86-64 ISA 级别。 isa-level-report=needed 将使链接器报告输入文件中的所需 x86-64 ISA 级别。 isa-level-report=used 将使链接器报告输入文件中的使用 x86-64 ISA 级别。 适用于 Linux/i386 和 Linux/x86_64。

其他关键字为了与 Solaris 兼容将被忽略。

--gnu-tls-tag
--no-gnu-tls-tag

当链接器针对 glibc 且输入可重定位目标文件调用“___tls_get_addr”时,在输出程序和共享库中添加“GLIBC_ABI_GNU_TLS”版本标签依赖项。 输出在运行时将无法加载并在不定义“GLIBC_ABI_GNU_TLS”版本标签的 glibc 上运行。 除非在链接器构建时通过 --disable-gnu-tls-tag 配置选项禁用,否则,当未指定任何选项时,如果输入具有“___tls_get_addr”调用并且 libc.so 定义了“GLIBC_ABI_GNU_TLS”版本标签,则链接器将添加“GLIBC_ABI_GNU_TLS”版本标签依赖项。 适用于 Linux/i386。

--gnu2-tls-tag
--no-gnu2-tls-tag

当链接器针对 glibc 且输入可重定位目标文件具有“R_386_TLS_DESC_CALL”或“R_X86_64_TLSDESC_CALL”重定位时,在输出程序和共享库中添加“GLIBC_ABI_GNU2_TLS”版本标签依赖项。 输出在运行时将无法加载并在不定义“GLIBC_ABI_GNU2_TLS”版本标签的 glibc 上运行。 除非在链接器构建时通过 --disable-gnu2-tls-tag 配置选项禁用,否则,当未指定任何选项时,如果输入具有“R_386_TLS_DESC_CALL”或“R_X86_64_TLSDESC_CALL”重定位并且 libc.so 定义了“GLIBC_ABI_GNU2_TLS”版本标签,则链接器将添加“GLIBC_ABI_GNU2_TLS”版本标签依赖项。 适用于 Linux/i386 和 Linux/x86_64。


-( archives -)
--start-group archives --end-group
存档应该是一个存档文件列表。它们可以是显式的文件名,也可以是 -l 选项。

指定的存档会重复搜索,直到不再创建新的未定义引用。通常,存档仅按命令行中指定的顺序搜索一次。如果存档中的符号需要解析由稍后出现的存档中的对象引用的未定义符号,则链接器将无法解析该引用。通过对存档进行分组,它们将全部重复搜索,直到所有可能的引用都得到解析。

使用此选项会产生显著的性能成本。最好仅在两个或多个存档之间存在无法避免的循环引用时才使用它。

--accept-unknown-input-arch
--no-accept-unknown-input-arch
告诉链接器接受无法识别架构的输入文件。假设用户知道自己在做什么,并且有意链接这些未知的输入文件。这是链接器的默认行为,直到 2.14 版本。从 2.14 版本开始,默认行为是拒绝此类输入文件,因此添加了 --accept-unknown-input-arch 选项以恢复旧行为。

--as-needed
--no-as-needed
此选项影响命令行中在 --as-needed 选项之后出现的动态库的 ELF DT\_NEEDED 标签。通常,链接器将为命令行中提到的每个动态库添加一个 DT\_NEEDED 标签,无论该库是否真正需要。--as-needed 导致仅当库在此时刻满足来自常规对象文件的非弱未定义符号引用,或者(如果该库未在其他所需库的 DT\_NEEDED 列表中找到),满足来自另一个所需动态库的非弱未定义符号引用时,才会为该库发出 DT\_NEEDED 标签。在命令行中出现在该库之后的对象文件或库不会影响是否将其视为“需要”。这类似于从存档中提取对象文件的规则。--no-as-needed 恢复默认行为。

注意:在基于 Linux 的系统上,`--as-needed` 选项也会影响 `--rpath` 和 `--rpath-link` 选项的行为。请参阅 `--rpath-link` 的描述以获取更多详细信息。

`--add-needed`
`--no-add-needed`

这两个选项已被弃用,因为它们的名称与 --as-needed--no-as-needed 选项非常相似。它们已被 --copy-dt-needed-entries--no-copy-dt-needed-entries 选项取代。

`-assert keyword`

此选项为了与 SunOS 兼容而被忽略。

`-Bdynamic`
`-dy`
`-call_shared`

链接到动态库。这仅在支持共享库的平台上才有意义。在这些平台上,此选项通常是默认设置。您可以在命令行中使用此选项多次:它会影响随后出现的 -l 选项的库搜索。

`-Bgroup`

在动态部分中的 DT_FLAGS_1 条目中设置 DF_1_GROUP 标志。这将导致运行时链接器处理此对象及其依赖项中的查找,仅在组内执行。这意味着 --unresolved-symbols=report-all。此选项仅在支持共享库的 ELF 平台上才有意义。

`-Bstatic`
`-dn`
`-non_shared`
`-static`

不链接到共享库。这仅在支持共享库的平台上才有意义。这些选项是为了与各种系统兼容。您可以在命令行中使用此选项多次:它会影响随后出现的 -l 选项的库搜索。此选项还意味着 --unresolved-symbols=report-all。此选项可以与 -shared 一起使用。这样做意味着正在创建一个共享库,但库的所有外部引用都必须通过从静态库中提取条目来解析。

`-Bsymbolic`

在创建共享库时,如果存在,将对共享库中全局符号的引用绑定到共享库内的定义。通常,链接到共享库的程序可以覆盖共享库内的定义。此选项仅在支持共享库的 ELF 平台上才有意义。

`-Bsymbolic-functions`

在创建共享库时,如果存在,将对共享库中全局函数符号的引用绑定到共享库内的定义。此选项仅在支持共享库的 ELF 平台上才有意义。

`-Bno-symbolic`

此选项可以取消之前指定的 -Bsymbolic-Bsymbolic-functions

`--dynamic-list=dynamic-list-file`

指定动态列表文件的名称。这通常用于在创建共享库时指定全局符号列表,这些符号的引用不应绑定到共享库内的定义,或者在创建动态链接的可执行文件时,指定应添加到可执行文件中符号表中的符号列表。此选项仅在支持共享库的 ELF 平台上才有意义。


动态列表的格式与不带作用域和节点名称的版本节点相同。 有关更多信息,请参阅 VERSION。

--dynamic-list-data

将所有全局数据符号包含到动态列表中。

--dynamic-list-cpp-new

为 C++ operator newdelete 提供内置的动态列表。 它主要用于 构建 libstdc++ 共享库。

--dynamic-list-cpp-typeinfo

为 C++ 运行时类型标识提供内置的动态列表。

--check-sections
--no-check-sections

指示链接器在分配节地址后,不要检查是否存在任何重叠。 通常,链接器会执行此检查,如果发现任何重叠, 它会生成合适的错误消息。 链接器确实知道并允许重叠部分,特别是在叠加(overlays)中。 默认行为可以通过使用 命令行开关 --check-sections 来恢复。 通常,在可重定位链接中不会检查节重叠。 您可以通过使用 --check-sections 选项来强制进行检查。

--copy-dt-needed-entries
--no-copy-dt-needed-entries

此选项会影响链接器处理 ELF 动态库中 DT_NEEDED 标签所引用的动态库的方式。 通常,链接器不会 为命令行中提到的输入动态库中的 DT_NEEDED 标签中的每个库,向输出二进制文件添加 DT_NEEDED 标签。 但是,如果在命令行中指定了 --copy-dt-needed-entries,则任何 后续的动态库都将具有其 DT_NEEDED 条目添加到输出文件中。 默认行为可以通过 --no-copy-dt-needed-entries 来恢复。

此选项还会影响动态库中符号的解析。 使用 --copy-dt-needed-entries 时,命令行中提到的动态库将递归搜索,按照其 DT_NEEDED 标签指向的其他库, 以解析输出二进制文件所需的符号。 但是,使用默认设置时,对后续动态库的搜索将停止在动态库本身。 不会遍历任何 DT_NEEDED 链接来解析符号。

--cref

输出交叉引用表。 如果正在生成链接器映射文件,则将交叉引用表打印到映射文件中。 否则,它将打印到标准输出。

表的格式是故意简单的,以便可以使用脚本轻松处理。 符号按名称排序后打印出来。 对于每个符号,都会给出一个文件名的列表。 如果定义了该符号,则列表中第一个文件是定义的位置。 如果符号被定义为公共值,则任何发生这种情况的文件将紧随其后。 最后,列出引用该符号的所有文件。


--ctf-variables
--no-ctf-variables

CTF 调试信息格式支持一个节,该节编码了程序中未出现在任何符号表中的变量的名称和类型。 显然,这些变量不能通过常规调试器通过地址进行查找,因此用于其类型和名称的空间通常会被浪费:类型通常很小,但名称通常很大。 --ctf-variables 会生成这样一个节。 可以使用 --no-ctf-variables 来恢复默认行为。

--ctf-share-types=method

调整在 CTF 中共享跨翻译单元的类型时使用的方法。

share-unconflicted

将所有没有歧义定义的类型放入共享字典中,调试器可以轻松访问这些类型,即使它们只在一个翻译单元中出现。 这是默认设置。

share-duplicated

仅将出现在多个翻译单元中的类型放入共享字典中:只有一个定义的类型进入每个翻译单元的字典中。 在多个翻译单元中具有歧义定义的类型始终进入每个翻译单元的字典中。 这样做往往会使 CTF 变大,但可能会减少共享字典中的 CTF 量。 对于非常大的项目,这可能会加快打开 CTF 的速度,并在运行时节省 CTF 消费者的内存。

--no-define-common

此选项会禁止为公共符号分配地址。 脚本命令“INHIBIT_COMMON_ALLOCATION”具有相同的效果。

--no-define-common 选项允许将是否为公共符号分配地址的决策与输出文件类型的选择分离;否则,非可重定位的输出类型会强制为公共符号分配地址。 使用 --no-define-common 允许从共享库引用的公共符号仅在主程序中分配地址。 这消除了共享库中未使用的重复空间,并防止在存在许多具有专门的运行时符号解析搜索路径的动态模块时,可能发生解析到错误的重复项的情况。

--force-group-allocation

此选项导致链接器像普通输入节一样放置节组的成员,并删除节组。 这是最终链接的默认行为,但此选项可用于更改可重定位链接 (-r) 的行为。 脚本命令“FORCE_GROUP_ALLOCATION”具有相同的效果。

--defsym=symbol=expression

在输出文件中创建一个全局符号,其中包含由表达式给出的绝对地址。 您可以根据需要多次使用此选项来在命令行中定义多个符号。 在这种情况下,表达式支持有限的算术运算:您可以给出十六进制常量或现有符号的名称,或者使用“+”和“-”来添加或减去十六进制常量或符号。 如果您需要更复杂的表达式,请考虑从脚本中使用链接器脚本语言。 注意:符号、等号(“=”)和表达式之间不应有空格。


链接器会按照顺序处理 --defsym 参数和 -T 参数,将 --defsym 放在 -T 之前,会在链接脚本(由 -T 指定)处理之前定义符号,而将 --defsym 放在 -T 之后,会在链接脚本处理之后定义符号。这种差异会影响链接脚本中使用的 --defsym 符号的表达式,正确的顺序取决于您想要实现的目标。

^ -demangle[=style] ^ -no-demangle 这些选项控制是否在错误消息和其他输出中对符号名称进行反混淆。当告知链接器进行反混淆时,它会尝试以可读的方式呈现符号名称:它会删除对象文件格式使用的前导下划线,并将 C++ 混淆的符号名称转换为用户可读的名称。不同的编译器具有不同的混淆样式。可选的反混淆样式参数可用于选择适合您编译器的反混淆样式。默认情况下,链接器会进行反混淆,除非设置了环境变量 COLLECT_NO_DEMANGLE。这些选项可用于覆盖默认设置。

^ Ifile ^ -dynamic-linker=file 设置动态链接器的名称。这仅在生成动态链接的 ELF 可执行文件时才有意义。默认动态链接器通常是正确的;除非您知道自己在做什么,否则不要使用此选项。

^ -no-dynamic-linker 在生成可执行文件时,省略对在加载时使用动态链接器的请求。这仅对包含动态重定位的 ELF 可执行文件才有意义,并且通常需要能够处理这些重定位的入口点代码。

^ -embedded-relocs 此选项类似于 --emit-relocs 选项,但不同之处在于,重定位存储在目标特定的部分中。此选项仅受 BFIN、CR16 和 M68K 目标的支持。

^ -disable-multiple-abs-defs 不允许对通过 -R--just-symbols 调用时包含在文件名中的符号进行多次定义。

^ -fatal-warnings ^ -no-fatal-warnings 将所有警告视为错误。可以使用 --no-fatal-warnings 选项恢复默认行为。

^ w ^ -no-warnings 不显示任何警告或错误消息。如果启用了 --fatal-warnings,则此选项会覆盖它。当已知输出二进制文件将无法工作,但仍然需要创建它时,可以使用此选项。

^ -force-exe-suffix 确保输出文件具有 .exe 后缀。

如果成功构建的完全链接的输出文件没有 .exe.dll 后缀,则此选项会强制链接器将输出文件复制到具有 .exe 后缀的同名文件。当在 Microsoft Windows 主机上使用未修改的 Unix Makefile 时,此选项非常有用,因为某些版本的 Windows 除非图像以 .exe 后缀结尾,否则无法运行该图像。


--gc-sections
--no-gc-sections

启用未使用的输入节的垃圾回收。对于不支持此选项的目标,此选项将被忽略。可以通过在命令行中指定 --no-gc-sections 来恢复默认行为(不执行此垃圾回收)。请注意,COFF 和 PE 格式的目标支持垃圾回收,但当前的实现被认为是实验性的。

--gc-sections 通过检查符号和重定位来确定哪些输入节被使用。包含入口符号的节以及包含在命令行中未定义的符号的节将被保留,同样,包含被动态对象引用的符号的节也将被保留。请注意,在构建共享库时,链接器必须假设任何可见符号都被引用。一旦确定了初始节集,链接器将递归地将通过其重定位引用的任何节标记为已使用。请参阅 --entry、--undefined 和 --gc-keep-exported。

此选项可以在执行部分链接(通过 -r 选项启用)时设置。在这种情况下,必须通过以下选项之一显式指定要保留的符号的根:--entry、--undefined 或 --gc-keep-exported,或者通过链接器脚本中的“ENTRY”命令。

作为 GNU 扩展,标记有“SHF_GNU_RETAIN”标志的 ELF 输入节将不会被垃圾回收。

--print-gc-sections
--no-print-gc-sections

列出所有被垃圾回收器删除的节。该列表将打印到 stderr。此选项仅在通过 --gc-sections 选项启用了垃圾回收时才有效。可以通过在命令行中指定 --no-print-gc-sections 来恢复默认行为(不列出删除的节)。

--gc-keep-exported

当 --gc-sections 启用时,此选项可防止垃圾回收未使用的输入节,这些节包含具有默认或受保护可见性的全局符号。此选项旨在用于可执行文件,在可执行文件中,即使节包含的符号具有外部可见性,否则未引用的节也会被垃圾回收。请注意,此选项在链接共享对象时不起作用,因为它已经是默认行为。此选项仅支持 ELF 格式的目标。

--print-output-format

打印默认输出格式的名称(可能受到其他命令行选项的影响)。这是将在“OUTPUT_FORMAT”链接器脚本命令中出现的字符串。

--print-memory-usage

打印已使用的内存大小、总内存大小以及使用 MEMORY 命令创建的内存区域的已使用大小。这对于嵌入式目标非常有用,可以快速查看可用内存量。输出的格式具有一个标题和每个区域一行。以下是输出示例:


内存区域 已用大小 区域大小 使用百分比 ROM: 256 KB 1 MB 25.00% RAM: 32 B 2 GB 0.00%

注意:如果您想了解链接器本身的内存使用情况,那么 `--stats` 选项会执行此操作。

--help

在标准输出上打印命令行选项的摘要并退出。

--target-help

在标准输出上打印所有目标特定选项的摘要并退出。

-Map=mapfile

将链接映射打印到文件 mapfile。请参见上面对 -M 选项的描述。如果 mapfile 只是字符 "-",则会将映射写入标准输出。

将目录指定为 mapfile 会将链接映射作为文件写入该目录中。通常,目录中的文件名是输出文件的基本名称,并附加 ".map"。但是,如果使用特殊字符 "%",则它将被替换为输出文件的完整路径。此外,如果在 "%" 符号之后有任何字符,则不再附加 ".map"。

-o foo.exe -Map=bar                  [创建 ./bar]
-o ../dir/foo.exe -Map=bar           [创建 ./bar]
-o foo.exe -Map=../dir               [创建 ../dir/foo.exe.map]
-o ../dir2/foo.exe -Map=../dir       [创建 ../dir/foo.exe.map]
-o foo.exe -Map=%                    [创建 ./foo.exe.map]
-o ../dir/foo.exe -Map=%             [创建 ../dir/foo.exe.map]
-o foo.exe -Map=%.bar                [创建 ./foo.exe.bar]
-o ../dir/foo.exe -Map=%.bar         [创建 ../dir/foo.exe.bar]
-o ../dir2/foo.exe -Map=../dir/%     [创建 ../dir/../dir2/foo.exe.map]
-o ../dir2/foo.exe -Map=../dir/%.bar [创建 ../dir/../dir2/foo.exe.bar]

指定超过一个 "%" 字符会出错。

如果映射文件已经存在,则此操作会覆盖它。

--no-keep-memory

ld 通常通过将输入文件的符号表缓存在内存中来优化速度而不是内存使用。此选项指示 ld 优化内存使用,并根据需要重新读取符号表。如果 ld 在链接大型可执行文件时耗尽内存空间,这可能是必需的。

--no-undefined
-z defs

报告来自常规目标文件中的未解析符号引用。即使链接器正在创建一个非符号化共享库,也会这样做。--[no-]allow-shlib-undefined 选项控制在链接共享库时报告未解析引用的行为。

可以使用 "-z undefs" 来撤销此选项的效果。

--allow-multiple-definition
-z muldefs

通常,当符号被多次定义时,链接器会报告致命错误。这些选项允许多次定义,并使用第一个定义。

--allow-shlib-undefined
--no-allow-shlib-undefined

允许或不允许共享库中存在未定义的符号。此开关类似于 --no-undefined,不同之处在于,它确定了当未定义的符号位于共享库中而不是常规目标文件中时的行为。它不会影响如何处理常规目标文件中未定义的符号。


默认情况下,链接器在创建可执行文件时,会报告共享库中任何未定义符号的错误;但在创建共享库时,则允许这些错误。

允许在链接时指定共享库中存在未定义符号的原因是:

指定的共享库在链接时可能与运行时可用的共享库不同,因此该符号实际上可以在运行时被解析。

在某些操作系统(例如 BeOS 和 HPPA)中,共享库中的未定义符号是正常的。

例如,BeOS 内核会在加载时修补共享库,以选择最适合当前体系结构的函数。这用于动态选择适当的 memset 函数。

--error-handling-script=scriptname

如果提供了此选项,则链接器会在遇到任何错误时调用 scriptname。目前,仅支持两种类型的错误:缺少符号和缺少库。将向脚本传递两个参数:关键字“undefined-symbol”或“missing-lib”,以及未定义符号或缺少库的名称。其目的是让脚本向用户提供有关该符号或库可能在哪里找到的建议。脚本完成后,将显示正常的链接器错误消息。

此选项的可用性由配置时开关控制,因此在特定实现中可能不存在。

--no-undefined-version

通常,当符号具有未定义的版本时,链接器会忽略它。此选项禁止使用具有未定义版本的符号,并会引发致命错误。

--default-symver

为未导出的导出符号创建并使用默认符号版本(soname)。

--default-imported-symver

为未导出的导入符号创建并使用默认符号版本(soname)。

--no-warn-mismatch

通常,如果尝试链接不兼容的输入文件,ld 会显示错误,例如,因为它们是为不同的处理器或不同的字节序编译的。此选项告诉 ld 应该静默地允许这些可能的错误。此选项应谨慎使用,仅在您已采取一些特殊措施以确保链接器错误不合适时使用。

--no-warn-search-mismatch

通常,如果 ld 在库搜索期间找到不兼容的库,它会发出警告。此选项会禁用该警告。

--no-whole-archive

关闭后续存档文件对 --whole-archive 选项的影响。


--noinhibit-exec
保留可用的可执行输出文件。通常,如果链接器在链接过程中遇到错误,它不会生成输出文件;当它发出任何错误时,它会退出而不写入输出文件。

-nostdlib
仅搜索命令行中明确指定的库目录。在链接器脚本中(包括命令行中指定的链接器脚本)指定的库目录将被忽略。

--oformat=output-format
ld 可以配置为支持多种对象文件。如果您的 ld 配置为这样,您可以使用 --oformat 选项来指定输出对象文件的二进制格式。即使 ld 配置为支持替代对象格式,通常也不需要指定此选项,因为 ld 应该配置为默认输出最常用的格式。output-format 是一个文本字符串,是 BFD 库支持的特定格式的名称。(您可以使用 objdump -i 列出可用的二进制格式。)脚本命令“OUTPUT_FORMAT”也可以指定输出格式,但此选项会覆盖它。

--out-implib file
为链接器正在生成的可执行文件(例如,DLL 或 ELF 程序)创建导入库文件。可以使用此导入库(对于 DLL 来说,应该命名为 "\*.dll.a" 或 "\*.a")来链接客户端,从而跳过单独的导入库创建步骤(例如,对于 DLL 来说,是“dlltool”)。此选项仅适用于针对 i386 PE 和 ELF 的链接器。

-pie
--pic-executable
创建位置无关的可执行文件。这目前仅支持 ELF 平台。位置无关的可执行文件由动态链接器重定位到操作系统为其选择的虚拟地址,这在不同的调用之间可能会有所不同。它们在 ELF 文件头中标记为 ET_DYN,但与共享库有许多不同之处。特别是,PIE 中定义的符号默认情况下不能被另一个对象覆盖,而共享库可以。

-no-pie
创建位置相关的可执行文件。这是默认设置。

-qmagic
此选项是为了 Linux 兼容性而被忽略。

-Qy 此选项是为了 SVR4 兼容性而被忽略。

--relax
--no-relax
这是一个具有机器相关效果的选项。此选项仅在少数目标平台上受支持。

在某些平台上,--relax 选项执行目标特定的全局优化,这些优化在链接器解析程序中的寻址时成为可能,例如放松寻址模式、合成新指令、选择当前指令的较短版本以及组合常量值。

在某些平台上,这些链接时全局优化可能会使结果可执行文件的符号调试变得不可能。已知对于 Matsushita MN10200 和 MN10300 系列处理器来说就是这种情况。

在支持此功能的平台上,可以使用 --no-relax 选项禁用该功能。

在不支持此功能的平台上,--relax 和 --no-relax 选项都会被接受,但会被忽略。

--retain-symbols-file=filename

仅保留文件中 filename 中列出的符号,并丢弃所有其他符号。filename 只是一个简单的纯文本文件,每行包含一个符号名称。此选项在某些环境中(例如 VxWorks)特别有用,这些环境会逐渐累积大量的全局符号表,以节省运行时内存。

--retain-symbols-file 不会丢弃未定义的符号或用于重定位的符号。

您只能在命令行中指定一次 --retain-symbols-file。它会覆盖 -s 和 -S。

-rpath=dir

将一个目录添加到运行时库搜索路径中。这在链接一个 ELF 可执行文件时使用共享对象。所有 -rpath 参数都会被连接起来并传递给运行时链接器,运行时链接器会使用它们在运行时查找共享对象。

-rpath 选项还用于查找显式包含在链接中的共享对象所需的共享对象;请参见 -rpath-link 选项的说明。以这种方式搜索 -rpath 仅受本机链接器和配置了 --with-sysroot 选项的交叉链接器的支持。

如果链接 ELF 可执行文件时未使用 -rpath,并且定义了环境变量 "LD_RUN_PATH",则会使用它的内容。

-rpath 选项也可以在 SunOS 上使用。默认情况下,在 SunOS 上,链接器会使用所有给定的 -L 选项来形成运行时搜索路径。如果使用 -rpath 选项,则运行时搜索路径将仅使用 -rpath 选项形成,忽略 -L 选项。当使用 gcc 时,这可能很有用,因为 gcc 会添加许多位于 NFS 挂载文件系统上的 -L 选项。

为了与其他 ELF 链接器兼容,如果 -R 选项后跟一个目录名而不是文件名,则将其视为 -rpath 选项。

-rpath-link=dir

当使用 ELF 或 SunOS 时,一个共享库可能需要另一个共享库。当 "ld -shared" 链接包含一个共享库作为其输入文件之一时,就会发生这种情况。

当链接器在执行非共享、非可重定位链接时遇到此类依赖关系时,如果它没有显式包含,它将自动尝试找到所需的共享库并将其包含在链接中。在这种情况下,将搜索以下几个目录。-rpath-link 选项指定要搜索的第一组目录。此选项可以通过提供用冒号分隔的名称列表,或者多次出现来指定一系列目录名称。

这些搜索目录中可以包含 $ORIGIN 和 $LIB 标记。它们将被替换为包含程序或共享对象的目录的完整路径(对于 $ORIGIN),或者对于 32 位二进制文件,替换为 lib,对于 64 位二进制文件,替换为 lib64。


这些令牌的替代形式——${ORIGIN} 和 ${LIB} 也可以使用。 ${PLATFORM} 令牌不受支持。

应谨慎使用 --rpath-link 选项,因为它会覆盖可能已硬编码到共享库中的搜索路径。 在这种情况下,可能会无意中使用与运行时链接器将使用的搜索路径不同的搜索路径。

当需要额外的共享库时,链接器将按照以下顺序搜索目录以查找它们。 但是,请注意,这仅适用于查找以满足已包含的共享库所需的附加库。 它不适用于通过 -l 命令行选项包含的库。 搜索 -l 库仅在通过 -L 选项指定的目录中进行。

通过 `-rpath-link` 选项指定的任何目录。

通过 `-rpath` 选项指定的任何目录。 `-rpath` 和 `-rpath-link` 之间的区别在于,通过 `-rpath` 选项指定的目录包含在可执行文件中并在运行时使用,而 `-rpath-link` 选项仅在链接时有效。 这种方式的搜索仅由本机链接器和已配置 `--with-sysroot` 选项的交叉链接器支持。

在 ELF 系统上,对于本机链接器,如果未使用 `-rpath` 和 `-rpath-link` 选项,则搜索环境变量 "LD_RUN_PATH" 的内容。

在 SunOS 上,如果未使用 `-rpath` 选项,则搜索使用 `-L` 选项指定的任何目录。

对于本机链接器,搜索环境变量 "LD_LIBRARY_PATH" 的内容。

对于本机 ELF 链接器,将搜索共享库中 "DT_RUNPATH" 或 "DT_RPATH" 中的目录以查找该共享库所需的共享库。 如果存在 "DT_RUNPATH" 条目,则将忽略 "DT_RPATH" 条目。

对于 Linux 系统的链接器,如果文件 `/etc/ld.so.conf` 存在,则搜索该文件中找到的目录列表。 注意:如果定义了 "sysroot" 值,则会将该文件的路径附加 "sysroot" 值,然后是链接器配置为 `--prefix=<path>` 选项时指定的任何 "prefix" 字符串。

对于本机链接器,在 FreeBSD 系统上,搜索在 `elf-hints.h` 头文件中定义的 "_PATH_ELF_HINTS" 宏中指定的任何目录。

通过在命令行给定的链接器脚本中指定的 "SEARCH_DIR" 命令指定的任何目录,包括通过 `-T`(但不包括 `-dT`)指定的脚本。

默认目录,通常是 `/lib` 和 `/usr/lib`。

通过插件 `LDPT_SET_EXTRA_LIBRARY_PATH` 指定的任何目录。

通过默认链接器脚本中指定的 "SEARCH_DIR" 命令指定的任何目录。

请注意,在基于 Linux 的系统上,还有另一个注意事项:如果激活了 --as-needed 选项并且找到了一个可以满足搜索的共享库,并且该库没有 libc.soDT_NEEDED 标记,并且在搜索目录集中稍后还有一个也满足搜索并且具有 libc.soDT_NEEDED 标记的第二个共享库,则将选择第二个库而不是第一个库。

如果找不到所需的共享库,链接器将发出警告并继续链接。

^ -section-ordering-file=script 此选项用于通过额外的映射将输入节映射到输出节,从而增强当前链接器脚本。此文件必须使用与普通链接器脚本相同的“SECTIONS”语法,但不应执行除将输入节放置到输出节之外的任何操作。@pxref{SECTIONS}

节顺序脚本的第二个约束是,它只能引用当前正在使用的链接器脚本(即,默认链接器脚本或命令行中指定的脚本)中已定义的输出节。但是,节顺序脚本的好处是,它可以将输入节映射到输出节的开头,以便可以确保输出节中节的顺序。例如,假设默认链接器脚本如下所示:

SECTIONS {
    .text : { *(.text.hot) ; *(.text .text.*) }
    .data : { *(.data.big) ; *(.data .data.*) }
}

然后,如果使用如下节顺序文件:

.text : { *(.text.first) ; *(.text.z*) }
.data : { foo.o(.data.first) ; *(.data.small) }

这将等效于如下链接器脚本:

SECTIONS {
    .text : { *(.text.first) ; *(.text.z*) ; *(.text.hot) ; *(.text .text.*) }
    .data : { foo.o(.data.first) ; *(.data.small) ; *(.data.big) ; *(.data .data.*) }
}

节顺序文件的优点是可以用来对用户关心的节进行排序,而无需担心任何其他节或内存区域。

^ shared ^ Bshareable 创建共享库。当前仅在 ELF、XCOFF 和 SunOS 平台上受支持。在 SunOS 上,如果未使用 -e 选项并且链接中存在未定义的符号,则链接器将自动创建一个共享库。

^ -sort-common ^ -sort-common=ascending ^ -sort-common=descending 此选项告诉 ld 在将其放置在适当的输出节中时,按对齐方式升序或降序对公共符号进行排序。考虑的符号对齐方式是 16 字节或更大、8 字节、4 字节、2 字节和 1 字节。这是为了防止由于对齐约束而导致符号之间的间隙。如果未指定排序顺序,则假定为降序。

^ -sort-section=name 此选项会将“SORT_BY_NAME”应用于链接器脚本中的所有通配符节模式。


--sort-section=alignment

此选项会将“SORT_BY_ALIGNMENT”应用于链接器脚本中的所有通配符部分模式。

--spare-dynamic-tags=count

此选项指定在 ELF 共享对象的“.dynamic”部分中留出多少个空槽。空槽可能由后处理工具(如预链接器)使用。默认值为 5。

--split-by-file[=size]

类似于 --split-by-reloc,当达到大小时,为每个输入文件创建一个新的输出部分。如果未提供,则大小默认为 1。

--split-by-reloc[=count]

尝试在输出文件中创建额外的部分,以便没有单个输出部分包含超过 count 个重定位。这对于生成大型可重定位文件以下载到某些实时内核(使用 COFF 对象文件格式)中非常有用;因为 COFF 不能在单个部分中表示超过 65535 个重定位。请注意,这对于不支持任意部分的对象文件格式将无法工作。链接器不会将单个输入部分拆分并重新分配,因此如果单个输入部分包含超过 count 个重定位,则一个输出部分将包含那么多重定位。count 默认值为 32768。

--stats[=filename]

计算并显示有关链接器操作的统计信息,例如执行时间和内存使用情况。

如果未提供可选的 filename 参数,则仅报告基本信息,并将其发送到标准错误输出流。如果提供了 filename 参数,则将扩展信息写入指定的文件中。如果 filename 设置为仅为该符号,则将扩展信息发送到标准输出流。如果 filename 以 + 开头,则以追加模式而不是覆盖模式打开该文件。

如果启用了 -Map 选项,则信息也会记录在 map 文件中。注意:如果同时给出了 --stats 选项和 -Map 选项,并且它们的 filename 参数匹配,则信息只会写入一次,而不是两次。

如果定义了“LD_STATS”环境变量,则其行为类似于 --stats 选项。如果该变量的值是字符串,则将将其用作记录信息的文件的名称。否则,信息将发送到标准输出流。使用环境变量可以在不更改链接器的命令行的情况下记录统计信息。注意:如果同时使用环境变量和 --stats 选项,则 --stats 选项优先。

报告的扩展信息包括使用的 CPU 时间,如果可以使用 getrusage() 系统库调用,则还会记录内存使用情况。这些信息会为链接过程的各个部分(称为阶段)报告。此外,信息也会为名为“ALL”的特殊阶段报告,该阶段涵盖整个链接过程。请注意,各个阶段可以包含或相互重叠,因此不应假定链接器使用的总资源是各个阶段使用资源的简单总和。


此外,当报告扩展信息时,链接器版本、命令行参数和链接器启动时间也会包含在内。 这使得更容易处理构建系统调用多个链接的情况,并确定哪些参数负责生成报告的统计信息。

扩展输出如下所示:

Stats: linker version: (GNU Binutils) 2.44.50.20250401
Stats: linker started: Wed Apr  2 09:36:41 2025
Stats: args: ld -z norelro -z nomemory-seal -z no-separate-code -o a.out [...]

Stats: phase               cpu time    memory      user time    system time
Stats: name                (microsec)   (KiB)      (seconds)      (seconds)
Stats: ALL                   390082    217740              0              0
Stats: ctf processing            12         0              0              0
Stats: string merge            1324         0              0              0
Stats: parsing                  349       288              0              0
Stats: plugins                    1         0              0              0
Stats: processing files      259616    214524              0              0
Stats: write                 116493         0              0              0

--no-stats

禁用使用统计信息报告,即使它通过 --stats 命令行选项或 LD_STATS 环境变量启用了该功能。

--sysroot=directory

directory 用作 sysroot 的位置,从而覆盖配置时设置的默认值。 此选项仅由使用 --with-sysroot 进行配置的链接器支持。

--task-link

这由基于 COFF/PE 的目标使用,用于创建一个任务链接的对象文件,其中所有全局符号都已转换为静态符号。

--traditional-format

对于某些目标,ld 的输出与某些现有链接器的输出在某些方面有所不同。 此开关请求 ld 使用传统的格式。

例如,在 SunOS 上,ld 会合并符号字符串表中重复的条目。 这可以通过 30% 以上的比例减少包含完整调试信息的输出文件的大小。 不幸的是,SunOS 的“dbx”程序无法读取生成的程序(“gdb”则没有问题)。 --traditional-format 开关告诉 ld 不要合并重复的条目。

--section-start=sectionname=org

在输出文件中,将一个部分定位到绝对地址 org。 您可以在命令行中根据需要多次使用此选项来定位多个部分。 org 必须是一个单独的十六进制整数;为了与其他链接器兼容,您可以省略通常与十六进制值相关的开头 0x。 注意:sectionname、等号 (=) 和 org 之间不应有任何空格。


--image-base=org

在使用 ELF 时,与 -Ttext-segment 相同,这两个选项实际上都设置了 ELF 可执行文件的基地址。

在使用 PE 时,将其值用作程序或 DLL 的基地址。这是程序或 DLL 在加载时将使用的最低内存位置。为了减少重定位的需求并提高 DLL 的性能,每个 DLL 都应该具有唯一的基地址,并且不应与其他 DLL 重叠。默认值为 0x400000(可执行文件)和 0x10000000(DLL)。

-Tbss=org
-Tdata=org
-Ttext=org

与 --section-start 相同,其中 ".bss"、".data" 或 ".text" 是节名称。

-Ttext-segment=org

在创建 ELF 可执行文件时,它将设置第一个段的第一个字节的地址。请注意,当使用 -pie 选项和 -Ttext-segment=org 时,输出的可执行文件将被标记为 ET_EXEC,以便在运行时保证文本段的第一个字节的地址为 org。

-Trodata-segment=org

在为具有单独只读数据段的 ELF 可执行文件或共享对象创建目标时,它将设置只读数据段的第一个字节的地址。

-Tldata-segment=org

在为 x86-64 中等内存模型创建 ELF 可执行文件或共享对象时,它将设置 ldata 段的第一个字节的地址。

--unresolved-symbols=method

确定如何处理未解析的符号。方法(method)有四个可能的值:

ignore-all

不报告任何未解析的符号。

report-all

报告所有未解析的符号。这是默认设置。

ignore-in-object-files

报告包含在共享库中的未解析的符号,但忽略来自普通对象文件的符号。

ignore-in-shared-libs

报告来自普通对象文件的未解析的符号,但忽略来自共享库的符号。这在创建动态二进制文件并且已知所有应引用的共享库都包含在链接器的命令行中时非常有用。

共享库本身的行为也可以通过 --[no-]allow-shlib-undefined 选项进行控制。

通常,链接器会为每个报告的未解析符号生成错误消息,但可以使用 --warn-unresolved-symbols 选项将其更改为警告。

--dll-verbose
--verbose[=NUMBER]

显示 ld 的版本号并列出链接器支持的链接器仿真。显示哪些输入文件可以打开,哪些不能打开。显示链接器正在使用的链接器脚本。如果可选的 NUMBER 参数 > 1,还将显示插件符号状态。

--version-script=version-scriptfile

指定链接器的版本脚本文件的名称。这通常用于创建共享库,以指定库版本层次结构的附加信息。此选项仅在支持共享库的 ELF 平台上完全支持;请参阅 VERSION。它在 PE 平台上部分受支持,PE 平台可以使用版本脚本来过滤自动导出模式中的符号可见性:版本脚本中标记为本地的任何符号都不会导出。


--warn-common

当一个公共符号与其他公共符号或符号定义组合时发出警告。 Unix 链接器允许这种有些不规范的做法,但某些其他操作系统的链接器不允许。 此选项允许您发现由组合全局符号可能导致的问题。 不幸的是,一些 C 库使用这种做法,因此您可能会收到一些关于库中以及程序中的符号的警告。

有三种类型的全局符号,以下通过 C 示例说明:

int i = 1;

一个定义,它位于输出文件的初始化数据部分。

extern int i;

一个未定义的引用,它不分配空间。在某个位置必须存在一个定义或公共符号。

int i;

一个公共符号。如果变量只有(一个或多个)公共符号,它将位于输出文件的未初始化数据区域。链接器将多个相同变量的公共符号合并为一个符号。如果它们的大小不同,它将选择最大的大小。链接器会将公共符号转换为声明,如果存在相同变量的定义。

^ -warn-common 选项可以生成五种警告。每个警告由两行组成:第一行描述遇到的符号,第二行描述之前遇到的具有相同名称的符号。这两个符号中的一个或两个将是公共符号。

     将公共符号转换为引用,因为已经存在该符号的定义。

<file>(<section>): 警告:`<symbol>' 的公共符号
被定义覆盖
<file>(<section>): 警告:定义在此处

     将公共符号转换为引用,因为遇到了后续的该符号的定义。
    这与前一种情况相同,只是符号的顺序不同。

<file>(<section>): 警告:`<symbol>' 的定义
覆盖公共符号
<file>(<section>): 警告:公共符号在此处

     将公共符号与之前的同大小的公共符号合并。

<file>(<section>): 警告:多个 `<symbol>' 的公共符号
<file>(<section>): 警告:之前的公共符号在此处

     将公共符号与之前的更大大小的公共符号合并。

<file>(<section>): 警告:`<symbol>' 的公共符号
被更大的公共符号覆盖
<file>(<section>): 警告:更大的公共符号在此处

     将公共符号与之前的更小大小的公共符号合并。
    这与前一种情况相同,只是符号的顺序不同。

<file>(<section>): 警告:`<symbol>'的公共符号
覆盖了较小的公共符号
<file>(<section>): 警告:较小的公共符号在此处

--warn-constructors

如果使用了任何全局构造函数,则发出警告。这仅对某些目标文件格式有用。 对于 COFF 或 ELF 等格式,链接器无法检测全局构造函数的使用。

--warn-execstack
--warn-execstack-objects
--no-warn-execstack

在 ELF 平台上,如果链接器被要求创建一个包含可执行堆栈的输出文件,则链接器可能会生成警告消息。 有三种可能的状态:

     不生成任何警告。

     始终生成警告,即使通过 -z execstack 命令行选项请求了可执行堆栈。

     仅当对象文件请求可执行堆栈时才生成警告,但不使用 -z execstack 选项时。

默认状态取决于链接器构建时的配置方式。--no-warn-execstack 选项始终将链接器置于无警告状态。
--warn-execstack 选项将链接器置于始终警告状态。
--warn-execstack-objects 选项将链接器置于仅针对对象文件警告状态。

注意:ELF 格式的输入文件可以通过在 .note.GNU-stack 部分设置其部分标志中的可执行位来指定它需要可执行堆栈。
它们可以通过使用相同的部分(但不设置可执行标志位)来指定它们不需要可执行堆栈。
如果输入文件没有 .note.GNU-stack 部分,则默认行为是特定于目标的。
对于某些目标,缺少这样的部分意味着需要可执行堆栈。这通常是手动编写的汇编文件的常见问题。

--error-execstack
--no-error-execstack

如果链接器将生成有关可执行堆栈的警告消息,则 --error-execstack 选项将把该警告更改为错误。 请注意,此选项不会更改链接器的 execstack 警告生成状态。使用 --warn-execstack 或 --warn-execstack-objects 来设置特定的警告状态。

--no-error-execstack 选项将恢复默认行为,即生成警告消息。

--warn-multiple-gp

如果需要在输出文件中使用多个全局指针值,则发出警告。这仅对某些处理器(例如 Alpha)有意义。 具体来说,某些处理器将大数值常量放在一个特殊部分中。 一个特殊的寄存器(全局指针)指向这个部分的中间位置,以便可以通过基寄存器相对寻址模式高效地加载常量。 由于基寄存器相对模式中的偏移量是固定的并且相对较小(例如,16 位),因此这限制了常量池的最大大小。 因此,在大型程序中,通常需要使用多个全局指针值,以便能够寻址所有可能的常量。 此选项导致每当发生这种情况时,都会发出警告。


--warn-once

仅针对每个未定义的符号发出一次警告,而不是针对引用该符号的每个模块发出一次警告。

--warn-rwx-segments
--no-warn-rwx-segments

如果链接器创建了一个可加载的、非零大小的段,并且该段同时具有读、写和执行权限,则发出警告。这样的段代表一种潜在的安全漏洞。此外,如果创建了一个具有执行权限标志的线程本地存储段,无论是否同时具有读和/或写权限标志,都会发出警告。

这些警告默认启用。可以通过 --no-warn-rwx-segments 选项禁用,并通过 --warn-rwx-segments 选项重新启用。

--error-rwx-segments
--no-error-rwx-segments

如果链接器将生成关于可执行段、可写段或可执行 TLS 段的警告消息,则 --error-rwx-segments 选项会将此警告转换为错误。--no-error-rwx-segments 选项将恢复默认行为,即仅生成警告消息。

注意:--error-rwx-segments 选项本身不会启用关于这些段的警告。这些警告要么默认启用(如果链接器已配置为启用),要么通过 --warn-rwx-segments 命令行选项启用。

--warn-section-align

如果由于对齐原因而更改了输出节的地址,则发出警告。通常,对齐由输入节设置。只有当未显式指定时(即,“SECTIONS”命令未为该节指定起始地址),该地址才会更改。

--warn-textrel

如果链接器将 DT_TEXTREL 添加到位置无关的可执行文件或共享对象中,则发出警告。

--warn-alternate-em

如果对象具有替代的 ELF 机器代码,则发出警告。

--warn-unresolved-symbols

如果链接器将报告一个未解析的符号(请参阅 --unresolved-symbols 选项),它通常会生成一个错误。此选项使它生成一个警告。

--error-unresolved-symbols

这会将链接器的默认行为恢复为在报告未解析的符号时生成错误。

--whole-archive

对于命令行中 --whole-archive 选项之后提到的每个存档文件,包含存档文件中的每个对象文件进行链接,而不是搜索存档文件以查找所需的对象文件。这通常用于将存档文件转换为共享库,强制每个对象都包含在生成的共享库中。此选项可以多次使用。

从 gcc 使用此选项时,请注意以下两点:首先,gcc 不了解此选项,因此您必须使用 -Wl,-whole-archive。其次,不要忘记在您的存档列表之后使用 -Wl,-no-whole-archive,因为 gcc 会将自己的存档列表添加到您的链接中,并且您可能不希望此标志影响这些存档。


--wrap=symbol
为 symbol 使用一个包装函数。对 symbol 的任何未定义引用都将被解析为 "__wrap_symbol"。对 "__real_symbol" 的任何未定义引用都将被解析为 symbol。

这可用于为系统函数提供一个包装。包装函数应命名为 "__wrap_symbol"。如果它希望调用系统函数,它应调用 "__real_symbol"。

这是一个简单的示例:

void *
__wrap_malloc (size_t c)
{
printf ("malloc called with %zu\n", c);
return __real_malloc (c);
}

如果将其他代码与此文件一起链接,并使用 --wrap malloc,则对 "malloc" 的所有调用都将调用函数 "__wrap_malloc"。在 "__wrap_malloc" 中对 "__real_malloc" 的调用将调用真实的 "malloc" 函数。

您可能希望提供一个 "__real_malloc" 函数,以便在没有 --wrap 选项的情况下进行链接也能成功。如果这样做,则不应将 "__real_malloc" 的定义放在与 "__wrap_malloc" 相同的文件中;如果这样做,汇编器可能会在链接器有机会将其包装到 "malloc" 之前就解析该调用。

只有未定义的引用才会被链接器替换。因此,在翻译单元内部对 symbol 的引用不会被解析为 "__wrap_symbol"。在下一个示例中,"g" 中对 "f" 的调用不会被解析为 "__wrap_f"。

int
f (void)
{
return 123;
}

int
g (void)
{
return f();
}

--eh-frame-hdr
--no-eh-frame-hdr

请求(--eh-frame-hdr)或禁止(--no-eh-frame-hdr)创建 ".eh_frame_hdr" 部分和 ELF "PT_GNU_EH_FRAME" 程序头。

--no-ld-generated-unwind-info

请求为链接器生成的代码部分(如 PLT)创建 ".eh_frame" 取消堆栈信息。如果链接器支持生成取消堆栈信息,则默认情况下启用此选项。此选项还控制为链接器生成的代码部分(如 PLT)生成 ".sframe" 堆栈跟踪信息。

--enable-new-dtags
--disable-new-dtags

此链接器可以创建 ELF 中的新动态标签。但是,较旧的 ELF 系统可能无法理解它们。如果您指定 --enable-new-dtags,则将根据需要创建新的动态标签,并且将省略较旧的动态标签。如果您指定 --disable-new-dtags,则不会创建新的动态标签。默认情况下,不创建新的动态标签。请注意,这些选项仅适用于 ELF 系统。

--hash-size=number

将链接器的哈希表的大小设置为接近 number 的质数。增加此值可以减少链接器执行其任务所需的时间,但会增加链接器的内存需求。同样,减少此值可以减少内存需求,但会降低速度。默认值为 4051(在正常情况下)和 1021(如果使用 --reduce-memory-overheads 命令行选项)。


--hash-style=style
设置链接器哈希表(s)的类型。style 可以是 "sysv",用于经典的 ELF ".hash" 段;"gnu",用于新的 GNU ".gnu.hash" 段;或者 "both",用于经典的 ELF ".hash" 段和新的 GNU ".gnu.hash" 哈希表。默认值取决于链接器的配置方式,但在大多数基于 Linux 的系统上,它将是 "both"。

--compress-debug-sections=none
--compress-debug-sections=zlib
--compress-debug-sections=zlib-gnu
--compress-debug-sections=zlib-gabi
--compress-debug-sections=zstd
在 ELF 平台上,这些选项控制使用 zlib 压缩 DWARF 调试段的方式。

--compress-debug-sections=none 不会压缩 DWARF 调试段。
--compress-debug-sections=zlib-gnu 压缩 DWARF 调试段,并将其重命名为以 .zdebug 开头,而不是 .debug。--compress-debug-sections=zlib-gabi 也压缩 DWARF 调试段,但不是重命名它们,而是设置段头中的 SHF_COMPRESSED 标志。

--compress-debug-sections=zlib 选项是 --compress-debug-sections=zlib-gabi 的别名。

--compress-debug-sections=zstd 使用 zstd 压缩 DWARF 调试段。

请注意,此选项会覆盖输入调试段中的任何压缩,因此,如果使用 --compress-debug-sections=none 链接二进制文件,则在将其复制到输出二进制文件中之前,输入文件中任何压缩的调试段都将被解压缩。

默认的压缩行为取决于目标和用于构建工具链的配置选项。可以通过检查链接器的 --help 选项的输出来确定默认值。

--reduce-memory-overheads
此选项可减少链接器运行时所需的内存,但会降低链接速度。这用于选择旧的 O(n^2) 算法来生成链接映射文件,而不是新的 O(n) 算法,后者在符号存储方面使用了大约 40% 更多的内存。

另一个效果是,如果使用了 --hash-size 选项,则此选项会将默认哈希表大小设置为 1021,这再次通过延长链接器运行时间来节省内存。

--reduce-memory-overheads 开关也可用于在链接器的未来版本中启用其他权衡。

--max-cache-size=size
ld 通常会将输入文件的重定位信息和符号表缓存到内存中,而缓存大小没有限制。此选项将最大缓存大小设置为 size。请注意,如果使用了 --no-keep-memory 命令行选项,则链接器会表现得好像最大缓存大小设置为 0,即不保留任何内容。

--build-id
--build-id=style
请求创建 ".note.gnu.build-id" ELF 注释部分或 ".buildid" COFF 部分。注释的内容是唯一标识此链接文件的位。style 可以是 "uuid",使用 128 位随机位;"sha1",使用 160 位 SHA1 哈希;"md5",使用 128 位 MD5 哈希;或 "xx",对输出内容的规范部分使用 128 位 XXHASH;或 "0xhexstring",使用指定的偶数个十六进制数字的位字符串(忽略 "-" 和 ":" 字符)。如果省略 style,则使用 "sha1"。

“md5”、“sha1”和“xx”样式会生成一个标识符,该标识符对于相同的输出文件始终保持不变,但几乎可以肯定的是,它在所有不相同的输出文件中都是唯一的。 它不打算用作文件内容的校验和进行比较。链接的文件可能会在以后被其他工具更改,但用于标识原始链接文件的构建 ID 位字符串不会更改。

将“none”传递给样式会禁用所有先前的“--build-id”选项。

--package-metadata=JSON
请求创建“.note.package”ELF 备注部分。备注的内容采用 JSON 格式,如 [包元数据规范](https://systemd.io/ELF_PACKAGE_METADATA/) 中所述。有关更多信息,请参见:https://systemd.io/ELF_PACKAGE_METADATA/。JSON 参数支持百分比编码和以下 %[string] 编码(其中 string 指的是 HTML 命名字符引用中的名称):%[comma] 表示,, %[lbrace] 表示 {, %[quot] 表示 ", %[rbrace] 表示 }, %[space] 表示空格字符。如果 JSON 参数缺失/为空,则将禁用先前通过先前出现的 --package-metadata 选项启用的元数据备注的创建。如果链接器是使用 libjansson 构建的,则将验证 JSON 字符串。

i386 PE 链接器支持 -shared 选项,该选项使输出成为动态链接库 (DLL),而不是普通的可执行文件。当使用此选项时,应将输出命名为“*.dll”。此外,链接器完全支持标准的“*.def”文件,这些文件可以像对象文件一样在链接器命令行中指定(事实上,它应该在它导出符号的存档之前,以确保它们被链接,就像普通的对象文件一样)。

除了所有目标通用的选项之外,i386 PE 链接器还支持其他 i386 PE 目标特定的命令行选项。带有值的选项可以通过空格或等号与它们的值分隔。

--add-stdcall-alias

如果给定,带有 stdcall 后缀(@nn)的符号将按原样导出,并且还会去除后缀。 [此选项是链接器 i386 PE 目标端口的特定选项]

--base-file file

将文件用作保存所有重定位的基本地址的文件名,这些重定位用于生成使用 dlltool 的 DLL。 [此选项是 i386 PE 特定选项]

--dll

创建 DLL 而不是普通的可执行文件。您也可以使用 -shared 或在给定的“.def”文件中指定“LIBRARY”。[此选项是链接器 i386 PE 目标端口的特定选项]


--enable-long-section-names
--disable-long-section-names

PE 格式的 COFF 对象文件格式添加了一个扩展,允许使用超过八个字符的节名称,这是 COFF 的正常限制。 默认情况下,这些名称仅允许在对象文件中使用,因为完全链接的可执行镜像不携带 COFF 字符串表,该字符串表是支持较长名称所必需的。 作为 GNU 扩展,也可以允许在可执行镜像中使用它们,或者(可能毫无意义地!)禁止在对象文件中使用它们,方法是使用这两个选项。 使用这些长节名称生成的可执行镜像略微不符合标准,因为它们包含一个字符串表,并且在使用非 GNU PE 兼容工具(如文件查看器和转储器)检查时可能会生成令人困惑的输出。 但是,GDB 依赖于使用 PE 长节名称才能在可执行镜像中找到 Dwarf-2 调试信息节,因此,如果在命令行中没有指定任何选项,ld 将启用长节名称,从而覆盖默认且技术上正确的行为,即在链接可执行镜像并且不剥离符号时。 [此选项适用于所有针对 PE 的链接器端口]

--enable-stdcall-fixup
--disable-stdcall-fixup

如果链接器找到无法解析的符号,它将尝试进行“模糊链接”,方法是查找另一个已定义的符号,该符号仅在符号名称的格式上有所不同(cdecl 与 stdcall),并将其链接到匹配的符号。 例如,未定义的符号“_foo”可能会链接到函数“_foo@12”,或者未定义的符号“_bar@16”可能会链接到函数“_bar”。 当链接器执行此操作时,它会打印一个警告,因为通常它应该失败,但有时从第三方 DLL 生成的导入库可能需要启用此功能才能使用。 如果指定 --enable-stdcall-fixup,则完全启用此功能,并且不会打印警告。 如果指定 --disable-stdcall-fixup,则禁用此功能,并将此类不匹配视为错误。 [此选项特定于针对 i386 PE 的链接器端口]

--leading-underscore
--no-leading-underscore

对于大多数目标,默认符号前缀是一个下划线,并在目标描述中定义。 通过此选项,可以禁用/启用默认下划线符号前缀。

--export-all-symbols
如果给定,则用于构建 DLL 的对象中的所有全局符号都将由 DLL 导出。 请注意,如果除此之外没有其他导出的符号,则这是默认设置。 当通过 DEF 文件或函数属性显式导出符号时,默认情况下不导出任何其他内容,除非指定此选项。 请注意,符号“DllMain@12”、“DllEntryPoint@0”、“DllMainCRTStartup@12”和“impure_ptr”不会自动导出。 此外,从其他 DLL 导入的符号将不会被重新导出,并且以“_head_”开头或以“_iname”结尾的符号(用于指定 DLL 的内部布局)也不会被导出。 此外,来自“libgcc”、“libstd++”、“libmingw32”或“crtX.o”的符号将不会被导出。 符号名称以“__rtti_”或“__builtin_”开头将不会被导出,以帮助构建 C++ DLL。 最后,有一个广泛的 cygwin 私有符号列表,这些符号不会被导出(显然,这仅适用于在为 cygwin 目标构建 DLL 时)。 这些 cygwin 排除项是:“_cygwin_dll_entry@12”、“_cygwin_crt0_common@8”、“_cygwin_noncygwin_dll_entry@12”、“_fmode”、“_impure_ptr”、“cygwin_attach_dll”、“cygwin_premain0”、“cygwin_premain1”、“cygwin_premain2”、“cygwin_premain3”和“environ”。 [此选项特定于针对 i386 PE 的链接器端口]

--exclude-symbols symbol,symbol,...
指定一个符号列表,这些符号不应自动导出。符号名称可以用逗号或冒号分隔。[此选项特定于针对 i386 PE 的链接器]

--exclude-all-symbols
指定不应导出任何符号。[此选项特定于针对 i386 PE 的链接器]

--file-alignment
指定文件对齐方式。文件中的各个部分将始终从文件偏移量开始,该偏移量是此数字的倍数。默认值为 512。[此选项特定于针对 i386 PE 的链接器]

--heap reserve
--heap reserve,commit
指定要为程序保留(并可选地提交)的用于堆的内存字节数。默认值为 1MB 保留,4K 提交。[此选项特定于针对 i386 PE 的链接器]

--kill-at
如果指定,则在导出符号之前,将从符号中删除 stdcall 后缀 (@nn)。[此选项特定于针对 i386 PE 的链接器]

--large-address-aware
如果指定,则将 COFF 标头“Characteristics”字段中的相应位设置为指示此可执行文件支持大于 2 GB 的虚拟地址。这应与 BOOT.INI 的“[操作系统]”部分中的 /3GB 或 /USERVA=value 兆字节开关一起使用。否则,此位将不起作用。[此选项特定于针对 PE 的链接器]

--disable-large-address-aware
撤消先前 --large-address-aware 选项的效果。如果 --large-address-aware 始终由编译器驱动程序(例如 Cygwin gcc)设置,并且可执行文件不支持大于 2 GB 的虚拟地址,则此选项很有用。[此选项特定于针对 PE 的链接器]

--major-image-version value
设置“image version”的主版本号。默认值为 1。[此选项特定于针对 i386 PE 的链接器]

--major-os-version value
设置“操作系统版本”的主版本号。默认为 4。 [此选项特定于针对 i386 PE 的链接器]

--major-subsystem-version value
设置“子系统版本”的主版本号。默认为 4。 [此选项特定于针对 i386 PE 的链接器]

--minor-image-version value
设置“映像版本”的次版本号。默认为 0。 [此选项特定于针对 i386 PE 的链接器]

--minor-os-version value
设置“操作系统版本”的次版本号。默认为 0。 [此选项特定于针对 i386 PE 的链接器]

--minor-subsystem-version value
设置“子系统版本”的次版本号。默认为 0。 [此选项特定于针对 i386 PE 的链接器]

--output-def file
链接器将创建文件 file,其中包含与链接器生成的 DLL 对应的 DEF 文件。 此 DEF 文件(应命名为“*.def”)可用于使用“dlltool”创建导入库,或可用作引用,以自动或隐式导出符号。 [此选项特定于针对 i386 PE 的链接器]

--enable-auto-image-base
--enable-auto-image-base=value
自动为 DLL 选择映像基址,可以选择从基址 value 开始,除非使用“--image-base”参数指定了基址。 通过使用从 DLL 名称生成的哈希值来为每个 DLL 创建唯一的映像基址,可以避免内存冲突和重定位,从而延迟程序执行。 [此选项特定于针对 i386 PE 的链接器]

--disable-auto-image-base
不自动生成唯一的映像基址。 如果没有用户指定的映像基址(“--image-base”),则使用平台默认值。 [此选项特定于针对 i386 PE 的链接器]

--dll-search-prefix string
在动态链接到没有导入库的 DLL 时,首先搜索“<string><basename>.dll”,而不是“lib<basename>.dll”。 此行为允许轻松区分为各种“子平台”构建的 DLL:本机、Cygwin、uwin、pw 等。 例如,Cygwin DLL 通常使用“--dll-search-prefix=cyg”。 [此选项特定于针对 i386 PE 的链接器]

--enable-auto-import
对 DLL 的“\_symbol”到“\_\_imp\_\_symbol”进行复杂的链接,以进行 DATA 导入,从而可以绕过用户端的 dllimport 机制,并引用未修改的符号名称。 [此选项特定于针对 i386 PE 的链接器]

以下说明与该功能的原始实现相关,现在对于 Cygwin 和 MinGW 目标而言已过时。

注意:使用“auto-import”扩展将导致映像文件的文本部分变为可写。 这不符合 Microsoft 发布的 PE-COFF 格式规范。

注意——使用“自动导入”扩展还会导致通常会放置在 .rdata 部分中的只读数据被放置在 .data 部分中。这是为了解决此处描述的常量问题: http://www.cygwin.com/ml/cygwin/2004-09/msg01101.html

通常,“自动导入”可以“正常工作”,但有时您可能会看到以下消息:

“变量 '<var>' 无法自动导入。请阅读 ld 的“--enable-auto-import”的文档以获取更多信息。”

当某些(子)表达式访问最终由两个常量之和给出的地址时,会发生此消息(Win32 导入表仅允许一个)。这可能发生的情况包括访问从 DLL 导入的结构变量的成员字段,以及使用常量索引访问从 DLL 导入的数组变量。任何多字变量(数组、结构体、长长型等)都可能触发此错误条件。但是,无论违规的导出变量的确切数据类型如何,ld 始终会检测到它,发出警告并退出。

有几种方法可以解决此问题,无论导出变量的数据类型如何:

一种方法是使用 --enable-runtime-pseudo-reloc 开关。这会将调整客户端代码中引用的任务留给运行时环境,因此只有当运行时环境支持此功能时,此方法才有效。

第二种解决方案是强制其中一个“常量”成为变量——也就是说,在编译时是未知的且无法进行优化。对于数组,有两种可能性:a) 将索引(数组的地址)设为变量,或者 b) 将“常量”索引设为变量。因此:

extern type extern_array[];
extern_array[1] -->
{ volatile type *t=extern_array; t[1] }

或者

extern type extern_array[];
extern_array[1] -->
{ volatile int t=1; extern_array[t] }

对于结构体(以及大多数其他多字数据类型),唯一选择是使结构体本身(或者长长型,或者……)变为变量:

extern struct s extern_struct;
extern_struct.field -->
{ volatile struct s *t=&extern_struct; t->field }

或者

extern long long extern_ll;
extern_ll -->
{ volatile long long * local_ll=&extern_ll; *local_ll }

第三种处理此问题的方法是放弃对违规符号的“自动导入”,并使用“__declspec(dllimport)”对其进行标记。但是,在实践中,这需要使用编译时 #define 来指示您是构建 DLL、构建将链接到 DLL 的客户端代码,还是仅构建/链接到静态库。在选择解决“具有常量偏移量的直接地址”问题的各种方法时,您应该考虑典型的实际用法。

原始代码:

--foo.h
extern int arr[];
--foo.c
#include "foo.h"
void main(int argc, char **argv){
printf("%d\n",arr[1]);
}

解决方案 1:

--foo.h
extern int arr[];
--foo.c
#include "foo.h"
void main(int argc, char **argv){
/* 此解决方法适用于 win32 和 cygwin;请勿进行“优化” */
volatile int *parr = arr;
printf("%d\n",parr[1]);
}

解决方案 2:

--foo.h
/* 注意:假定自动导出(没有 __declspec(dllexport)) */
#if (defined(_WIN32) || defined(__CYGWIN__)) && \
!(defined(FOO_BUILD_DLL) || defined(FOO_STATIC))
#define FOO_IMPORT __declspec(dllimport)
#else
#define FOO_IMPORT
#endif
extern FOO_IMPORT int arr[];
--foo.c
#include "foo.h"
void main(int argc, char **argv){
printf("%d\n",arr[1]);
}

第四种避免此问题的方法是重新编写您的库,以便使用函数接口,而不是针对有问题的变量使用数据接口(例如,set_foo() 和 get_foo() 访问函数)。

--disable-auto-import
不要尝试对来自 DLL 的“\_symbol”到“\_\_imp\_\_symbol”进行复杂的链接,用于 DATA 导入。 [此选项仅适用于针对 i386 PE 的链接器]

--enable-runtime-pseudo-reloc
如果您的代码包含 --enable-auto-import 部分中描述的表达式,即,来自具有非零偏移量的 DLL 的 DATA 导入,则此开关将创建一个“运行时伪重定位”向量,该向量可由运行时环境用于调整客户端代码中对此数据的引用。 [此选项仅适用于针对 i386 PE 的链接器]

--disable-runtime-pseudo-reloc
不要为来自具有非零偏移量的 DLL 的 DATA 导入创建伪重定位。 [此选项仅适用于针对 i386 PE 的链接器]

--enable-extra-pe-debug
显示与自动导入符号转换相关的其他调试信息。 [此选项仅适用于针对 i386 PE 的链接器]

--section-alignment
设置节对齐方式。内存中的节始终从该数字的倍数地址开始。 默认值为 0x1000。 [此选项仅适用于针对 i386 PE 的链接器]

--stack reserve
--stack reserve,commit
指定要为该程序保留(并可选地提交)的内存字节数,用作堆栈。 默认值为保留 2MB,提交 4KB。 [此选项仅适用于针对 i386 PE 的链接器]

--subsystem which
--subsystem which:major
--subsystem which:major.minor
指定程序将执行的子系统。 which 的有效值为“native”、“windows”、“console”、“posix”和“xbox”。 您还可以选择设置子系统版本。 也可以接受 which 的数字值。 [此选项仅适用于针对 i386 PE 的链接器]

以下选项设置 PE 文件标头中“DllCharacteristics”字段中的标志:
[这些选项仅适用于针对 PE 的链接器]

--high-entropy-va
--disable-high-entropy-va

映像与 64 位地址空间布局随机化 (ASLR) 兼容。此选项默认针对 MinGW 目标的 64 位 PE 映像启用。

此选项还意味着启用 --dynamicbase--enable-reloc-section

--dynamicbase
--disable-dynamicbase

映像的基础地址可以使用地址空间布局随机化 (ASLR) 进行重新定位。此功能是在面向 i386 PE 目标的 MS Windows Vista 中引入的。此选项默认针对 MinGW 目标启用,但可以通过 --disable-dynamicbase 选项禁用。此选项还意味着启用 --enable-reloc-section

--forceinteg
--disable-forceinteg

强制执行代码完整性检查。此选项默认禁用。

--nxcompat
--disable-nxcompat

映像与数据执行保护 (DEP) 兼容。此功能是在面向 i386 PE 目标的 MS Windows XP SP2 中引入的。此选项默认针对 MinGW 目标启用。

--no-isolation
--disable-no-isolation

虽然映像了解隔离,但不要隔离映像。此选项默认禁用。

--no-seh
--disable-no-seh

映像不使用 SEH。不允许从此映像调用任何 SE 处理程序。此选项默认禁用。

--no-bind
--disable-no-bind

不要绑定此映像。此选项默认禁用。

--wdmdriver
--disable-wdmdriver

驱动程序使用 MS Windows 驱动程序模型。此选项默认禁用。

--tsaware
--disable-tsaware

映像了解终端服务器。此选项默认禁用。

--insert-timestamp
--no-insert-timestamp

在映像中插入真实的日期戳。这是默认行为,因为它与旧代码匹配,并且意味着映像可以与其他专有工具一起工作。此默认设置的问题是,每次从相同的源代码链接时,都会生成略有不同的映像。可以使用 --no-insert-timestamp 选项插入零值作为日期戳,从而确保从相同的源代码生成的二进制文件将完全相同。

如果激活了 --insert-timestamp,则插入的时间是链接发生的时间,或者,如果定义了“SOURCE_DATE_EPOCH”环境变量,则为该变量指定的自 Unix 纪元以来的秒数。

--enable-reloc-section
--disable-reloc-section

创建基本重定位表,如果映像加载的基础地址与 PE 标头中指定的地址不同,则这是必需的。此选项默认启用。

C6X uClinux 目标使用一种称为 DSBT 的二进制格式来支持共享库。系统中的每个共享库都需要具有唯一的索引;所有可执行文件都使用索引 0。

--dsbt-size size

此选项设置当前可执行文件或共享库的 DSBT 中条目的数量为 size。默认情况下,创建包含 64 个条目的表。


--dsbt-index index

此选项将当前可执行文件或共享库的 DSBT 索引设置为 index。默认值为 0,适用于生成可执行文件。如果使用 DSBT 索引为 0 生成共享库,则会将“R_C6000_DSBT_INDEX”重定位项复制到输出文件中。

--no-merge-exidx-entries

此开关会禁用帧展开信息中相邻 exidx 条目的合并。

--branch-stub

此选项通过在需要时插入分支 stub 部分来启用链接器分支放松,以扩展分支的范围。此选项通常不需要,因为 C-SKY 支持可访问完整内存范围的跳转和调用指令,并且通常由编译器或汇编器处理分支放松。

--stub-group-size=N

此选项允许更精细地控制链接器分支 stub 的创建。它设置可以由单个 stub 部分处理的输入部分组的最大大小。N 的负值将 stub 部分放置在其分支之后,而正值允许 stub 部分出现在分支之前或之后。值为 1 或 -1 表示链接器应选择合适的默认值。

68HC11 和 68HC12 链接器支持特定的选项,用于控制内存银行切换映射和跳转代码生成。

--no-trampoline

此选项禁用跳转代码的生成。默认情况下,对于使用“jsr”指令调用的每个远函数,都会生成一个跳转代码(当获取指向远函数的指针时)。

--bank-window name

此选项指示链接器 MEMORY 规范中描述内存银行窗口的内存区域的名称。然后,链接器将使用此区域的定义来计算分页和内存窗口内的地址。

以下选项支持控制链接到 68K 目标平台时 GOT 生成的处理。

--got=type

此选项告诉链接器使用哪种 GOT 生成方案。type 应该是 single、negative、multigot 或 target 中的一个。有关更多信息,请参阅 ld 的 Info 条目。

以下选项支持控制链接到 MIPS 目标平台时微 MIPS 指令生成和 ISA 模式转换的分支重定位检查。

--insn32
--no-insn32

这些选项控制链接器生成代码中使用的微 MIPS 指令的选择,例如 PLT 或延迟绑定 stub 中,或在放松过程中使用的指令。如果使用 --insn32,则链接器仅使用 32 位指令编码。默认情况下,或者如果使用 --no-insn32,则使用所有指令编码,包括 16 位编码。

--ignore-branch-isa
--no-ignore-branch-isa

这些选项控制无效 ISA 模式转换的分支重定位检查。如果使用 --ignore-branch-isa,则链接器接受任何分支重定位,并且在重定位计算中会丢失任何所需的 ISA 模式转换,除了某些“BAL”指令,这些指令满足放松条件,并被转换为等效的“JALX”指令,因为相关的重定位是计算出来的。默认情况下,或者如果使用 --no-ignore-branch-isa,则会进行检查,导致 ISA 模式转换的丢失会产生错误。


--compact-branches
--no-compact-branches

这些选项控制链接器在 PLT 条目中生成紧凑指令,用于 MIPS R6。

对于 pdp11-aout 目标,可以生成三种输出格式,通过以下选项选择。对于 pdp11-aout 目标,默认变体是 --omagic 选项,而对于其他目标,默认变体是 --nmagic。--imagic 选项仅定义用于 pdp11-aout 目标,而其他选项在这里描述它们如何应用于 pdp11-aout 目标。

-N
--omagic

在 a.out 标头中将输出标记为“OMAGIC”(0407),以指示文本段不应进行写保护和共享。由于文本和数据部分都可读且可写,因此数据部分会立即分配在文本段之后。这是 PDP11 可执行程序的较旧格式,也是 PDP11 Unix 系统从最初到 2.11BSD 中 ld 的默认格式。

-n
--nmagic

在 a.out 标头中将输出标记为“NMAGIC”(0410),以指示当执行输出文件时,文本部分将为只读,并且所有执行相同文件的进程之间共享。这涉及到将数据区域移动到文本结尾后的第一个可能的 8K 字节页边界。此选项创建纯可执行格式。

-z
--imagic

在 a.out 标头中将输出标记为“IMAGIC”(0411),以指示当执行输出文件时,程序文本和数据区域将加载到单独的地址空间中,使用更大的 PDP11 型号的内存管理单元中的拆分指令和数据空间功能。这会将程序可用的地址空间加倍。文本段再次为纯文本、写保护且可共享。与此选项和其他选项之间的输出格式的唯一区别(除了魔术数字之外)是,文本部分和数据部分都从位置 0 开始。-z 选项在 2.11BSD 中选择了此格式。此选项创建单独的可执行格式。

--no-omagic

对于 pdp11-aout,与 --nmagic 等效。

环境变量

您可以使用环境变量“GNUTARGET”、“LDEMULATION”和“COLLECT_NO_DEMANGLE”来更改 ld 的行为。

“GNUTARGET”确定输入文件的对象格式,如果您不使用 -b(或其同义词 --format)。它的值应该是 BFD 中输入格式的名称之一。如果环境中没有“GNUTARGET”,则 ld 使用目标的自然格式。如果将“GNUTARGET”设置为“default”,则 BFD 会尝试通过检查二进制输入文件来发现输入格式;这种方法通常会成功,但存在潜在的歧义,因为没有一种方法可以确保用于指定对象文件格式的魔术数字是唯一的。但是,每个系统上 BFD 的配置过程会将该系统的传统格式放在搜索列表的开头,因此歧义将通过支持约定来解决。

“LDEMULATION” 确定了如果不使用 -m 选项时的默认仿真。仿真会影响链接器的各种行为,特别是默认链接器脚本。您可以使用 --verbose 或 -V 选项列出可用的仿真。如果未使用 -m 选项,并且未定义 “LDEMULATION” 环境变量,则默认仿真取决于链接器的配置方式。

通常,链接器会默认对符号进行去混淆。但是,如果环境中设置了“COLLECT\_NO\_DEMANGLE”,那么它将默认不进行符号去混淆。此环境变量由“gcc”链接器包装程序以类似的方式使用。可以通过 --demangle 和 --no-demangle 选项覆盖默认设置。

如果 PE/COFF 特定的 --insert-timestamp 选项已激活,并且定义了 SOURCE\_DATE\_EPOCH 环境变量,则此变量中的时间戳值将被插入到 COFF 标头中,而不是使用当前时间。

如果定义了“LD\_STATS”环境变量,则链接器资源使用信息将被记录下来,就像使用了 --stats 选项一样。如果“LD\_STATS”变量具有字符串值,则该值将用作存储信息的文件的名称。否则,信息将发送到标准输出流。

参见

ar(1), nm(1), objcopy(1), objdump(1), readelf(1) 以及 binutils 和 ld 的 Info 条目。

版权

版权所有 (c) 1991-2025 自由软件基金会。

允许根据 GNU 自由文档许可协议,版本 1.3 或由自由软件基金会发布的任何更高版本,复制、分发和/或修改本文档;不包含不变部分,不包含封面文字,也不包含封底文字。许可协议的副本包含在名为“GNU 自由文档许可协议”的部分中。