From: eliben Date: Mon, 19 Sep 2011 10:10:57 +0000 (+0300) Subject: Implemented ELFFile.get_section_by_name and changed readelf.py to use it X-Git-Tag: v0.10~109 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=54e39b2c99ac909ba3b17277aff51dfc43f7abcc;p=pyelftools.git Implemented ELFFile.get_section_by_name and changed readelf.py to use it --- diff --git a/elftools/elf/elffile.py b/elftools/elf/elffile.py index 8195c7f..8704249 100644 --- a/elftools/elf/elffile.py +++ b/elftools/elf/elffile.py @@ -46,6 +46,7 @@ class ELFFile(object): self.e_ident_raw = self.stream.read(16) self._file_stringtable_section = self._get_file_stringtable() + self._section_name_map = None def num_sections(self): """ Number of sections in the file @@ -59,6 +60,20 @@ class ELFFile(object): section_header = self._get_section_header(n) return self._make_section(section_header) + def get_section_by_name(self, name): + """ Get a section from the file, by name. Return None if no such + section exists. + """ + # The first time this method is called, construct a name to number + # mapping + # + if self._section_name_map is None: + self._section_name_map = {} + for i, sec in enumerate(self.iter_sections()): + self._section_name_map[sec.name] = i + secnum = self._section_name_map.get(name, None) + return None if secnum is None else self.get_section(secnum) + def iter_sections(self): """ Yield all the sections in the file """ diff --git a/scripts/readelf.py b/scripts/readelf.py index 44e15db..4554ab0 100755 --- a/scripts/readelf.py +++ b/scripts/readelf.py @@ -270,13 +270,12 @@ class ReadElf(object): """ Display a hex dump of a section. section_spec is either a section number or a name. """ - secnum = self._section_num_from_spec(section_spec) - if secnum is None: + section = self._section_from_spec(section_spec) + if section is None: self._emitline("Section '%s' does not exist in the file!" % ( section_spec)) return - section = self.elffile.get_section(secnum) self._emitline("\nHex dump of section '%s':" % section.name) addr = section['sh_addr'] @@ -314,15 +313,13 @@ class ReadElf(object): """ Display a strings dump of a section. section_spec is either a section number or a name. """ - secnum = self._section_num_from_spec(section_spec) - if secnum is None: + section = self._section_from_spec(section_spec) + if section is None: self._emitline("Section '%s' does not exist in the file!" % ( section_spec)) return printables = set(string.printable) - - section = self.elffile.get_section(secnum) self._emitline("\nString dump of section '%s':" % section.name) found = False @@ -376,18 +373,19 @@ class ReadElf(object): field = '%' + '0%sx' % fieldsize return s + field % addr - def _section_num_from_spec(self, spec): - """ Translate a section "spec" (either number or name) to its number. + def _section_from_spec(self, spec): + """ Retrieve a section given a "spec" (either number or name). Return None if no such section exists in the file. """ try: num = int(spec) - return num if num < self.elffile.num_sections() else None + if num < self.elffile.num_sections(): + return self.elffile.get_section(num) + else: + return None except ValueError: # Not a number. Must be a name then - for nsec, section in enumerate(self.elffile.iter_sections()): - if section.name == spec: - return nsec + return self.elffile.get_section_by_name(spec) def _emit(self, s=''): """ Emit an object to output diff --git a/z.py b/z.py index bddd6e0..8ef75d2 100644 --- a/z.py +++ b/z.py @@ -16,53 +16,22 @@ stream = open('tests/testfiles/z.elf', 'rb') efile = ELFFile(stream) print '===> %s sections!' % efile.num_sections() -print '===> %s segments!' % efile.num_segments() -for sec in efile.iter_sections(): - print type(sec), sec.name - if isinstance(sec, SymbolTableSection): - print ' linked string table:', sec.stringtable.name +print efile.get_section_by_name('.debug_info').name -for seg in efile.iter_segments(): - print type(seg), seg['p_type'], seg['p_offset'] +#~ print '===> %s segments!' % efile.num_segments() for sec in efile.iter_sections(): + print type(sec), sec.name if isinstance(sec, SymbolTableSection): - print 'symbol table "%s ~~~"' % sec.name - for sym in sec.iter_symbols(): - print '%-26s %s %s' % (sym.name, sym['st_info']['type'], sym['st_info']['bind']) - - -#~ print 'num', efile.num_sections() -#~ sec = efile.get_section(39) -#~ print sec.header -#~ print sec.name -#~ print sec['sh_type'] -#~ print map(ord, sec.data()) - -#~ print sec.stream -#~ print map(ord, efile._stringtable) - -#~ print efile.header -#~ print dir(efile) -#~ print efile['e_type'] - -#~ shtable_offset = efile['e_shoff'] -#~ strtable_section_offset = shtable_offset + efile['e_shstrndx'] * efile['e_shentsize'] - -#~ # get to the section header for the sh string table -#~ print strtable_section_offset -#~ stream.seek(strtable_section_offset) -#~ sheader = es.Elf_Shdr.parse_stream(stream) -#~ print sheader - -#~ # yay, looks correct!! -#~ stream.seek(sheader.sh_offset) -#~ buf = stream.read(sheader.sh_size) -#~ for c in buf: - #~ sys.stdout.write('%02X' % ord(c)) - + print ' linked string table:', sec.stringtable.name +#~ for seg in efile.iter_segments(): + #~ print type(seg), seg['p_type'], seg['p_offset'] +#~ for sec in efile.iter_sections(): + #~ if isinstance(sec, SymbolTableSection): + #~ print 'symbol table "%s ~~~"' % sec.name + #~ for sym in sec.iter_symbols(): + #~ print '%-26s %s %s' % (sym.name, sym['st_info']['type'], sym['st_info']['bind']) -#~ print es.Elf_Ehdr