air_sys_types/mem.rs
1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5//! Types de la famille `mem` — mappings, protection, memfd, etc.
6//!
7//! Cf. `docs/specs/layer-0/family-mem.md`.
8
9use core::ptr::NonNull;
10
11use bitflags::bitflags;
12
13bitflags! {
14 /// Protections d'accès pour les mappings mémoire (`mmap`, `mprotect`).
15 ///
16 /// Correspond aux constantes `PROT_*` de `<sys/mman.h>`.
17 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
18 pub struct ProtectionFlags: i32 {
19 /// Aucun accès autorisé.
20 const NONE = 0;
21 /// Lecture autorisée.
22 const READ = 1;
23 /// Écriture autorisée.
24 const WRITE = 2;
25 /// Exécution autorisée.
26 const EXEC = 4;
27 }
28}
29
30bitflags! {
31 /// Drapeaux de type de mapping pour `mmap(2)`.
32 ///
33 /// Les drapeaux [`MapFlags::SHARED`] et [`MapFlags::PRIVATE`] sont
34 /// mutuellement exclusifs et obligatoires. Le wrapper valide ce
35 /// point avant l'appel syscall.
36 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
37 pub struct MapFlags: i32 {
38 /// Modifications visibles aux autres processus partageant le même
39 /// fichier/objet. Nécessaire pour memfd partagé entre processus.
40 const SHARED = 0x0000_0001;
41 /// Copie-on-write : les modifications ne sont pas répercutées vers
42 /// le fichier sous-jacent ni visibles par les autres processus.
43 const PRIVATE = 0x0000_0002;
44 /// Mappe exactement à l'adresse spécifiée. Écrase tout mapping
45 /// existant à cette adresse. Voir aussi `FIXED_NOREPLACE`.
46 const FIXED = 0x0000_0010;
47 /// Mapping anonyme sans fichier sous-jacent. Toujours positionné
48 /// par `mmap_anonymous`.
49 const ANONYMOUS = 0x0000_0020;
50 /// La pile grandit vers le bas (pile thread).
51 const GROWSDOWN = 0x0000_0100;
52 /// Empêche le fichier d'être ouvert en écriture (obsolète).
53 const DENYWRITE = 0x0000_0800;
54 /// Mapping exécutable (obsolète ; utilisez `ProtectionFlags::EXEC`).
55 const EXECUTABLE = 0x0000_1000;
56 /// Pages verrouillées en mémoire (comme `mlock`).
57 const LOCKED = 0x0000_2000;
58 /// Pas de réservation de swap pour ce mapping.
59 const NORESERVE = 0x0000_4000;
60 /// Pré-alloue les pages physiques (fault in) lors du mmap.
61 const POPULATE = 0x0000_8000;
62 /// Ne bloque pas lors de la pré-allocation des pages.
63 const NONBLOCK = 0x0001_0000;
64 /// Mapping de pile (hint kernel).
65 const STACK = 0x0002_0000;
66 /// Huge pages transparentes.
67 const HUGETLB = 0x0004_0000;
68 /// Synchronisation avec le fichier sur les accès directs.
69 const SYNC = 0x0008_0000;
70 /// Comme `FIXED` mais retourne `EEXIST` si l'adresse est déjà
71 /// occupée. Linux 4.17+. Préféré à `FIXED` dans les cas normaux.
72 const FIXED_NOREPLACE = 0x0010_0000;
73 }
74}
75
76bitflags! {
77 /// Drapeaux pour `mremap(2)`.
78 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
79 pub struct MremapFlags: i32 {
80 /// Autorise le déplacement du mapping si le redimensionnement
81 /// sur place est impossible.
82 const MAYMOVE = 1;
83 /// Déplace vers une adresse fixe (combiné avec `MAYMOVE`).
84 const FIXED = 2;
85 /// Garde le mapping source intact après déplacement.
86 /// Linux 5.7+.
87 const DONTUNMAP = 4;
88 }
89}
90
91/// Conseil kernel sur le pattern d'accès mémoire pour `madvise(2)`.
92///
93/// Ces conseils sont de simples hints : le kernel peut les ignorer.
94/// Les valeurs numériques correspondent aux constantes `MADV_*` de Linux.
95#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
96#[repr(i32)]
97pub enum MadviseAdvice {
98 /// Comportement normal (supprime les conseils précédents).
99 Normal = 0,
100 /// Accès aléatoires : désactive le préfetch.
101 Random = 1,
102 /// Accès séquentiels : active un préfetch agressif.
103 Sequential = 2,
104 /// Les pages seront bientôt accédées (préfetch immédiat).
105 WillNeed = 3,
106 /// Les pages ne sont plus nécessaires ; libère la mémoire physique
107 /// sans désallouer le mapping (les pages sont remises à zéro au
108 /// prochain accès).
109 DontNeed = 4,
110 /// Libère les pages propres sans désallouer (Linux 4.5+).
111 Free = 8,
112 /// Supprime les pages et l'espace de backing (seulement pour
113 /// `MAP_SHARED` sur des fichiers supportant `FALLOC_FL_PUNCH_HOLE`).
114 Remove = 9,
115 /// Les pages ne doivent pas être héritées par les processus fils.
116 DontFork = 10,
117 /// Annule `DONTFORK`.
118 DoFork = 11,
119 /// Active le KSM (Kernel Samepage Merging) pour ces pages.
120 Mergeable = 12,
121 /// Désactive le KSM pour ces pages.
122 Unmergeable = 13,
123 /// Active les huge pages transparentes.
124 HugePage = 14,
125 /// Désactive les huge pages transparentes.
126 NoHugePage = 15,
127 /// Exclut ces pages des core dumps.
128 DontDump = 16,
129 /// Réintègre ces pages dans les core dumps.
130 DoDump = 17,
131 /// Efface les pages lors d'un fork (Linux 4.14+).
132 WipeOnFork = 18,
133 /// Conserve les pages lors d'un fork (Linux 4.14+).
134 KeepOnFork = 19,
135 /// Indique que les pages sont "froides" (Linux 5.4+).
136 Cold = 20,
137 /// Pousse les pages vers le swap (Linux 5.4+).
138 PageOut = 21,
139 /// Pré-fault les pages en lecture (Linux 5.14+).
140 PopulateRead = 22,
141 /// Pré-fault les pages en écriture (Linux 5.14+).
142 PopulateWrite = 23,
143 /// Libère les pages verrouillées (Linux 5.18+).
144 DontNeedLocked = 24,
145 /// Compacte les huge pages transparentes (Linux 6.1+).
146 Collapse = 25,
147}
148
149bitflags! {
150 /// Drapeaux pour `mlock2(2)` (cf. `linux/mman.h`).
151 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
152 pub struct MlockFlags: u32 {
153 /// Verrouille les pages au fur et à mesure des fautes mémoire,
154 /// plutôt qu'immédiatement (Linux 4.4+).
155 const ONFAULT = 1;
156 }
157}
158
159bitflags! {
160 /// Drapeaux pour `mlockall(2)` (cf. `linux/mman.h`).
161 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
162 pub struct MlockallFlags: i32 {
163 /// Verrouille les pages du mapping actuel.
164 const CURRENT = 1;
165 /// Verrouille automatiquement les futures allocations.
166 const FUTURE = 2;
167 /// Verrouille au fur et à mesure des fautes (combiné avec
168 /// `CURRENT` ou `FUTURE`, Linux 4.4+).
169 const ONFAULT = 4;
170 }
171}
172
173bitflags! {
174 /// Drapeaux pour `memfd_create(2)` (cf. `linux/memfd.h`).
175 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
176 pub struct MemfdFlags: u32 {
177 /// Ferme le FD à l'`exec`.
178 const CLOEXEC = 0x0001;
179 /// Autorise le scellement du FD via `fcntl(F_ADD_SEALS)`.
180 /// Nécessaire pour partager en lecture seule via SCM_RIGHTS.
181 const ALLOW_SEALING = 0x0002;
182 /// Alloue des huge pages pour le backing store.
183 const HUGETLB = 0x0004;
184 /// Scelle automatiquement l'exécution à la création (Linux 6.3+).
185 const NOEXEC_SEAL = 0x0008;
186 /// Autorise l'exécution des pages (doit être combiné avec
187 /// un mapping `PROT_EXEC`, Linux 6.3+).
188 const EXEC = 0x0010;
189 }
190}
191
192bitflags! {
193 /// Drapeaux pour `msync(2)` (cf. `linux/mman.h`).
194 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
195 pub struct MsyncFlags: i32 {
196 /// Demande la synchronisation asynchrone (retourne immédiatement).
197 const ASYNC = 1;
198 /// Invalide les pages pour forcer un rechargement depuis le fichier.
199 const INVALIDATE = 2;
200 /// Attend que la synchronisation soit complète avant de retourner.
201 const SYNC = 4;
202 }
203}
204
205/// Segment mémoire distant pour `process_vm_readv`/`process_vm_writev`.
206///
207/// Décrit une plage de mémoire dans l'espace d'adressage d'un autre
208/// processus (adresse et longueur en octets). Correspond à `struct iovec`
209/// du côté remote dans le kernel (iova).
210///
211/// `#[repr(C)]` garantit la compatibilité de layout avec `struct iovec`
212/// du kernel Linux sur les architectures LP64 (x86_64, aarch64) :
213/// `{ iov_base: u64, iov_len: usize }`.
214#[repr(C)]
215#[derive(Debug, Clone, Copy)]
216pub struct RemoteIoSlice {
217 /// Adresse dans l'espace d'adressage du processus cible.
218 pub addr: u64,
219 /// Longueur en octets.
220 pub len: usize,
221}
222
223/// Pointeur brut vers un mapping mémoire sans ownership RAII.
224///
225/// Contrairement au type `Mapping` de `air-sys-syscall::mem`, ce type ne
226/// libère **pas** automatiquement la mémoire à la destruction. Il est
227/// utilisé pour les cas avancés (`mmap_fixed`) où l'appelant gère
228/// explicitement la durée de vie du mapping.
229///
230/// # Safety
231///
232/// L'appelant est responsable d'appeler `munmap` avec l'adresse et la
233/// longueur correctes avant que ce type soit abandonné, ou d'utiliser
234/// `mmap_fixed` pour remplacer le mapping.
235#[derive(Debug)]
236pub struct MappingPointer {
237 /// Adresse de base du mapping.
238 pub address: NonNull<u8>,
239 /// Longueur du mapping en octets.
240 pub length: usize,
241}
242
243// SAFETY: Un mapping mémoire est intrinsèquement un pointeur vers de la
244// mémoire partagée — Send + Sync sont corrects si l'accès concurrent est
245// géré par l'appelant (mutex, atomic, etc.). Le wrapper ne garantit pas
246// la synchronisation ; c'est la responsabilité de l'utilisateur.
247unsafe impl Send for MappingPointer {}
248unsafe impl Sync for MappingPointer {}