blob: d44ec9083dbdf81085aadc2cd6184d5afa476de7 [file] [log] [blame]
#
# Copyright (C) 2018 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""This file contains ELF C structs and data types."""
import ctypes
from vts.utils.python.library.elf import consts
# ELF data types.
Elf32_Addr = ctypes.c_uint32
Elf32_Off = ctypes.c_uint32
Elf32_Half = ctypes.c_uint16
Elf32_Word = ctypes.c_uint32
Elf32_Sword = ctypes.c_int32
Elf64_Addr = ctypes.c_uint64
Elf64_Off = ctypes.c_uint64
Elf64_Half = ctypes.c_uint16
Elf64_Word = ctypes.c_uint32
Elf64_Sword = ctypes.c_int32
Elf64_Xword = ctypes.c_uint64
Elf64_Sxword = ctypes.c_int64
# ELF C structs.
class CStructure(ctypes.LittleEndianStructure):
"""Little endian C structure base class."""
pass
class CUnion(ctypes.Union):
"""Native endian C union base class."""
pass
class _Ehdr(CStructure):
"""ELF header base class."""
def GetFileClass(self):
"""Returns the file class."""
return self.e_ident[consts.EI_CLASS]
def GetDataEncoding(self):
"""Returns the data encoding of the file."""
return self.e_ident[consts.EI_DATA]
class Elf32_Ehdr(_Ehdr):
"""ELF 32-bit header."""
_fields_ = [('e_ident', ctypes.c_uint8 * consts.EI_NIDENT),
('e_type', Elf32_Half),
('e_machine', Elf32_Half),
('e_version', Elf32_Word),
('e_entry', Elf32_Addr),
('e_phoff', Elf32_Off),
('e_shoff', Elf32_Off),
('e_flags', Elf32_Word),
('e_ehsize', Elf32_Half),
('e_phentsize', Elf32_Half),
('e_phnum', Elf32_Half),
('e_shentsize', Elf32_Half),
('e_shnum', Elf32_Half),
('e_shstrndx', Elf32_Half)]
class Elf64_Ehdr(_Ehdr):
"""ELF 64-bit header."""
_fields_ = [('e_ident', ctypes.c_uint8 * consts.EI_NIDENT),
('e_type', Elf64_Half),
('e_machine', Elf64_Half),
('e_version', Elf64_Word),
('e_entry', Elf64_Addr),
('e_phoff', Elf64_Off),
('e_shoff', Elf64_Off),
('e_flags', Elf64_Word),
('e_ehsize', Elf64_Half),
('e_phentsize', Elf64_Half),
('e_phnum', Elf64_Half),
('e_shentsize', Elf64_Half),
('e_shnum', Elf64_Half),
('e_shstrndx', Elf64_Half)]
class Elf32_Shdr(CStructure):
"""ELF 32-bit section header."""
_fields_ = [('sh_name', Elf32_Word),
('sh_type', Elf32_Word),
('sh_flags', Elf32_Word),
('sh_addr', Elf32_Addr),
('sh_offset', Elf32_Off),
('sh_size', Elf32_Word),
('sh_link', Elf32_Word),
('sh_info', Elf32_Word),
('sh_addralign', Elf32_Word),
('sh_entsize', Elf32_Word)]
class Elf64_Shdr(CStructure):
"""ELF 64-bit section header."""
_fields_ = [('sh_name', Elf64_Word),
('sh_type', Elf64_Word),
('sh_flags', Elf64_Xword),
('sh_addr', Elf64_Addr),
('sh_offset', Elf64_Off),
('sh_size', Elf64_Xword),
('sh_link', Elf64_Word),
('sh_info', Elf64_Word),
('sh_addralign', Elf64_Xword),
('sh_entsize', Elf64_Xword)]
class Elf32_Dyn(CStructure):
"""ELF 32-bit dynamic section entry."""
class _Elf32_Dyn__d_un(CUnion):
_fields_ = [('d_val', Elf32_Word),
('d_ptr', Elf32_Addr)]
_fields_ = [('d_tag', Elf32_Sword),
('d_un', _Elf32_Dyn__d_un)]
class Elf64_Dyn(CStructure):
"""ELF 64-bit dynamic section entry."""
class _Elf64_Dyn__d_un(CUnion):
_fields_ = [('d_val', Elf64_Xword),
('d_ptr', Elf64_Addr)]
_fields_ = [('d_tag', Elf64_Sxword),
('d_un', _Elf64_Dyn__d_un)]
class _Sym(CStructure):
"""ELF symbol table entry base class."""
def GetBinding(self):
"""Returns the symbol binding."""
return self.st_info >> 4
def GetType(self):
"""Returns the symbol type."""
return self.st_info & 0xf
def SetBinding(self, binding):
"""Sets the symbol binding.
Args:
binding: An integer specifying the new binding.
"""
self.SetSymbolAndType(binding, self.GetType())
def SetType(self, type_):
"""Sets the symbol type.
Args:
type_: An integer specifying the new type.
"""
self.SetSymbolAndType(self.GetBinding(), type_)
def SetBindingAndType(self, binding, type_):
"""Sets the symbol binding and type.
Args:
binding: An integer specifying the new binding.
type_: An integer specifying the new type.
"""
self.st_info = (binding << 4) | (type_ & 0xf)
class Elf32_Sym(_Sym):
"""ELF 32-bit symbol table entry."""
_fields_ = [('st_name', Elf32_Word),
('st_value', Elf32_Addr),
('st_size', Elf32_Word),
('st_info', ctypes.c_uint8),
('st_other', ctypes.c_uint8),
('st_shndx', Elf32_Half)]
class Elf64_Sym(_Sym):
"""ELF 64-bit symbol table entry."""
_fields_ = [('st_name', Elf64_Word),
('st_info', ctypes.c_uint8),
('st_other', ctypes.c_uint8),
('st_shndx', Elf64_Half),
('st_value', Elf64_Addr),
('st_size', Elf64_Xword)]
class _32_Rel(CStructure):
"""ELF 32-bit relocation table entry base class."""
def GetSymbol(self):
"""Returns the symbol table index with respect to the relocation.
Symbol table index with respect to which the relocation must be made.
"""
return self.r_info >> 8
def GetType(self):
"""Returns the relocation type."""
return self.r_info & 0xff
def SetSymbol(self, symndx):
"""Sets the relocation's symbol table index.
Args:
symndx: An integer specifying the new symbol table index.
"""
self.SetSymbolAndType(symndx, self.GetType())
def SetType(self, type_):
"""Sets the relocation type.
Args:
type_: An integer specifying the new relocation type.
"""
self.SetSymbolAndType(self.GetSymbol(), type_)
def SetSymbolAndType(self, symndx, type_):
"""Sets the relocation's symbol table index and type.
Args:
symndx: An integer specifying the new symbol table index.
type_: An integer specifying the new relocation type.
"""
self.r_info = (symndx << 8) | (type_ & 0xff)
class Elf32_Rel(_32_Rel):
"""ELF 32-bit relocation table entry."""
_fields_ = [('r_offset', Elf32_Addr),
('r_info', Elf32_Word)]
class Elf32_Rela(_32_Rel):
"""ELF 32-bit relocation table entry with explicit addend."""
_fields_ = [('r_offset', Elf32_Addr),
('r_info', Elf32_Word),
('r_addend', Elf32_Sword)]
class _64_Rel(CStructure):
"""ELF 64-bit relocation table entry base class."""
def GetSymbol(self):
"""Returns the symbol table index with respect to the relocation.
Symbol table index with respect to which the relocation must be made.
"""
return self.r_info >> 32
def GetType(self):
"""Returns the relocation type."""
return self.r_info & 0xffffffff
def SetSymbol(self, symndx):
"""Sets the relocation's symbol table index.
Args:
symndx: An integer specifying the new symbol table index.
"""
self.SetSymbolAndType(symndx, self.GetType())
def SetType(self, type_):
"""Sets the relocation type.
Args:
type_: An integer specifying the new relocation type.
"""
self.SetSymbolAndType(self.GetSymbol(), type_)
def SetSymbolAndType(self, symndx, type_):
"""Sets the relocation's symbol table index and type.
Args:
symndx: An integer specifying the new symbol table index.
type_: An integer specifying the new relocation type.
"""
self.r_info = (symndx << 32) | (type_ & 0xffffffff)
class Elf64_Rel(_64_Rel):
"""ELF 64-bit relocation table entry."""
_fields_ = [('r_offset', Elf64_Addr),
('r_info', Elf64_Xword)]
class Elf64_Rela(_64_Rel):
"""ELF 64-bit relocation table entry with explicit addend."""
_fields_ = [('r_offset', Elf64_Addr),
('r_info', Elf64_Xword),
('r_addend', Elf64_Sxword)]
class Elf32_Phdr(CStructure):
"""ELF 32-bit program header."""
_fields_ = [('p_type', Elf32_Word),
('p_offset', Elf32_Off),
('p_vaddr', Elf32_Addr),
('p_paddr', Elf32_Addr),
('p_filesz', Elf32_Word),
('p_memsz', Elf32_Word),
('p_flags', Elf32_Word),
('p_align', Elf32_Word)]
class Elf64_Phdr(CStructure):
"""ELF 64-bit program header."""
_fields_ = [('p_type', Elf64_Word),
('p_flags', Elf64_Word),
('p_offset', Elf64_Off),
('p_vaddr', Elf64_Addr),
('p_paddr', Elf64_Addr),
('p_filesz', Elf64_Xword),
('p_memsz', Elf64_Xword),
('p_align', Elf64_Xword)]
class Elf32_Nhdr(CStructure):
"""ELF 32-bit note header."""
_fields_ = [('n_namesz', Elf32_Word),
('n_descsz', Elf32_Word),
('n_type', Elf32_Word)]
class Elf64_Nhdr(CStructure):
"""ELF 64-bit note header."""
_fields_ = [('n_namesz', Elf64_Word),
('n_descsz', Elf64_Word),
('n_type', Elf64_Word)]