max_chain_pos = self._chain_pos + \
(max_idx - self.params['symoffset']) * self._wordsize
self.elffile.stream.seek(max_chain_pos)
+ hash_format = '<I' if self.elffile.little_endian else '>I'
# Walk the chain to its end (lowest bit is set)
while True:
- cur_hash = struct.unpack('I', self.elffile.stream.read(self._wordsize))[0]
+ cur_hash = struct.unpack(hash_format, self.elffile.stream.read(self._wordsize))[0]
if cur_hash & 1:
return max_idx + 1
return None
self.elffile.stream.seek(self._chain_pos + (symidx - self.params['symoffset']) * self._wordsize)
+ hash_format = '<I' if self.elffile.little_endian else '>I'
while True:
- cur_hash = struct.unpack('I', self.elffile.stream.read(self._wordsize))[0]
+ cur_hash = struct.unpack(hash_format, self.elffile.stream.read(self._wordsize))[0]
if cur_hash | 1 == namehash | 1:
symbol = self._symboltable.get_symbol(symidx)
if name == symbol.name:
symbol_f1 = hash_section.get_symbol('function1_ver1_1')
self.assertIsNotNone(symbol_f1)
self.assertEqual(symbol_f1['st_value'], int(0x9a2))
+
+ def test_get_symbol_big_endian(self):
+ """ Verify we can get a specific symbol from a GNU hash section in a
+ big-endian file.
+ """
+ with open(os.path.join('test', 'testfiles_for_unittests',
+ 'aarch64_be_gnu_hash.so.elf'), 'rb') as f:
+ elf = ELFFile(f)
+ self.assertFalse(elf.little_endian)
+ hash_section = elf.get_section_by_name('.gnu.hash')
+ self.assertIsNotNone(hash_section)
+ symbol_f1 = hash_section.get_symbol('caller')
+ self.assertIsNotNone(symbol_f1)
+ self.assertEqual(symbol_f1['st_value'], int(0x5a4))