55f1a63faf
- Implements application tracing module which allows to send arbitrary data to host over JTAG. This feature is useful for analyzing program modules behavior, dumping run-time application data etc. - Implements printf-like logging functions on top of apptrace module. This feature is a kind of semihosted printf functionality with lower overhead and impact on system behaviour as compared to standard printf.
274 lines
8.6 KiB
Python
274 lines
8.6 KiB
Python
from ctypes import *
|
|
from ..constants import EI_NIDENT
|
|
|
|
# Obtained from /usr/lib/elf.h
|
|
|
|
# Type for a 16-bit quantity.
|
|
Elf32_Half = c_uint16
|
|
Elf64_Half = c_uint16
|
|
|
|
# Types for signed and unsigned 32-bit quantities.
|
|
Elf32_Word = c_uint32
|
|
Elf32_Sword = c_int32
|
|
Elf64_Word = c_uint32
|
|
Elf64_Sword = c_int32
|
|
|
|
# Types for signed and unsigned 64-bit quantities.
|
|
Elf32_Xword = c_uint64
|
|
Elf32_Sxword = c_int64
|
|
Elf64_Xword = c_uint64
|
|
Elf64_Sxword = c_int64
|
|
|
|
# Type of addresses.
|
|
Elf32_Addr = c_uint32
|
|
Elf64_Addr = c_uint64
|
|
|
|
# Type of file offsets.
|
|
Elf32_Off = c_uint32
|
|
Elf64_Off = c_uint64
|
|
|
|
# Type for section indices, which are 16-bit quantities.
|
|
Elf32_Section = c_uint16
|
|
Elf64_Section = c_uint16
|
|
|
|
# Type for version symbol information.
|
|
Elf32_Versym = Elf32_Half
|
|
Elf64_Versym = Elf64_Half
|
|
|
|
# The ELF file header. This appears at the start of every ELF file.
|
|
|
|
Elf_IdentT = c_char * EI_NIDENT
|
|
|
|
Elf_Cmd = c_int
|
|
|
|
class _ElfStructure(Structure):
|
|
def __str__(self):
|
|
return self.__class__.__name__ + '(' + \
|
|
','.join([field[0] + '=' + str(getattr(self, field[0])) for field in self._fields_]) + ')'
|
|
|
|
class _ElfUnion(Union):
|
|
def __str__(self):
|
|
return self.__class__.__name__ + '(' + \
|
|
','.join([field[0] + '=' + str(getattr(self, field[0])) for field in self._fields_]) + ')'
|
|
|
|
# Libelf opaque handles
|
|
class Elf(_ElfStructure):
|
|
_fields_ = []
|
|
class Elf_Scn(_ElfStructure):
|
|
_fields_ = []
|
|
|
|
class Elf_Data(_ElfStructure):
|
|
_fields_ = [
|
|
('d_buf', c_void_p),
|
|
('d_type', c_int),
|
|
('d_size', c_size_t),
|
|
('d_off', c_size_t),
|
|
('d_align', c_size_t),
|
|
('d_version', c_uint)
|
|
]
|
|
|
|
ElfP = POINTER(Elf)
|
|
Elf_ScnP = POINTER(Elf_Scn)
|
|
Elf_DataP = POINTER(Elf_Data)
|
|
|
|
class Elf32_Ehdr(_ElfStructure):
|
|
_fields_ = [
|
|
('e_ident', Elf_IdentT ), # Magic number and other info
|
|
('e_type', Elf32_Half ), # Object file type
|
|
('e_machine', Elf32_Half ), # Architecture
|
|
('e_version', Elf32_Word ), # Object file version
|
|
('e_entry', Elf32_Addr ), # Entry point virtual address
|
|
('e_phoff', Elf32_Off), # Program header table file offset
|
|
('e_shoff', Elf32_Off), # Section header table file offset
|
|
('e_flags', Elf32_Word ), # Processor-specific flags
|
|
('e_ehsize', Elf32_Half ), # ELF header size in bytes
|
|
('e_phentsize', Elf32_Half ), # Program header table entry size
|
|
('e_phnum', Elf32_Half ), # Program header table entry count
|
|
('e_shentsize', Elf32_Half ), # Section header table entry size
|
|
('e_shnum', Elf32_Half ), # Section header table entry count
|
|
('e_shstrndx', Elf32_Half ), # Section header string table index
|
|
]
|
|
|
|
class Elf64_Ehdr(_ElfStructure):
|
|
_fields_ = [
|
|
('e_ident', Elf_IdentT ), # Magic number and other info
|
|
('e_type', Elf64_Half ), # Object file type
|
|
('e_machine', Elf64_Half ), # Architecture
|
|
('e_version', Elf64_Word ), # Object file version
|
|
('e_entry', Elf64_Addr ), # Entry point virtual address
|
|
('e_phoff', Elf64_Off), # Program header table file offset
|
|
('e_shoff', Elf64_Off), # Section header table file offset
|
|
('e_flags', Elf64_Word ), # Processor-specific flags
|
|
('e_ehsize', Elf64_Half ), # ELF header size in bytes
|
|
('e_phentsize', Elf64_Half ), # Program header table entry size
|
|
('e_phnum', Elf64_Half ), # Program header table entry count
|
|
('e_shentsize', Elf64_Half ), # Section header table entry size
|
|
('e_shnum', Elf64_Half ), # Section header table entry count
|
|
('e_shstrndx', Elf64_Half ), # Section header string table index
|
|
]
|
|
|
|
class Elf32_Shdr(_ElfStructure):
|
|
_fields_ = [
|
|
('sh_name', Elf32_Word), # Section name (string tbl index)
|
|
('sh_type', Elf32_Word), # Section type
|
|
('sh_flags', Elf32_Word), # Section flags
|
|
('sh_addr', Elf32_Addr), # Section virtual addr at execution
|
|
('sh_offset', Elf32_Off), # Section file offset
|
|
('sh_size', Elf32_Word), # Section size in bytes
|
|
('sh_link', Elf32_Word), # Link to another section
|
|
('sh_info', Elf32_Word), # Additional section information
|
|
('sh_addralign', Elf32_Word), # Section alignment
|
|
('sh_entsize', Elf32_Word), # Entry size if section holds table
|
|
]
|
|
|
|
class Elf64_Shdr(_ElfStructure):
|
|
_fields_ = [
|
|
('sh_name', Elf64_Word), # Section name (string tbl index)
|
|
('sh_type', Elf64_Word), # Section type
|
|
('sh_flags', Elf64_Xword), # Section flags
|
|
('sh_addr', Elf64_Addr), # Section virtual addr at execution
|
|
('sh_offset', Elf64_Off), # Section file offset
|
|
('sh_size', Elf64_Xword), # Section size in bytes
|
|
('sh_link', Elf64_Word), # Link to another section
|
|
('sh_info', Elf64_Word), # Additional section information
|
|
('sh_addralign', Elf64_Xword), # Section alignment
|
|
('sh_entsize', Elf64_Xword), # Entry size if section holds table
|
|
]
|
|
|
|
class Elf32_Phdr(_ElfStructure):
|
|
_fields_ = [
|
|
('p_type', Elf32_Word), # Segment type
|
|
('p_offset', Elf32_Off), # Segment file offset
|
|
('p_vaddr', Elf32_Addr), # Segment virtual address
|
|
('p_paddr', Elf32_Addr), # Segment physical address
|
|
('p_filesz', Elf32_Word), # Segment size in file
|
|
('p_memsz', Elf32_Word), # Segment size in memory
|
|
('p_flags', Elf32_Word), # Segment flags
|
|
('p_align', Elf32_Word), # Segment alignment
|
|
]
|
|
|
|
class Elf64_Phdr(_ElfStructure):
|
|
_fields_ = [
|
|
('p_type', Elf64_Word), # Segment type
|
|
('p_flags', Elf64_Word), # Segment flags
|
|
('p_offset', Elf64_Off), # Segment file offset
|
|
('p_vaddr', Elf64_Addr), # Segment virtual address
|
|
('p_paddr', Elf64_Addr), # Segment physical address
|
|
('p_filesz', Elf64_Xword), # Segment size in file
|
|
('p_memsz', Elf64_Xword), # Segment size in memory
|
|
('p_align', Elf64_Xword), # Segment alignment
|
|
]
|
|
|
|
# /* Symbol table entry. */
|
|
class Elf32_Sym(_ElfStructure):
|
|
_fields_ = [
|
|
('st_name', Elf32_Word), # Symbol name (string tbl index)
|
|
('st_value', Elf32_Addr), # Symbol value
|
|
('st_size', Elf32_Word), # Symbol size
|
|
('st_info', c_char), # Symbol type and binding
|
|
('st_other', c_char), # Symbol visibility
|
|
('st_shndx', Elf32_Section), # Section index
|
|
]
|
|
|
|
class Elf64_Sym(_ElfStructure):
|
|
_fields_ = [
|
|
('st_name', Elf64_Word), # Symbol name (string tbl index)
|
|
('st_info', c_char), # Symbol type and binding
|
|
('st_other', c_char), # Symbol visibility
|
|
('st_shndx', Elf64_Section), # Section index
|
|
('st_value', Elf64_Addr), # Symbol value
|
|
('st_size', Elf64_Xword), # Symbol size
|
|
]
|
|
|
|
#/* The syminfo section if available contains additional information about
|
|
# every dynamic symbol. */
|
|
|
|
class Elf32_Syminfo(_ElfStructure):
|
|
_fields_ = [
|
|
('si_boundto', Elf32_Half), # Direct bindings, symbol bound to
|
|
('si_flags', Elf32_Half), # Per symbol flags
|
|
]
|
|
|
|
class Elf64_Syminfo(_ElfStructure):
|
|
_fields_ = [
|
|
('si_boundto', Elf64_Half), # Direct bindings, symbol bound to
|
|
('si_flags', Elf64_Half), # Per symbol flags
|
|
]
|
|
|
|
# /* Relocation table entry without addend (in section of type SHT_REL). */
|
|
|
|
class Elf32_Rel(_ElfStructure):
|
|
_fields_ = [
|
|
('r_offset', Elf32_Addr), # Address
|
|
('r_info', Elf32_Word), # Relocation type and symbol index
|
|
]
|
|
|
|
class Elf64_Rel(_ElfStructure):
|
|
_fields_ = [
|
|
('r_offset', Elf64_Addr), # Address
|
|
('r_info', Elf64_Xword), # Relocation type and symbol index
|
|
]
|
|
|
|
# # Relocation table entry with addend (in section of type SHT_RELA).
|
|
|
|
class Elf32_Rela(_ElfStructure):
|
|
_fields_ = [
|
|
('r_offset', Elf32_Addr), # Address
|
|
('r_info', Elf32_Word), # Relocation type and symbol index
|
|
('r_addend', Elf32_Sword), # Addend
|
|
]
|
|
|
|
class Elf64_Rela(_ElfStructure):
|
|
_fields_ = [
|
|
('r_offset', Elf64_Addr), # Address
|
|
('r_info', Elf64_Xword), # Relocation type and symbol index
|
|
('r_addend', Elf64_Sxword), # Addend
|
|
]
|
|
|
|
time_t = c_int64
|
|
uid_t = c_int32
|
|
gid_t = c_int32
|
|
mode_t = c_int32
|
|
off_t = c_int64
|
|
|
|
class Elf_Arhdr(_ElfStructure):
|
|
_fields_ = [
|
|
('ar_name', c_char_p),
|
|
('ar_date', time_t),
|
|
('ar_uid', uid_t),
|
|
('ar_gid', gid_t),
|
|
('ar_mode', mode_t),
|
|
('ar_size', off_t),
|
|
('ar_fmag', POINTER(c_char)),
|
|
]
|
|
|
|
class _Elf64_DynUnion(_ElfUnion):
|
|
_fields_ = [
|
|
('d_val', Elf64_Xword),
|
|
('d_ptr', Elf64_Addr),
|
|
]
|
|
|
|
class Elf64_Dyn(_ElfStructure):
|
|
_fields_ = [
|
|
('d_tag', Elf64_Xword),
|
|
('d_un', _Elf64_DynUnion),
|
|
]
|
|
|
|
# GNU Extensions
|
|
class Elf64_Verneed(_ElfStructure):
|
|
_fields_ = [
|
|
('vn_version', Elf64_Half),
|
|
('vn_cnt', Elf64_Half),
|
|
('vn_file', Elf64_Word),
|
|
('vn_aux', Elf64_Word),
|
|
('vn_next', Elf64_Word),
|
|
]
|
|
|
|
class Elf64_Vernaux(_ElfStructure):
|
|
_fields_ = [
|
|
('vna_hash', Elf64_Word),
|
|
('vna_flags', Elf64_Half),
|
|
('vna_other', Elf64_Half),
|
|
('vna_name', Elf64_Word),
|
|
('vna_next', Elf64_Word),
|
|
]
|