xmas_elf/
dynamic.rs

1use core::fmt;
2use zero::Pod;
3use {P32, P64};
4
5#[derive(Debug)]
6#[repr(C)]
7pub struct Dynamic<P>
8where
9    Tag_<P>: fmt::Debug,
10{
11    tag: Tag_<P>,
12    un: P,
13}
14
15unsafe impl<P> Pod for Dynamic<P> where Tag_<P>: fmt::Debug {}
16
17#[derive(Copy, Clone)]
18pub struct Tag_<P>(P);
19
20#[derive(Debug, PartialEq, Eq)]
21pub enum Tag<P> {
22    Null,
23    Needed,
24    PltRelSize,
25    Pltgot,
26    Hash,
27    StrTab,
28    SymTab,
29    Rela,
30    RelaSize,
31    RelaEnt,
32    StrSize,
33    SymEnt,
34    Init,
35    Fini,
36    SoName,
37    RPath,
38    Symbolic,
39    Rel,
40    RelSize,
41    RelEnt,
42    PltRel,
43    Debug,
44    TextRel,
45    JmpRel,
46    BindNow,
47    InitArray,
48    FiniArray,
49    InitArraySize,
50    FiniArraySize,
51    RunPath,
52    Flags,
53    PreInitArray,
54    PreInitArraySize,
55    SymTabShIndex,
56    RelrSize,
57    Relr,
58    RelrEnt,
59    Flags1,
60    OsSpecific(P),
61    ProcessorSpecific(P),
62}
63
64macro_rules! impls {
65    ($p: ident) => {
66        impl Dynamic<$p> {
67            pub fn get_tag(&self) -> Result<Tag<$p>, &'static str> {
68                self.tag.as_tag()
69            }
70
71            pub fn get_val(&self) -> Result<$p, &'static str> {
72                match self.get_tag()? {
73                    Tag::Needed
74                    | Tag::PltRelSize
75                    | Tag::RelaSize
76                    | Tag::RelaEnt
77                    | Tag::StrSize
78                    | Tag::SymEnt
79                    | Tag::SoName
80                    | Tag::RPath
81                    | Tag::RelSize
82                    | Tag::RelEnt
83                    | Tag::PltRel
84                    | Tag::InitArraySize
85                    | Tag::FiniArraySize
86                    | Tag::RunPath
87                    | Tag::Flags
88                    | Tag::PreInitArraySize
89                    | Tag::RelrSize
90                    | Tag::RelrEnt
91                    | Tag::Flags1
92                    | Tag::OsSpecific(_)
93                    | Tag::ProcessorSpecific(_) => Ok(self.un),
94                    _ => Err("Invalid value"),
95                }
96            }
97
98            pub fn get_ptr(&self) -> Result<$p, &'static str> {
99                match self.get_tag()? {
100                    Tag::Pltgot
101                    | Tag::Hash
102                    | Tag::StrTab
103                    | Tag::SymTab
104                    | Tag::Rela
105                    | Tag::Init
106                    | Tag::Fini
107                    | Tag::Rel
108                    | Tag::Debug
109                    | Tag::JmpRel
110                    | Tag::InitArray
111                    | Tag::FiniArray
112                    | Tag::PreInitArray
113                    | Tag::SymTabShIndex
114                    | Tag::Relr
115                    | Tag::OsSpecific(_)
116                    | Tag::ProcessorSpecific(_) => Ok(self.un),
117                    _ => Err("Invalid ptr"),
118                }
119            }
120        }
121
122        impl Tag_<$p> {
123            fn as_tag(self) -> Result<Tag<$p>, &'static str> {
124                match self.0 {
125                    0 => Ok(Tag::Null),
126                    1 => Ok(Tag::Needed),
127                    2 => Ok(Tag::PltRelSize),
128                    3 => Ok(Tag::Pltgot),
129                    4 => Ok(Tag::Hash),
130                    5 => Ok(Tag::StrTab),
131                    6 => Ok(Tag::SymTab),
132                    7 => Ok(Tag::Rela),
133                    8 => Ok(Tag::RelaSize),
134                    9 => Ok(Tag::RelaEnt),
135                    10 => Ok(Tag::StrSize),
136                    11 => Ok(Tag::SymEnt),
137                    12 => Ok(Tag::Init),
138                    13 => Ok(Tag::Fini),
139                    14 => Ok(Tag::SoName),
140                    15 => Ok(Tag::RPath),
141                    16 => Ok(Tag::Symbolic),
142                    17 => Ok(Tag::Rel),
143                    18 => Ok(Tag::RelSize),
144                    19 => Ok(Tag::RelEnt),
145                    20 => Ok(Tag::PltRel),
146                    21 => Ok(Tag::Debug),
147                    22 => Ok(Tag::TextRel),
148                    23 => Ok(Tag::JmpRel),
149                    24 => Ok(Tag::BindNow),
150                    25 => Ok(Tag::InitArray),
151                    26 => Ok(Tag::FiniArray),
152                    27 => Ok(Tag::InitArraySize),
153                    28 => Ok(Tag::FiniArraySize),
154                    29 => Ok(Tag::RunPath),
155                    30 => Ok(Tag::Flags),
156                    32 => Ok(Tag::PreInitArray),
157                    33 => Ok(Tag::PreInitArraySize),
158                    34 => Ok(Tag::SymTabShIndex),
159                    35 => Ok(Tag::RelrSize),
160                    36 => Ok(Tag::Relr),
161                    37 => Ok(Tag::RelrEnt),
162                    0x6ffffffb => Ok(Tag::Flags1),
163                    t if (0x6000000D..0x70000000).contains(&t) => Ok(Tag::OsSpecific(t)),
164                    t if (0x70000000..0x80000000).contains(&t) => Ok(Tag::ProcessorSpecific(t)),
165                    _ => Err("Invalid tag value"),
166                }
167            }
168        }
169
170        impl fmt::Debug for Tag_<$p> {
171            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
172                self.as_tag().fmt(f)
173            }
174        }
175    };
176}
177
178impls!(P32);
179impls!(P64);
180
181/* Flag values used in the DT_FLAGS_1 .dynamic entry.  */
182pub const FLAG_1_NOW: u64 = 0x00000001;
183pub const FLAG_1_GLOBAL: u64 = 0x00000002;
184pub const FLAG_1_GROUP: u64 = 0x00000004;
185pub const FLAG_1_NODELETE: u64 = 0x00000008;
186pub const FLAG_1_LOADFLTR: u64 = 0x00000010;
187pub const FLAG_1_INITFIRST: u64 = 0x00000020;
188pub const FLAG_1_NOOPEN: u64 = 0x00000040;
189pub const FLAG_1_ORIGIN: u64 = 0x00000080;
190pub const FLAG_1_DIRECT: u64 = 0x00000100;
191pub const FLAG_1_TRANS: u64 = 0x00000200;
192pub const FLAG_1_INTERPOSE: u64 = 0x00000400;
193pub const FLAG_1_NODEFLIB: u64 = 0x00000800;
194pub const FLAG_1_NODUMP: u64 = 0x00001000;
195pub const FLAG_1_CONFALT: u64 = 0x00002000;
196pub const FLAG_1_ENDFILTEE: u64 = 0x00004000;
197pub const FLAG_1_DISPRELDNE: u64 = 0x00008000;
198pub const FLAG_1_DISPRELPND: u64 = 0x00010000;
199pub const FLAG_1_NODIRECT: u64 = 0x00020000;
200pub const FLAG_1_IGNMULDEF: u64 = 0x00040000;
201pub const FLAG_1_NOKSYMS: u64 = 0x00080000;
202pub const FLAG_1_NOHDR: u64 = 0x00100000;
203pub const FLAG_1_EDITED: u64 = 0x00200000;
204pub const FLAG_1_NORELOC: u64 = 0x00400000;
205pub const FLAG_1_SYMINTPOSE: u64 = 0x00800000;
206pub const FLAG_1_GLOBAUDIT: u64 = 0x01000000;
207pub const FLAG_1_SINGLETON: u64 = 0x02000000;
208pub const FLAG_1_STUB: u64 = 0x04000000;
209pub const FLAG_1_PIE: u64 = 0x08000000;