multiboot2_header/
relocatable.rs1use crate::{HeaderTagFlag, HeaderTagHeader, HeaderTagType};
2use core::fmt;
3use core::fmt::{Debug, Formatter};
4use multiboot2_common::{MaybeDynSized, Tag};
5
6#[repr(u32)]
12#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
13pub enum RelocatableHeaderTagPreference {
14 None = 0,
16 Low = 1,
18 High = 2,
20}
21
22#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
24#[repr(C, align(8))]
25pub struct RelocatableHeaderTag {
26 header: HeaderTagHeader,
27 min_addr: u32,
29 max_addr: u32,
31 align: u32,
33 preference: RelocatableHeaderTagPreference,
34}
35
36impl RelocatableHeaderTag {
37 #[must_use]
39 pub const fn new(
40 flags: HeaderTagFlag,
41 min_addr: u32,
42 max_addr: u32,
43 align: u32,
44 preference: RelocatableHeaderTagPreference,
45 ) -> Self {
46 let header =
47 HeaderTagHeader::new(HeaderTagType::Relocatable, flags, size_of::<Self>() as u32);
48 Self {
49 header,
50 min_addr,
51 max_addr,
52 align,
53 preference,
54 }
55 }
56
57 #[must_use]
59 pub const fn typ(&self) -> HeaderTagType {
60 self.header.typ()
61 }
62
63 #[must_use]
65 pub const fn flags(&self) -> HeaderTagFlag {
66 self.header.flags()
67 }
68
69 #[must_use]
71 pub const fn size(&self) -> u32 {
72 self.header.size()
73 }
74
75 #[must_use]
77 pub const fn min_addr(&self) -> u32 {
78 self.min_addr
79 }
80
81 #[must_use]
83 pub const fn max_addr(&self) -> u32 {
84 self.max_addr
85 }
86
87 #[must_use]
89 pub const fn align(&self) -> u32 {
90 self.align
91 }
92
93 #[must_use]
95 pub const fn preference(&self) -> RelocatableHeaderTagPreference {
96 self.preference
97 }
98}
99
100impl Debug for RelocatableHeaderTag {
101 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
102 f.debug_struct("RelocatableHeaderTag")
103 .field("type", &self.typ())
104 .field("flags", &self.flags())
105 .field("size", &self.size())
106 .field("min_addr", &self.min_addr)
108 .field("max_addr", &self.max_addr)
109 .field("align", &self.align)
110 .field("preference", &self.preference)
111 .finish()
112 }
113}
114
115impl MaybeDynSized for RelocatableHeaderTag {
116 type Header = HeaderTagHeader;
117
118 const BASE_SIZE: usize = size_of::<Self>();
119}
120
121impl Tag for RelocatableHeaderTag {
122 type IDType = HeaderTagType;
123 const ID: HeaderTagType = HeaderTagType::Relocatable;
124}
125
126#[cfg(test)]
127mod tests {
128 use crate::RelocatableHeaderTag;
129
130 #[test]
131 fn test_assert_size() {
132 assert_eq!(size_of::<RelocatableHeaderTag>(), 2 + 2 + 4 + 4 + 4 + 4 + 4);
133 }
134}