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
pub mod endian;
pub use self::endian::{read_endian,Endian};
pub mod wordsize;
pub use self::wordsize::{read_platform,Platform};
pub mod abi;
pub use self::abi::{read_abi,ABI};
pub mod kind;
pub use self::kind::{read_kind, Kind};
pub mod arch;
pub use self::arch::{read_arch,Arch};
use super::{
Elf_Addr,
Elf_Off,
Elf_Word,
Elf_Half,
};
use super::value::{
define_reader,
read_word,
read_addr,
read_off,
read_half
};
use super::nom::IResult;
#[derive(Debug,Clone,PartialEq,Eq)]
struct Header {
pub endian: Endian,
pub wordsize: Platform,
pub abi: ABI
}
named!(read_header<Header>, chain!(
tag!("\x7F\x45\x4C\x46")~
e: read_endian~
w: read_platform~
a: read_abi,
|| Header {
endian: e,
wordsize: w,
abi: a
}
));
impl Header {
pub fn define_platfrom(&self) {
define_reader(&self.endian,&self.wordsize);
}
}
#[allow(dead_code)]
pub struct ElfHeader {
pub endian: Endian,
pub wordsize: Platform,
pub abi: ABI,
pub kind: Kind,
pub arch: Arch,
pub entry: Elf_Addr,
pub phoff: Elf_Off,
pub shoff: Elf_Off,
pub flags: Elf_Word,
pub ehsize: Elf_Half,
pub phentsize: Elf_Half,
pub phnum: Elf_Half,
pub shentsize: Elf_Half,
pub shnum: Elf_Half,
pub shstrndx: Elf_Half
}
named!( read_full_elf_header<ElfHeader>, chain!(
kind: read_kind~
arch: read_arch~
read_word~
entr: read_addr~
phof: read_off~
shof: read_off~
flag: read_word~
ehsi: read_half~
phen: read_half~
phnu: read_half~
shen: read_half~
shun: read_half~
shst: read_half,
|| ElfHeader{
endian: Endian::Little,
wordsize: Platform::Bit32,
abi: ABI::SystemV,
kind: kind,
arch: arch,
entry: entr,
phoff: phof,
shoff: shof,
flags: flag,
ehsize: ehsi,
phentsize: phen,
phnum: phnu,
shentsize: shen,
shnum: shun,
shstrndx: shst
}
));
macro_rules! try_parse {
($data:expr) => {
match $data {
IResult::Done(x,y) => (x,y),
IResult::Incomplete(z) => return IResult::Incomplete(z),
IResult::Error(z) => return IResult::Error(z)
};
}
}
#[allow(dead_code)]
#[inline(always)]
pub fn read_elf_header<'a>(i: &'a[u8]) -> IResult<&'a[u8], ElfHeader> {
let (_,header) = try_parse!(read_header(i));
header.define_platfrom();
let (rem,mut full_header) = try_parse!(read_full_elf_header(&i[16..]));
full_header.endian = header.endian.clone();
full_header.wordsize = header.wordsize.clone();
full_header.abi = header.abi.clone();
IResult::Done(rem,full_header)
}