from .structs import ELFStructs
from .sections import (
Section, StringTableSection, SymbolTableSection,
- SUNWSyminfoTableSection, NullSection, NoteSection)
+ SUNWSyminfoTableSection, NullSection, NoteSection,
+ StabSection)
from .dynamic import DynamicSection, DynamicSegment
from .relocation import RelocationSection, RelocationHandler
from .gnuversions import (
return DynamicSection(section_header, name, self.stream, self)
elif sectype == 'SHT_NOTE':
return NoteSection(section_header, name, self.stream, self)
+ elif sectype == 'SHT_PROGBITS' and name == '.stab':
+ return StabSection(section_header, name, self.stream, self)
else:
return Section(section_header, name, self.stream)
others.
"""
return iter_notes(self.elffile, self['sh_offset'], self['sh_size'])
+
+class StabSection(Section):
+ """ ELF stab section.
+ """
+ def __init__(self, header, name, stream, elffile):
+ super(StabSection, self).__init__(header, name, stream)
+ self.elffile = elffile
+
+ def iter_stabs(self):
+ """ Yield all stab entries. Result type is ELFStructs.Elf_Stabs.
+ """
+ elffile = self.elffile
+ offset = self['sh_offset']
+ size = self['sh_size']
+ end = offset + size
+ while offset < end:
+ stabs = struct_parse(
+ elffile.structs.Elf_Stabs,
+ elffile.stream,
+ stream_pos=offset)
+ stabs['n_offset'] = offset
+ offset += elffile.structs.Elf_Stabs.sizeof()
+ elffile.stream.seek(offset)
+ yield stabs
+
self._create_gnu_verdef()
self._create_gnu_versym()
self._create_note()
+ self._create_stabs()
def _create_ehdr(self):
self.Elf_Ehdr = Struct('Elf_Ehdr',
self.Elf_word('abi_minor'),
self.Elf_word('abi_tiny'),
)
+
+ def _create_stabs(self):
+ # Structure of one stabs entry, see binutils/bfd/stabs.c
+ # Names taken from https://sourceware.org/gdb/current/onlinedocs/stabs.html#Overview
+ self.Elf_Stabs = Struct('Elf_Stabs',
+ self.Elf_word('n_strx'),
+ self.Elf_byte('n_type'),
+ self.Elf_byte('n_other'),
+ self.Elf_half('n_desc'),
+ self.Elf_word('n_value'),
+ )
--- /dev/null
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+import os
+
+from utils import setup_syspath; setup_syspath()
+from elftools.elf.elffile import ELFFile
+from elftools.elf.sections import StabSection
+
+class TestStab(unittest.TestCase):
+ def test_stab(self):
+ expected = [
+ ("obj_stabs.S", 0, 0, 0x2, 33), # generated by compiler
+ ("label", 0x95, 0xc8, 0x4072, 0xdeadbeef),
+ ("another label", 0x41, 0x66, 0xf9b1, 0xcafebabe),
+ ]
+ with open(os.path.join('test', 'testfiles_for_unittests',
+ 'obj_stabs.elf'), 'rb') as f:
+ elf = ELFFile(f)
+
+ # using correct type?
+ for s in elf.iter_sections():
+ if s.name == '.stab':
+ self.assertIsInstance (s, StabSection)
+
+ # check section contents
+ stab = elf.get_section_by_name('.stab')
+ stabstr = elf.get_section_by_name('.stabstr')
+ for entry, golden in zip (stab.iter_stabs (), expected):
+ self.assertEqual(stabstr.get_string (entry.n_strx), golden[0])
+ self.assertEqual(entry.n_type, golden[1])
+ self.assertEqual(entry.n_other, golden[2])
+ self.assertEqual(entry.n_desc, golden[3])
+ self.assertEqual(entry.n_value, golden[4])
+
+if __name__ == '__main__':
+ unittest.main()
--- /dev/null
+# gcc -c -o obj_stabs.o obj_stabs.S
+.stabs "label", 0x95, 0xc8, 0x4072, 0xdeadbeef
+.stabs "another label", 0x41, 0x66, 0xf9b1, 0xcafebabe