1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
//! # linker_lang
//!
//! A small static linker: it combines independently compiled [`Object`]s into a single
//! laid-out [`Image`].
//!
//! Each compilation unit a backend produces is its own island — a few named byte
//! [sections](Object::section), a set of [symbols](Object::define) that mark addresses
//! inside them, and [relocations](Object::relocate) that still need an address filled in.
//! Linking is the step that joins those islands: it lays the sections of every object end
//! to end, resolves each symbol to its final address in that layout, and patches the
//! relocations with the addresses they were waiting for. The result is an [`Image`] whose
//! bytes are ready to load and whose symbol table says where everything ended up.
//!
//! [`link`] is the one-call entry point; [`Linker`] is the same thing with a base address
//! and an entry point to configure. The model is format-agnostic — an ELF or PE reader
//! feeds the same [`Object`], and a writer turns an [`Image`] back into a file — so the
//! crate carries the linking logic without committing to one container format.
//!
//! ## Linking model
//!
//! - A [`section`](Object::section) is a named run of bytes (`.text`, `.data`, …).
//! Sections that share a name across objects are concatenated into one output section,
//! in the order the objects are given.
//! - A [`symbol`](Object::define) names an offset inside a section. After layout it
//! resolves to an absolute address — its section's address plus the object's place in
//! that section plus the offset.
//! - A [`relocation`](Object::relocate) is a hole at some offset in a section that must
//! hold the address of a named symbol (plus an addend). The linker resolves the target
//! and writes the address into the section bytes, little-endian, in the requested
//! [`Width`].
//!
//! ## Example
//!
//! Link two objects where a `.data` slot must point at a symbol defined in `.text`:
//!
//! ```
//! use linker_lang::{link, Width};
//!
//! // The code: a symbol `start` at the top of `.text`.
//! let mut code = linker_lang::Object::new("code");
//! code.section(".text", [0x90, 0x90, 0x90, 0x90]);
//! code.define("start", ".text", 0);
//!
//! // The data: an 8-byte slot that should hold the address of `start`.
//! let mut data = linker_lang::Object::new("data");
//! data.section(".data", [0; 8]);
//! data.relocate(".data", 0, "start", Width::U64, 0);
//!
//! let image = link(&[code, data]).expect("symbols resolve");
//!
//! // `.text` is laid out first at address 0, so `start` resolves there, and the slot in
//! // `.data` was patched with that address.
//! assert_eq!(image.symbol("start"), Some(0));
//! let slot = &image.section(".data").unwrap().data()[..8];
//! assert_eq!(u64::from_le_bytes(slot.try_into().unwrap()), 0);
//! ```
//!
//! ## Features
//!
//! - `std` (default) — links the standard library. Without it the crate is `#![no_std]`
//! and needs only `alloc`.
//! - `serde` — derives `Serialize` and `Deserialize` for [`Image`] and [`LinkError`], so a
//! linked image or a failure can be cached, logged, or moved between tools.
//!
//! ## Stability
//!
//! The public surface is frozen and stable as of `1.0.0`: it follows Semantic Versioning,
//! with no breaking changes before `2.0`. [`LinkError`] is `#[non_exhaustive]`, so a linker
//! reporting a new kind of failure is an additive, non-breaking change. The full surface and
//! the SemVer promise are catalogued in
//! [`docs/API.md`](https://github.com/jamesgober/linker-lang/blob/main/docs/API.md#semver-promise).
extern crate alloc;
pub use LinkError;
pub use ;
pub use ;
pub use ;