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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
//! Memory management (§58, §85 Phase 1).
//!
//! Wraps the allocator hooks from `crate::abi::allocator` for use by the XML
//! implementation modules. This module provides the internal Rust interface
//! to the allocator system.
//!
//! # UPSTREAM-PARITY
//!
//! libxml2 exposes several memory management APIs:
//!
//! - `xmlMemSetup` / `xmlMemGet` — set/get custom allocator hooks
//! - `xmlGcMemSetup` / `xmlGcMemGet` — GC-aware variants (now identical)
//! - `xmlMalloc` / `xmlMallocAtomic` / `xmlRealloc` / `xmlFree` / `xmlMemStrdup`
//! - `xmlMallocZero` / `xmlMallocAtomicZero` / `xmlReallocZero`
//! - `xmlMemUsed` / `xmlMemBlocks` — debugging statistics
//! - `xmlMemDisplay` / `xmlMemShow` — debugging output
//! - `xmlInitMemory` / `xmlCleanupMemory` — lifecycle
//!
//! All of these are implemented in `crate::abi::allocator`. This module
//! re-exports them for internal use.
//!
//! # Phase 1 status
//!
//! Complete — all memory functions delegate to the ABI allocator layer.
//!
//! # Upstream contract
//!
//! Mirrors upstream xmlmemory.c (SRC-LIBXML2-2.15.0-XMLMEMORY-C): xmlMemSetup
//! / xmlMemGet / xmlGcMemSetup / xmlMemUsed / xmlMemBlocks / xmlMemDisplay /
//! xmlMemShow and the xmlMalloc* family. The actual implementation lives in
//! `crate::abi::allocator`; this module is the internal Rust interface.
//!
//! # Conceptual behavior
//!
//! Wraps the allocator hooks for use by the XML implementation modules. The
//! allocator defaults to libc malloc and is swappable via xmlMemSetup; the
//! block registry (R-000131) tracks blocks for xmlMemSize, xmlMemUsed and the
//! debug dumps.
//!
//! # Ownership & safety invariants
//!
//! Ownership rule (atlas/OWNERSHIP_ATLAS.md): a pointer returned by an xml*
//! allocator must be freed by xmlFree; a pointer from libc::calloc inside the
//! engine is freed internally and never escapes. SAFETY: xmlFree on a
//! foreign/unknown pointer is a no-op removal from the registry (documented
//! safe divergence — upstream would corrupt).
//!
//! # Historical quirks & epochs
//!
//! The debug allocator with block tracking has been part of libxml2 since the
//! early 2.x era; xmlMemDisplayLast / xmlMemShow report per-block data.
//! xmlMemSetup keeps counter-only accounting when custom allocators are
//! installed (R-000131 divergence, matching upstream debug-allocator-only
//! block table).
//!
//! # Deliberate oddities
//!
//! Deliberate oddities: the exported allocator entry points are DATA
//! function-pointer globals (xmlMallocImpl etc.) matching the oracle ABI
//! (R-000162: upstream exports them as data variables so the xmlMalloc =
//! custom override can link).
//!
//! # Proving courts
//!
//! ALLOCATOR court family, the DATA-GLOBALS-001 probe (allocator globals
//! byte-identical), ASan full-suite runs (0 invalid reads/writes, 0 double-
//! free) and `cargo test --lib` (1135+ tests).
//!
//! # Tempting simplifications that would break parity
//!
//! A tempting simplification is routing all allocation through the Rust global
//! allocator — it would break xmlMemSetup overrides, xmlMemUsed accounting
//! and the exported xmlMalloc data-symbol ABI (R-000162). Do not replace the
//! registry no-op free with a real free of foreign pointers: that would
//! corrupt the allocator (documented divergence, OWNERSHIP_ATLAS section 8).
pub use crate;
/// Initialize the memory subsystem.
///
/// Called during `xmlInitParser`. Returns 0 on success.
pub const
/// Clean up the memory subsystem.
pub const
// ═══════════════════════════════════════════════════════════════════════════════
// Tests
// ═══════════════════════════════════════════════════════════════════════════════