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, Deserializer, Serialize, de::Error as _};
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)]
119#[serde(deny_unknown_fields)]
120pub struct MemoryManagerAuthorityRecord {
121 pub(crate) range: MemoryManagerIdRange,
123 pub(crate) authority: String,
125 pub(crate) mode: MemoryManagerRangeMode,
127 #[serde(deserialize_with = "crate::cbor::deserialize_present_option")]
129 pub(crate) purpose: Option<String>,
130}
131
132impl MemoryManagerAuthorityRecord {
133 pub fn new(
135 range: MemoryManagerIdRange,
136 authority: impl Into<String>,
137 mode: MemoryManagerRangeMode,
138 purpose: Option<String>,
139 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
140 let record = Self {
141 range,
142 authority: authority.into(),
143 mode,
144 purpose,
145 };
146 validate_authority_record(&record)?;
147 Ok(record)
148 }
149
150 #[must_use]
152 pub const fn range(&self) -> MemoryManagerIdRange {
153 self.range
154 }
155
156 #[must_use]
158 pub fn authority(&self) -> &str {
159 &self.authority
160 }
161
162 #[must_use]
164 pub const fn mode(&self) -> MemoryManagerRangeMode {
165 self.mode
166 }
167
168 #[must_use]
170 pub fn purpose(&self) -> Option<&str> {
171 self.purpose.as_deref()
172 }
173
174 pub fn validate(&self) -> Result<(), MemoryManagerRangeAuthorityError> {
176 validate_authority_record(self)
177 }
178}
179
180#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize)]
199#[serde(deny_unknown_fields)]
200pub struct MemoryManagerRangeAuthority {
201 authorities: Vec<MemoryManagerAuthorityRecord>,
202}
203
204#[derive(Deserialize)]
205#[serde(deny_unknown_fields)]
206struct MemoryManagerRangeAuthorityDto {
207 authorities: Vec<MemoryManagerAuthorityRecord>,
208}
209
210impl<'de> Deserialize<'de> for MemoryManagerRangeAuthority {
211 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
212 let dto = MemoryManagerRangeAuthorityDto::deserialize(deserializer)?;
213 Self::from_records(dto.authorities).map_err(D::Error::custom)
214 }
215}
216
217impl MemoryManagerRangeAuthority {
218 #[must_use]
220 pub const fn new() -> Self {
221 Self {
222 authorities: Vec::new(),
223 }
224 }
225
226 pub fn from_records(
231 records: Vec<MemoryManagerAuthorityRecord>,
232 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
233 let mut authority = Self::new();
234 for record in records {
235 authority = authority.insert_record(record)?;
236 }
237 Ok(authority)
238 }
239
240 pub fn reserve(
245 self,
246 range: MemoryManagerIdRange,
247 authority: impl Into<String>,
248 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
249 self.reserve_with_purpose(range, authority, None)
250 }
251
252 pub fn reserve_ids(
257 self,
258 start: u8,
259 end: u8,
260 authority: impl Into<String>,
261 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
262 self.reserve(MemoryManagerIdRange::new(start, end)?, authority)
263 }
264
265 pub fn reserve_with_purpose(
270 self,
271 range: MemoryManagerIdRange,
272 authority: impl Into<String>,
273 purpose: Option<String>,
274 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
275 self.insert(range, authority, MemoryManagerRangeMode::Reserved, purpose)
276 }
277
278 pub fn reserve_ids_with_purpose(
283 self,
284 start: u8,
285 end: u8,
286 authority: impl Into<String>,
287 purpose: Option<String>,
288 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
289 self.reserve_with_purpose(MemoryManagerIdRange::new(start, end)?, authority, purpose)
290 }
291
292 pub fn allow(
297 self,
298 range: MemoryManagerIdRange,
299 authority: impl Into<String>,
300 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
301 self.allow_with_purpose(range, authority, None)
302 }
303
304 pub fn allow_ids(
309 self,
310 start: u8,
311 end: u8,
312 authority: impl Into<String>,
313 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
314 self.allow(MemoryManagerIdRange::new(start, end)?, authority)
315 }
316
317 pub fn allow_with_purpose(
322 self,
323 range: MemoryManagerIdRange,
324 authority: impl Into<String>,
325 purpose: Option<String>,
326 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
327 self.insert(range, authority, MemoryManagerRangeMode::Allowed, purpose)
328 }
329
330 pub fn allow_ids_with_purpose(
335 self,
336 start: u8,
337 end: u8,
338 authority: impl Into<String>,
339 purpose: Option<String>,
340 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
341 self.allow_with_purpose(MemoryManagerIdRange::new(start, end)?, authority, purpose)
342 }
343
344 pub fn validate_slot_authority(
346 &self,
347 slot: &AllocationSlotDescriptor,
348 expected_authority: &str,
349 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
350 let id = slot
351 .memory_manager_id()
352 .map_err(MemoryManagerRangeAuthorityError::Slot)?;
353 self.validate_id_authority(id, expected_authority)
354 }
355
356 pub fn validate_slot_authority_mode(
358 &self,
359 slot: &AllocationSlotDescriptor,
360 expected_authority: &str,
361 expected_mode: MemoryManagerRangeMode,
362 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
363 let id = slot
364 .memory_manager_id()
365 .map_err(MemoryManagerRangeAuthorityError::Slot)?;
366 self.validate_id_authority_mode(id, expected_authority, expected_mode)
367 }
368
369 pub fn validate_id_authority(
371 &self,
372 id: u8,
373 expected_authority: &str,
374 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
375 validate_diagnostic_string("expected_authority", expected_authority)?;
376 let record = self.covering_record(id)?;
377
378 if record.authority != expected_authority {
379 return Err(MemoryManagerRangeAuthorityError::AuthorityMismatch {
380 id,
381 expected_authority: expected_authority.to_string(),
382 actual_authority: record.authority.clone(),
383 });
384 }
385
386 Ok(record)
387 }
388
389 pub fn validate_id_authority_mode(
391 &self,
392 id: u8,
393 expected_authority: &str,
394 expected_mode: MemoryManagerRangeMode,
395 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
396 let record = self.validate_id_authority(id, expected_authority)?;
397 if record.mode != expected_mode {
398 return Err(MemoryManagerRangeAuthorityError::ModeMismatch {
399 id,
400 authority: record.authority.clone(),
401 expected_mode,
402 actual_mode: record.mode,
403 });
404 }
405 Ok(record)
406 }
407
408 pub fn authority_for_id(
410 &self,
411 id: u8,
412 ) -> Result<Option<&MemoryManagerAuthorityRecord>, MemoryManagerRangeAuthorityError> {
413 validate_memory_manager_id(id).map_err(MemoryManagerRangeAuthorityError::Slot)?;
414 Ok(self
415 .authorities
416 .iter()
417 .find(|record| record.range.contains(id)))
418 }
419
420 #[must_use]
426 pub fn authorities(&self) -> &[MemoryManagerAuthorityRecord] {
427 &self.authorities
428 }
429
430 pub fn validate_complete_coverage(
436 &self,
437 target: MemoryManagerIdRange,
438 ) -> Result<(), MemoryManagerRangeAuthorityError> {
439 if self.authorities.is_empty() {
440 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
441 start: target.start(),
442 end: target.end(),
443 });
444 }
445
446 for record in &self.authorities {
447 if record.range.start() < target.start() || record.range.end() > target.end() {
448 return Err(
449 MemoryManagerRangeAuthorityError::RangeOutsideCoverageTarget {
450 start: record.range.start(),
451 end: record.range.end(),
452 target_start: target.start(),
453 target_end: target.end(),
454 },
455 );
456 }
457 }
458
459 let mut next_uncovered = u16::from(target.start());
460 let target_end = u16::from(target.end());
461 for record in &self.authorities {
462 let record_start = u16::from(record.range.start());
463 let record_end = u16::from(record.range.end());
464
465 if record_start > next_uncovered {
466 let start = u8::try_from(next_uncovered).map_err(|_| {
467 MemoryManagerRangeAuthorityError::MissingCoverage {
468 start: target.start(),
469 end: target.end(),
470 }
471 })?;
472 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
473 start,
474 end: record.range.start() - 1,
475 });
476 }
477
478 if record_end >= next_uncovered {
479 next_uncovered = record_end + 1;
480 }
481 }
482
483 if next_uncovered <= target_end {
484 let start = u8::try_from(next_uncovered).map_err(|_| {
485 MemoryManagerRangeAuthorityError::MissingCoverage {
486 start: target.start(),
487 end: target.end(),
488 }
489 })?;
490 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
491 start,
492 end: target.end(),
493 });
494 }
495
496 Ok(())
497 }
498
499 fn insert(
500 self,
501 range: MemoryManagerIdRange,
502 authority: impl Into<String>,
503 mode: MemoryManagerRangeMode,
504 purpose: Option<String>,
505 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
506 let record = MemoryManagerAuthorityRecord {
507 range,
508 authority: authority.into(),
509 mode,
510 purpose,
511 };
512 self.insert_record(record)
513 }
514
515 fn insert_record(
516 mut self,
517 record: MemoryManagerAuthorityRecord,
518 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
519 validate_authority_record(&record)?;
520
521 for existing in &self.authorities {
522 if ranges_overlap(existing.range, record.range) {
523 return Err(MemoryManagerRangeAuthorityError::OverlappingRanges {
524 existing_start: existing.range.start(),
525 existing_end: existing.range.end(),
526 candidate_start: record.range.start(),
527 candidate_end: record.range.end(),
528 });
529 }
530 }
531
532 self.authorities.push(record);
533 self.authorities.sort_by_key(|record| record.range.start());
534 Ok(self)
535 }
536
537 fn covering_record(
538 &self,
539 id: u8,
540 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
541 let Some(record) = self.authority_for_id(id)? else {
542 return Err(MemoryManagerRangeAuthorityError::UnclaimedId { id });
543 };
544 Ok(record)
545 }
546}
547
548fn validate_authority_record(
549 record: &MemoryManagerAuthorityRecord,
550) -> Result<(), MemoryManagerRangeAuthorityError> {
551 record.range.validate()?;
552 validate_diagnostic_string("authority", &record.authority)?;
553 if let Some(purpose) = &record.purpose {
554 validate_diagnostic_string("purpose", purpose)?;
555 }
556 Ok(())
557}
558
559#[non_exhaustive]
564#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
565pub enum MemoryManagerRangeAuthorityError {
566 #[error(transparent)]
568 Range(#[from] MemoryManagerRangeError),
569 #[error("{0}")]
571 Slot(#[from] MemoryManagerSlotError),
572 #[error(
574 "MemoryManager authority range {candidate_start}-{candidate_end} overlaps existing range {existing_start}-{existing_end}"
575 )]
576 OverlappingRanges {
577 existing_start: u8,
579 existing_end: u8,
581 candidate_start: u8,
583 candidate_end: u8,
585 },
586 #[error("{field} {reason}")]
588 InvalidDiagnosticString {
589 field: &'static str,
591 reason: &'static str,
593 },
594 #[error("MemoryManager ID {id} is not covered by an authority range")]
596 UnclaimedId {
597 id: u8,
599 },
600 #[error(
602 "MemoryManager ID {id} belongs to authority '{actual_authority}', not '{expected_authority}'"
603 )]
604 AuthorityMismatch {
605 id: u8,
607 expected_authority: String,
609 actual_authority: String,
611 },
612 #[error(
614 "MemoryManager ID {id} belongs to authority '{authority}' with mode {actual_mode:?}, not {expected_mode:?}"
615 )]
616 ModeMismatch {
617 id: u8,
619 authority: String,
621 expected_mode: MemoryManagerRangeMode,
623 actual_mode: MemoryManagerRangeMode,
625 },
626 #[error("MemoryManager authority coverage is missing range {start}-{end}")]
628 MissingCoverage {
629 start: u8,
631 end: u8,
633 },
634 #[error(
636 "MemoryManager authority range {start}-{end} is outside coverage target {target_start}-{target_end}"
637 )]
638 RangeOutsideCoverageTarget {
639 start: u8,
641 end: u8,
643 target_start: u8,
645 target_end: u8,
647 },
648}
649
650const fn ranges_overlap(left: MemoryManagerIdRange, right: MemoryManagerIdRange) -> bool {
651 left.start() <= right.end() && right.start() <= left.end()
652}
653
654fn validate_diagnostic_string(
655 field: &'static str,
656 value: &str,
657) -> Result<(), MemoryManagerRangeAuthorityError> {
658 if value.is_empty() {
659 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
660 field,
661 reason: "must not be empty",
662 });
663 }
664 if value.len() > DIAGNOSTIC_STRING_MAX_BYTES {
665 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
666 field,
667 reason: "must be at most 256 bytes",
668 });
669 }
670 if !value.is_ascii() {
671 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
672 field,
673 reason: "must be ASCII",
674 });
675 }
676 if value.bytes().any(|byte| byte.is_ascii_control()) {
677 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
678 field,
679 reason: "must not contain ASCII control characters",
680 });
681 }
682 Ok(())
683}