Repository navigation
Report rebased PT_DYNAMIC and dlpi_adds from dl_iterate_phdr - #19
Open
buyemune-sys wants to merge 3 commits into
Open
buyemune-sys wants to merge 3 commits into
buyemune-sys wants to merge 3 commits into
Conversation
Security updates replaced libapparmor1 4.0.1really4.0.1-0ubuntu0.24.04.7 with .9 and libexpat1 2.6.1-2ubuntu0.4 with ubuntu0.6, and the pool kept only the new files, so the cold-cache Fetch x86_64 job answers 404 and every x86-64 job behind it is skipped. Both pins move to the versions noble-updates ships now; their SHA256s match the archive's Packages index. The other twelve pins are still served.
ld.so rebases the address-valued entries of a writable dynamic section in place: DT_STRTAB, DT_SYMTAB, the hash tables, the relocation tables, DT_PLTGOT and DT_VERSYM hold addresses once an object is loaded. Code that walks PT_DYNAMIC through dl_iterate_phdr or link_map's l_ld reads them that way. LuaJIT's memprof and sysprof do so for every stripped library, to dump its dynamic symbols. Under the bridge the entries kept their link-time offsets, and the walk dereferenced them as addresses near zero. The loader now applies glibc's adjustment to every image with a writable dynamic section, right after parsing it and before RELRO seals it. The bridge's own image is no object ld.so would have loaded, and its static PIE startup left the offsets in place. dl_iterate_phdr reports it with PT_DYNAMIC blanked to PT_NULL, so walkers skip it, as LuaJIT skips the read-only vDSO under glibc. The conformance battery checks that no reported image still holds an offset in DT_STRTAB. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
glibc reports in dlpi_adds how many objects ever joined the list, and in dlpi_subs how many left it, so a walker can tell whether anything changed since it last looked. The bridge left both at zero. LuaJIT's memprof and sysprof rely on exactly that: they dump the symbols of the libraries added since the previous dump. With zero adds they see no libraries at all. A profile taken under solo then names no C function, which is what Tarantool's gh-5813-resolving-of-c-symbols test catches. The loader now counts the images that reach Ready, and dl_iterate_phdr adds the host entries it reports itself. Nothing unloads, so dlpi_subs stays zero, which is also what glibc reports before any dlclose. The conformance battery checks that dlpi_adds covers the images walked. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
buyemune-sys
force-pushed
the
fix/dl-iterate-phdr-adds
branch
from
October 20, 2026 08:11
43f5d45 to
a1e71e7
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The problem
Two things in what
dl_iterate_phdrhands out differ from glibc. Together they break LuaJIT's memprof and sysprof, which name C functions by walking the loaded objects (lj_symtab.c).dlpi_addsanddlpi_subswere always zero. glibc counts every object that ever joined the list, and those that left it:adds=4at startup,5after adlopen. memprof dumps the libraries added since its previous dump. With zero adds it dumps none, and a profile names no C function. Tarantool'sgh-5813-resolving-of-c-symbolstest fails all 5 checks.PT_DYNAMIC entries kept their link-time offsets. ld.so rebases the address-valued entries of a writable dynamic section in place, and walkers read them that way:
DT_STRTAB,DT_SYMTAB, the hash tables, the relocation tables,DT_PLTGOT,DT_VERSYM. For a stripped library memprof reads the dynamic symbols through them.This stayed hidden only because of (1). Once memprof sees the libraries, it dereferences
0x240and crashes (misclib-memprof-lapi.test.lua).The fix
Two commits, in this order:
parseDynamic, and before RELRO seals the section, the loader applies glibc's adjustment to the same tags glibc adjusts, for images whosePT_DYNAMICis writable (LinkMap::rebaseDynamic,lib/elf_loader.cpp:1705).parseDynamichas already cached everything the loader itself reads.dl_iterate_phdrreports it withPT_DYNAMICblanked toPT_NULL(hostHeaders,lib/glibc_shim.cpp:3772), so walkers skip it, as LuaJIT skips the read-only vDSO under glibc.dl_iterate_phdr'sdlpi_adds.dl_iterate_phdradds the host entries it reports itself.dlpi_subsstays zero, which is also what glibc reports before anydlclose.Test
The conformance battery's
dynamicLinking()checks two things:DT_STRTAB;dlpi_addscovers the images walked.On
mainboth fail, one per commit. With the fix:./build testpasses.Under solo, LuaJIT's test suite then fails only where it also fails natively, plus
lj-522, which needsLD_PRELOAD.