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