# That didn't work for some reason. Let's use the section header
# even though this ELF is super weird.
- self._stringtable = self._elffile.get_section_by_name(b'.dynstr')
+ self._stringtable = self._elffile.get_section_by_name('.dynstr')
return self._stringtable
def _iter_tags(self, type=None):
We assume that if it has the debug_info section, it has all theother
required sections as well.
"""
- return bool(self.get_section_by_name(b'.debug_info'))
+ return bool(self.get_section_by_name('.debug_info'))
def get_dwarf_info(self, relocate_dwarf_sections=True):
""" Return a DWARFInfo object representing the debugging information in
# Sections that aren't found will be passed as None to DWARFInfo.
#
debug_sections = {}
- for secname in (b'.debug_info', b'.debug_abbrev', b'.debug_str',
- b'.debug_line', b'.debug_frame',
- b'.debug_loc', b'.debug_ranges'):
+ for secname in ('.debug_info', '.debug_abbrev', '.debug_str',
+ '.debug_line', '.debug_frame',
+ '.debug_loc', '.debug_ranges'):
section = self.get_section_by_name(secname)
if section is None:
debug_sections[secname] = None
little_endian=self.little_endian,
default_address_size=self.elfclass // 8,
machine_arch=self.get_machine_arch()),
- debug_info_sec=debug_sections[b'.debug_info'],
- debug_abbrev_sec=debug_sections[b'.debug_abbrev'],
- debug_frame_sec=debug_sections[b'.debug_frame'],
+ debug_info_sec=debug_sections['.debug_info'],
+ debug_abbrev_sec=debug_sections['.debug_abbrev'],
+ debug_frame_sec=debug_sections['.debug_frame'],
# TODO(eliben): reading of eh_frame is not hooked up yet
eh_frame_sec=None,
- debug_str_sec=debug_sections[b'.debug_str'],
- debug_loc_sec=debug_sections[b'.debug_loc'],
- debug_ranges_sec=debug_sections[b'.debug_ranges'],
- debug_line_sec=debug_sections[b'.debug_line'])
+ debug_str_sec=debug_sections['.debug_str'],
+ debug_loc_sec=debug_sections['.debug_loc'],
+ debug_ranges_sec=debug_sections['.debug_ranges'],
+ debug_line_sec=debug_sections['.debug_line'])
def get_machine_arch(self):
""" Return the machine architecture, as detected from the ELF header.
found.
"""
reloc_section_names = (
- b'.rel' + section.name,
- b'.rela' + section.name)
+ '.rel' + section.name,
+ '.rela' + section.name)
# Find the relocation section aimed at this one. Currently assume
# that either .rel or .rela section exists for this section, but
# not both.
"""
table_offset = self['sh_offset']
s = parse_cstring_from_stream(self.stream, table_offset + offset)
- return s
+ return s.decode('ascii')
class SymbolTableSection(Section):
"""
path_offset = self['p_offset']
return struct_parse(
- CString(''),
+ CString('', encoding='ascii'),
self.stream,
stream_pos=path_offset)
elffile = ELFFile(stream)
# Just use the public methods of ELFFile to get what we need
- # Note that section names, like everything read from the file, are bytes
- # objects.
+ # Note that section names are strings.
print(' %s sections' % elffile.num_sections())
- section = elffile.get_section_by_name(b'.symtab')
+ section = elffile.get_section_by_name('.symtab')
if not section:
print(' No symbol table found. Perhaps this ELF has been stripped?')
# A section type is in its header, but the name was decoded and placed in
# a public attribute.
- # bytes2str is used to print the name of the section for consistency of
- # output between Python 2 and 3. The section name is a bytes object.
print(' Section name: %s, type: %s' %(
- bytes2str(section.name), section['sh_type']))
+ section.name, section['sh_type']))
# But there's more... If this section is a symbol table section (which is
# the case in the sample ELF file that comes with the examples), we can
num_symbols = section.num_symbols()
print(" It's a symbol section with %s symbols" % num_symbols)
print(" The name of the last symbol in the section is: %s" % (
- bytes2str(section.get_symbol(num_symbols - 1).name)))
+ section.get_symbol(num_symbols - 1).name))
if __name__ == '__main__':
# Read the .rela.dyn section from the file, by explicitly asking
# ELFFile for this section
- # Recall that section names are bytes objects
- reladyn_name = b'.rela.dyn'
+ # The section names are strings
+ reladyn_name = '.rela.dyn'
reladyn = elffile.get_section_by_name(reladyn_name)
if not isinstance(reladyn, RelocationSection):
- print(' The file has no %s section' % bytes2str(reladyn_name))
+ print(' The file has no %s section' % reladyn_name)
print(' %s section with %s relocations' % (
- bytes2str(reladyn_name), reladyn.num_relocations()))
+ reladyn_name, reladyn.num_relocations()))
for reloc in reladyn.iter_relocations():
print(' Relocation (%s)' % 'RELA' if reloc.is_RELA() else 'REL')
elffile = ELFFile(f)
for section in elffile.iter_sections():
- # Section names are bytes objects
- if section.name.startswith(b'.debug'):
- print(' ' + bytes2str(section.name))
+ # Section names are string
+ if section.name.startswith('.debug'):
+ print(' ' + section.name)
if __name__ == '__main__':
if isinstance(segment, InterpSegment):
self._emitline(' [Requesting program interpreter: %s]' %
- bytes2str(segment.get_interp_name()))
+ segment.get_interp_name())
# Sections to segments mapping
#
for section in self.elffile.iter_sections():
if ( not section.is_null() and
segment.section_in_segment(section)):
- self._emit('%s ' % bytes2str(section.name))
+ self._emit('%s ' % section.name)
self._emitline('')
#
for nsec, section in enumerate(self.elffile.iter_sections()):
self._emit(' [%2u] %-17.17s %-15.15s ' % (
- nsec, bytes2str(section.name), describe_sh_type(section['sh_type'])))
+ nsec, section.name, describe_sh_type(section['sh_type'])))
if self.elffile.elfclass == 32:
self._emitline('%s %s %s %s %3s %2s %3s %2s' % (
if section['sh_entsize'] == 0:
self._emitline("\nSymbol table '%s' has a sh_entsize of zero!" % (
- bytes2str(section.name)))
+ section.name))
continue
self._emitline("\nSymbol table '%s' contains %s entries:" % (
- bytes2str(section.name), section.num_symbols()))
+ section.name, section.num_symbols()))
if self.elffile.elfclass == 32:
self._emitline(' Num: Value Size Type Bind Vis Ndx Name')
if (section['sh_type'] == 'SHT_DYNSYM' and
self._versioninfo['type'] == 'GNU'):
version = self._symbol_version(nsym)
- if (version['name'] != bytes2str(symbol.name) and
+ if (version['name'] != symbol.name and
version['index'] not in ('VER_NDX_LOCAL',
'VER_NDX_GLOBAL')):
if version['filename']:
describe_symbol_bind(symbol['st_info']['bind']),
describe_symbol_visibility(symbol['st_other']['visibility']),
describe_symbol_shndx(symbol['st_shndx']),
- bytes2str(symbol.name),
+ symbol.name,
version_info))
def display_dynamic_tags(self):
padding = 20 + (8 if self.elffile.elfclass == 32 else 0)
for tag in section.iter_tags():
if tag.entry.d_tag == 'DT_NEEDED':
- parsed = 'Shared library: [%s]' % bytes2str(tag.needed)
+ parsed = 'Shared library: [%s]' % tag.needed
elif tag.entry.d_tag == 'DT_RPATH':
- parsed = 'Library rpath: [%s]' % bytes2str(tag.rpath)
+ parsed = 'Library rpath: [%s]' % tag.rpath
elif tag.entry.d_tag == 'DT_RUNPATH':
- parsed = 'Library runpath: [%s]' % bytes2str(tag.runpath)
+ parsed = 'Library runpath: [%s]' % tag.runpath
elif tag.entry.d_tag == 'DT_SONAME':
- parsed = 'Library soname: [%s]' % bytes2str(tag.soname)
+ parsed = 'Library soname: [%s]' % tag.soname
elif tag.entry.d_tag.endswith(('SZ', 'ENT')):
parsed = '%i (bytes)' % tag['d_val']
elif tag.entry.d_tag.endswith(('NUM', 'COUNT')):
has_relocation_sections = True
self._emitline("\nRelocation section '%s' at offset %s contains %s entries:" % (
- bytes2str(section.name),
+ section.name,
self._format_hex(section['sh_offset']),
section.num_relocations()))
if section.is_RELA():
symbol['st_value'],
fullhex=True, lead0x=False),
' ' if self.elffile.elfclass == 32 else '',
- bytes2str(symbol_name)))
+ symbol_name))
if section.is_RELA():
self._emit(' %s %x' % (
'+' if rel['r_addend'] >= 0 else '-',
self._format_hex(offset, fieldsize=6,
alternate=True),
verdef['vd_version'], flags, verdef['vd_ndx'],
- verdef['vd_cnt'], bytes2str(name)))
+ verdef['vd_cnt'], name))
verdaux_offset = (
offset + verdef['vd_aux'] + verdaux['vda_next'])
for idx, verdaux in enumerate(verdaux_iter, start=1):
self._emitline(' %s: Parent %i: %s' %
(self._format_hex(verdaux_offset, fieldsize=4),
- idx, bytes2str(verdaux.name)))
+ idx, verdaux.name))
verdaux_offset += verdaux['vda_next']
offset += verdef['vd_next']
self._emitline(' %s: Version: %i File: %s Cnt: %i' % (
self._format_hex(offset, fieldsize=6,
alternate=True),
- verneed['vn_version'], bytes2str(verneed.name),
+ verneed['vn_version'], verneed.name,
verneed['vn_cnt']))
vernaux_offset = offset + verneed['vn_aux']
self._emitline(
' %s: Name: %s Flags: %s Version: %i' % (
self._format_hex(vernaux_offset, fieldsize=4),
- bytes2str(vernaux.name), flags,
+ vernaux.name, flags,
vernaux['vna_other']))
vernaux_offset += vernaux['vna_next']
section_spec))
return
- self._emitline("\nHex dump of section '%s':" % bytes2str(section.name))
+ self._emitline("\nHex dump of section '%s':" % section.name)
self._note_relocs_for_section(section)
addr = section['sh_addr']
data = section.data()
section_spec))
return
- self._emitline("\nString dump of section '%s':" % bytes2str(section.name))
+ self._emitline("\nString dump of section '%s':" % section.name)
found = False
data = section.data()
num_entries = version_section.num_symbols()
self._emitline("\n%s section '%s' contains %s entries:" %
- (name, bytes2str(version_section.name), num_entries))
+ (name, version_section.name, num_entries))
self._emitline('%sAddr: %s Offset: %s Link: %i (%s)' % (
' ' * indent,
self._format_hex(
self._format_hex(
version_section['sh_offset'], fieldsize=6, lead0x=True),
version_section['sh_link'],
- bytes2str(
- self.elffile.get_section(version_section['sh_link']).name)
+ self.elffile.get_section(version_section['sh_link']).name
)
)
index <= self._versioninfo['verdef'].num_versions()):
_, verdaux_iter = \
self._versioninfo['verdef'].get_version(index)
- symbol_version['name'] = bytes2str(next(verdaux_iter).name)
+ symbol_version['name'] = next(verdaux_iter).name
else:
verneed, vernaux = \
self._versioninfo['verneed'].get_version(index)
- symbol_version['name'] = bytes2str(vernaux.name)
- symbol_version['filename'] = bytes2str(verneed.name)
+ symbol_version['name'] = vernaux.name
+ symbol_version['filename'] = verneed.name
symbol_version['index'] = index
return symbol_version
return None
except ValueError:
# Not a number. Must be a name then
- return self.elffile.get_section_by_name(str2bytes(spec))
+ return self.elffile.get_section_by_name(spec)
def _note_relocs_for_section(self, section):
""" If there are relocation sections pointing to the givne section,
"""
reference_data = [
- b'libz.so.1',
- b'libc.so.6',
- b'lib_versioned.so.1',
+ 'libz.so.1',
+ 'libc.so.6',
+ 'lib_versioned.so.1',
]
def _test_double_dynstr_section_generic(self, testfile):
elf = ELFFile(f)
# Find the symbol table.
- symtab = elf.get_section_by_name(b'.symtab')
+ symtab = elf.get_section_by_name('.symtab')
self.assertIsNotNone(symtab)
# Test we can find a symbol by its name.
- mains = symtab.get_symbol_by_name(b'main')
+ mains = symtab.get_symbol_by_name('main')
self.assertIsNotNone(mains)
# Test it is actually the symbol we expect.
self.assertIsInstance(mains, list)
self.assertEqual(len(mains), 1)
main = mains[0]
- self.assertEqual(main.name, b'main')
+ self.assertEqual(main.name, 'main')
self.assertEqual(main['st_value'], 0x8068)
self.assertEqual(main['st_size'], 0x28)
elf = ELFFile(f)
# Find the symbol table.
- symtab = elf.get_section_by_name(b'.symtab')
+ symtab = elf.get_section_by_name('.symtab')
self.assertIsNotNone(symtab)
# Test we get None when we look up a symbol that doesn't exist.
- undef = symtab.get_symbol_by_name(b'non-existent symbol')
+ undef = symtab.get_symbol_by_name('non-existent symbol')
self.assertIsNone(undef)
def test_duplicated_symbol(self):
elf = ELFFile(f)
# Find the symbol table.
- symtab = elf.get_section_by_name(b'.symtab')
+ symtab = elf.get_section_by_name('.symtab')
self.assertIsNotNone(symtab)
# The '$a' symbols that are present in the test file.
0x8068]
# Test we get all expected instances of the symbol '$a'.
- arm_markers = symtab.get_symbol_by_name(b'$a')
+ arm_markers = symtab.get_symbol_by_name('$a')
self.assertIsNotNone(arm_markers)
self.assertIsInstance(arm_markers, list)
self.assertEqual(len(arm_markers), len(expected_symbols))
for symbol in arm_markers:
- self.assertEqual(symbol.name, b'$a')
+ self.assertEqual(symbol.name, '$a')
self.assertIn(symbol['st_value'], expected_symbols)
if __name__ == '__main__':
class TestSymbolVersioning(unittest.TestCase):
versym_reference_data = [
- {'name': b'', 'ndx': 'VER_NDX_LOCAL'},
- {'name': b'', 'ndx': 'VER_NDX_LOCAL'},
- {'name': b'_ITM_deregisterTMCloneTable', 'ndx': 'VER_NDX_LOCAL'},
- {'name': b'puts', 'ndx': 5},
- {'name': b'strlcat', 'ndx': 'VER_NDX_LOCAL'},
- {'name': b'__stack_chk_fail', 'ndx': 6},
- {'name': b'__gmon_start__', 'ndx': 'VER_NDX_LOCAL'},
- {'name': b'gzoffset', 'ndx': 7},
- {'name': b'_Jv_RegisterClasses', 'ndx': 'VER_NDX_LOCAL'},
- {'name': b'_ITM_registerTMCloneTable', 'ndx': 'VER_NDX_LOCAL'},
- {'name': b'__cxa_finalize', 'ndx': 5},
- {'name': b'_edata', 'ndx': 'VER_NDX_GLOBAL'},
- {'name': b'VER_1.0', 'ndx': 2},
- {'name': b'function1_ver1_1', 'ndx': 'VER_NDX_GLOBAL'},
- {'name': b'_end', 'ndx': 'VER_NDX_GLOBAL'},
- {'name': b'function1', 'ndx': 4 | 0x8000},
- {'name': b'__bss_start', 'ndx': 'VER_NDX_GLOBAL'},
- {'name': b'function1', 'ndx': 2},
- {'name': b'VER_1.1', 'ndx': 3},
- {'name': b'_init', 'ndx': 'VER_NDX_GLOBAL'},
- {'name': b'function1_ver1_0', 'ndx': 'VER_NDX_GLOBAL'},
- {'name': b'_fini', 'ndx': 'VER_NDX_GLOBAL'},
- {'name': b'VER_1.2', 'ndx': 4},
- {'name': b'function2', 'ndx': 3},
+ {'name': '', 'ndx': 'VER_NDX_LOCAL'},
+ {'name': '', 'ndx': 'VER_NDX_LOCAL'},
+ {'name': '_ITM_deregisterTMCloneTable', 'ndx': 'VER_NDX_LOCAL'},
+ {'name': 'puts', 'ndx': 5},
+ {'name': 'strlcat', 'ndx': 'VER_NDX_LOCAL'},
+ {'name': '__stack_chk_fail', 'ndx': 6},
+ {'name': '__gmon_start__', 'ndx': 'VER_NDX_LOCAL'},
+ {'name': 'gzoffset', 'ndx': 7},
+ {'name': '_Jv_RegisterClasses', 'ndx': 'VER_NDX_LOCAL'},
+ {'name': '_ITM_registerTMCloneTable', 'ndx': 'VER_NDX_LOCAL'},
+ {'name': '__cxa_finalize', 'ndx': 5},
+ {'name': '_edata', 'ndx': 'VER_NDX_GLOBAL'},
+ {'name': 'VER_1.0', 'ndx': 2},
+ {'name': 'function1_ver1_1', 'ndx': 'VER_NDX_GLOBAL'},
+ {'name': '_end', 'ndx': 'VER_NDX_GLOBAL'},
+ {'name': 'function1', 'ndx': 4 | 0x8000},
+ {'name': '__bss_start', 'ndx': 'VER_NDX_GLOBAL'},
+ {'name': 'function1', 'ndx': 2},
+ {'name': 'VER_1.1', 'ndx': 3},
+ {'name': '_init', 'ndx': 'VER_NDX_GLOBAL'},
+ {'name': 'function1_ver1_0', 'ndx': 'VER_NDX_GLOBAL'},
+ {'name': '_fini', 'ndx': 'VER_NDX_GLOBAL'},
+ {'name': 'VER_1.2', 'ndx': 4},
+ {'name': 'function2', 'ndx': 3},
]
def test_versym_section(self):
self.assertEqual(versym['ndx'], ref_versym['ndx'])
verneed_reference_data = [
- {'name': b'libz.so.1', 'vn_version': 1, 'vn_cnt': 1,
+ {'name': 'libz.so.1', 'vn_version': 1, 'vn_cnt': 1,
'vernaux': [
- {'name': b'ZLIB_1.2.3.5', 'vna_flags': 0, 'vna_other': 7}]},
- {'name': b'libc.so.6', 'vn_version': 1, 'vn_cnt': 2,
+ {'name': 'ZLIB_1.2.3.5', 'vna_flags': 0, 'vna_other': 7}]},
+ {'name': 'libc.so.6', 'vn_version': 1, 'vn_cnt': 2,
'vernaux': [
- {'name': b'GLIBC_2.4', 'vna_flags': 0, 'vna_other': 6},
- {'name': b'GLIBC_2.2.5', 'vna_flags': 0, 'vna_other': 5}]},
+ {'name': 'GLIBC_2.4', 'vna_flags': 0, 'vna_other': 6},
+ {'name': 'GLIBC_2.2.5', 'vna_flags': 0, 'vna_other': 5}]},
]
def test_verneed_section(self):
{'vd_ndx': 1, 'vd_version': 1, 'vd_flags': VER_FLAGS.VER_FLG_BASE,
'vd_cnt': 1,
'verdaux': [
- {'name': b'lib_versioned.so.1'}]},
+ {'name': 'lib_versioned.so.1'}]},
{'vd_ndx': 2, 'vd_version': 1, 'vd_flags': 0, 'vd_cnt': 1,
'verdaux': [
- {'name': b'VER_1.0'}]},
+ {'name': 'VER_1.0'}]},
{'vd_ndx': 3, 'vd_version': 1, 'vd_flags': 0, 'vd_cnt': 2,
'verdaux': [
- {'name': b'VER_1.1'},
- {'name': b'VER_1.0'}]},
+ {'name': 'VER_1.1'},
+ {'name': 'VER_1.0'}]},
{'vd_ndx': 4, 'vd_version': 1, 'vd_flags': 0, 'vd_cnt': 2,
'verdaux': [
- {'name': b'VER_1.2'},
- {'name': b'VER_1.1'}]},
+ {'name': 'VER_1.2'},
+ {'name': 'VER_1.1'}]},
]
def test_verdef_section(self):
with open(os.path.join('test', 'testfiles_for_unittests',
testfile), 'rb') as f:
elf = ELFFile(f)
- syminfo_section = elf.get_section_by_name(b'.SUNW_syminfo')
+ syminfo_section = elf.get_section_by_name('.SUNW_syminfo')
self.assertIsNotNone(syminfo_section)
# The test files were compiled against libc.so.1 with
# in the syminfo table.
# We check that this is properly detected.
exit_symbols = [s for s in syminfo_section.iter_symbols()
- if b'exit' in s.name]
+ if 'exit' in s.name]
self.assertNotEqual(len(exit_symbols), 0)
for symbol in exit_symbols:
def test_SUNW_syminfo_section_sparc64(self):
self._test_SUNW_syminfo_section_generic('exe_solaris64_cc.sparc.elf')
- ldsynsym_reference_data = [b'', b'exe_solaris32.elf', b'crti.s', b'crt1.o',
- b'crt1.s', b'fsr.s', b'values-Xa.c',
- b'exe_solaris64.elf.c', b'crtn.s']
+ ldsynsym_reference_data = ['', 'exe_solaris32.elf', 'crti.s', 'crt1.o',
+ 'crt1.s', 'fsr.s', 'values-Xa.c',
+ 'exe_solaris64.elf.c', 'crtn.s']
def _test_SUNW_ldynsym_section_generic(self, testfile, reference_data):
with open(os.path.join('test', 'testfiles_for_unittests',
testfile), 'rb') as f:
elf = ELFFile(f)
- ldynsym_section = elf.get_section_by_name(b'.SUNW_ldynsym')
+ ldynsym_section = elf.get_section_by_name('.SUNW_ldynsym')
self.assertIsNotNone(ldynsym_section)
for symbol, ref_symbol_name in zip(
def test_SUNW_ldynsym_section_x64(self):
reference_data = copy.deepcopy(
TestSolarisSupport.ldsynsym_reference_data)
- reference_data[1] = b'exe_solaris64.elf'
- reference_data[3] = b'crt1x.o'
- reference_data[5] = b'fsrx.s'
+ reference_data[1] = 'exe_solaris64.elf'
+ reference_data[3] = 'crt1x.o'
+ reference_data[5] = 'fsrx.s'
self._test_SUNW_ldynsym_section_generic('exe_solaris64_cc.elf',
reference_data)