Coverage Report

Created: 2025-07-11 06:22

/rust/registry/src/index.crates.io-6f17d22bba15001f/linux-raw-sys-0.9.4/src/elf.rs
Line
Count
Source (jump to first uncovered line)
1
//! The ELF ABI. 🧝
2
//!
3
//! This module is not as comprehensive as bindgened [`elf_uapi`] and provides only types for target
4
//! pointer width: instead of [`elf32_phdr`] and [`elf64_phdr`] there's only [`Elf_Phdr`].
5
//!
6
//! [`elf_uapi`]: super::elf_uapi
7
//! [`elf32_phdr`]: super::elf_uapi::elf32_phdr
8
//! [`elf64_phdr`]: super::elf_uapi::elf64_phdr
9
10
pub const SELFMAG: usize = 4;
11
pub const ELFMAG: [u8; SELFMAG] = [0x7f, b'E', b'L', b'F'];
12
pub const EI_CLASS: usize = 4;
13
pub const EI_DATA: usize = 5;
14
pub const EI_VERSION: usize = 6;
15
pub const EI_OSABI: usize = 7;
16
pub const EI_ABIVERSION: usize = 8;
17
pub const EV_CURRENT: u8 = 1;
18
#[cfg(target_pointer_width = "32")]
19
pub const ELFCLASS: u8 = 1; // ELFCLASS32
20
#[cfg(target_pointer_width = "64")]
21
pub const ELFCLASS: u8 = 2; // ELFCLASS64
22
#[cfg(target_endian = "little")]
23
pub const ELFDATA: u8 = 1; // ELFDATA2LSB
24
#[cfg(target_endian = "big")]
25
pub const ELFDATA: u8 = 2; // ELFDATA2MSB
26
pub const ELFOSABI_SYSV: u8 = 0;
27
pub const ELFOSABI_LINUX: u8 = 3;
28
// At present all of our supported platforms use 0.
29
pub const ELFABIVERSION: u8 = 0;
30
pub const ET_DYN: u16 = 3;
31
pub const EI_NIDENT: usize = 16;
32
pub const SHN_UNDEF: u16 = 0;
33
pub const SHN_ABS: u16 = 0xfff1;
34
pub const PN_XNUM: u16 = 0xffff;
35
pub const PT_LOAD: u32 = 1;
36
pub const PT_DYNAMIC: u32 = 2;
37
pub const PT_INTERP: u32 = 3;
38
pub const PT_PHDR: u32 = 6;
39
pub const PT_TLS: u32 = 7;
40
pub const PT_GNU_STACK: u32 = 0x6474_e551;
41
pub const PT_GNU_RELRO: u32 = 0x6474_e552;
42
pub const PF_X: u32 = 1;
43
pub const PF_W: u32 = 2;
44
pub const PF_R: u32 = 4;
45
pub const DT_NULL: usize = 0;
46
pub const DT_HASH: usize = 4;
47
pub const DT_STRTAB: usize = 5;
48
pub const DT_SYMTAB: usize = 6;
49
pub const DT_RELA: usize = 7;
50
pub const DT_RELASZ: usize = 8;
51
pub const DT_RELAENT: usize = 9;
52
pub const DT_REL: usize = 17;
53
pub const DT_RELSZ: usize = 18;
54
pub const DT_RELENT: usize = 19;
55
pub const DT_SYMENT: usize = 11;
56
pub const DT_GNU_HASH: usize = 0x6fff_fef5;
57
pub const DT_VERSYM: usize = 0x6fff_fff0;
58
pub const DT_VERDEF: usize = 0x6fff_fffc;
59
pub const STB_WEAK: u8 = 2;
60
pub const STB_GLOBAL: u8 = 1;
61
pub const STT_NOTYPE: u8 = 0;
62
pub const STT_FUNC: u8 = 2;
63
pub const STN_UNDEF: u32 = 0;
64
pub const VER_FLG_BASE: u16 = 0x1;
65
pub const VER_DEF_CURRENT: u16 = 1;
66
pub const STV_DEFAULT: u8 = 0;
67
#[cfg(target_arch = "arm")]
68
pub const EM_CURRENT: u16 = 40; // EM_ARM
69
#[cfg(target_arch = "x86")]
70
pub const EM_CURRENT: u16 = 3; // EM_386
71
#[cfg(target_arch = "powerpc")]
72
pub const EM_CURRENT: u16 = 20; // EM_PPC
73
#[cfg(target_arch = "powerpc64")]
74
pub const EM_CURRENT: u16 = 21; // EM_PPC64
75
#[cfg(target_arch = "s390x")]
76
pub const EM_CURRENT: u16 = 22; // EM_S390
77
#[cfg(any(
78
    target_arch = "mips",
