annotate python/elffile.py @ 148:e5263f74b287

Added c3 language frontend initial parser
author Windel Bouwman
date Fri, 01 Mar 2013 10:24:01 +0100
parents bbf4c9b138d4
children
rev   line source
118
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
1 import struct
126
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
2 import collections
118
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
3
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
4 class ElfFile:
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
5 def __init__(self, f):
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
6 self.f = f
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
7 self.parse()
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
8 def parse(self):
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
9 self.parseHeader()
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
10 @property
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
11 def ElfClass(self):
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
12 return classes[self.ei_class]
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
13 def parseHeader(self):
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
14 # Parse identifier
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
15 e_ident = self.f.read(16)
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
16 ELFMAGIC = bytes([0x7f]) + b'ELF'
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
17 assert e_ident[0:4] == ELFMAGIC
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
18 self.ei_class = e_ident[4]
126
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
19 # Change the class of this object in some strange way:
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
20 self.__class__ = classes[self.ei_class]
118
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
21 print('ELF class: ', self.ElfClass)
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
22 assert self.ei_class in classes.keys()
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
23 self.ei_data = e_ident[5]
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
24 print('ei_data:', self.ei_data)
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
25 ei_version = e_ident[6]
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
26 assert ei_version == 1
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
27
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
28 # rest of the ELF header:
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
29 e_type = self.readHalf()
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
30 e_machine = self.readHalf()
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
31 e_version = self.readWord()
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
32 e_entry = self.readAddr()
126
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
33 self.e_phoff = self.readOff()
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
34 self.e_shoff = self.readOff()
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
35 self.e_flags = self.readWord()
118
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
36 e_ehsize = self.readHalf()
126
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
37 self.e_phentsize = self.readHalf()
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
38 self.e_phnum = self.readHalf()
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
39 self.e_shentsize = self.readHalf()
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
40 self.e_shnum = self.readHalf()
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
41 self.e_shstrndx = self.readHalf()
118
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
42
126
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
43 assert e_ehsize == self.HEADERSIZE
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
44 print('program header size', self.e_phentsize, self.e_phnum)
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
45 print('section header size', self.e_shentsize, self.e_shnum)
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
46 print('string index:', self.e_shstrndx)
118
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
47 def readFmt(self, fmt):
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
48 size = struct.calcsize(fmt)
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
49 return struct.unpack(fmt, self.f.read(size))
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
50 def readHalf(self):
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
51 return self.readFmt('<H')[0]
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
52 def readWord(self):
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
53 return self.readFmt('<I')[0]
126
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
54 def parsePrograms(self):
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
55 # Skip to start of program headers:
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
56 self.f.seek(self.e_phoff)
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
57 pheaders = []
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
58 for i in range(self.e_phnum):
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
59 pheaders.append(self.parseProgramHeader())
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
60 return pheaders
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
61
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
62 ProgramHeader = collections.namedtuple('ProgramHeader', ['p_type',
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
63 'p_flags', 'p_offset', 'p_vaddr', 'p_paddr', 'p_filesz', 'p_memsz'])
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
64
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
65 class Elf32File(ElfFile):
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
66 HEADERSIZE=52
118
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
67 def readAddr(self):
126
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
68 return self.readFmt('<I')[0]
118
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
69 readOff = readAddr
126
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
70 def parseProgramHeader(self):
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
71 p_type = self.readWord()
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
72 p_offset = self.readOff()
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
73 p_vaddr = self.readAddr()
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
74 p_paddr = self.readAddr()
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
75 p_filesz = self.readWord()
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
76 p_memsz = self.readWord()
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
77 p_flags = self.readWord()
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
78 p_align = self.readWord()
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
79 return ProgramHeader(p_type, p_flags, p_offset, p_vaddr, p_paddr, p_filesz, p_memsz)
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
80
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
81 class Elf64File(ElfFile):
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
82 HEADERSIZE=64
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
83 def readAddr(self):
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
84 return self.readFmt('<Q')[0]
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
85 readOff = readAddr
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
86 readXword = readAddr
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
87 def parseProgramHeader(self):
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
88 p_type = self.readWord()
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
89 p_flags = self.readWord()
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
90 p_offset = self.readOff()
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
91 p_vaddr = self.readAddr()
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
92 p_paddr = self.readAddr()
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
93 p_filesz = self.readXword()
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
94 p_memsz = self.readXword()
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
95 p_align = self.readXword()
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
96 return ProgramHeader(p_type, p_flags, p_offset, p_vaddr, p_paddr)
118
db8aafe00d27 Added elf file read scripts
Windel Bouwman
parents:
diff changeset
97
126
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
98 classes = {1:Elf32File, 2:Elf64File}
bbf4c9b138d4 Changes to elf reading
Windel Bouwman
parents: 118
diff changeset
99