summaryrefslogtreecommitdiff
path: root/src/elf.rs
blob: 8d714c4075db3d0bd7db9e170e882c85a3e0a0c9 (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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
// basic ELF types and constants

use std::{io, mem};

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

// segment type
pub const PT_LOAD: u32 = 1;
// segment flags
pub const PF_X: u32 = 1 << 0;
pub const PF_W: u32 = 1 << 1;
pub const PF_R: u32 = 1 << 2;


pub const DT_NEEDED: u32 = 1;
pub const DT_HASH: u32 = 4;
pub const DT_STRTAB: u32 = 5;
pub const DT_SYMTAB: u32 = 6;
pub const DT_STRSZ: u32 = 10;
pub const DT_SYMENT: u32 = 11;
pub const DT_REL: u32 = 17;
pub const DT_RELSZ: u32 = 18;
pub const DT_RELENT: u32 = 19;
  
pub const PT_DYNAMIC: u32 = 2;
pub const PT_INTERP: u32 = 3;

#[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 Ehdr32 {
	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 Ehdr32 {
	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 Ehdr32 {
	pub fn offsetof_entry(&self) -> usize {
		0x18
	}
	
	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,
}

#[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) }
	}
}