linux_raw_sys/
elf.rs

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