summaryrefslogtreecommitdiff
path: root/src/elf.rs
blob: 23c267ffa54b3fa754a77cdec23916b4e7719e64 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// basic ELF types and constants

use std::{io, mem};

// executable type
pub const ET_REL: u16 = 1;
pub const ET_EXEC: u16 = 2;

#[allow(unused)]
pub const SHT_PROGBITS: u32 = 1; // Program data
#[allow(unused)]
pub const SHT_SYMTAB: u32 = 2; // Symbol table
#[allow(unused)]
pub const SHT_STRTAB: u32 = 3; // String table
#[allow(unused)]
pub const SHT_RELA: u32 = 4; // Relocation entries with addends
#[allow(unused)]
pub const SHT_HASH: u32 = 5; // Symbol hash table
#[allow(unused)]
pub const SHT_DYNAMIC: u32 = 6; // Dynamic linking information
#[allow(unused)]
pub const SHT_NOTE: u32 = 7; // Notes
#[allow(unused)]
pub const SHT_NOBITS: u32 = 8; // Program space with no data (bss)
#[allow(unused)]
pub const SHT_REL: u32 = 9; // Relocation entries, no addends

// symbol type
pub const STT_OBJECT: u8 = 1;
pub const STT_FUNC: u8 = 2;

// symbol bind
pub const STB_LOCAL: u8 = 0;
pub const STB_GLOBAL: u8 = 1;
pub const STB_WEAK: u8 = 2;

// section number (for relocations)
pub const SHN_UNDEF: u16 = 0;
pub const SHN_ABS: u16 = 0xfff1;
pub const SHN_COMMON: u16 = 0xfff2;

#[repr(C)]
pub struct Header32 {
	pub ident: [u8; 4],
	pub class: u8,
	pub data: u8,
	pub version: u8,
	pub abi: u8,
	pub abiversion: u8,
	pub pad: [u8; 7],
	pub r#type: u16,
	pub machine: u16,
	pub version2: u32,
	pub entry: u32,
	pub phoff: u32,
	pub shoff: u32,
	pub flags: u32,
	pub ehsize: u16,
	pub phentsize: u16,
	pub phnum: u16,
	pub shentsize: u16,
	pub shnum: u16,
	pub shstrndx: u16,
}

impl Default for Header32 {
	fn default() -> Self {
		Self {
			ident: [0x7F, b'E', b'L', b'F'],
			class: 1,
			data: 1,
			version: 1,
			abi: 0,
			abiversion: 0,
			pad: [0; 7],
			r#type: ET_EXEC,
			machine: 3,
			version2: 1,
			entry: 0,
			phoff: 0,
			shoff: 0,
			flags: 0,
			ehsize: mem::size_of::<Self>() as _,
			phentsize: mem::size_of::<Phdr32>() as _,
			phnum: 0,
			shentsize: mem::size_of::<Shdr32>() as _,
			shnum: 0,
			shstrndx: 0,
		}
	}
}

impl Header32 {
	pub fn section_offset(&self, ndx: u16) -> u64 {
		ndx as u64 * self.shentsize as u64 + self.shoff as u64
	}

	pub fn section_seek(&self, ndx: u16) -> io::SeekFrom {
		io::SeekFrom::Start(self.section_offset(ndx))
	}

	pub fn to_bytes(self) -> [u8; 0x34] {
		unsafe { mem::transmute(self) }
	}
}

#[repr(C)]
#[derive(Clone)]
pub struct Shdr32 {
	pub name: u32,
	pub r#type: u32,
	pub flags: u32,
	pub addr: u32,
	pub offset: u32,
	pub size: u32,
	pub link: u32,
	pub info: u32,
	pub addralign: u32,
	pub entsize: u32,
}

pub const PT_LOAD: u32 = 0;

#[repr(C)]
pub struct Phdr32 {
	pub r#type: u32,
	pub offset: u32,
	pub vaddr: u32,
	pub paddr: u32,
	pub filesz: u32,
	pub memsz: u32,
	pub flags: u32,
	pub align: u32,
}

impl Default for Phdr32 {
	fn default() -> Self {
		Self {
			r#type: PT_LOAD,
			offset: 0,
			vaddr: 0,
			paddr: 0,
			filesz: 0,
			memsz: 0,
			flags: 0,
			align: 0x1000,
		}
	}
}

impl Phdr32 {
	pub fn to_bytes(self) -> [u8; 0x20] {
		unsafe { mem::transmute(self) }
	}
}