79
    target_arch = "mips32r6",
80
    target_arch = "mips64",
81
    target_arch = "mips64r6"
82
))]
83
pub const EM_CURRENT: u16 = 8; // EM_MIPS
84
#[cfg(target_arch = "x86_64")]
85
pub const EM_CURRENT: u16 = 62; // EM_X86_64
86
#[cfg(target_arch = "aarch64")]
87
pub const EM_CURRENT: u16 = 183; // EM_AARCH64
88
#[cfg(target_arch = "riscv64")]
89
pub const EM_CURRENT: u16 = 243; // EM_RISCV
90
91
#[inline]
92
pub const fn ELF_ST_VISIBILITY(o: u8) -> u8 {
93
    o & 0x03
94
}
95
96
#[inline]
97
0
pub const fn ELF_ST_BIND(val: u8) -> u8 {
98
0
    val >> 4
99
0
}
100
101
#[inline]
102
0
pub const fn ELF_ST_TYPE(val: u8) -> u8 {
103
0
    val & 0xf
104
0
}
105
106
#[repr(C)]
107
pub struct Elf_Ehdr {
108
    pub e_ident: [u8; EI_NIDENT],
109
    pub e_type: u16,
110
    pub e_machine: u16,
111
    pub e_version: u32,
112
    pub e_entry: usize,
113
    pub e_phoff: usize,
114
    pub e_shoff: usize,
115
    pub e_flags: u32,
116
    pub e_ehsize: u16,
117
    pub e_phentsize: u16,
118
    pub e_phnum: u16,
119
    pub e_shentsize: u16,
120
    pub e_shnum: u16,
121
    pub e_shstrndx: u16,
122
}
123
124
#[cfg(target_pointer_width = "32")]
125
#[repr(C)]
126
pub struct Elf_Phdr {
127
    pub p_type: u32,
128
    pub p_offset: usize,
129
    pub p_vaddr: usize,
130
    pub p_paddr: usize,
131
    pub p_filesz: usize,
132
    pub p_memsz: usize,
133
    pub p_flags: u32,
134
    pub p_align: usize,
135
}
136
137
#[cfg(target_pointer_width = "64")]
138
#[repr(C)]
139
pub struct Elf_Phdr {
140
    pub p_type: u32,
141
    pub p_flags: u32,
142
    pub p_offset: usize,
143
    pub p_vaddr: usize,
144
    pub p_paddr: usize,
145
    pub p_filesz: usize,
146
    pub p_memsz: usize,
147
    pub p_align: usize,
148
}
149
150
#[cfg(target_pointer_width = "32")]
151
#[repr(C)]
152
pub struct Elf_Sym {
153
    pub st_name: u32,
154
    pub st_value: usize,
155
    pub st_size: usize,
156
    pub st_info: u8,
157
    pub st_other: u8,
158
    pub st_shndx: u16,
159
}
160
161
#[cfg(target_pointer_width = "64")]
162
#[repr(C)]
163
pub struct Elf_Sym {
164
    pub st_name: u32,
165
    pub st_info: u8,
166
    pub st_other: u8,
167
    pub st_shndx: u16,
168
    pub st_value: usize,
169
    pub st_size: usize,
170
}
171
172
#[repr(C)]
173
pub struct Elf_Verdef {
174
    pub vd_version: u16,
175
    pub vd_flags: u16,
176
    pub vd_ndx: u16,
177
    pub vd_cnt: u16,
178
    pub vd_hash: u32,
179
    pub vd_aux: u32,
180
    pub vd_next: u32,
181
}
182
183
#[repr(C)]
184
pub struct Elf_Verdaux {
185
    pub vda_name: u32,
186
    pub _vda_next: u32,
187
}
188
189
#[cfg(target_pointer_width = "32")]
190
#[repr(C)]
191
#[derive(Copy, Clone)]
192
pub struct Elf_Dyn {
193
    pub d_tag: usize,
194
    pub d_un: Elf_Dyn_Union,
195
}
196
197
#[cfg(target_pointer_width = "32")]
198
#[repr(C)]
199
#[derive(Copy, Clone)]
200
pub union Elf_Dyn_Union {
201
    pub d_val: u32,
202
    pub d_ptr: usize,
203
}
204
205
#[cfg(target_pointer_width = "64")]
206
#[repr(C)]
207
#[derive(Copy, Clone)]
208
pub struct Elf_Dyn {
209
    pub d_tag: usize,
210
    pub d_un: Elf_Dyn_Union,
211
}
212
213
#[cfg(target_pointer_width = "64")]
214
#[repr(C)]
215
#[derive(Copy, Clone)]
216
pub union Elf_Dyn_Union {
217
    pub d_val: u64,
218
    pub d_ptr: usize,
219
}
220
221
#[cfg(target_pointer_width = "32")]
222
#[repr(C)]
223
pub struct Elf_Rela {
224
    pub r_offset: usize,
225
    pub r_info: u32,
226
    pub r_addend: usize,
227
}
228
229
#[cfg(target_pointer_width = "64")]
230
#[repr(C)]
231
pub struct Elf_Rela {
232
    pub r_offset: usize,
233
    pub r_info: u64,
234
    pub r_addend: usize,
235
}
236
237
impl Elf_Rela {
238
    #[inline]
239
    pub fn type_(&self) -> u32 {
240
        #[cfg(target_pointer_width = "32")]
241
        {
242
            self.r_info & 0xff
243
        }
244
        #[cfg(target_pointer_width = "64")]
245
        {
246
            (self.r_info & 0xffff_ffff) as u32
247
        }
248
    }
249
}
250
251
#[cfg(target_pointer_width = "32")]
252
#[repr(C)]
253
pub struct Elf_Rel {
254
    pub r_offset: usize,
255
    pub r_info: u32,
256
}
257
258
#[cfg(target_pointer_width = "64")]
259
#[repr(C)]
260
pub struct Elf_Rel {
261
    pub r_offset: usize,
262
    pub r_info: u64,
263
}
264
265
impl Elf_Rel {
266
    #[inline]
267
    pub fn type_(&self) -> u32 {
268
        #[cfg(target_pointer_width = "32")]
269
        {
270
            self.r_info & 0xff
271
        }
272
        #[cfg(target_pointer_width = "64")]
273
        {
274
            (self.r_info & 0xffff_ffff) as u32
275
        }
276
    }
277
}
278
279
#[cfg(target_arch = "x86_64")]
280
pub const R_RELATIVE: u32 = 8; // `R_X86_64_RELATIVE`
281
#[cfg(target_arch = "x86")]
282
pub const R_RELATIVE: u32 = 8; // `R_386_RELATIVE`
283
#[cfg(target_arch = "aarch64")]
284
pub const R_RELATIVE: u32 = 1027; // `R_AARCH64_RELATIVE`
285
#[cfg(target_arch = "riscv64")]
286
pub const R_RELATIVE: u32 = 3; // `R_RISCV_RELATIVE`
287
#[cfg(target_arch = "arm")]
288
pub const R_RELATIVE: u32 = 23; // `R_ARM_RELATIVE`
289
290
#[repr(C)]
291
#[derive(Clone)]
292
pub struct Elf_auxv_t {
293
    pub a_type: usize,
294
295
    // Some of the values in the auxv array are pointers, so we make `a_val` a
296
    // pointer, in order to preserve their provenance. For the values which are
297
    // integers, we cast this to `usize`.
298
    pub a_val: *mut crate::ctypes::c_void,
299
}