添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

个人笔记,仅供参考!!

Command-line Options

链接器支持大量的命令行选项,但在实践中,仅有很少的选项可以在任意上下文中使用。
ld 的一个常用用法是在一个受支持的标准Unix系统上,链接标准Unix对象文件。

ld 中的一些命令行选项可以在命令行中的任何位置指定。但是,引用文件的选项,如’-l’或’-T’,会导致在命令行出现该选项时读取文件(相对于目标文件和其它文件选项)。使用不同的参数重复非文件选项,可能没有实际效果也可能会覆盖前面出现的该选项。
那些多次指定,可能具有实际意义的选项,将在下面的描述中注明。

非选项参数是要链接在一起的目标文件或归档文件 。它们可以跟在命令行选项后面、前面,也可以与命令行选项混合在一起,但是对象文件参数(指目标文件或归档文件)不能放在选项和它的参数之间。

通常使用至少一个对象文件来调用链接器,但可以’-l’,’-R’和脚本命令语言指定其它形式的二进制输入文件。如果没有指定任何二进制输入文件,链接器不会产生任何输出,并发出消息’no input files’。

如果链接器不能识别目标文件的格式,它将假定它是一个链接器脚本。以这种方式指定的脚本,增强了用于链接的主链接器脚本(默认链接器脚本,或使用’-T’指定的链接器脚本)。这个特性允许链接器链接到一个看起来是对象或存档的文件,但实际上只是定义了一些符号值,或使用INPUT或GTROUP来加载其它对象。以这种方式指定一个链接脚本只是增强了主链接器脚本,即在主脚本之后放置了额外的命令。

对于名称为单个字母的选项,选项参数可以紧跟选项字母且不加空格,或者作为单独的参数紧跟在需要它们的选项后面。例如:
-o outputfile 等价于 -ooutputfile,它们的作用都是将输出文件名设置为outputfile

对于名称由多个字母组成的选项,可以在选项名称前加一个或两个波折号;例如,’-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 (向链接器传递选项 –start-group 和 –end-group 并且选项参数为foo.o bar.o。 这个选项是用来处理链接过程中两个库间相互引用的问题 )
这一点很重要,否则编译器驱动程序可能会静默地丢弃链接器选项,从而导致错误的链接。当通过驱动程序传递需要值的选项时,也可能存在混淆,因为在选项和参数之间使用空格作为分隔符,导致驱动程序可能仅将选项传递给链接器并将参数传递给编译器。为了避免这种情况,最简单的方法是使用单字母和多字母的连接形式,例如:
gcc foo.o bar.o -Wl,-eENTRY -Wl,-Map=a.map (向链接器传递选项 -e 参数为 ENTRY,传递选项-map 参数为 a.map)

下面是 GUN 链接器接受的通用命令行选项:

@file

该选项用来告诉链接器从指定文件(file)中读取链接器的选项和参数。一般用于将大量的链接选项及参数放在一个文件中,然后在命令行中引用这个文件,使命令行更简洁,便于管理。
file中的选项以空格分隔,通过将整个选项用单引号或双引号括起来,可以将空白字符包含在其中。文件内容中可以包含额外的@file选项,会自动被链接器递归处理。
例如: ld @linker_options.txt
linker_options.txt的内容为:

1
2
3
4
5
6


--verbose
-o output.elf
section1.o
section2.o
-b input-format && –format=input-format

这两个选项用来指定特定的二进制格式。当需要链接某种特定的二进制格式文件时,可以在特定格式的每组目标文件前使用 -b input-format 来明确切换二进制格式。(objdump -i 命令可以查看支持的二进制格式。通常不需要特殊指定该选项,因为ld通常会被配置机器上最常用的格式作为默认输入格式。)

-c MRI-commandfile && –mri-script=MRI-commandfile

该选项是为了兼容MRI链接器使用的链接脚本,方便用户从MRI链接器过渡到GUN连接器。如果MRI-commandfile不存在,链接器会从 ‘-L’ 选项指定的目录中检索它。

-r && –relocatable**

