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#[derive(Clone, Copy, Debug, Eq, thiserror::Error, PartialEq)]
76pub enum MemoryManagerRangeError {
77 #[error("MemoryManager ID range is invalid: start={start} end={end}")]
79 InvalidRange {
80 start: u8,
82 end: u8,
84 },
85 #[error("MemoryManager ID {id} is not a usable allocation slot")]
87 InvalidMemoryManagerId {
88 id: u8,
90 },
91}
92
93#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
100pub enum MemoryManagerRangeMode {
101 Reserved,
105 Allowed,
109}
110
111#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
116#[serde(deny_unknown_fields)]
117pub struct MemoryManagerAuthorityRecord {
118 pub range: MemoryManagerIdRange,
120 pub authority: String,
122 pub mode: MemoryManagerRangeMode,
124 pub purpose: Option<String>,
126}
127
128impl MemoryManagerAuthorityRecord {
129 pub fn new(
131 range: MemoryManagerIdRange,
132 authority: impl Into<String>,
133 mode: MemoryManagerRangeMode,
134 purpose: Option<String>,
135 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
136 let record = Self {
137 range,
138 authority: authority.into(),
139 mode,
140 purpose,
141 };
142 validate_authority_record(&record)?;
143 Ok(record)
144 }
145}
146
147#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
162#[serde(deny_unknown_fields)]
163pub struct MemoryManagerRangeAuthority {
164 authorities: Vec<MemoryManagerAuthorityRecord>,
165}
166
167impl MemoryManagerRangeAuthority {
168 #[must_use]
170 pub const fn new() -> Self {
171 Self {
172 authorities: Vec::new(),
173 }
174 }
175
176 pub fn from_records(
181 records: Vec<MemoryManagerAuthorityRecord>,
182 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
183 let mut authority = Self::new();
184 for record in records {
185 authority = authority.insert_record(record)?;
186 }
187 Ok(authority)
188 }
189
190 pub fn reserve(
195 self,
196 range: MemoryManagerIdRange,
197 authority: impl Into<String>,
198 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
199 self.reserve_with_purpose(range, authority, None)
200 }
201
202 pub fn reserve_ids(
207 self,
208 start: u8,
209 end: u8,
210 authority: impl Into<String>,
211 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
212 self.reserve(MemoryManagerIdRange::new(start, end)?, authority)
213 }
214
215 pub fn reserve_with_purpose(
220 self,
221 range: MemoryManagerIdRange,
222 authority: impl Into<String>,
223 purpose: Option<String>,
224 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
225 self.insert(range, authority, MemoryManagerRangeMode::Reserved, purpose)
226 }
227
228 pub fn reserve_ids_with_purpose(
233 self,
234 start: u8,
235 end: u8,
236 authority: impl Into<String>,
237 purpose: Option<String>,
238 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
239 self.reserve_with_purpose(MemoryManagerIdRange::new(start, end)?, authority, purpose)
240 }
241
242 pub fn allow(
247 self,
248 range: MemoryManagerIdRange,
249 authority: impl Into<String>,
250 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
251 self.allow_with_purpose(range, authority, None)
252 }
253
254 pub fn allow_ids(
259 self,
260 start: u8,
261 end: u8,
262 authority: impl Into<String>,
263 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
264 self.allow(MemoryManagerIdRange::new(start, end)?, authority)
265 }
266
267 pub fn allow_with_purpose(
272 self,
273 range: MemoryManagerIdRange,
274 authority: impl Into<String>,
275 purpose: Option<String>,
276 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
277 self.insert(range, authority, MemoryManagerRangeMode::Allowed, purpose)
278 }
279
280 pub fn allow_ids_with_purpose(
285 self,
286 start: u8,
287 end: u8,
288 authority: impl Into<String>,
289 purpose: Option<String>,
290 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
291 self.allow_with_purpose(MemoryManagerIdRange::new(start, end)?, authority, purpose)
292 }
293
294 pub fn validate_slot_authority(
296 &self,
297 slot: &AllocationSlotDescriptor,
298 expected_authority: &str,
299 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
300 let id = slot
301 .memory_manager_id()
302 .map_err(MemoryManagerRangeAuthorityError::Slot)?;
303 self.validate_id_authority(id, expected_authority)
304 }
305
306 pub fn validate_slot_authority_mode(
308 &self,
309 slot: &AllocationSlotDescriptor,
310 expected_authority: &str,
311 expected_mode: MemoryManagerRangeMode,
312 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
313 let id = slot
314 .memory_manager_id()
315 .map_err(MemoryManagerRangeAuthorityError::Slot)?;
316 self.validate_id_authority_mode(id, expected_authority, expected_mode)
317 }
318
319 pub fn validate_id_authority(
321 &self,
322 id: u8,
323 expected_authority: &str,
324 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
325 validate_diagnostic_string("expected_authority", expected_authority)?;
326 let record = self.covering_record(id)?;
327
328 if record.authority != expected_authority {
329 return Err(MemoryManagerRangeAuthorityError::AuthorityMismatch {
330 id,
331 expected_authority: expected_authority.to_string(),
332 actual_authority: record.authority.clone(),
333 });
334 }
335
336 Ok(record)
337 }
338
339 pub fn validate_id_authority_mode(
341 &self,
342 id: u8,
343 expected_authority: &str,
344 expected_mode: MemoryManagerRangeMode,
345 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
346 let record = self.validate_id_authority(id, expected_authority)?;
347 if record.mode != expected_mode {
348 return Err(MemoryManagerRangeAuthorityError::ModeMismatch {
349 id,
350 authority: record.authority.clone(),
351 expected_mode,
352 actual_mode: record.mode,
353 });
354 }
355 Ok(record)
356 }
357
358 pub fn authority_for_id(
360 &self,
361 id: u8,
362 ) -> Result<Option<&MemoryManagerAuthorityRecord>, MemoryManagerRangeAuthorityError> {
363 validate_memory_manager_id(id).map_err(MemoryManagerRangeAuthorityError::Slot)?;
364 Ok(self
365 .authorities
366 .iter()
367 .find(|record| record.range.contains(id)))
368 }
369
370 #[must_use]
376 pub fn authorities(&self) -> &[MemoryManagerAuthorityRecord] {
377 &self.authorities
378 }
379
380 pub fn validate_complete_coverage(
386 &self,
387 target: MemoryManagerIdRange,
388 ) -> Result<(), MemoryManagerRangeAuthorityError> {
389 if self.authorities.is_empty() {
390 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
391 start: target.start(),
392 end: target.end(),
393 });
394 }
395
396 for record in &self.authorities {
397 if record.range.start() < target.start() || record.range.end() > target.end() {
398 return Err(
399 MemoryManagerRangeAuthorityError::RangeOutsideCoverageTarget {
400 start: record.range.start(),
401 end: record.range.end(),
402 target_start: target.start(),
403 target_end: target.end(),
404 },
405 );
406 }
407 }
408
409 let mut next_uncovered = u16::from(target.start());
410 let target_end = u16::from(target.end());
411 for record in &self.authorities {
412 let record_start = u16::from(record.range.start());
413 let record_end = u16::from(record.range.end());
414
415 if record_start > next_uncovered {
416 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
417 start: u8::try_from(next_uncovered).expect("valid MemoryManager ID"),
418 end: record.range.start() - 1,
419 });
420 }
421
422 if record_end >= next_uncovered {
423 next_uncovered = record_end + 1;
424 }
425 }
426
427 if next_uncovered <= target_end {
428 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
429 start: u8::try_from(next_uncovered).expect("valid MemoryManager ID"),
430 end: target.end(),
431 });
432 }
433
434 Ok(())
435 }
436
437 fn insert(
438 self,
439 range: MemoryManagerIdRange,
440 authority: impl Into<String>,
441 mode: MemoryManagerRangeMode,
442 purpose: Option<String>,
443 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
444 let record = MemoryManagerAuthorityRecord {
445 range,
446 authority: authority.into(),
447 mode,
448 purpose,
449 };
450 self.insert_record(record)
451 }
452
453 fn insert_record(
454 mut self,
455 record: MemoryManagerAuthorityRecord,
456 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
457 validate_authority_record(&record)?;
458
459 for existing in &self.authorities {
460 if ranges_overlap(existing.range, record.range) {
461 return Err(MemoryManagerRangeAuthorityError::OverlappingRanges {
462 existing_start: existing.range.start(),
463 existing_end: existing.range.end(),
464 candidate_start: record.range.start(),
465 candidate_end: record.range.end(),
466 });
467 }
468 }
469
470 self.authorities.push(record);
471 self.authorities.sort_by_key(|record| record.range.start());
472 Ok(self)
473 }
474
475 fn covering_record(
476 &self,
477 id: u8,
478 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
479 let Some(record) = self.authority_for_id(id)? else {
480 return Err(MemoryManagerRangeAuthorityError::UnclaimedId { id });
481 };
482 Ok(record)
483 }
484}
485
486fn validate_authority_record(
487 record: &MemoryManagerAuthorityRecord,
488) -> Result<(), MemoryManagerRangeAuthorityError> {
489 record.range.validate()?;
490 validate_diagnostic_string("authority", &record.authority)?;
491 if let Some(purpose) = &record.purpose {
492 validate_diagnostic_string("purpose", purpose)?;
493 }
494 Ok(())
495}
496
497#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
502pub enum MemoryManagerRangeAuthorityError {
503 #[error(transparent)]
505 Range(#[from] MemoryManagerRangeError),
506 #[error("{0}")]
508 Slot(#[from] MemoryManagerSlotError),
509 #[error(
511 "MemoryManager authority range {candidate_start}-{candidate_end} overlaps existing range {existing_start}-{existing_end}"
512 )]
513 OverlappingRanges {
514 existing_start: u8,
516 existing_end: u8,
518 candidate_start: u8,
520 candidate_end: u8,
522 },
523 #[error("{field} {reason}")]
525 InvalidDiagnosticString {
526 field: &'static str,
528 reason: &'static str,
530 },
531 #[error("MemoryManager ID {id} is not covered by an authority range")]
533 UnclaimedId {
534 id: u8,
536 },
537 #[error(
539 "MemoryManager ID {id} belongs to authority '{actual_authority}', not '{expected_authority}'"
540 )]
541 AuthorityMismatch {
542 id: u8,
544 expected_authority: String,
546 actual_authority: String,
548 },
549 #[error(
551 "MemoryManager ID {id} belongs to authority '{authority}' with mode {actual_mode:?}, not {expected_mode:?}"
552 )]
553 ModeMismatch {
554 id: u8,
556 authority: String,
558 expected_mode: MemoryManagerRangeMode,
560 actual_mode: MemoryManagerRangeMode,
562 },
563 #[error("MemoryManager authority coverage is missing range {start}-{end}")]
565 MissingCoverage {
566 start: u8,
568 end: u8,
570 },
571 #[error(
573 "MemoryManager authority range {start}-{end} is outside coverage target {target_start}-{target_end}"
574 )]
575 RangeOutsideCoverageTarget {
576 start: u8,
578 end: u8,
580 target_start: u8,
582 target_end: u8,
584 },
585}
586
587const fn ranges_overlap(left: MemoryManagerIdRange, right: MemoryManagerIdRange) -> bool {
588 left.start() <= right.end() && right.start() <= left.end()
589}
590
591fn validate_diagnostic_string(
592 field: &'static str,
593 value: &str,
594) -> Result<(), MemoryManagerRangeAuthorityError> {
595 if value.is_empty() {
596 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
597 field,
598 reason: "must not be empty",
599 });
600 }
601 if value.len() > DIAGNOSTIC_STRING_MAX_BYTES {
602 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
603 field,
604 reason: "must be at most 256 bytes",
605 });
606 }
607 if !value.is_ascii() {
608 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
609 field,
610 reason: "must be ASCII",
611 });
612 }
613 if value.bytes().any(|byte| byte.is_ascii_control()) {
614 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
615 field,
616 reason: "must not contain ASCII control characters",
617 });
618 }
619 Ok(())
620}