This repository was archived by the owner on Jun 24, 2026. It is now read-only.
[dlfcn] E: Add tests for ctors/dtors and DT_RUNPATH#174
Open
esaurez wants to merge 1 commit into
Open
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a new POSIX test suite that validates Nanvix’s dynamic loader behavior around ELF constructors/destructors and DT_RUNPATH resolution, integrating it into the build and standalone test harness wiring.
Changes:
- Introduces new suite
dlfcn-init-runpath-cthat checks.init_arrayondlopen,.fini_arrayondlclose, andDT_RUNPATH-drivenDT_NEEDEDlookup. - Registers the suite in the build system (
Makefile,src/Makefile) so it’s built alongside existing suites. - Hooks the suite into
.nanvix/z.pystandalone execution and ramfs library staging (including staginglibchild.sounderlib/subdir/).
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
src/Makefile |
Adds dlfcn-init-runpath-c to the full suite build list. |
src/dlfcn-init-runpath-c/Makefile |
Builds the new test ELF and its companion shared libraries (libctor.so, libparent.so, libchild.so). |
src/dlfcn-init-runpath-c/main.c |
Implements the three runtime checks for ctor/dtor execution and DT_RUNPATH dependency search. |
src/dlfcn-init-runpath-c/libs/subdir/child.c |
Defines libchild.so dependency target for DT_NEEDED resolution via DT_RUNPATH. |
src/dlfcn-init-runpath-c/libs/parent.c |
Defines libparent.so that declares DT_NEEDED on libchild.so. |
src/dlfcn-init-runpath-c/libs/ctor.c |
Defines libctor.so with constructor/destructor sentinels used by the test. |
Makefile |
Adds dlfcn-init-runpath-c to the Docker/host build suite list. |
.nanvix/z.py |
Registers suite and stages required shared libraries into the ramfs (including subdir placement for DT_RUNPATH). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Add a new test suite (`dlfcn-init-runpath-c`) that exercises the
three System V ABI capabilities the Nanvix dynamic loader now
implements (esaurez/nanvix PR `feat/dlfcn-init-array-and-runpath`):
1. `libctor.so` defines `.init_array` and `.fini_array` entries via
`__attribute__((constructor))` / `((destructor))`. The
constructor writes a sentinel into a library-local global; the
destructor writes a different sentinel into the test program's
exported `g_dtor_ran` global so the witness survives the
library being unloaded. The test asserts both sentinels appear
in the expected order.
2. `libparent.so` is linked against `libchild.so` (creating a
`DT_NEEDED` edge) and built with `-Wl,--enable-new-dtags,
-rpath,lib/subdir`, which the linker emits as `DT_RUNPATH
lib/subdir`. At runtime `libchild.so` is staged into
`lib/subdir/` only — never `lib/` — so the only way `dlopen`
can succeed is by honouring `libparent.so`'s `DT_RUNPATH`.
Both libraries are built flat in `build/` and re-staged into the
correct ramfs paths via the existing `SUITE_RAMFS_LIBS` mechanism
in `.nanvix/z.py`, matching the pattern already used by
`dlfcn-c`. The suite is registered in `STANDALONE_ONLY_SUITES`
because it requires ramfs-bundled `.so` files, and in
`ALL_SUITES`, the host `Makefile`, and the container
`src/Makefile`.
Test output on a standalone Nanvix VM running the updated loader:
=== dlfcn init_array + DT_RUNPATH tests ===
PASS: init_array fires on dlopen
PASS: fini_array fires on dlclose
PASS: DT_RUNPATH dependency search
3 passed, 0 failed
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
ee7a87a to
16403c8
Compare
This was referenced Jun 9, 2026
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
Summary
Add a new test suite
dlfcn-init-runpath-cthat exercises three System V ABI capabilities of the Nanvix dynamic loader:.init_arrayconstructor invocation ondlopen.fini_arraydestructor invocation ondlcloseDT_RUNPATH-drivenDT_NEEDEDresolutionThe companion loader PR that implements these features is nanvix/nanvix#2473.
Test design
libctor.so— has__attribute__((constructor))writing a sentinel to a library-local global, and__attribute__((destructor))writing a different sentinel to the test program'sextern volatile int g_dtor_ran(exported by-rdynamic). The destructor witness survives the library being unloaded because the global lives in the main executable.libparent.so— linked with-lchild -Wl,--enable-new-dtags,-rpath,lib/subdir. The linker emitsDT_NEEDED libchild.soplusDT_RUNPATH lib/subdir.libchild.so— staged intolib/subdir/only (neverlib/) viaSUITE_RAMFS_LIBS. The only way the loader can find it is by honouring libparent'sDT_RUNPATH.Hooks
src/dlfcn-init-runpath-c/{Makefile,main.c,libs/*}Makefile,src/Makefiledlfcn-init-runpath-cinSUITES.nanvix/z.pyALL_SUITES,STANDALONE_ONLY_SUITES, andSUITE_RAMFS_LIBS(the latter stageslibchild.sounderlib/subdir/)Validation
Run on a standalone Nanvix VM with the loader changes from nanvix/nanvix#2473:
All 15 testable suites pass (the new suite plus the 14 pre-existing ones).
ELF metadata sanity check
This PR is unlinked-but-meaningful without the loader change: the test would fail with "destructor sentinel not set" / "DT_RUNPATH dependency search" / "constructor sentinel not set" on an unpatched loader.