The World of Linkers/ Labs/ 16 articles
3 min readPublic

[The World of Linkers—Lab 07] Archives on Demand: A Fixed Point of Member Extraction

Select object members from a static library to satisfy unresolved global names, then pass them to the existing linker. Theory 03 explains archives, input order, and repeated scans.

Starting point: class7 code and tests, in the private repository; access is required. Reuse ELF parsing, class3 global selection, and class6 linking. Implement three interfaces in the class7 crate library. The CLI is supplied; implementation code must not invoke ar, nm, or ld.

Implementation tasks

TaskInterfaceRequired result
C7.1membersValidate ordinary GNU/System V ar framing and names, returning borrowed object payloads
C7.2selectExtract required members in input order, scanning the current archive to a fixed point
C7.3linkPass selected objects to class6 without loading every archive member

class7 README defines records, name encodings, and selection rules. Validate all member framing before resolving names. The newline following an odd-length payload is padding, not payload. Support GNU long names even when their table follows the reference. Duplicate filenames are valid: position identifies a member. Names need not be UTF-8.

Explicit objects enter immediately. At each archive, parse every ordinary member's ELF symbol metadata, then scan members in archive order for definitions satisfying current GLOBAL/UNDEF requirements. Recompute requirements after each extraction. Repeat the current archive while a pass extracts anything. Updating only at the end of a pass is not equivalent, and earlier archives are not automatically revisited.

Unresolved WEAK does not request extraction. An existing WEAK or COMMON definition already satisfies a name; do not extract another member merely to upgrade it. Entry lookup occurs after selection and does not force extraction. These are explicit stage policies. Thin archives, groups, whole-archive, and library search are not implemented here.

Every ordinary member must pass symbol-metadata validation, including unused members. Allocated-section policy applies only to selected objects. A valid unused member cannot introduce duplicate definitions or TLS storage into the output.

The smallest fixed-point example is: main.o references a; the archive first contains a.o, which defines a but itself references b; a later member b.o defines b. After extracting a.o, the unresolved set gains b, so the current archive must be scanned again and extract b.o. Computing requirements only once leaves b unresolved, while expanding the whole archive incorrectly includes unused members.

Acceptance and what it establishes

From the cloned repository root, on native x86-64 Linux:

cargo test --locked -p class7
cargo test --locked -p class7 --release
python3 scripts/grade.py class7

Contract tests cover framing, padding, long and duplicate names, truncation, and scan rules. Native tests build inputs with GNU as/ar, put a dependency before its caller to require a second scan, and include members that must remain unselected.

Tests assert both the selected object set and final execution. Selection assertions check demand-driven extraction; execution checks that the chosen objects link correctly. Separate cases cover earlier archives not being revisited, weak references, the first provider satisfying a name, and malformed metadata in unused members.