def show_sym(fname, data, endian, evtype, sym): """Show information about an evspy entry Args: fname (str): Filename of ELF file data (bytes): Data for this symbol endian (str): Endianness to use ('little', 'big', 'auto') evtype (str): Event type, e.g. 'MISC_INIT_F' sym (elf.Symbol): Symbol to show """ def _unpack_val(sym_data, offset): start = offset * func_size val_data = sym_data[start:start + func_size] fmt = '%s%s' % ('>' if endian == 'big' else '<', 'L' if func_size == 4 else 'Q') val = struct.unpack(fmt, val_data)[0] return val # Get the data, which is a struct evspy_info sym_data = data[sym.offset:sym.offset + sym.size] # Figure out the word size of the struct func_size = 4 if sym.size < 16 else 8 # Read the function name for evspy_info->func while True: # Switch to big-endian if we see a failure func_addr = _unpack_val(sym_data, 0) func_name = elf.GetSymbolFromAddress(fname, func_addr) if not func_name and endian == 'auto': endian = 'big' else: break has_id = sym.size in [12, 24] if has_id: # Find the address of evspy_info->id in the ELF id_addr = _unpack_val(sym_data, 2) # Get the file offset for that address id_ofs = elf.GetFileOffset(fname, id_addr) # Read out a nul-terminated string id_data = data[id_ofs:id_ofs + 80] pos = id_data.find(0) if pos: id_data = id_data[:pos] id_str = id_data.decode('utf-8') else: id_str = None # Find the file/line for the function cmd = ['addr2line', '-e', fname, '%x' % func_addr] out = tools.run(*cmd).strip() # Drop the full path if it is the current directory if out.startswith(src_path): out = out[len(src_path) + 1:] print('%-20s %-30s %s' % (evtype, id_str or f'f:{func_name}', out))
def test_get_file_offset_fail(self): """Test calling GetFileOffset() without elftools""" try: old_val = elf.ELF_TOOLS elf.ELF_TOOLS = False fname = self.ElfTestFile('embed_data') with self.assertRaises(ValueError) as e: elf.GetFileOffset(fname, 0) self.assertIn("Python: No module named 'elftools'", str(e.exception)) finally: elf.ELF_TOOLS = old_val
def test_get_file_offset(self): """Test GetFileOffset() gives the correct file offset for a symbol""" fname = self.ElfTestFile('embed_data') syms = elf.GetSymbols(fname, ['embed']) addr = syms['embed'].address offset = elf.GetFileOffset(fname, addr) data = tools.read_file(fname) # Just use the first 4 bytes and assume it is little endian embed_data = data[offset:offset + 4] embed_value = struct.unpack('<I', embed_data)[0] self.assertEqual(0x1234, embed_value)