生成可重定位的输出。即生成一个输出文件,该输出文件又可以作为 ld 的输入。通常称为部分链接。例如:

1
ld -r a.o b.o -o output.o

在支持标准Unix魔数的环境中,输出文件的魔数会被设置为OMAGIC(告诉系统,这是一个可重定位的对象文件,而不是一个绝对可执行文件)。

-i

执行增量链接,作用与 -r 选项相同。

-d && -dc && -dp

这三个选项是等价的,定义了三个是为了和其它链接器兼容。设置该选项后,即使指定了可重定位的输出文件(使用了’-r’)链接器也会为公共符号(common symbols)分配空间。
关于common symbols,大致是为了应对多个独立编译单元均声明了同一个名称的未初始化变量的情况(参考:
All about COMMON symbols 以及 bss vs COMMON: what goes where?

–depaudit AUDITLIB && -P AUDITLIB

该选项表示将AUDITLIB添加到动态段(包含了程序运行时所需的动态链接信息)的DT_DEPAUDIT条目中。可以通过多次使用该选项来指定多个审计接口,它们会以冒号分割的形式列在DT_DEPAUDIT中。该选项仅适用于支持rtld-audit接口的ELF平台(rtld-audit是一种用于动态链接库的接口,用于执行运行时的审计和跟踪)。-P 选项是为了与Solaris系统兼容。

–enable-linker-version

该选项用于使能链接版本信息插入。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* 在 .text 段之后插入链接器版本信息 */
SECTIONS {
. = 0x1000; /* 设置当前位置为地址 0x1000 */
.text : {
/* 这里放置你的代码 */
*(.text) /* 将所有 .text 段的内容放在这里 */
}
/* 插入链接器版本信息 */
.version : {
BYTE(0) /* 一个空字节,用于分隔版本信息 */
/* 这里是链接器版本信息 */
BYTE(LINKER_VERSION)
}
}

当启用该选项后,链接器在链接过程中会将链接器版本信息(LINKER_VERSION会被替换为实际版本信息)插入到.version段中。

–disable-linker-version:

禁用连接器的LINK_VERSION指令,这样连接器就不会在连接过程中插入版本字符串信息。

–enable-non-contiguous-regions:

该选项的作用,是让链接器在输入段找不到匹配的输出段时,避免发生错误。链接器会尝试将输入部分分配给后续匹配的输出部分,并仅在没有足够大的输出段可以放输入段时,才生成错误。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
}

with input sections:
.data.1: size 8
.data.2: size 0x10
.data.3: size 4

results in .data.1 affected to mem1, and .data.2 and .data.3
affected to mem2, even though .data.3 would fit in mem3.

上面的例子中,虽然第三个输入段.data.3可以适配到MEM3中,但由于链接器尝试将输入段分配给后续的适配的输出段,因此.data.3被分配给了MEM2,这是因为MEM2是第一个足够大的输出段。

注意 :该选项与链接脚本中的INSERT语句不兼容,例如下面的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
SECTIONS {
.text : {
*(.text)
}
.data : {
*(.data)
}
.rodata : {
*(.rodata)
}
INSERT : {
/* 插入自定义节 */
my_custom_section
}
.bss : {
*(.bss)
}
}

假设存在以下输入段:
.text : { ... } /* 输入的.text节 */
.data : { ... } /* 输入的.data节 */
.rodata : { ... } /* 输入的.rodata节 */
.bss : { ... } /* 输入的.bss节 */
.my_custom_section : { ... } /* 输入的自定义节 */

当启用 –enable-non-contiguous-regions 选项后,链接器在将输入段分配到输出段时,自定义节可能会被链接器放置在任何合适的输出段中,这导致自定义节的位置可能与插入语句指定的位置不一致。

–enable-non-contiguous-regions-warnings:

开启 --enable-non-contiguous-regions 选项后,可能存在输入段被放置在了不符合预期的位置上,或者某些内容被丢弃,导致结果与预期不符合。在启用了 --enable-non-contiguous-regions-warnings 选项后,链接器会产生警告提醒开发者这种潜在问题。等于是在 --enable-non-contiguous-regions 真实生效后(输入段受该选项影响,被放到了一些非预期段中,这种行为可能存在问题,也可能并不影响连接生成的可执行程序),链接器会发出警告,提醒开发者检查确认链接器所做的链接行为是否存在问题。

