glibc 2.36 loads packed relative relocations
DT_RELR compresses the locations of relative relocations in shared objects and position-independent executables. glibc 2.36 adds the loader half of a change that also requires linker support.
A position-independent executable still contains addresses that need adjustment when its image is loaded. Describing every adjustment can take a substantial relocation table even when the operation at each location is simple. The glibc 2.36 announcement, published on August 2, adds support for the ELF DT_RELR format, which packs the description of relative relocations.
Its relevance extends to shared libraries as well as position-independent main executables. The change has two participants. A linker produces the packed representation, and the dynamic loader interprets it. Installing a loader that understands the format does not rewrite existing executables or make their relocation tables smaller. The release announcement explicitly requires linker support for -z pack-relative-relocs, available for some targets in recent binutils versions.
I think C's practical importance is closely tied to these binary contracts. Application developers can use a higher-level language and still depend on a loader interpreting the resulting ELF objects. This release changes that shared execution environment without asking application source to adopt a new language construct.
Relative relocations have repetitive information
The 2.36 loader implementation shows what makes this class of relocation suitable for packing. At each designated location, the loader adds the object's load address to the value already stored there. The table therefore needs to describe where the additions happen. It does not need a separate symbol lookup for every entry in this loop.
The implementation first checks for a DT_RELR dynamic entry. If it is absent, the packed-relocation step has nothing to do. When present, the loader obtains the table pointer and uses DT_RELRSZ to establish its end. It then interprets each entry according to the entry's lowest bit.
An entry whose low bit is zero gives a location directly. The loader combines that entry with the load address, adjusts the value at that location, and advances its working pointer to the following address-sized location. This establishes a position for interpreting subsequent packed information.
An entry whose low bit is one is a bitmap. The loader shifts away that marker and adds the load address at positions whose corresponding bits are set. It then advances its working pointer by the number of data bits represented in that entry. A single table word can therefore describe adjustments at several nearby locations without repeating their full addresses.
The bitmap compresses locations
That encoding benefits a set of relocation locations that can be represented within the bitmap windows. It does not compress the pointed-to application data, and it does not remove the requirement to make the additions. The smaller object-file representation concerns metadata describing those additions.
The source makes the window size explicit as CHAR_BIT multiplied by the size of a relocation entry, minus one marker bit. It also advances over unset positions. This is why the working pointer can move beyond locations that receive no adjustment. A bitmap describes a span of possible locations, not just a contiguous count of writes.
The release announcement says lazy binding does not apply to DT_RELR. This matches the direct adjustment operation visible in the implementation. It should not be described as another form of deferred function-symbol resolution. In the loader's relocation macro, packed relative relocation processing appears before the ordinary REL and RELA processing steps.
For a build, this means the relevant question is whether its linker emits the packed form and whether the deployment loader accepts it. Existing objects can continue using their existing relocation formats. Enabling packing for newly linked objects creates a runtime format requirement that belongs in the deployment description alongside other loader dependencies.
My preference is to treat this as a coordinated toolchain change. The loader's compact loop explains the mechanism, while the linker's selected output determines whether a particular executable uses it. A generic claim that upgrading glibc makes every binary smaller would confuse those two roles.
Process handles address a different identity problem
The same release adds Linux wrappers for pidfd_open, pidfd_getfd, and pidfd_send_signal. The announcement motivates these through PID reuse. A numeric process identifier can eventually designate a different process, so an interface using a process descriptor addresses a different identity contract from one using only the number.
glibc also adds process_madvise, which applies advice to a target process identified through a pidfd. Another wrapper, process_mrelease, releases memory associated with a dying process. The announcement states that this release work executes in the caller's context, using its CPU affinity and priority and charging CPU usage to it.
Those details are relevant to code supervising other processes. They identify which process is the target and which process incurs the work. Merely describing these additions as new Linux functions would omit the identity and accounting rules that explain why they exist. Their presence in glibc supplies convenient library entry points, while the operations remain Linux-specific.
Resolver diagnostics have a narrow purpose
Another operational addition is the resolver's no-aaaa option. According to the announcement, it suppresses AAAA queries issued by the stub resolver, including queries triggered through NSS interfaces such as getaddrinfo. It is intended primarily to diagnose whether those queries cause adverse effects.
The scope is deliberately narrower than disabling IPv6. IPv6 entries in /etc/hosts remain usable. Passive address queries can still produce IPv6 addresses, and configured IPv6 name servers remain in use. To preserve correct name-error results, the resolver translates AAAA queries to A queries.
The announcement also identifies incompatibility with EDNS0 and application DNSSEC validation. Those qualifications make this an option whose meaning should be recorded with the diagnostic being performed. It is not evidence that an application has stopped using all IPv6 paths, and it does not describe a general network configuration policy.
These additions coexist with the binary-loading change without sharing its adoption mechanism. A resolver setting changes query behaviour for an environment. A new pidfd wrapper exposes a kernel operation to source code. DT_RELR instead changes the representation consumed by the loader, so its use depends on the linker output distributed with the program.