1use super::descriptor::AllocationSlotDescriptor;
2use super::memory_manager::{
3 MEMORY_MANAGER_INVALID_ID, MEMORY_MANAGER_MAX_ID, MEMORY_MANAGER_MIN_ID,
4 MemoryManagerSlotError, validate_memory_manager_id,
5};
6use serde::{Deserialize, Serialize};
7
8const DIAGNOSTIC_STRING_MAX_BYTES: usize = 256;
9
10#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
15pub struct MemoryManagerIdRange {
16 pub(crate) start: u8,
17 pub(crate) end: u8,
18}
19
20impl MemoryManagerIdRange {
21 pub const fn new(start: u8, end: u8) -> Result<Self, MemoryManagerRangeError> {
23 if start > end {
24 return Err(MemoryManagerRangeError::InvalidRange { start, end });
25 }
26 if start == MEMORY_MANAGER_INVALID_ID {
27 return Err(MemoryManagerRangeError::InvalidMemoryManagerId { id: start });
28 }
29 if end == MEMORY_MANAGER_INVALID_ID {
30 return Err(MemoryManagerRangeError::InvalidMemoryManagerId { id: end });
31 }
32 Ok(Self { start, end })
33 }
34
35 #[must_use]
37 pub const fn all_usable() -> Self {
38 Self {
39 start: MEMORY_MANAGER_MIN_ID,
40 end: MEMORY_MANAGER_MAX_ID,
41 }
42 }
43
44 #[must_use]
46 pub const fn contains(&self, id: u8) -> bool {
47 id >= self.start && id <= self.end
48 }
49
50 #[must_use]
52 pub const fn start(&self) -> u8 {
53 self.start
54 }
55
56 #[must_use]
58 pub const fn end(&self) -> u8 {
59 self.end
60 }
61}
62
63#[derive(Clone, Copy, Debug, Eq, thiserror::Error, PartialEq)]
68pub enum MemoryManagerRangeError {
69 #[error("MemoryManager ID range is invalid: start={start} end={end}")]
71 InvalidRange {
72 start: u8,
74 end: u8,
76 },
77 #[error("MemoryManager ID {id} is not a usable allocation slot")]
79 InvalidMemoryManagerId {
80 id: u8,
82 },
83}
84
85#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
92pub enum MemoryManagerRangeMode {
93 Reserved,
97 Allowed,
101}
102
103#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
108pub struct MemoryManagerAuthorityRecord {
109 pub range: MemoryManagerIdRange,
111 pub authority: String,
113 pub mode: MemoryManagerRangeMode,
115 pub purpose: Option<String>,
117}
118
119impl MemoryManagerAuthorityRecord {
120 pub fn new(
122 range: MemoryManagerIdRange,
123 authority: impl Into<String>,
124 mode: MemoryManagerRangeMode,
125 purpose: Option<String>,
126 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
127 let record = Self {
128 range,
129 authority: authority.into(),
130 mode,
131 purpose,
132 };
133 validate_authority_record(&record)?;
134 Ok(record)
135 }
136}
137
138#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
148pub struct MemoryManagerRangeAuthority {
149 authorities: Vec<MemoryManagerAuthorityRecord>,
150}
151
152impl MemoryManagerRangeAuthority {
153 #[must_use]
155 pub const fn new() -> Self {
156 Self {
157 authorities: Vec::new(),
158 }
159 }
160
161 pub fn from_records(
166 records: Vec<MemoryManagerAuthorityRecord>,
167 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
168 let mut authority = Self::new();
169 for record in records {
170 authority = authority.insert_record(record)?;
171 }
172 Ok(authority)
173 }
174
175 pub fn reserve(
180 self,
181 range: MemoryManagerIdRange,
182 authority: impl Into<String>,
183 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
184 self.reserve_with_purpose(range, authority, None)
185 }
186
187 pub fn reserve_ids(
192 self,
193 start: u8,
194 end: u8,
195 authority: impl Into<String>,
196 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
197 self.reserve(MemoryManagerIdRange::new(start, end)?, authority)
198 }
199
200 pub fn reserve_with_purpose(
205 self,
206 range: MemoryManagerIdRange,
207 authority: impl Into<String>,
208 purpose: Option<String>,
209 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
210 self.insert(range, authority, MemoryManagerRangeMode::Reserved, purpose)
211 }
212
213 pub fn reserve_ids_with_purpose(
218 self,
219 start: u8,
220 end: u8,
221 authority: impl Into<String>,
222 purpose: Option<String>,
223 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
224 self.reserve_with_purpose(MemoryManagerIdRange::new(start, end)?, authority, purpose)
225 }
226
227 pub fn allow(
232 self,
233 range: MemoryManagerIdRange,
234 authority: impl Into<String>,
235 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
236 self.allow_with_purpose(range, authority, None)
237 }
238
239 pub fn allow_ids(
244 self,
245 start: u8,
246 end: u8,
247 authority: impl Into<String>,
248 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
249 self.allow(MemoryManagerIdRange::new(start, end)?, authority)
250 }
251
252 pub fn allow_with_purpose(
257 self,
258 range: MemoryManagerIdRange,
259 authority: impl Into<String>,
260 purpose: Option<String>,
261 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
262 self.insert(range, authority, MemoryManagerRangeMode::Allowed, purpose)
263 }
264
265 pub fn allow_ids_with_purpose(
270 self,
271 start: u8,
272 end: u8,
273 authority: impl Into<String>,
274 purpose: Option<String>,
275 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
276 self.allow_with_purpose(MemoryManagerIdRange::new(start, end)?, authority, purpose)
277 }
278
279 pub fn validate_slot_authority(
281 &self,
282 slot: &AllocationSlotDescriptor,
283 expected_authority: &str,
284 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
285 let id = slot
286 .memory_manager_id()
287 .map_err(MemoryManagerRangeAuthorityError::Slot)?;
288 self.validate_id_authority(id, expected_authority)
289 }
290
291 pub fn validate_slot_authority_mode(
293 &self,
294 slot: &AllocationSlotDescriptor,
295 expected_authority: &str,
296 expected_mode: MemoryManagerRangeMode,
297 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
298 let id = slot
299 .memory_manager_id()
300 .map_err(MemoryManagerRangeAuthorityError::Slot)?;
301 self.validate_id_authority_mode(id, expected_authority, expected_mode)
302 }
303
304 pub fn validate_id_authority(
306 &self,
307 id: u8,
308 expected_authority: &str,
309 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
310 validate_diagnostic_string("expected_authority", expected_authority)?;
311 let record = self.covering_record(id)?;
312
313 if record.authority != expected_authority {
314 return Err(MemoryManagerRangeAuthorityError::AuthorityMismatch {
315 id,
316 expected_authority: expected_authority.to_string(),
317 actual_authority: record.authority.clone(),
318 });
319 }
320
321 Ok(record)
322 }
323
324 pub fn validate_id_authority_mode(
326 &self,
327 id: u8,
328 expected_authority: &str,
329 expected_mode: MemoryManagerRangeMode,
330 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
331 let record = self.validate_id_authority(id, expected_authority)?;
332 if record.mode != expected_mode {
333 return Err(MemoryManagerRangeAuthorityError::ModeMismatch {
334 id,
335 authority: record.authority.clone(),
336 expected_mode,
337 actual_mode: record.mode,
338 });
339 }
340 Ok(record)
341 }
342
343 pub fn authority_for_id(
345 &self,
346 id: u8,
347 ) -> Result<Option<&MemoryManagerAuthorityRecord>, MemoryManagerRangeAuthorityError> {
348 validate_memory_manager_id(id).map_err(MemoryManagerRangeAuthorityError::Slot)?;
349 Ok(self
350 .authorities
351 .iter()
352 .find(|record| record.range.contains(id)))
353 }
354
355 #[must_use]
361 pub fn authorities(&self) -> &[MemoryManagerAuthorityRecord] {
362 &self.authorities
363 }
364
365 #[must_use]
367 pub fn to_records(&self) -> Vec<MemoryManagerAuthorityRecord> {
368 self.authorities.clone()
369 }
370
371 pub fn validate_complete_coverage(
377 &self,
378 target: MemoryManagerIdRange,
379 ) -> Result<(), MemoryManagerRangeAuthorityError> {
380 if self.authorities.is_empty() {
381 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
382 start: target.start(),
383 end: target.end(),
384 });
385 }
386
387 for record in &self.authorities {
388 if record.range.start() < target.start() || record.range.end() > target.end() {
389 return Err(
390 MemoryManagerRangeAuthorityError::RangeOutsideCoverageTarget {
391 start: record.range.start(),
392 end: record.range.end(),
393 target_start: target.start(),
394 target_end: target.end(),
395 },
396 );
397 }
398 }
399
400 let mut next_uncovered = u16::from(target.start());
401 let target_end = u16::from(target.end());
402 for record in &self.authorities {
403 let record_start = u16::from(record.range.start());
404 let record_end = u16::from(record.range.end());
405
406 if record_start > next_uncovered {
407 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
408 start: u8::try_from(next_uncovered).expect("valid MemoryManager ID"),
409 end: record.range.start() - 1,
410 });
411 }
412
413 if record_end >= next_uncovered {
414 next_uncovered = record_end + 1;
415 }
416 }
417
418 if next_uncovered <= target_end {
419 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
420 start: u8::try_from(next_uncovered).expect("valid MemoryManager ID"),
421 end: target.end(),
422 });
423 }
424
425 Ok(())
426 }
427
428 fn insert(
429 self,
430 range: MemoryManagerIdRange,
431 authority: impl Into<String>,
432 mode: MemoryManagerRangeMode,
433 purpose: Option<String>,
434 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
435 let record = MemoryManagerAuthorityRecord {
436 range,
437 authority: authority.into(),
438 mode,
439 purpose,
440 };
441 self.insert_record(record)
442 }
443
444 fn insert_record(
445 mut self,
446 record: MemoryManagerAuthorityRecord,
447 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
448 validate_authority_record(&record)?;
449
450 for existing in &self.authorities {
451 if ranges_overlap(existing.range, record.range) {
452 return Err(MemoryManagerRangeAuthorityError::OverlappingRanges {
453 existing_start: existing.range.start(),
454 existing_end: existing.range.end(),
455 candidate_start: record.range.start(),
456 candidate_end: record.range.end(),
457 });
458 }
459 }
460
461 self.authorities.push(record);
462 self.authorities.sort_by_key(|record| record.range.start());
463 Ok(self)
464 }
465
466 fn covering_record(
467 &self,
468 id: u8,
469 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
470 let Some(record) = self.authority_for_id(id)? else {
471 return Err(MemoryManagerRangeAuthorityError::UnclaimedId { id });
472 };
473 Ok(record)
474 }
475}
476
477fn validate_authority_record(
478 record: &MemoryManagerAuthorityRecord,
479) -> Result<(), MemoryManagerRangeAuthorityError> {
480 validate_diagnostic_string("authority", &record.authority)?;
481 if let Some(purpose) = &record.purpose {
482 validate_diagnostic_string("purpose", purpose)?;
483 }
484 Ok(())
485}
486
487#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
492pub enum MemoryManagerRangeAuthorityError {
493 #[error(transparent)]
495 Range(#[from] MemoryManagerRangeError),
496 #[error("{0}")]
498 Slot(#[from] MemoryManagerSlotError),
499 #[error(
501 "MemoryManager authority range {candidate_start}-{candidate_end} overlaps existing range {existing_start}-{existing_end}"
502 )]
503 OverlappingRanges {
504 existing_start: u8,
506 existing_end: u8,
508 candidate_start: u8,
510 candidate_end: u8,
512 },
513 #[error("{field} {reason}")]
515 InvalidDiagnosticString {
516 field: &'static str,
518 reason: &'static str,
520 },
521 #[error("MemoryManager ID {id} is not covered by an authority range")]
523 UnclaimedId {
524 id: u8,
526 },
527 #[error(
529 "MemoryManager ID {id} belongs to authority '{actual_authority}', not '{expected_authority}'"
530 )]
531 AuthorityMismatch {
532 id: u8,
534 expected_authority: String,
536 actual_authority: String,
538 },
539 #[error(
541 "MemoryManager ID {id} belongs to authority '{authority}' with mode {actual_mode:?}, not {expected_mode:?}"
542 )]
543 ModeMismatch {
544 id: u8,
546 authority: String,
548 expected_mode: MemoryManagerRangeMode,
550 actual_mode: MemoryManagerRangeMode,
552 },
553 #[error("MemoryManager authority coverage is missing range {start}-{end}")]
555 MissingCoverage {
556 start: u8,
558 end: u8,
560 },
561 #[error(
563 "MemoryManager authority range {start}-{end} is outside coverage target {target_start}-{target_end}"
564 )]
565 RangeOutsideCoverageTarget {
566 start: u8,
568 end: u8,
570 target_start: u8,
572 target_end: u8,
574 },
575}
576
577const fn ranges_overlap(left: MemoryManagerIdRange, right: MemoryManagerIdRange) -> bool {
578 left.start() <= right.end() && right.start() <= left.end()
579}
580
581fn validate_diagnostic_string(
582 field: &'static str,
583 value: &str,
584) -> Result<(), MemoryManagerRangeAuthorityError> {
585 if value.is_empty() {
586 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
587 field,
588 reason: "must not be empty",
589 });
590 }
591 if value.len() > DIAGNOSTIC_STRING_MAX_BYTES {
592 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
593 field,
594 reason: "must be at most 256 bytes",
595 });
596 }
597 if !value.is_ascii() {
598 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
599 field,
600 reason: "must be ASCII",
601 });
602 }
603 if value.bytes().any(|byte| byte.is_ascii_control()) {
604 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
605 field,
606 reason: "must not contain ASCII control characters",
607 });
608 }
609 Ok(())
610}
611
612impl crate::policy::RangeAuthority for MemoryManagerRangeAuthority {
613 type Error = MemoryManagerRangeAuthorityError;
614
615 fn validate_slot(&self, slot: &AllocationSlotDescriptor) -> Result<(), Self::Error> {
616 let id = slot.memory_manager_id()?;
617 if self.authority_for_id(id)?.is_none() {
618 return Err(MemoryManagerRangeAuthorityError::UnclaimedId { id });
619 }
620 Ok(())
621 }
622}