10 def __init__(self, path):
12 # Snarf all the data so we can seek.
13 self.file = StringIO.StringIO(sys.stdin.read())
15 self.file = open(path, "rb")
24 data = self.file.read(N)
26 raise ValueError, "Out of data!"
30 return (ord(self.read(1)), 8)
33 return (struct.unpack('><'[self.isLSB] + 'H', self.read(2))[0], 16)
36 return (struct.unpack('><'[self.isLSB] + 'I', self.read(4))[0], 32)
39 return (struct.unpack('><'[self.isLSB] + 'Q', self.read(8))[0], 64)
48 def __init__(self, strings):
49 self.string_table = strings
51 def __getitem__(self, index):
52 end = self.string_table.index('\x00', index)
53 return self.string_table[index:end]
56 def __init__(self, f):
57 self.sh_name = f.read32()
58 self.sh_type = f.read32()
59 self.sh_flags = f.readWord()
60 self.sh_addr = f.readWord()
61 self.sh_offset = f.readWord()
62 self.sh_size = f.readWord()
63 self.sh_link = f.read32()
64 self.sh_info = f.read32()
65 self.sh_addralign = f.readWord()
66 self.sh_entsize = f.readWord()
68 def dump(self, shstrtab, f, strtab, dumpdata):
69 print " (('sh_name', %s)" % common_dump.HexDump(self.sh_name), "# %r" % shstrtab[self.sh_name[0]]
70 print " ('sh_type', %s)" % common_dump.HexDump(self.sh_type)
71 print " ('sh_flags', %s)" % common_dump.HexDump(self.sh_flags)
72 print " ('sh_addr', %s)" % common_dump.HexDump(self.sh_addr)
73 print " ('sh_offset', %s)" % common_dump.HexDump(self.sh_offset)
74 print " ('sh_size', %s)" % common_dump.HexDump(self.sh_size)
75 print " ('sh_link', %s)" % common_dump.HexDump(self.sh_link)
76 print " ('sh_info', %s)" % common_dump.HexDump(self.sh_info)
77 print " ('sh_addralign', %s)" % common_dump.HexDump(self.sh_addralign)
78 print " ('sh_entsize', %s)" % common_dump.HexDump(self.sh_entsize)
79 if self.sh_type[0] == 2: # SHT_SYMTAB
80 print " ('_symbols', ["
81 dumpSymtab(f, self, strtab)
83 elif self.sh_type[0] == 4 or self.sh_type[0] == 9: # SHT_RELA / SHT_REL
84 print " ('_relocations', ["
85 dumpRel(f, self, self.sh_type[0] == 4)
88 f.seek(self.sh_offset[0])
89 if self.sh_type != 8: # != SHT_NOBITS
90 data = f.read(self.sh_size[0])
91 print " ('_section_data', '%s')" % common_dump.dataToHex(data)
93 print " ('_section_data', '')"
96 def dumpSymtab(f, section, strtab):
97 entries = section.sh_size[0] // section.sh_entsize[0]
99 for index in range(entries):
100 f.seek(section.sh_offset[0] + index * section.sh_entsize[0])
101 print " # Symbol %s" % index
103 print " (('st_name', %s)" % common_dump.HexDump(name), "# %r" % strtab[name[0]]
105 print " ('st_value', %s)" % common_dump.HexDump(f.read32())
106 print " ('st_size', %s)" % common_dump.HexDump(f.read32())
107 st_info = f.read8()[0]
108 st_bind = (st_info >> 4, 4)
109 st_type = (st_info & 0xf, 4)
110 print " ('st_bind', %s)" % common_dump.HexDump(st_bind)
111 print " ('st_type', %s)" % common_dump.HexDump(st_type)
112 print " ('st_other', %s)" % common_dump.HexDump(f.read8())
113 print " ('st_shndx', %s)" % common_dump.HexDump(f.read16())
115 print " ('st_value', %s)" % common_dump.HexDump(f.read64())
116 print " ('st_size', %s)" % common_dump.HexDump(f.read64())
119 def dumpRel(f, section, dumprela = False):
120 entries = section.sh_size[0] // section.sh_entsize[0]
122 for index in range(entries):
123 f.seek(section.sh_offset[0] + index * section.sh_entsize[0])
124 print " # Relocation %s" % index
125 print " (('r_offset', %s)" % common_dump.HexDump(f.readWord())
133 print " ('r_sym', %s)" % common_dump.HexDump(r_sym)
134 print " ('r_ssym', %s)" % common_dump.HexDump(r_ssym)
135 print " ('r_type3', %s)" % common_dump.HexDump(r_type3)
136 print " ('r_type2', %s)" % common_dump.HexDump(r_type2)
137 print " ('r_type', %s)" % common_dump.HexDump(r_type)
139 r_info = f.readWord()[0]
141 r_sym = (r_info >> 32, 32)
142 r_type = (r_info & 0xffffffff, 32)
144 r_sym = (r_info >> 8, 24)
145 r_type = (r_info & 0xff, 8)
146 print " ('r_sym', %s)" % common_dump.HexDump(r_sym)
147 print " ('r_type', %s)" % common_dump.HexDump(r_type)
149 print " ('r_addend', %s)" % common_dump.HexDump(f.readWord())
152 def dumpELF(path, opts):
156 assert magic == '\x7FELF'
158 fileclass = f.read8()
159 if fileclass[0] == 1: # ELFCLASS32
161 elif fileclass[0] == 2: # ELFCLASS64
164 raise ValueError, "Unknown file class %s" % common_dump.HexDump(fileclass)
165 print "('e_indent[EI_CLASS]', %s)" % common_dump.HexDump(fileclass)
167 byteordering = f.read8()
168 if byteordering[0] == 1: # ELFDATA2LSB
170 elif byteordering[0] == 2: # ELFDATA2MSB
173 raise ValueError, "Unknown byte ordering %s" % common_dump.HexDump(byteordering)
174 print "('e_indent[EI_DATA]', %s)" % common_dump.HexDump(byteordering)
176 print "('e_indent[EI_VERSION]', %s)" % common_dump.HexDump(f.read8())
177 print "('e_indent[EI_OSABI]', %s)" % common_dump.HexDump(f.read8())
178 print "('e_indent[EI_ABIVERSION]', %s)" % common_dump.HexDump(f.read8())
180 f.seek(16) # Seek to end of e_ident.
182 print "('e_type', %s)" % common_dump.HexDump(f.read16())
184 # Does any other architecture use N64?
185 e_machine = f.read16()
186 if e_machine[0] == 0x0008 and f.is64Bit: # EM_MIPS && 64 bit
189 print "('e_machine', %s)" % common_dump.HexDump(e_machine)
190 print "('e_version', %s)" % common_dump.HexDump(f.read32())
191 print "('e_entry', %s)" % common_dump.HexDump(f.readWord())
192 print "('e_phoff', %s)" % common_dump.HexDump(f.readWord())
193 e_shoff = f.readWord()
194 print "('e_shoff', %s)" % common_dump.HexDump(e_shoff)
195 print "('e_flags', %s)" % common_dump.HexDump(f.read32())
196 print "('e_ehsize', %s)" % common_dump.HexDump(f.read16())
197 print "('e_phentsize', %s)" % common_dump.HexDump(f.read16())
198 print "('e_phnum', %s)" % common_dump.HexDump(f.read16())
199 e_shentsize = f.read16()
200 print "('e_shentsize', %s)" % common_dump.HexDump(e_shentsize)
202 print "('e_shnum', %s)" % common_dump.HexDump(e_shnum)
203 e_shstrndx = f.read16()
204 print "('e_shstrndx', %s)" % common_dump.HexDump(e_shstrndx)
206 # Read all section headers
208 for index in range(e_shnum[0]):
209 f.seek(e_shoff[0] + index * e_shentsize[0])
213 # Read .shstrtab so we can resolve section names
214 f.seek(sections[e_shstrndx[0]].sh_offset[0])
215 shstrtab = StringTable(f.read(sections[e_shstrndx[0]].sh_size[0]))
217 # Get the symbol string table
219 for section in sections:
220 if shstrtab[section.sh_name[0]] == ".strtab":
221 f.seek(section.sh_offset[0])
222 strtab = StringTable(f.read(section.sh_size[0]))
225 print "('_sections', ["
226 for index in range(e_shnum[0]):
227 print " # Section %s" % index
228 sections[index].dump(shstrtab, f, strtab, opts.dumpSectionData)
231 if __name__ == "__main__":
232 from optparse import OptionParser, OptionGroup
233 parser = OptionParser("usage: %prog [options] {files}")
234 parser.add_option("", "--dump-section-data", dest="dumpSectionData",
235 help="Dump the contents of sections",
236 action="store_true", default=False)
237 (opts, args) = parser.parse_args()