-e entry && –entry=entry:

该选项用于设定程序入口(第一条执行的指令)。如果链接器没有找到名为 entry 的符号,则链接器会将 entry 解释为数值并作为程序的入口地址(默认解释为10进制,16进行需要使用’0x’前缀,8进制需要使用’0’)。
对于程序入口的设定,链接器会依次尝试下面几种方法,直到找到一个匹配的:

  • 链接命令中使用 -e 选项来指定
  • 链接脚本中通过ENTRY(symbol)来指定
  • 使用目标特定的符号值(如果定义了的话)。对许多目标来说,这个符号通常是 start
  • 如果存在代码段,并且正在创建一个可执行文件,则使用代码段的第一个字节的地址作为程序入口。通常情况下,代码段是 .text
  • 0作为入口地址。
  • –exclude-libs lib,lib,…

    该选项用于指定一组库,它们的符号不会被自动导出。其中,库名称使用逗号或冒号进行分割。如果指定了 --exclude-libs ALL ,所有库中的符号都不会被自动导出。该选项一般用来:

  • 避免符号冲突:同时使用了多个库,某些库中可能使用了相同名称的函数或变量,通过排除某些库中符号的自动导出,可以避免冲突。
  • 隐藏实现细节:过排除这些库中的符号自动导出,可以防止其他模块或者程序直接使用这些函数或变量。
  • (如果排除了某个库中的符号自动导出,但是又需要使用该库中的一些函数,可以将这些函数放到.def文件中让其可以导出(linux下可用?),也可以在函数定义处添加 __attribute__((visibility("default"))) 让其默认可见。)
    (感觉这个选项的作用,更多的是对库中非对外的函数进行屏蔽,这些内部函数命名,可能不同库中存在相同的名字。)

    -E && –export-dynamic && –no-export-dynamic:

    -E 或 –export-dynamic 选项会让链接器将所有符号添加到动态符号表中,这两个选项会将所有符号暴漏给动态链接的对象。如果不使用-E 或 –export-dynamic选项(或者使用–no-export-dynamic恢复默认行为),则动态符号表通常只包含链接中使用的共享库的符号,而不包含程序自身定义的符号。(例如,你的程序加载了一个共享库 libfoo.so ,而这个共享库中的某些函数需要调用你的程序中的一些函数,那么就需要在编译时使用-E 或 –export-dynamic选项,以便将程序自身的符号添加到动态符号表中,使得libfoo.so可以正确地调用这些函数。)

    –export-dynamic-symbol=glob

    1:在创建动态链接的可执行文件时,与通配符模式 glob 匹配的符号会被添加到动态符号表中。动态符号表是在运行时对其他动态对象可见的符号集合,即这些符号可以被动态加载的其它共享库访问到。
    2:创建共享库时使用该选项,则与通配符模式 glob 匹配的符号引用不会被静态绑定到该共享库内部的定义,这些符号会被添加到动态符号表中,并在运行时动态解析。(如果一个共享库中的某些符号希望能被其它共享库使用(使用而不是引用),那么这些符号不能被静态的绑定到当前共享库的定义)。注意,当创建共享库时,如果没有指定 -Bsymbolic 或 –dynamic-list,则该选项不会起作用。
    该选项仅对支持共享库的ELF平台有意义。

    –export-dynamic-symbol-list=file

    该选项用于从指定的文件中读取模式,文件中的每一行都是一个模式。该选项的作用是方便地从文件中批量指定需要导出的符号模式,而不必在命令行中逐个指定。例如:
    假设存在一个名为 symbols.txt 的文件,内容为:

    1
    2
    foo_*
    bar_*

    链接时,使用:ld –export-dynamic-symbol-list=symbols.txt …
    则文件中所列的每个模式都会被解析为一个 –export-dynamic-symbol 选项。

    -EB:

    该选项用于在链接时指定生成 大端 字节序的输出文件。

    -EL:

    该选项用于在链接时指定生成 小端 字节序的输出文件。

    -f name && –auxiliary=name :

    该选项用于创建 ELF 共享对象时,设置内部的 DT_AUXILIARY 字段为指定的名称。DT_AUXILIARY 字段告诉动态链接器,共享对象的符号表应该作为共享对象name(这里指name表示的共享对象)的辅助过滤器。举例:

    1
    ld -shared -o A.so --auxiliary=B.so A.o

    在创建共享对象 A.so 时,指定了 --auxiliary=B.so 。则当共享对象 A.so 被程序动态链接时,当动态链接器需要解析任何 A.so 中的符号时,它将首先检查 B.so 是否存在该符号的定义。如果存在,它将使用 B.so 中的定义,如果不存在才使用 A.so 中的定义。

    因此,name表示的共享对象可用于提供某些功能的替代实现,可能用于调试或特定于机器的高性能实现。

    -F name && –filter=name
    1
    ld -shared -o A.so -F=B.so A.o

    与–auxiliary=name 类似,区域在于:在创建共享对象 A.so 时,指定了 --filter=B.so 。则当共享对象 A.so 被程序动态链接时,当动态链接器需要解析任何 A.so 中的符号时, 它总是在 B.so 中查找该符号的定义。(如果找不到,链接器会继续查找命令行中指定的其它共享对象,直到找到符号的定义或者报告符号未解析错误。即与–auxiliary=name相比,链接器不会回退到使用 A.SO 中的定义)
    参考
    https://docs.oracle.com/cd/E23824_01/html/819-0690/chapter4-4.html

    -fini=name

    该选项用于在创建ELF可执行文件或共享对象时,指定它被卸载时调用的函数。该选项会将 DT_FINI 设置为指定函数(name)的地址。默认情况下,链接器会使用 -fini 作为要调用的函数名。
    该选项可以用来在可执行文件或共享对象被卸载时,执行一些清理工作。

    -g

    该选项是用来兼容其它工具的。例如,在Solaris的链接器中, -g 选项用来指示链接器将调试信息放在输出文件中。然而,在 GUN ld 中,调试信息处理通常由编译器来完成,而不是链接器。因此 -g 在GUN ld 中被忽略。

    -G value && –gpsize=value

    该选项仅适用于MIPS ELF等支持将大型和小型对象放置在不同节中的目标文件格式。该选项用来设置可以使用全局指针寄存器(GP)进行优化的对象的最大大小。
    备注:在MIPS架构中,由于架构的特殊性,对于较大的全局变量或静态变量,寄存器无法直接寻址。为了处理这种特殊的情况,需要使用特殊的加载指令来加载数据,这会导致额外的指令和性能开销。为了优化性能,MIPS ELF可以将其中相对较小的全局变量和静态变量放置在一个可以通过全局寄存器直接寻址的节中。然后,只有较大的对象才需要额外的指令来加载数据。通过 -G 选项,可以设置一个值,告诉连接器只有大小小于或等于该值的对象,才会被放置在可以通过GP直接寻址的段中,而其它更大的对象则会采用其它方式来访问。(-G 设置过大,可能导致一些很大的只读变量被放到了 可读写的GP直接寻址段中,可能会浪费内存)

    -h name && -soname=name

    当创建elf共享库,并使用该选项时,会将该共享库内的 DT_SONAME 字段设置为 name
    当可执行文件与具有 DT_SONAME 字段的共享库链接后,当可执行文件运行时,动态链接器将尝试加载由 DT_SONAME 字段指定的共享库,而不是创建可执行文件时给连接器的共享库名。
    soname通常用于提供版本向后兼容信息,例如版本1.0到1.9的共享库 libx 提供了相同的API,那么它们可以设置相同的soname,例如 libx.so.1
    如果创建可执行文件 APP 时,链接的共享库为 libx.so.1.2 (其soname为 libx.so.1 ),但系统当前只包含了该共享库的 1.3版本 libx.so.1.3 。那么系统可以使用 libx.so.1.3 来替代最初的 libx.so.1.2 。(前缀匹配?)参考
    https://en.wikipedia.org/wiki/Soname

    -init=name

    该选项用于在创建ELF可执行文件或共享对象时,设置 DT_INIT 为函数(name)的地址,使elf或共享对象被加载时,调用该指定的函数。默认情况下,链接器使用 _init 作为加载时调用的函数。

    -l namespec && –library=namespec

    该选项用于将指定的库添加到链接的文件列表中。 该选项可以被使用多次
    如果namespec的形式为 :filename ,链接器会在库路径中搜索名为 filename 的库,否则链接器会在库路径中搜索名为 libnamespec.a 的库。例如:

    1
    2
    3
    ld -o output_file main.o -l:custom_library.a  # 搜索custom_library.a 库文件

    ld -o output_file main.o -lfoo # 搜索libfoo.a 库文件

    此外,在支持共享对象的系统中,例如,在支持ELF可执行文件的系统中,链接器在搜索名为libnamespec.a的库之前,会先搜索名为libnamespec.so的库(该规则不适用于:filename格式,该格式总是用于指定名为filename的文件)。

    需要注意的是,链接器只会在命令行中指定该库的位置搜索一次库。
    如果库中定义了在命令行上在它之前的某个对象中未定义的符号,链接器将包含库中的适当文件。但是,在命令行上它之后出现的对象中的未定义符号不会导致链接器再次搜索该库(保证了链接器对每个库只会搜索一次,以提高链接效率)。
    如果需要强制连接器多次搜索该库,可是使用 -( 选项
    这种库的搜索方式是Unix链接器的标准,在AIX上使用的ld与这里所说的行为不同。

    -L searchdir && –library-path=searchdir
    将目录 searchdir 添加到链接器的库和控制脚本搜索路径列表中。该命令可以使用多次。目录按它们在命令行中指定的顺序进行搜索,这些命令行中指定的目录会在默认目录之前进行搜索。
    如果指定的路径以 = $SYSROOT 开头,那么这些前缀会被替换为系统根目录前缀(系统根目录前缀由 --sysroot 选项控制,或在链接器配置时指定)。

    -m emulation
    该选项用于指定链接器要模拟的仿真模式。在链接时,不同的操作系统或硬件平台可能需要使用不同的链接器仿真模式。如果没有使用 -m 选项,链接器会尝试从环境变量 LDEMULATION 中获取仿真模式,如果该环境变量也没定义,则会使用默认仿真模式(链接器配置时确定的)。
    备注:“仿真模式”是指链接器在链接时模拟的目标系统或硬件平台的环境。在编译和链接过程中,链接器需要知道要生成的可执行文件或库文件将要在哪种操作系统或硬件架构上运行,以便正确地生成与目标环境兼容的输出文件(能在目标环境上运行)。

    –remap-inputs=pattern=filename && –remap-inputs-file=file:
    该选项用于在链接器尝试打开输入文件之前更改它们的名称。例如, --remap-inputs=foo*.o=bar.o 会导致链接器在试图加载任何匹配 foo*.o 模式的输入文件时,实际上会加载 bar.o 文件。
    --remap-inputs-file=file 允许从文件中读取替换规则。文件中的每一行包含一个替换规则。空行被忽略, # 开始的行为注释,映射模式与文件名之间可以用空格或 = 分割。
    这两个选项可以使用多次,其内容会累积。替换规则会按照它们在命令行中出现的顺序进行处理,一旦找到了匹配的规则,就不会再进一步检查。
    如果替换的文件名是 /dev/null NULL ,则该规则实际上会导致输入文件被忽略(方便从复杂的构建环境中移除输入文件)。
    需要注意,该选项是位置相关的,只会影响其后出现的文件名,例如:

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

    不会产生效果,而

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

    会导致输入文件 foo.o 被替换为 bar.o

    此外,该选项也会影响到连接脚本中 INPUT 语句引用的文件(也会应用替换规则)。

    -M && –print-map
    该选项将链接映射打印到标准输出。包含符号在内存的地址、符号大小等信息。

    -Map=mapfile
    同上,将链接映射输出到文件中保存。如果 mapfile - ,表示输出到标准输出。

    –print-map-discarded && –no-print-map-discarded
    选项 --print-map-discarded 为默认开启的,它会在链接映射过程中打印被丢弃的链接段信息。该选项提供了对链接过程中丢弃段的可视化,以便开发人员了解哪些部分被丢弃了。
    如果使用 --no-print-map-discarded 选项,则链接器不会输出丢弃的节信息。

    –print-map-locals && –no-print-map-locals
    --print-map-locals 该选项启动时,链接器将在链接映射中打印局部符号(局部符号在其名称前有local标识)。以便了解在链接过程中使用的所有符号,包括全局和局部范围的符号。
    --no-print-map-locals 该选项为默认配置,链接器不会在链接映射中打印局部符号,有助于简化输出信息。

    -n && –nmagic :
    该选项用于关闭段对齐,并禁止链接到共享库。如果输出格式支持Unix风格的魔数,链接器会将输出标记为 NMAGIC (标记为 NMAGIC 表示对象文件不可重定位,是一个绝对可执行文件,是已经经过链接和地址解析,可以直接运行的)。

    -N && –omagic
    该选项用于将文本和数据段设置为可读可写。此外,还会关闭数据段的页面对齐功能,并禁止链接到共享库。如果输出格式支持Unix风格的魔数,则输出文件被标记为OMAGIC。

  • 通常情况下,程序的文本和数据段是可读的,以确保程序的安全性和稳定性。使用该选项后,这些段被设置为可读可写,使得程序可以修改自身的代码和数据(这里应该是指的生成的可执行文件中的数据段可写,当程序被加载运行后,操作系统一般会将数据段设置为可读)。
  • 标记为OMAGIC的可执行文件,是可重定位的(例如多个目标文件和库链接在一起,但没有完全链接),可以进一步与其它对象文件链接以生成最终可执行文件。

    –no-omagic
    该选项是对 -N 选项一些特性的反作用。具体来说:

  • 将文本段设置为只读,有助于提高程序的安全和稳定性。
  • 强制数据段进行页面对齐,有助于提高程序加载速度。
  • 该选项也会设置链接器不链接共享库。(使用 -Bdynamic 来启用链接共享库)
  • -o output && –output=output :
    用来指定链接后的输出文件名为 output 。如不指定,默认产生 a.out 。此外,脚本文件中也可以通过命令OUTPUT来指定输出文件。

    –dependency-file=depfile
    该选项的作用是生成一个依赖文件,其中描述了生成输出文件所需的所有输入文件的规则。(生成的这个依赖文件,可以用于构建系统快速识别依赖文件的修改,提高构建效率)

    -O level
    该选项用于控制链接器的优化级别,目前该选项只影响 ELF 共享库的生成。例如,连接器可能会对共享库中的符号进行分析,识别出一些没有使用的函数,然后将这些无用的函数从最终的共享库中剔除掉,减小共享库的大小。

    注意 该选项与编译器选项中 -O 的区别,编译器选项 -O 用来控制编译器的优化级别,通过代码内联、循环展开、常量折叠等优化技术来改善生成目标代码的性能/大小。这些优化技术应用于 源代码到目标代码的转换过程 。而连接器中的该选项应用于生成最终的可执行文件或共享库。

    -plugin name
    该选项可以用来指定链接过程中使用的插件。

    –push-state && –pop-state :
    这两个选项的作用是保存和恢复链接器的状态。在链接过程中,可能会涉及到一系列标志选项来控制输入文件的处理方式,如静态链接、动态链接等。使用 --push-state 可以将当前的这些标志选项状态保存起来,而使用 --pop-state 可以将之前保存的状态恢复,以便后续的操作继续使用这些标志状态。
    实际使用中,可能一些文件需要使用多个标志选项,当处理后续不需要这些标志选项的输入文件时,就可以使用 --push-state ,而后续又碰到需要使用这些标志选项的输入文件时可以再次使用 --push-state 恢复。

    -q && –emit-relocs
    该选项让链接器在生成可执行文件时,保留重定位段和内容。(这些信息对于后续的链接分析和优化工具有用,一些分析工具或优化工具可能会对可执行文件进行修改,以提高性能、减小体积或修复错误,重定位信息能帮助这些工具更精确的了解程序中各个符号的使用方式。)
    该选项仅在ELF平台上支持。

    –force-dynamic:
    该选项针对VxWorks系统,作用是强制使输出文件具有动态段,以确保在VxWorks目标上正确的进行动态链接。
    (动态段包含了与动态链接相关的信息,例如动态链接库的依赖关系、重定位信息等)

    -R filename && –just-symbols=filename :
    该选项会从指定文件中读取符号名和它们的地址,但不会对指定文件进行重定位或将其包含在最终的输出文件中。(通过引用其它程序定义的符号的内存位置,可以在目标输出文件中使用这些符号来访问其它程序的功能或数据,而不必将这些代码或数据包含在目标输出文件中)
    如果 -R 后跟的是目录,链接器会将其视为 -rpath 选项。

    -s && –strip-all
    该选项用于从输出文件中省略所有符号信息(函数名,变量名等)。这样可以减少输出目标文件大小,但会使调试更加困难。

    -S && –strip-debug :
    省略调试器符号信息(源代码行号,局部变量名等),但保留其它符号信息(函数名、变量名等)

    –strip-discarded && –no-strip-discarded
    选项 --strip-discarded 设置后(默认启用),链接器会省略在被丢弃的段(可能是包含未使用的代码或数据的段)中定义的全局符号。而选项 --no-strip-discarded 启用时,链接器会保留在被丢弃的段中定义的全局符号。

    -t && –trace
    启用该选项,链接器在处理输入文件时会打印它们的名称。如果使用了两次 -t (-t -t),链接器会将归档(archives)文件中的成员名称也打印出来。

    -T scriptfile && –script=scriptfile :
    该选项用于指定自定义的链接脚本文件,自定义链接过程。可以使用多次 -T 指定多个文件,链接器会按照顺序依次处理。

    -dT scriptfile && –default-script=scriptfile
    该选项用于指定文件 scriptfile 作为默认链接器脚本。但是该脚本被处理,是在命令行中的其它选项都被处理完后,才会处理该脚本。这意味着,命令行中出现在 –default-script 选项之后的选项和参数会影响到该脚本的行为。

    -u symbol && –undefined=symbol :
    该选项用于强制将符号 symbol 加入到输出文件中作为一个未定义符号。链接器在链接过程中就会尝试在其它的可用库中寻找 symbol 的定义,并将相关的模块链接到最终输出中,以确保程序可以成功编译运行。(例如,有些符号可能是非公开的,不会自动暴露给链接器,通过指定 -u 选项,可以强制告诉链接器要解析这些非公开的符号。)

    –require-defined=symbol
    该选项要求输出文件中必须定义指定的符号 symbol ,类似于 --undefined 选项,但如果链接器在输出文件中找不到指定的符号定义,则会报错并退出。

    -Ur :
    该选项用于生成可重定位的输出文件(输出文件可以再作为链接器的输入文件)。对于不使用构造函数或析构函数的程序,或对于基于ELF的系统,该选项等价于 -r 。对于其它类型的二进制文件, -Ur -r 类似,但它还会解析对构造函数和析构函数的引用。使用 -Ur 选项时,应该确保该选项只用于最后一次的部分链接,而不要用于之前的部分链接(有一些系统中,如果文件本身是使用 -Ur 选项进行链接的,那么在后续的部分链接中,使用 -Ur 选项是无效的。这是因为一旦构造函数表已经构建,就无法再添加了。因此,在这种情况下,应该仅在最后一次的部分链接中使用 -Ur ,而在其他情况下使用 -r

    –orphan-handling=MODE
    该选项用于控制孤立段的处理方式。

  • place:孤立段(输入)会被放到一个适当的输出中,具体策略为:
  •