Skip to content

mold 0.9

Compare
Choose a tag to compare
@rui314 rui314 released this 29 Jun 13:38
· 4562 commits to main since this release

mold is a new linker that is optimized for modern multi-core machines. mold is command-line compatible with the other major linkers, GNU ld, GNU gold and LLVM lld, yet it is several times faster than them. Its goal is to increase programmer productivity by speeding up program build time, especially for rapid edit-build-test-debug cycles. (Disclaimer: I'm the original creator of the current version of LLVM lld.)

Highlights of mold 0.9

In the mold 0.9 release cycle, we focused on improving compatibility with other linkers. To find out compatibility issues, we tried to build all Gentoo Linux packages in a Docker environment with mold being set to /usr/bin/ld (the default linker's path) and also run their unittests if available. Gentoo was an ideal distro to conduct this test because of its source-based package system. We then analyzed all build and test failures one by one and fixed almost all issues during this release cycle.

Quantitatively speaking, among 6769 Gentoo packages that we could built with GNU ld, mold succeeded to build 6746 packages. This is ~99.7% success rate. A small number of packages were unable to be built with mold or failed to complete their unittests for various reasons. You can see our analysis of the failures on this spreadsheet.

So, we believe that as long as you are building your user-land program on a relatively new Linux distro, chances are mold will "just work" for your program. We don't want to set a bar too high, but we believe that you probably wouldn't notice any difference except a short program link time. We bumped the mold's version from 0.1.1 to 0.9 to show that mold is getting ready for production.

If you experience any compatibility issue, please file a bug at https://github.com/rui314/mold/issues.

Changes in mold 0.9

  • Following options have been added: --warn-unresolved-symbols --error-unresolved-symbols --relocatable -z muldefs -z nodump -z origin --unique``--unresolved-symbols -z text -z textoff z notext -z keep-text-section-prefix --allow-multiple-definition --compress-debug-info=zlib{,-gnu,-gabi,none} -R --retain-symbols-file --warp --image-base
  • mold used to embed its command line arguments to .comment section for traceability. Even though it's useful for debugging, it causes some OCaml tests which compare linker's output files byte-by-byte to fail. To appease them, mold embeds command line arguments to .comment only when MOLD_DEBUG environment variable is set to a non-empty string.
  • mold now writes relocation addends to sections even for RELA-type dynamic relocations. This is for bug-compatibility with Go. Go's linker wrongly assumes that addends are always written to sections, although the correct value are in fact in RELA-type relocation themselves.
  • mold now handles common symbols as if they were undefined symbols until a symbol resolution phase is done. This change makes an observable difference if an object file contains a common symbol and an archive file contains a non-common definition of the symbol. Previously, mold didn't pull out an object file from an archive to resolve a common symbol. Since mold 0.9, it pulls out an object file in that case. This change was made to build programs compiled with GNU Fortran.
  • mold now exports undefined weak symbol as an undefined weak dynamic symbol, so that the symbol gets another chance to be resolved at load-time.
  • .gnu.warning.* sections are now not only ignored but also discarded.
  • mold no longer put local symbols to the dynamic symbol table. This change reduces the size of the dynamic symbol table.
  • mold used to handle .ctors and .dtors sections as a normal section. These sections contain pointers to functions that are executed on program start up and exit. Today, their roles are superseded by .init_array and .fini_array sections. mold 0.9 now supports a feature to translate .ctors and .dtors to .init_array and .fini_array at link-time.
  • mold now skips a library found by -l option if it's not for the target architecture. For example, mold skips libraries for i386 when creating an x86-64 executable.
  • mold now defines end, etext and edata symbols.
  • The version string displayed for --version now contains not only GNU ld but also GNU gold. This change appease some configure scripts that expect GNU gold in the --version string. (I wrote an essay about this kind of issue a few years ago.)
  • The help message displayed for --help now contains supported targets and supported emulations strings to appease some configure scripts.
  • If -z keep-text-section-prefix is given, mold now keeps .text.hot, .text.unknown, .text.unlikely, .text.startup, and .text.exit sections as they are instead of merging them into .text section. This change should slightly improve code locality at runtime, as hot code and cold code are aggregated to different places.
  • Other various compatibility issues were fixed.

Demonstration

Here is a side-by-side comparison of per-core CPU usage of lld (left) and mold (right). They are linking the same program, Chromium executable.

As you can see, mold uses all available cores throughout its run and finishes quickly. On the other hand, lld fails to use available cores most of the time and takes much longer to finish. This is the Amdahl's law in action β€” only a limited number of internal passes of lld are parallelized, while almost all internal passes of mold are parallelized. On this demo, the maximum parallelism is capped to 16 so that the bars fit in the screen.