Skip to content

Commit baeb747

Browse files
authored
Add types and constants for working with Linux's ELF ABI. (#78)
* Add types and constants for working with Linux's ELF ABI. * Remove Mips targets from CI.
1 parent c3a08b4 commit baeb747

5 files changed

Lines changed: 261 additions & 4 deletions

File tree

.github/workflows/main.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,6 @@ jobs:
5353
aarch64-unknown-linux-musl
5454
powerpc64le-unknown-linux-gnu
5555
armv5te-unknown-linux-gnueabi
56-
mipsel-unknown-linux-gnu
57-
mips64el-unknown-linux-gnuabi64
5856
- run: cargo check --tests -vv
5957
- run: cargo check --tests -vv --target=x86_64-unknown-linux-musl
6058
- run: cargo check --tests -vv --target=x86_64-unknown-linux-gnux32
@@ -65,8 +63,6 @@ jobs:
6563
- run: cargo check --tests -vv --target=aarch64-unknown-linux-musl
6664
- run: cargo check --tests -vv --target=powerpc64le-unknown-linux-gnu
6765
- run: cargo check --tests -vv --target=armv5te-unknown-linux-gnueabi
68-
- run: cargo check --tests -vv --target=mipsel-unknown-linux-gnu
69-
- run: cargo check --tests -vv --target=mips64el-unknown-linux-gnuabi64
7066

7167
gen:
7268
name: Update generated files

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,5 @@ system = []
3838
default = ["std", "general", "errno"]
3939
std = []
4040
no_std = []
41+
elf = []
4142
rustc-dep-of-std = ["core", "compiler_builtins", "no_std"]

gen/src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ fn main() {
173173
writeln!(cargo_toml, "default = [\"std\", {}]", DEFAULT_FEATURES).unwrap();
174174
writeln!(cargo_toml, "std = []").unwrap();
175175
writeln!(cargo_toml, "no_std = []").unwrap();
176+
writeln!(cargo_toml, "elf = []").unwrap();
176177
writeln!(
177178
cargo_toml,
178179
"rustc-dep-of-std = [\"core\", \"compiler_builtins\", \"no_std\"]"

src/elf.rs

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

src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,9 @@ pub mod signal_macros {
186186
}
187187
}
188188

189+
#[cfg(feature = "elf")]
190+
pub mod elf;
191+
189192
// The rest of this file is auto-generated!
190193
#[cfg(feature = "errno")]
191194
#[cfg(target_arch = "arm")]

0 commit comments

Comments
 (0)