Skip to content

mold 2.42.0

Latest

Choose a tag to compare

@rui314 rui314 released this 12 Aug 01:27

mold 2.42.0 is a new release of the high-speed linker. It includes the following new features and bug fixes.

New Features

  • We have made numerous optimizations throughout the linker during this release cycle. mold 2.42.0 should be noticeably faster than previous versions, especially when linking large programs on machines with many cores.

  • --pack-dyn-relocs=android and --pack-dyn-relocs=android+relr are now supported. These options encode dynamic relocations in the Android packed relocation format (APS2), which significantly reduces the size of the dynamic relocation table of Android binaries. (59957fc, 7a66f71, 400dfad)

  • --compress-debug-sections now accepts a compression level, such as zstd:9 or zlib:6. Plain zstd and zlib remain equivalent to zstd:3 and zlib:1, respectively, which were the previous hardcoded defaults. (56fc571, 0420959, 6695f13)

  • The -w and --no-warnings options are now supported. They suppress warnings and cancel --fatal-warnings, while real errors are still reported. This matches the behavior of lld. (51b9683)

  • The -Ttext-segment option, which sets the address of the first byte of the text segment, is now supported for compatibility with GNU ld. (ac73431)

  • mold now supports the SFrame version 3 stack unwinding format. SFrame is a compact alternative to .eh_frame used for asynchronous stack unwinding by profilers and debuggers. As of binutils 2.46, the GNU assembler emits SFrame version 3 when the --gsframe flag is given, so object files containing .sframe sections are becoming common. .sframe sections cannot be treated as opaque bytes; mold parses input .sframe sections, discards entries for functions removed by --gc-sections or --icf, and rebuilds a single merged section sorted by function address, along with a PT_GNU_SFRAME segment so that the runtime can locate it. Relocatable output (-r) is supported as well. (d0aa95a)

  • mold now discards temporary local symbols such as .L.str.42 by default, as lld does. Compilers emit a large number of such symbols for unnamed program elements, but they are compiler-internal; nothing references them through the symbol table, and debug info refers to their data by section offset. Discarding them makes large debug builds a few percent smaller and keeps compiler-internal labels out of symbolized addresses. The new --discard-none option restores the previous behavior. -r and --emit-relocs continue to keep all local symbols. (45dea59)

