Posts

  • 22nd August 2021

FreeBSD src browsing on Linux and my rtld contribution

Before September 2020 FreeBSD could only be built on a FreeBSD host. Alexander Richardson did a lot of work making this possible: https://wiki.freebsd.org/BuildingOnNonFreeBSD.

…

Read more →
  • 15th August 2021

Extract an archive member to satisfy a DSO undef

In ELF linkers, undefined symbols from DSO participate in symbol resolution, just like undef from .o. The differences with undef from .o are:

  • undef purely from DSO do not need .symtab entries
  • --no-allow-shlib-undefined can error for such undef (-rpath-link ("load dependent libraries") behavior can suppress some errors.

ELF linkers extract an archive member to satisfy an undefined symbol from a shared object. Here is an example:

…

Read more →
  • 8th August 2021

Toolchain testing

Updated in 2025-06.

Some random notes about toolchain testing.

Classification

Testing levels.

…

Read more →
  • 25th July 2021

COMDAT and section group

Updated in 2025-09.

The blog post explores how COMDAT (in the PE format) and section groups (in the ELF format) provide a mechanism to group related sections for efficient deduplication and garbage collection.

Vague linkage

In C++, inline functions, template instantiations, and a few other things can be defined in multiple object files but need deduplication at link time. In the dark ages the functionality was implemented by weak definitions: the linker does not report duplicate definition errors and resolves the references to the first definition. The downside is that unneeded copies remained in the linked image.

…

Read more →
  • 4th July 2021

SECTIONS and OVERWRITE_SECTIONS

The main task of a linker script is to define extra symbols and define how input sections map into output sections. It has other miscellaneous features which can be implemented via command line options:

  • The ENTRY command can be replaced by --entry.
  • The OUTPUT_FORMAT command can usually be replaced by -m.
  • The SEARCH_DIRS command can be replaced by -L.
  • The VERSION command can be replaced by --version-script.
  • The INPUT and GROUP commands can add other files as input. This provides a mechanism to split an archive/shared object into multiple files.
…

Read more →
  • 20th June 2021

Symbol processing

UNDER CONSTRUCTION (COFF, Mach-O)

Symbol processing is a major step in a linker. In most binary formats, the linker maintains a global symbol table and performs symbols resolution for each input file (object file, shared object, archive, LLVM bitcode file). Some command line options can define/undefine symbols as well. The symbol resolution can affect archive processing and many subsequent steps (LTO, relocation processing, as-needed shared objects, etc).

…

Read more →
  • 13th June 2021

Dependency related linker options

This article describes the dependency related linker options -z defs, --no-allow-shlib-undefined, and --warn-backrefs. Deploying them in a build system can improve build health.

-z defs

…

Read more →
  • 16th May 2021

ELF interposition and -Bsymbolic

This article describes ELF interposition, the linker option -Bsymbolic, and its friends. In the end, it will discuss an ambitious plan which I dubbed "the Last Alliance of ELF and Men".

Motivated by a great post by Daniel Colascione ("Python is 1.3x faster when compiled in a way that re-examines shitty technical decisions from the 1990s.") and a recent rant from Linus Torvalds on shared objects' performance issues, I have summarized the current unfortunate ELF state and filed some GCC/binutils feature requests. I believe the performance of our shared object oriented world will be no slower than one with mostly statically linked executables.

(I wrote -fno-semantic-interposition first but then realized reorganization would improve readability, so moved some parts and added some stuff to this new article.)

…

Read more →
  • 9th May 2021

-fno-semantic-interposition

Updated in 2022-05.

This article is a continuation to ELF interposition and -Bsymbolic. It focuses on the GCC/Clang option -fno-semantic-interposition and why it can (sometimes incredibly) optimize -fPIC programs.

…

Read more →
  • 25th April 2021

Weak symbol

Updated in 2026-03.

C/C++

GCC and Clang support __attribute__((weak)) which marks a symbol weak. The same effect can be achieved with a preprocessor directive #pragma weak symbol.

Object file format

In ELF, there are three main symbol bindings. The ELF specification says:

  • STB_LOCAL: Local symbols are not visible outside the object file containing their definition. Local symbols of the same name may exist in multiple files without interfering with each other.
  • STB_GLOBAL: Global symbols are visible to all object files being combined. One file's definition of a global symbol will satisfy another file's undefined reference to the same global symbol.
  • STB_WEAK: Weak symbols resemble global symbols, but their definitions have lower precedence.
…

Read more →