MOLD(1) | General Commands Manual | MOLD(1) |
mold
— a modern
linker
mold |
[-options ] objfile
... |
mold
is a faster drop-in replacement for
the default GNU ld(1).
mold
mold
is designed to be a drop-in
replacement for the GNU linkers for linking user-land programs. If your
user-land program cannot be built due to missing command-line options,
please file a bug at
https://github.com/rui314/mold/issues.
mold
supports a very limited set of linker
script features, which is just sufficient to read
/usr/lib/x86_64-linux-gnu/libc.so on Linux systems
(on Linux, that file is despite its name not a shared library but an ASCII
linker script that loads a real libc.so file.)
Beyond that, we have no plan to support any linker script features. The
linker script is an ad-hoc, over-designed, complex language which we believe
needs to be disrupted by a simpler mechanism. We have a plan to add a
replacement for the linker script to mold
instead.
Traditionally, Unix linkers are sensitive to the order in which
input files appear on command line. They process input files from the first
(left-most) file to the last (right-most) file one-by-one. While reading
input files, they maintain sets of defined and undefined symbols. When
visiting an archive file (.a
files), they pull out
object files to resolve as many undefined symbols as possible and go on to
the next input file. Object files that weren't pulled out will never have a
chance for a second look.
Due to this semantics, you usually have to add archive files at the end of a command line, so that when a linker reaches archive files, it knows what symbols are remain undefined. If you put archive files at the beginning of a command line, a linker doesn't have any undefined symbol, and thus no object files will be pulled out from archives.
You can change the processing order by
--start-group
and
--end-group
options, though they make a linker
slower.
mold
as well as LLVM
lld(1) linker take a different approach. They memorize
what symbols can be resolved from archive files instead of forgetting it
after processing each archive. Therefore, mold
and
lld(1) can "go back" in a command line to pull
out object files from archives, if they are needed to resolve remaining
undefined symbols. They are not sensitive to the input file order.
--start-group
and
--end-group
are still accepted by
mold
and lld(1) for compatibility
with traditional linkers, but they are silently ignored.
Some Unix linker features are unable to be understood without
understanding the semantics of dynamic symbol resolution. Therefore, even
though that's not specific to mold
, we'll explain it
here.
We use "ELF module" or just "module" as a collective term to refer an executable or a shared library file in the ELF format.
An ELF module may have lists of imported symbols and exported symbols, as well as a list of shared library names from which imported symbols should be imported. The point is that imported symbols are not bound to any specific shared library until runtime.
Here is how the Unix dynamic linker resolves dynamic symbols. Upon the start of an ELF program, the dynamic linker construct a list of ELF modules which as a whole consist of a complete program. The executable file is always at the beginning of the list followed by its depending shared libraries. An imported symbol is searched from the beginning of the list to the end. If two or more modules define the same symbol, the one that appears first in the list takes precedence over the others.
This Unix semantics are contrary to systems such as Windows that have the two-level namespace for dynamic symbols. On Windows, for example, dynamic symbols are represented as a tuple of (symbol-name, shared-library-name), so that each dynamic symbol is guaranteed to be resolved from some specific library.
Typically, an ELF module that exports a symbol also imports the same symbol. Such a symbol is usually resolved to itself, but that's not the case if a module that appears before in the symbol search list provides another definition of the same symbol.
Let me take malloc(3) as an example. Assume that you define your version of malloc(3) in your main executable file. Then, all malloc calls from any module are resolved to your function instead of that in libc, because the executable is always at the beginning of the dynamic symbol search list. Note that even malloc(3) calls within libc are resolved to your definition since libc exports and imports malloc. Therefore, by defining malloc yourself, you can overwrite a library function, and the malloc(3) in libc becomes dead code.
These Unix semantics are tricky and sometimes considered harmful. For example, assume that you accidentally define atoi(3) as a global function in your executable that behaves completely differently from the one in the C standard. Then, all atoi function calls from any modules (even function calls within libc) are redirected to your function instead of the one in libc which obviously causes a problem. That is a somewhat surprising consequence for an accidental name conflict. On the other hand, this semantic is sometimes considered useful because it allows users to overwrite library functions without recompiling modules containing them. Whether good or bad, you should keep this semantic in mind to understand the Unix linkers behaviors.
mold
's output is deterministic. That is,
if you pass the same object files and the same command-line options to the
same version of mold
, it is guaranteed to always
produce the same output. The linker's internal randomness, such as the
timing of thread scheduling or iteration orders of hash tables, doesn't
affect the output.
mold
does not have any host-specific
default settings. This is contrary to the GNU linkers to which some
configurable values, such as system-dependent library search paths, are
hard-coded. mold
depends only on its command-line
arguments.
--chroot
=dir--color-diagnostics
=[auto
|
always
|
never]--color-diagnostics
--no-color-diagnostics
Show diagnostics messages in color using ANSI escape
sequences. auto means that
mold
prints out messages in color only if the
standard output is connected to a TTY. Default is
auto.
--fork
--no-fork
mold
process.
--fork
hides that latency. By default, it does
fork.
--perf
--print-dependencies
Each line of the output for this option shows that which file
depends on which file to use which symbol. This option is useful to
debug why some object file in a static archive got linked or why some
shared library is kept in an output file's dependency list even with
--as-needed
.
-N
,
--omagic
--no-omagic
mold
to emit an output file with an
old-fashioned memory layout. First, it makes the first data segment to not
be aligned to a page boundary. Second, text segments are marked as
writable if the option is given.
--repro
--reverse-sections
This option is useful for finding a bug that depends on an initialization order of global objects. In C++, constructors of global objects in a single source file are guaranteed to be executed in the source order, but there's no such guarantee across compilation units. Usually, constructors are executed in the order given to the linker, but depending on it is a mistake.
By reversing the order of input sections using
--reverse-sections
, you can easily test that
your program works in the reversed initialization order.
--run
command
arg
file ...command
with mold
as
/usr/bin/ld. Specifically,
mold
runs a given command with the LD_PRELOAD
environment set to intercept exec(3) family functions
and replaces argv[0] with itself if it is ld,
ld.gold or ld.lld.
--shuffle-sections
--shuffle-sections
=numberThis option is useful for benchmarking. Modern CPUs are sensitive to program's memory layout. A seeming benign change in program layout (such as a small size increase of a function in the middle of a program) can affect program's performance. Therefore, even if you write new code and get a good benchmark result, it is hard to say whether or not the new code improves the programs performance. It is possible that the new memory layout happens to perform better.
By running a benchmark multiple time with shuffling memory
layout using --shuffle-sections
, you can isolate
your program's real performance number from the randomness caused by
memory layout changes.
--stats
--thread-count
=count--threads
--no-threads
mold
uses as
many threads as the number of cores or 32, whichever is the smallest. The
reason why it is capped to 32 is because mold
doesn't scale well beyond that point. To use only one thread, pass
--no-threads
or
--thread-count
=1.
--quick-exit
--no-quick-exit
quick_exit
to exit.--help
-v
,
--version
-V
-C
dir, --directory
dir-E
,
--export-dynamic
--no-export-dynamic
-E
option
causes all global symbols to be put into the dynamic symbol table, so that
the symbols are visible from other ELF modules at runtime.
By default, or if --no-export-dynamic
is given, only symbols that are referenced by DSOs at link-time are
exported from an executable.
-F
libname,
--filter
=libnameDT_FILTER
dynamic section field to
libname.
-I
file,
--dynamic-linker
=file--no-dynamic-linker
-I
option is given, or if
--no-dynamic-linker
is given, no dynamic linker
path is set to an output file. This is contrary to the GNU linkers which
sets a default dynamic linker path in that case. However, this difference
doesn't usually make any difference because the compiler driver always
passes -I
to a linker.
-L
dir,
--library-path
=dirmold
searches libraries for the -l
option.
Unlike the GNU linkers, mold
does not
have the default search paths. This difference doesn't usually make any
difference because the compiler driver always passes all necessary
search paths to a linker.
-M
,
--print-map
-N
,
--omagic
--no-omagic
mold
to emit an output file with an
old-fashioned memory layout. First, it makes the first data segment to not
be aligned to a page boundary. Second, text segments are marked as
writable if the option is given.
-S
,
--strip-debug
.debug_*
sections from the output file.
-T
file,
--script
=file-X
,
--discard-locals
.L
. Compilers usually generate such symbols
for unnamed program elements such as string literals or floating-point
literals.
-e
symbol,
--entry
=symbol-f
shlib,
--auxiliary
=shlibDT_AUXILIARY
dynamic section field to
shlib.
-h
libname,
--soname
=libnameDT_SONAME
dynamic section field to
libname. This option is used when creating a shared
object file. Typically, when you create SyXXX lib
foo.so,
you want to pass
--soname
=foo to a linker.
-l
libname-m
[target]-o
file,
--output
=file-r
,
--relocatable
--relocatable-merge-sections
mold
doesn't merge input sections by
name when merging input object files into a single output object file for
-r
. For example, .text.foo
and .text.bar aren't merged for
-r
even though they are merged into
.text according to the default section merging
rules.
This option changes the behavior so that
mold
merges input sections by name by the
default section merging rules.
-s
,
--strip-all
.symtab
section from the output file.
-u
symbol,
--undefined
=symbol--Bdynamic
--Bstatic
--Bsymbolic
--Bsymbolic-functions
--Bsymbolic
but works only
for function symbols. Data symbols remains being both imported and
exported.
--Bno-symbolic
--Bsymbolic
and
--Bsymbolic-functions
.
--Map
=file--Tbss
=address--section-start=.bss
=address.
--Tdata
=address--section-start=.data
=address.
--Ttext
=address--section-start=.text
=address.
--allow-multiple-definition
--as-needed
--no-as-needed
--as-needed
are added to the list
only when at least one symbol is actually used by an object file. In other
words, shared libraries after --as-needed
are not
added to the list of needed libraries if they are not needed by a program.
The --no-as-needed
option restores the
default behavior for subsequent files.
--build-id
--build-id
=[none
| md5 | sha1 | sha256
| uuid |
0xhexstring]--no-build-id
.note.gnu.build-id
section containing a
byte string to uniquely identify an output file.
--build-id
and
--build-id
=sha256 compute a
256-bit cryptographic hash of an output file and set it to build-id.
md5 and sha1 compute the same hash but
truncate it to 128 and 160 bits, respectively, before setting it to
build-id. uuid sets a random 128-bit UUID.
0xhexstring sets
hexstring.
--defsym
=symbol=value--compress-debug-sections
=[none
| zlib |
zlib-gabi
|
zstd]-zlib-gabi
is an alias for
-zlib
.
--defsym
=symbol=valuevalue is either an integer (in decimal or hexadecimal with ‘0x’ prefix) or a symbol name. If an integer is given as a value, symbol is defined as an absolute symbol with the given value.
--default-symver
--demangle
--no-demangle
--dependency-file
=filemake
, which defines
only one rule with the linker's output file as a target and all input
files as its prerequisite. Users are expected to include the generated
dependency file into a Makefile to automate the dependency management.
This option is analogous to the compiler's -MM
-MF
options.
--dynamic-list
=file--export-dynamic-symbol-list
, except that it
implies --Bsymbolic
.
If file does not exist in the current directory, it is searched from library search paths for the sake of compatibility with GNU ld.
--eh-frame-hdr
--no-eh-frame-hdr
.eh_frame_hdr
section.
--emit-relocs
The --emit-relocs
instructs the linker
to leave relocation sections in the output file. Some post-link binary
analysis or optimization tools such as LLVM Bolt need them.
mold
emits DT_RUNPATH for
--rpath
. If you pass
--disable-new-dtags,
mold emits DT_RPATH for
--rpath
instead.
--execute-only
As a mitigation, some recent processors allows "execute-only" pages. If a page is execute-only, you can call a function there as long as you know its address but can't read it as data.
This option marks text segments execute-only. This option currently works only on some ARM64 processors.
--exclude-libs
=libraries...--export-dynamic-symbol
=sym--export-dynamic-symbol-list
or
--version-script
.
--export-dynamic-symbol-list
=file--fatal-warnings
--no-fatal-warnings
--fini
=symbol--gc-sections
--no-gc-sections
--gdb-index
.gdb_index
section to speed up GNU
debugger. To use this, you need to compile source files with the
-ggnu-pubnames
compiler flag.
--hash-style
=[sysv
| gnu |
both]--icf
=[none
| safe |
all]--no-icf
If --icf=all
is given,
mold
tries to merge all identical functions.
This reduces the size of the output most, but it is not
“safe” optimization. It is guaranteed in C and C++ that
two pointers pointing two different functions will never be equal, but
--icf=all
breaks that assumption as two
functions have the same address after merging. So a care must be taken
when you use that flag that your program does not depend on the function
pointer uniqueness.
--icf=safe
is a
flag to merge functions only when it is safe to do so. That is, if a
program does not take an address of a function, it is safe to merge that
function with other function, as you cannot compare a function pointer
with something else without taking an address of a function. needs to be
used with a compiler that supports
.llvm_addrsig
section which contains the information as to what symbols are
address-taken. LLVM/Clang supports that section by default. Since GCC
does not support it yet, you cannot use
--icf=safe
with GCC (it doesn't do any harm but
can't optimize at all.)
--icf=none
and
--no-icf
disables ICF.
--ignore-data-address-equality
--icf=all
.
--image-base
=addr--init
=symbol--no-undefined
--shared
).
--noinhibit-exec
--pack-dyn-relocs
=[none
| relr]R_*_RELATIVE
relocations are put into
.relr.dyn
section instead of
.rel.dyn
or .rela.dyn
section. Since .relr.dyn
section uses a
space-efficient encoding scheme, specifying this flag can reduce the size
of the output. This is typically most effective for position-independent
executable.
Note that a runtime loader has to support
.relr.dyn
to run executables or shared libraries
linked with --pack-dyn-relocs=relr
, and only
ChromeOS, Android and Fuchsia support it as of now in 2022.
--package-metadata
=stringrpm
to embed metadata regarding a package to each
executable file.
--pie
,
--pic-executable
--no-pie
,
--no-pic-executable
--print-gc-sections
--no-print-gc-sections
--print-icf-sections
--no-print-icf-sections
--push-state
--pop-state
--push-state
saves the current values of --as-needed
,
--whole-archive
, --static
,
and --start-lib
. The saved values can be restored
by --pop-state
.
--push-state
and
--pop-state
pairs can nest.
These options are useful when you want to construct linker
command line options programmatically. For example, if you want to link
libfoo.so by as-needed basis but don't want to
change the global state of --as-needed
, you can
append "--push-state --as-needed -lfoo --pop-state" to the
linker command line options.
--relax
--no-relax
--require-defined
=symbol--undefined
, except the new symbol must be
defined by the end of the link.
--retain-symbols-file
=filefile is a text file containing a symbol
name on each line. mold
discards all local
symbols as well as global symbol that are not in
file. Note that this option removes symbols only
from .symtab
section and does not affect
.dynsym
section, which is used for dynamic
linking.
--rpath
=dir--section-start
=section=address.dynamic
section.
--start-lib
--end-lib
--start-lib
and
--end-lib
as if they were in an archive file. That
means object files between them are linked only when they are needed to
resolve undefined symbols. The options are useful if you want to link
object files only when they are needed but want to avoid the overhead of
running ar(3).
--static
--sysroot
=dir--trace
--undefined-version
--no-undefined-version
mold
warns on a symbol specified by a
version script or by --export-dynamic-symbol
if it
is not defined. You can silence the warning by
--undefined-version
.
--unique
=pattern--unresolved-symbols
=[report-all
|
ignore-all
|
ignore-in-object-files
|
ignore-in-shared-libs]--version-script
=file--warn-common
--no-warn-common
--warn-once
--warn-unresolved-symbols
--error-unresolved-symbols
--warn-unresolved-symbols
option turns it into a
warning. --error-unresolved-symbols
option
restores the default behavior.
--whole-archive
--no-whole-archive
--whole-archive
changes that behavior for
subsequent archives so that a linker extracts all object files and link
them to an output. For example, if you are creating a shared object file
and you want to include all archive members to the output, you should pass
--whole-archive
.
--no-whole-archive
restores the default behavior
for subsequent archives.
--wrap
=symbol-z
cet-report
=[none |
warning | error]-fcf-protection
flag.
-z
cet-report
flag is used to make sure that all object files were compiled with a
correct -fcf-protection
flag. If
warning or error are given,
mold
prints out a warning or an error message if
an object file was not compiled with the compiler flag.
mold
looks for
GNU_PROPERTY_X86_FEATURE_1_IBT
bit and
GNU_PROPERTY_X86_FEATURE_1_SHSTK
bit in
.note.gnu.property
section to determine whether
or not an object file was compiled with
-fcf-protection
.
-z
now
-z
lazy
-z
now
marks an executable
or a shared library file so that all dynamic symbols are loaded when a
file is loaded to memory. -z
lazy
restores the default behavior.
-z
origin
$ORIGIN
processing
at runtime.
-z
ibt
GNU_PROPERTY_X86_FEATURE_1_IBT
bit in
.note.gnu.property
section to indicate that the
output uses IBT-enabled PLT. This option implies
-z
ibtplt
.
-z
ibtplt
-z
execstack
-z
noexecstack
-z
execstack
makes it
executable. -z
noexecstack
restores the default behavior.
-z
keep-text-section-prefix
-z
nokeep-text-section-prefix
.text.hot
,
.text.unknown
,
.text.unlikely
,
.text.startup
and
.text.exit
as separate sections in the final
binary.
-z
relro
-z
norelro
.dynamic
have to be writable
only during an executable or a shared library file is being loaded to
memory. Once the dynamic linker finishes its job, such sections won't be
mutated by anyone. As a security mitigation, it is preferred to make such
segments read-only during program execution.
-z
relro
puts
such sections into a special segment called
relro
. The dynamic linker make a relro segment
read-only after it finishes its job.
By default, mold
generates a relro
segment. -z
norelro
disables the feature.
-z
separate-loadable-segments
-z
separate-code
-z
noseparate-code
separate-loadable-segments
adds
paddings between segments with different attributes so that they do not
share the same page. This is the default.
separate-code
adds paddings only
between executable and non-executable segments.
noseparate-code
does not add any
paddings between segments.
-z
defs
-z
nodefs
--shared
).
-z
shstk
.note.gnu.property
output section. Shadow stack is
part of Intel Control-flow Enforcement Technology (CET), which is
available since Tiger Lake (2020).
-z
text
-z
notext
, -z
textoff
mold
by default reports an error if dynamic
relocations are created in read-only sections. If
-z
notext
or
-z
textoff
are given,
mold
creates such dynamic relocations without
reporting an error. -z
text
restores the default behavior.
-z
max-page-size
The default value is 4 KiB for i386, x86-64 and RISC-V, and 64 KiB for ARM64.
-z
nodefaultlib
-z
nodelete
-z
nodlopen
-z
nodump
-z
nocopyreloc
-z
initfirst
-z
interpose
Rui Ueyama <ruiu@cs.stanford.edu>
Report bugs to https://github.com/rui314/mold/issues.
June 19, 2024 | Debian |