Bug Fixes and Compatibility Improvements

  • Fixed a longstanding ICF bug in which two functions with identical machine code but different exception tables or personality routines could be folded into one, changing which exceptions the surviving function could catch. (a06b623, 923df2f)

  • ICF no longer considers a relocation against a preemptible symbol equivalent to a relocation against another symbol whose body happens to be identical, since preemptible symbols can be interposed at runtime. (17e705e)

  • When ICF folds sections with different alignment requirements, the surviving section now gets the strictest alignment of the group. Previously, a function requiring 4-byte alignment could be folded into a less-aligned copy and placed at an odd address, which broke member function pointers on x86, as they use the least significant bit of the address to distinguish virtual functions from non-virtual ones. (899655b)

  • Fixed a spurious "refers to a discarded COMDAT section" error when linking a mix of LTO and non-LTO archive files. COMDAT group selection is now redone from a clean slate after LTO so that groups are chosen among the files that actually remain in the link. A race condition in COMDAT owner selection during LTO has also been fixed. (920a516, 2708ba6)

  • Fixed symbol resolution against shared libraries that contain legacy compatibility aliases created with .symver foo, foo@VER (defined dynamic symbols with the hidden-version bit set). mold mistakenly let such an alias satisfy unversioned references to foo, silently binding callers to the legacy implementation at runtime instead of the default version foo@@VER. (5898fbc)

  • mold now reads version information for undefined symbols in shared libraries. Previously, a versioned undefined reference such as foo@VER_1.0 in a shared library was looked up by its bare name, so a non-default versioned definition in another shared library did not satisfy it, and --no-allow-shlib-undefined could report a spurious "undefined symbol" error. In addition, undefined references whose version index is 0, which some old versions of GNU ld emit, are no longer silently ignored. (6b8293b, 6b0ecea)

  • A symbol exported with an empty default version (foo@@) is no longer hidden by a version script's local: *; wildcard, matching GNU ld. (71cbd79)

  • mold now reports an error if both foo@@VER and foo@VER are defined and exported, since they are duplicate definitions of the same versioned name. Previously, we silently emitted a dynamic symbol table containing two definitions of foo@VER, leaving it up to the dynamic loader which one a versioned reference binds to. GNU ld and lld reject this too. (fba0a21)

  • mold now reports an error for a shared library that contains a defined dynamic symbol whose version index is 0 (VER_NDX_LOCAL). Such a file is ill-formed; a certain version of GNU ld produced one, and mold previously ignored the symbol and reported a confusing "undefined symbol" error for a symbol that plainly exists in the library. (1fb2901)

  • mold now reports an error if a shared library is given as an input file in a static link. Previously, the file was silently ignored, producing an executable that crashes at runtime. GNU ld and lld reject this at link time, and so do we now. (2b60527)

  • Global symbols that are not exported to the dynamic symbol table are no longer demoted to local symbols in .symtab. Previously, in an ordinary executable, nm printed t main instead of T main, which misled tools that depend on symbol bindings. Only symbols hidden by visibility or localized by a version script are now emitted as local, following lld. (35f4a33)

  • With --gc-sections, sections whose names are valid C identifiers are no longer unconditionally treated as roots. They are now kept alive only if their __start_/__stop_ marker symbols are actually referenced. The old behavior could pull in unrelated code and cause spurious "undefined symbol" errors that GNU ld and lld do not produce. (384527f)

  • If all sections that referenced a shared library are removed by --gc-sections, the library's DT_NEEDED entry is now omitted, matching lld's behavior. (3d546cd)

  • --emit-relocs now rewrites relocations for instructions that the linker has relaxed, so that the emitted relocations match the output code. Previously, input relocations were copied verbatim, and the stale relocation types and offsets confused post-link tools such as BOLT. This applies to x86-64, i386, ARM64, s390x, RISC-V and LoongArch. (f147d78, ad4c489)

  • --gdb-index now produces bit-identical output regardless of the number of threads. (6f8d62e)

  • Fixed --gdb-index handling of DW_FORM_rnglistx range lists, which Clang emits. The generated address table could contain overlapping ranges, which GDB 17 detects, causing it to print a warning and ignore the index entirely. (70ca8ff)

  • mold no longer emits PT_INTERP when creating a shared library even if --dynamic-linker is given, matching GNU ld and lld. Shared libraries are loaded by the dynamic linker itself, so PT_INTERP serves no purpose in them. (10b37a8)

  • Fixed a PT_LOAD alignment issue for sections whose alignment is larger than the page size. The file offset is now adjusted so that p_offset and p_vaddr remain congruent modulo the alignment. (ad4a683)

  • Fixed a regression introduced in 2.41.0 in which a response file (@file) with a relative path could not be opened when the -C option was also given. (61933bf)

  • Glob patterns now accept ! as a negation marker in bracket expressions (e.g. [!abc]) in addition to ^, following the POSIX shell convention. Version scripts generated for lld use this form. (e2d0c1a)

  • DTPREL relocations in non-allocatable sections, which compilers emit for thread-local variables in debug info, are now supported on AArch64, m68k, RISC-V and SH4. (4b00446)

  • [i386] In-place relocation addends are now sign-extended when read. (85c115e)

  • [AArch64] Added support for the R_AARCH64_MOVW_PREL_G* relocations. (a0c46e9)

  • [SH4] Fixed dynamic relocations losing their addends. mold emitted symbolic dynamic relocations with the addend stored in the relocated place, but the glibc dynamic loader reads it only from r_addend, so any symbolic dynamic relocation with a non-zero addend, such as a typeinfo vtable pointer in a position-independent executable, was resolved incorrectly. (be3d214)

  • [SPARC64] Added support for the large PLT format. (4afb95a)

  • [LoongArch] A GOT load is no longer relaxed to pcaddi if the target symbol is not 4-byte aligned, since pcaddi can only materialize addresses that are multiples of 4. (84c411b)

  • [PPC64] mold now rejects object files whose combination of ABI and endianness is unsupported, such as big-endian ELFv2, which musl supports. Previously, such files were silently linked as if they used the conventional ABI for their endianness, producing a broken executable. (5157cef)

Build Changes

  • mold now requires mimalloc v3. By default, mold will build the bundled mimalloc 3.4.5 and statically link it. To link against a system-wide mimalloc shared library instead, pass -DMOLD_USE_SYSTEM_MIMALLOC=ON to cmake.

Acknowledgements

mold is an open-source project, and we accept donations via GitHub Sponsors and OpenCollective. We thank everyone who sponsors our project. In particular, we would like to acknowledge the following organizations and people who have sponsored $32/month or more during this release cycle: