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 crate::constants::DIAGNOSTIC_STRING_MAX_BYTES;
7use serde::{Deserialize, Serialize};
8
9#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
14#[serde(deny_unknown_fields)]
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 pub const fn validate(&self) -> Result<(), MemoryManagerRangeError> {
52 match Self::new(self.start, self.end) {
53 Ok(_) => Ok(()),
54 Err(err) => Err(err),
55 }
56 }
57
58 #[must_use]
60 pub const fn start(&self) -> u8 {
61 self.start
62 }
63
64 #[must_use]
66 pub const fn end(&self) -> u8 {
67 self.end
68 }
69}
70
71#[non_exhaustive]
76#[derive(Clone, Copy, Debug, Eq, thiserror::Error, PartialEq)]
77pub enum MemoryManagerRangeError {
78 #[error("MemoryManager ID range is invalid: start={start} end={end}")]
80 InvalidRange {
81 start: u8,
83 end: u8,
85 },
86 #[error("MemoryManager ID {id} is not a usable allocation slot")]
88 InvalidMemoryManagerId {
89 id: u8,
91 },
92}
93
94#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
101pub enum MemoryManagerRangeMode {
102 Reserved,
106 Allowed,
110}
111
112#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
117#[serde(deny_unknown_fields)]
118pub struct MemoryManagerAuthorityRecord {
119 pub(crate) range: MemoryManagerIdRange,
121 pub(crate) authority: String,
123 pub(crate) mode: MemoryManagerRangeMode,
125 pub(crate) purpose: Option<String>,
127}
128
129impl MemoryManagerAuthorityRecord {
130 pub fn new(
132 range: MemoryManagerIdRange,
133 authority: impl Into<String>,
134 mode: MemoryManagerRangeMode,
135 purpose: Option<String>,
136 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
137 let record = Self {
138 range,
139 authority: authority.into(),
140 mode,
141 purpose,
142 };
143 validate_authority_record(&record)?;
144 Ok(record)
145 }
146
147 #[must_use]
149 pub const fn range(&self) -> MemoryManagerIdRange {
150 self.range
151 }
152
153 #[must_use]
155 pub fn authority(&self) -> &str {
156 &self.authority
157 }
158
159 #[must_use]
161 pub const fn mode(&self) -> MemoryManagerRangeMode {
162 self.mode
163 }
164
165 #[must_use]
167 pub fn purpose(&self) -> Option<&str> {
168 self.purpose.as_deref()
169 }
170}
171
172#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
187#[serde(deny_unknown_fields)]
188pub struct MemoryManagerRangeAuthority {
189 authorities: Vec<MemoryManagerAuthorityRecord>,
190}
191
192impl MemoryManagerRangeAuthority {
193 #[must_use]
195 pub const fn new() -> Self {
196 Self {
197 authorities: Vec::new(),
198 }
199 }
200
201 pub fn from_records(
206 records: Vec<MemoryManagerAuthorityRecord>,
207 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
208 let mut authority = Self::new();
209 for record in records {
210 authority = authority.insert_record(record)?;
211 }
212 Ok(authority)
213 }
214
215 pub fn reserve(
220 self,
221 range: MemoryManagerIdRange,
222 authority: impl Into<String>,
223 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
224 self.reserve_with_purpose(range, authority, None)
225 }
226
227 pub fn reserve_ids(
232 self,
233 start: u8,
234 end: u8,
235 authority: impl Into<String>,
236 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
237 self.reserve(MemoryManagerIdRange::new(start, end)?, authority)
238 }
239
240 pub fn reserve_with_purpose(
245 self,
246 range: MemoryManagerIdRange,
247 authority: impl Into<String>,
248 purpose: Option<String>,
249 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
250 self.insert(range, authority, MemoryManagerRangeMode::Reserved, purpose)
251 }
252
253 pub fn reserve_ids_with_purpose(
258 self,
259 start: u8,
260 end: u8,
261 authority: impl Into<String>,
262 purpose: Option<String>,
263 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
264 self.reserve_with_purpose(MemoryManagerIdRange::new(start, end)?, authority, purpose)
265 }
266
267 pub fn allow(
272 self,
273 range: MemoryManagerIdRange,
274 authority: impl Into<String>,
275 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
276 self.allow_with_purpose(range, authority, None)
277 }
278
279 pub fn allow_ids(
284 self,
285 start: u8,
286 end: u8,
287 authority: impl Into<String>,
288 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
289 self.allow(MemoryManagerIdRange::new(start, end)?, authority)
290 }
291
292 pub fn allow_with_purpose(
297 self,
298 range: MemoryManagerIdRange,
299 authority: impl Into<String>,
300 purpose: Option<String>,
301 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
302 self.insert(range, authority, MemoryManagerRangeMode::Allowed, purpose)
303 }
304
305 pub fn allow_ids_with_purpose(
310 self,
311 start: u8,
312 end: u8,
313 authority: impl Into<String>,
314 purpose: Option<String>,
315 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
316 self.allow_with_purpose(MemoryManagerIdRange::new(start, end)?, authority, purpose)
317 }
318
319 pub fn validate_slot_authority(
321 &self,
322 slot: &AllocationSlotDescriptor,
323 expected_authority: &str,
324 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
325 let id = slot
326 .memory_manager_id()
327 .map_err(MemoryManagerRangeAuthorityError::Slot)?;
328 self.validate_id_authority(id, expected_authority)
329 }
330
331 pub fn validate_slot_authority_mode(
333 &self,
334 slot: &AllocationSlotDescriptor,
335 expected_authority: &str,
336 expected_mode: MemoryManagerRangeMode,
337 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
338 let id = slot
339 .memory_manager_id()
340 .map_err(MemoryManagerRangeAuthorityError::Slot)?;
341 self.validate_id_authority_mode(id, expected_authority, expected_mode)
342 }
343
344 pub fn validate_id_authority(
346 &self,
347 id: u8,
348 expected_authority: &str,
349 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
350 validate_diagnostic_string("expected_authority", expected_authority)?;
351 let record = self.covering_record(id)?;
352
353 if record.authority != expected_authority {
354 return Err(MemoryManagerRangeAuthorityError::AuthorityMismatch {
355 id,
356 expected_authority: expected_authority.to_string(),
357 actual_authority: record.authority.clone(),
358 });
359 }
360
361 Ok(record)
362 }
363
364 pub fn validate_id_authority_mode(
366 &self,
367 id: u8,
368 expected_authority: &str,
369 expected_mode: MemoryManagerRangeMode,
370 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
371 let record = self.validate_id_authority(id, expected_authority)?;
372 if record.mode != expected_mode {
373 return Err(MemoryManagerRangeAuthorityError::ModeMismatch {
374 id,
375 authority: record.authority.clone(),
376 expected_mode,
377 actual_mode: record.mode,
378 });
379 }
380 Ok(record)
381 }
382
383 pub fn authority_for_id(
385 &self,
386 id: u8,
387 ) -> Result<Option<&MemoryManagerAuthorityRecord>, MemoryManagerRangeAuthorityError> {
388 validate_memory_manager_id(id).map_err(MemoryManagerRangeAuthorityError::Slot)?;
389 Ok(self
390 .authorities
391 .iter()
392 .find(|record| record.range.contains(id)))
393 }
394
395 #[must_use]
401 pub fn authorities(&self) -> &[MemoryManagerAuthorityRecord] {
402 &self.authorities
403 }
404
405 pub fn validate_complete_coverage(
411 &self,
412 target: MemoryManagerIdRange,
413 ) -> Result<(), MemoryManagerRangeAuthorityError> {
414 if self.authorities.is_empty() {
415 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
416 start: target.start(),
417 end: target.end(),
418 });
419 }
420
421 for record in &self.authorities {
422 if record.range.start() < target.start() || record.range.end() > target.end() {
423 return Err(
424 MemoryManagerRangeAuthorityError::RangeOutsideCoverageTarget {
425 start: record.range.start(),
426 end: record.range.end(),
427 target_start: target.start(),
428 target_end: target.end(),
429 },
430 );
431 }
432 }
433
434 let mut next_uncovered = u16::from(target.start());
435 let target_end = u16::from(target.end());
436 for record in &self.authorities {
437 let record_start = u16::from(record.range.start());
438 let record_end = u16::from(record.range.end());
439
440 if record_start > next_uncovered {
441 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
442 start: u8::try_from(next_uncovered).expect("valid MemoryManager ID"),
443 end: record.range.start() - 1,
444 });
445 }
446
447 if record_end >= next_uncovered {
448 next_uncovered = record_end + 1;
449 }
450 }
451
452 if next_uncovered <= target_end {
453 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
454 start: u8::try_from(next_uncovered).expect("valid MemoryManager ID"),
455 end: target.end(),
456 });
457 }
458
459 Ok(())
460 }
461
462 fn insert(
463 self,
464 range: MemoryManagerIdRange,
465 authority: impl Into<String>,
466 mode: MemoryManagerRangeMode,
467 purpose: Option<String>,
468 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
469 let record = MemoryManagerAuthorityRecord {
470 range,
471 authority: authority.into(),
472 mode,
473 purpose,
474 };
475 self.insert_record(record)
476 }
477
478 fn insert_record(
479 mut self,
480 record: MemoryManagerAuthorityRecord,
481 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
482 validate_authority_record(&record)?;
483
484 for existing in &self.authorities {
485 if ranges_overlap(existing.range, record.range) {
486 return Err(MemoryManagerRangeAuthorityError::OverlappingRanges {
487 existing_start: existing.range.start(),
488 existing_end: existing.range.end(),
489 candidate_start: record.range.start(),
490 candidate_end: record.range.end(),
491 });
492 }
493 }
494
495 self.authorities.push(record);
496 self.authorities.sort_by_key(|record| record.range.start());
497 Ok(self)
498 }
499
500 fn covering_record(
501 &self,
502 id: u8,
503 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
504 let Some(record) = self.authority_for_id(id)? else {
505 return Err(MemoryManagerRangeAuthorityError::UnclaimedId { id });
506 };
507 Ok(record)
508 }
509}
510
511fn validate_authority_record(
512 record: &MemoryManagerAuthorityRecord,
513) -> Result<(), MemoryManagerRangeAuthorityError> {
514 record.range.validate()?;
515 validate_diagnostic_string("authority", &record.authority)?;
516 if let Some(purpose) = &record.purpose {
517 validate_diagnostic_string("purpose", purpose)?;
518 }
519 Ok(())
520}
521
522#[non_exhaustive]
527#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
528pub enum MemoryManagerRangeAuthorityError {
529 #[error(transparent)]
531 Range(#[from] MemoryManagerRangeError),
532 #[error("{0}")]
534 Slot(#[from] MemoryManagerSlotError),
535 #[error(
537 "MemoryManager authority range {candidate_start}-{candidate_end} overlaps existing range {existing_start}-{existing_end}"
538 )]
539 OverlappingRanges {
540 existing_start: u8,
542 existing_end: u8,
544 candidate_start: u8,
546 candidate_end: u8,
548 },
549 #[error("{field} {reason}")]
551 InvalidDiagnosticString {
552 field: &'static str,
554 reason: &'static str,
556 },
557 #[error("MemoryManager ID {id} is not covered by an authority range")]
559 UnclaimedId {
560 id: u8,
562 },
563 #[error(
565 "MemoryManager ID {id} belongs to authority '{actual_authority}', not '{expected_authority}'"
566 )]
567 AuthorityMismatch {
568 id: u8,
570 expected_authority: String,
572 actual_authority: String,
574 },
575 #[error(
577 "MemoryManager ID {id} belongs to authority '{authority}' with mode {actual_mode:?}, not {expected_mode:?}"
578 )]
579 ModeMismatch {
580 id: u8,
582 authority: String,
584 expected_mode: MemoryManagerRangeMode,
586 actual_mode: MemoryManagerRangeMode,
588 },
589 #[error("MemoryManager authority coverage is missing range {start}-{end}")]
591 MissingCoverage {
592 start: u8,
594 end: u8,
596 },
597 #[error(
599 "MemoryManager authority range {start}-{end} is outside coverage target {target_start}-{target_end}"
600 )]
601 RangeOutsideCoverageTarget {
602 start: u8,
604 end: u8,
606 target_start: u8,
608 target_end: u8,
610 },
611}
612
613const fn ranges_overlap(left: MemoryManagerIdRange, right: MemoryManagerIdRange) -> bool {
614 left.start() <= right.end() && right.start() <= left.end()
615}
616
617fn validate_diagnostic_string(
618 field: &'static str,
619 value: &str,
620) -> Result<(), MemoryManagerRangeAuthorityError> {
621 if value.is_empty() {
622 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
623 field,
624 reason: "must not be empty",
625 });
626 }
627 if value.len() > DIAGNOSTIC_STRING_MAX_BYTES {
628 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
629 field,
630 reason: "must be at most 256 bytes",
631 });
632 }
633 if !value.is_ascii() {
634 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
635 field,
636 reason: "must be ASCII",
637 });
638 }
639 if value.bytes().any(|byte| byte.is_ascii_control()) {
640 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
641 field,
642 reason: "must not contain ASCII control characters",
643 });
644 }
645 Ok(())
646}