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)]
8#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
9pub enum RelocatableHeaderTagPreference {
10 None = 0,
12 Low = 1,
15 High = 2,
18}
19
20#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
22#[repr(C, align(8))]
23pub struct RelocatableHeaderTag {
24 header: HeaderTagHeader,
25 min_addr: u32,
29 max_addr: u32,
33 align: u32,
35 preference: RelocatableHeaderTagPreference,
36}
37
38impl RelocatableHeaderTag {
39 #[must_use]
41 pub const fn new(
42 flags: HeaderTagFlag,
43 min_addr: u32,
44 max_addr: u32,
45 align: u32,
46 preference: RelocatableHeaderTagPreference,
47 ) -> Self {
48 let header =
49 HeaderTagHeader::new(HeaderTagType::Relocatable, flags, size_of::<Self>() as u32);
50 Self {
51 header,
52 min_addr,
53 max_addr,
54 align,
55 preference,
56 }
57 }
58
59 #[must_use]
61 pub const fn typ(&self) -> HeaderTagType {
62 self.header.typ()
63 }
64
65 #[must_use]
67 pub const fn flags(&self) -> HeaderTagFlag {
68 self.header.flags()
69 }
70
71 #[must_use]
73 pub const fn size(&self) -> u32 {
74 self.header.size()
75 }
76
77 #[must_use]
79 pub const fn min_addr(&self) -> u32 {
80 self.min_addr
81 }
82
83 #[must_use]
85 pub const fn max_addr(&self) -> u32 {
86 self.max_addr
87 }
88
89 #[must_use]
91 pub const fn align(&self) -> u32 {
92 self.align
93 }
94
95 #[must_use]
97 pub const fn preference(&self) -> RelocatableHeaderTagPreference {
98 self.preference
99 }
100}
101
102impl Debug for RelocatableHeaderTag {
103 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
104 f.debug_struct("RelocatableHeaderTag")
105 .field("type", &self.typ())
106 .field("flags", &self.flags())
107 .field("size", &self.size())
108 .field("min_addr", &self.min_addr)
110 .field("max_addr", &self.max_addr)
111 .field("align", &self.align)
112 .field("preference", &self.preference)
113 .finish()
114 }
115}
116
117impl MaybeDynSized for RelocatableHeaderTag {
118 type Header = HeaderTagHeader;
119
120 const BASE_SIZE: usize = size_of::<Self>();
121}
122
123impl Tag for RelocatableHeaderTag {
124 type IDType = HeaderTagType;
125 const ID: HeaderTagType = HeaderTagType::Relocatable;
126}
127
128#[cfg(test)]
129mod tests {
130 use crate::RelocatableHeaderTag;
131
132 #[test]
133 fn test_assert_size() {
134 assert_eq!(size_of::<RelocatableHeaderTag>(), 2 + 2 + 4 + 4 + 4 + 4 + 4);
135 }
136}