mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-22 09:58:09 +00:00
coredump: enable coredump generation on arm
Add relevant elf header constants and notes for the arm platform to enable coredump generation. Signed-off-by: समीर सिंह Sameer Singh <lumarzeli30@gmail.com>
This commit is contained in:
parent
da90b33a42
commit
38b9807cd5
@ -6,7 +6,7 @@ import sys
|
|||||||
|
|
||||||
import criu_coredump
|
import criu_coredump
|
||||||
|
|
||||||
PLATFORMS = ["aarch64", "x86_64"]
|
PLATFORMS = ["aarch64", "armv7l", "x86_64"]
|
||||||
|
|
||||||
|
|
||||||
def coredump(opts):
|
def coredump(opts):
|
||||||
|
@ -95,8 +95,13 @@ class coredump:
|
|||||||
buf.write(b"\0" * (8 - len(note.owner)))
|
buf.write(b"\0" * (8 - len(note.owner)))
|
||||||
buf.write(note.data)
|
buf.write(note.data)
|
||||||
|
|
||||||
offset = ctypes.sizeof(elf.Elf64_Ehdr())
|
bits = platform.architecture()[0] # 32 or 64 bits
|
||||||
offset += (len(self.vmas) + 1) * ctypes.sizeof(elf.Elf64_Phdr())
|
|
||||||
|
ehdr = {"32bit": elf.Elf32_Ehdr, "64bit": elf.Elf64_Ehdr}
|
||||||
|
phdr = {"32bit": elf.Elf32_Phdr, "64bit": elf.Elf64_Phdr}
|
||||||
|
|
||||||
|
offset = ctypes.sizeof(ehdr[bits]())
|
||||||
|
offset += (len(self.vmas) + 1) * ctypes.sizeof(phdr[bits]())
|
||||||
|
|
||||||
filesz = 0
|
filesz = 0
|
||||||
for note in self.notes:
|
for note in self.notes:
|
||||||
@ -132,9 +137,18 @@ class coredump_generator:
|
|||||||
pagemaps = {} # pagemap by pid;
|
pagemaps = {} # pagemap by pid;
|
||||||
|
|
||||||
# thread info key based on the current arch
|
# thread info key based on the current arch
|
||||||
thread_info_key = {"aarch64": "ti_aarch64", "x86_64": "thread_info"}
|
thread_info_key = {
|
||||||
|
"aarch64": "ti_aarch64",
|
||||||
|
"armv7l": "ti_arm",
|
||||||
|
"x86_64": "thread_info",
|
||||||
|
}
|
||||||
|
|
||||||
machine = platform.machine() # current arch
|
machine = platform.machine() # current arch
|
||||||
|
bits = platform.architecture()[0] # 32 or 64 bits
|
||||||
|
|
||||||
|
ehdr = {"32bit": elf.Elf32_Ehdr, "64bit": elf.Elf64_Ehdr} # 32 or 64 bits Ehdr
|
||||||
|
nhdr = {"32bit": elf.Elf32_Nhdr, "64bit": elf.Elf64_Nhdr} # 32 or 64 bits Nhdr
|
||||||
|
phdr = {"32bit": elf.Elf32_Phdr, "64bit": elf.Elf64_Phdr} # 32 or 64 bits Phdr
|
||||||
|
|
||||||
def _img_open_and_strip(self, name, single=False, pid=None):
|
def _img_open_and_strip(self, name, single=False, pid=None):
|
||||||
"""
|
"""
|
||||||
@ -207,23 +221,30 @@ class coredump_generator:
|
|||||||
"""
|
"""
|
||||||
Generate elf header for process pid with program headers phdrs.
|
Generate elf header for process pid with program headers phdrs.
|
||||||
"""
|
"""
|
||||||
ehdr = elf.Elf64_Ehdr()
|
ei_class = {"32bit": elf.ELFCLASS32, "64bit": elf.ELFCLASS64}
|
||||||
|
|
||||||
|
ehdr = self.ehdr[self.bits]()
|
||||||
|
|
||||||
ctypes.memset(ctypes.addressof(ehdr), 0, ctypes.sizeof(ehdr))
|
ctypes.memset(ctypes.addressof(ehdr), 0, ctypes.sizeof(ehdr))
|
||||||
ehdr.e_ident[elf.EI_MAG0] = elf.ELFMAG0
|
ehdr.e_ident[elf.EI_MAG0] = elf.ELFMAG0
|
||||||
ehdr.e_ident[elf.EI_MAG1] = elf.ELFMAG1
|
ehdr.e_ident[elf.EI_MAG1] = elf.ELFMAG1
|
||||||
ehdr.e_ident[elf.EI_MAG2] = elf.ELFMAG2
|
ehdr.e_ident[elf.EI_MAG2] = elf.ELFMAG2
|
||||||
ehdr.e_ident[elf.EI_MAG3] = elf.ELFMAG3
|
ehdr.e_ident[elf.EI_MAG3] = elf.ELFMAG3
|
||||||
ehdr.e_ident[elf.EI_CLASS] = elf.ELFCLASS64
|
ehdr.e_ident[elf.EI_CLASS] = ei_class[self.bits]
|
||||||
ehdr.e_ident[elf.EI_DATA] = elf.ELFDATA2LSB
|
ehdr.e_ident[elf.EI_DATA] = elf.ELFDATA2LSB
|
||||||
ehdr.e_ident[elf.EI_VERSION] = elf.EV_CURRENT
|
ehdr.e_ident[elf.EI_VERSION] = elf.EV_CURRENT
|
||||||
|
|
||||||
|
if self.machine == "armv7l":
|
||||||
|
ehdr.e_ident[elf.EI_OSABI] = elf.ELFOSABI_ARM
|
||||||
|
else:
|
||||||
|
ehdr.e_ident[elf.EI_OSABI] = elf.ELFOSABI_NONE
|
||||||
|
|
||||||
ehdr.e_type = elf.ET_CORE
|
ehdr.e_type = elf.ET_CORE
|
||||||
ehdr.e_machine = self._get_e_machine()
|
ehdr.e_machine = self._get_e_machine()
|
||||||
ehdr.e_version = elf.EV_CURRENT
|
ehdr.e_version = elf.EV_CURRENT
|
||||||
ehdr.e_phoff = ctypes.sizeof(elf.Elf64_Ehdr())
|
ehdr.e_phoff = ctypes.sizeof(self.ehdr[self.bits]())
|
||||||
ehdr.e_ehsize = ctypes.sizeof(elf.Elf64_Ehdr())
|
ehdr.e_ehsize = ctypes.sizeof(self.ehdr[self.bits]())
|
||||||
ehdr.e_phentsize = ctypes.sizeof(elf.Elf64_Phdr())
|
ehdr.e_phentsize = ctypes.sizeof(self.phdr[self.bits]())
|
||||||
# FIXME Case len(phdrs) > PN_XNUM should be handled properly.
|
# FIXME Case len(phdrs) > PN_XNUM should be handled properly.
|
||||||
# See fs/binfmt_elf.c from linux kernel.
|
# See fs/binfmt_elf.c from linux kernel.
|
||||||
ehdr.e_phnum = len(phdrs)
|
ehdr.e_phnum = len(phdrs)
|
||||||
@ -234,7 +255,11 @@ class coredump_generator:
|
|||||||
"""
|
"""
|
||||||
Get the e_machine field based on the current architecture.
|
Get the e_machine field based on the current architecture.
|
||||||
"""
|
"""
|
||||||
e_machine_dict = {"aarch64": elf.EM_AARCH64, "x86_64": elf.EM_X86_64}
|
e_machine_dict = {
|
||||||
|
"aarch64": elf.EM_AARCH64,
|
||||||
|
"armv7l": elf.EM_ARM,
|
||||||
|
"x86_64": elf.EM_X86_64,
|
||||||
|
}
|
||||||
return e_machine_dict[self.machine]
|
return e_machine_dict[self.machine]
|
||||||
|
|
||||||
def _gen_phdrs(self, pid, notes, vmas):
|
def _gen_phdrs(self, pid, notes, vmas):
|
||||||
@ -243,15 +268,15 @@ class coredump_generator:
|
|||||||
"""
|
"""
|
||||||
phdrs = []
|
phdrs = []
|
||||||
|
|
||||||
offset = ctypes.sizeof(elf.Elf64_Ehdr())
|
offset = ctypes.sizeof(self.ehdr[self.bits]())
|
||||||
offset += (len(vmas) + 1) * ctypes.sizeof(elf.Elf64_Phdr())
|
offset += (len(vmas) + 1) * ctypes.sizeof(self.phdr[self.bits]())
|
||||||
|
|
||||||
filesz = 0
|
filesz = 0
|
||||||
for note in notes:
|
for note in notes:
|
||||||
filesz += ctypes.sizeof(note.nhdr) + ctypes.sizeof(note.data) + 8
|
filesz += ctypes.sizeof(note.nhdr) + ctypes.sizeof(note.data) + 8
|
||||||
|
|
||||||
# PT_NOTE
|
# PT_NOTE
|
||||||
phdr = elf.Elf64_Phdr()
|
phdr = self.phdr[self.bits]()
|
||||||
ctypes.memset(ctypes.addressof(phdr), 0, ctypes.sizeof(phdr))
|
ctypes.memset(ctypes.addressof(phdr), 0, ctypes.sizeof(phdr))
|
||||||
phdr.p_type = elf.PT_NOTE
|
phdr.p_type = elf.PT_NOTE
|
||||||
phdr.p_offset = offset
|
phdr.p_offset = offset
|
||||||
@ -271,7 +296,7 @@ class coredump_generator:
|
|||||||
for vma in vmas:
|
for vma in vmas:
|
||||||
offset += filesz
|
offset += filesz
|
||||||
filesz = vma.filesz
|
filesz = vma.filesz
|
||||||
phdr = elf.Elf64_Phdr()
|
phdr = self.phdr[self.bits]()
|
||||||
ctypes.memset(ctypes.addressof(phdr), 0, ctypes.sizeof(phdr))
|
ctypes.memset(ctypes.addressof(phdr), 0, ctypes.sizeof(phdr))
|
||||||
phdr.p_type = elf.PT_LOAD
|
phdr.p_type = elf.PT_LOAD
|
||||||
phdr.p_align = PAGESIZE
|
phdr.p_align = PAGESIZE
|
||||||
@ -328,7 +353,7 @@ class coredump_generator:
|
|||||||
prpsinfo.pr_psargs = self._gen_cmdline(pid)[:80]
|
prpsinfo.pr_psargs = self._gen_cmdline(pid)[:80]
|
||||||
prpsinfo.pr_fname = core["tc"]["comm"].encode()
|
prpsinfo.pr_fname = core["tc"]["comm"].encode()
|
||||||
|
|
||||||
nhdr = elf.Elf64_Nhdr()
|
nhdr = self.nhdr[self.bits]()
|
||||||
nhdr.n_namesz = 5
|
nhdr.n_namesz = 5
|
||||||
nhdr.n_descsz = ctypes.sizeof(elf.elf_prpsinfo())
|
nhdr.n_descsz = ctypes.sizeof(elf.elf_prpsinfo())
|
||||||
nhdr.n_type = elf.NT_PRPSINFO
|
nhdr.n_type = elf.NT_PRPSINFO
|
||||||
@ -360,7 +385,7 @@ class coredump_generator:
|
|||||||
|
|
||||||
self._set_pr_regset(prstatus.pr_reg, regs)
|
self._set_pr_regset(prstatus.pr_reg, regs)
|
||||||
|
|
||||||
nhdr = elf.Elf64_Nhdr()
|
nhdr = self.nhdr[self.bits]()
|
||||||
nhdr.n_namesz = 5
|
nhdr.n_namesz = 5
|
||||||
nhdr.n_descsz = ctypes.sizeof(elf.elf_prstatus())
|
nhdr.n_descsz = ctypes.sizeof(elf.elf_prstatus())
|
||||||
nhdr.n_type = elf.NT_PRSTATUS
|
nhdr.n_type = elf.NT_PRSTATUS
|
||||||
@ -390,6 +415,25 @@ class coredump_generator:
|
|||||||
pr_reg.sp = regs["sp"]
|
pr_reg.sp = regs["sp"]
|
||||||
pr_reg.pc = regs["pc"]
|
pr_reg.pc = regs["pc"]
|
||||||
pr_reg.pstate = regs["pstate"]
|
pr_reg.pstate = regs["pstate"]
|
||||||
|
elif self.machine == "armv7l":
|
||||||
|
pr_reg.r0 = regs["r0"]
|
||||||
|
pr_reg.r1 = regs["r1"]
|
||||||
|
pr_reg.r2 = regs["r2"]
|
||||||
|
pr_reg.r3 = regs["r3"]
|
||||||
|
pr_reg.r4 = regs["r4"]
|
||||||
|
pr_reg.r5 = regs["r5"]
|
||||||
|
pr_reg.r6 = regs["r6"]
|
||||||
|
pr_reg.r7 = regs["r7"]
|
||||||
|
pr_reg.r8 = regs["r8"]
|
||||||
|
pr_reg.r9 = regs["r9"]
|
||||||
|
pr_reg.r10 = regs["r10"]
|
||||||
|
pr_reg.fp = regs["fp"]
|
||||||
|
pr_reg.ip = regs["ip"]
|
||||||
|
pr_reg.sp = regs["sp"]
|
||||||
|
pr_reg.lr = regs["lr"]
|
||||||
|
pr_reg.pc = regs["pc"]
|
||||||
|
pr_reg.cpsr = regs["cpsr"]
|
||||||
|
pr_reg.orig_r0 = regs["orig_r0"]
|
||||||
elif self.machine == "x86_64":
|
elif self.machine == "x86_64":
|
||||||
pr_reg.r15 = regs["r15"]
|
pr_reg.r15 = regs["r15"]
|
||||||
pr_reg.r14 = regs["r14"]
|
pr_reg.r14 = regs["r14"]
|
||||||
@ -495,6 +539,34 @@ class coredump_generator:
|
|||||||
|
|
||||||
return note
|
return note
|
||||||
|
|
||||||
|
def _gen_arm_vfp(self, tid):
|
||||||
|
"""
|
||||||
|
Generate NT_ARM_VFP note for thread tid of process pid.
|
||||||
|
"""
|
||||||
|
core = self.cores[tid]
|
||||||
|
fpstate = core["ti_arm"]["fpstate"]
|
||||||
|
|
||||||
|
data = elf.vfp_hard_struct()
|
||||||
|
ctypes.memset(ctypes.addressof(data), 0, ctypes.sizeof(data))
|
||||||
|
|
||||||
|
data.vfp_regs = (ctypes.c_uint64 * len(fpstate["vfp_regs"]))(*fpstate["vfp_regs"])
|
||||||
|
data.fpexc = fpstate["fpexc"]
|
||||||
|
data.fpscr = fpstate["fpscr"]
|
||||||
|
data.fpinst = fpstate["fpinst"]
|
||||||
|
data.fpinst2 = fpstate["fpinst2"]
|
||||||
|
|
||||||
|
nhdr = elf.Elf32_Nhdr()
|
||||||
|
nhdr.n_namesz = 6
|
||||||
|
nhdr.n_descsz = ctypes.sizeof(data)
|
||||||
|
nhdr.n_type = elf.NT_ARM_VFP
|
||||||
|
|
||||||
|
note = elf_note()
|
||||||
|
note.data = data
|
||||||
|
note.owner = b"LINUX"
|
||||||
|
note.nhdr = nhdr
|
||||||
|
|
||||||
|
return note
|
||||||
|
|
||||||
def _gen_x86_xstate(self, pid, tid):
|
def _gen_x86_xstate(self, pid, tid):
|
||||||
"""
|
"""
|
||||||
Generate NT_X86_XSTATE note for thread tid of process pid.
|
Generate NT_X86_XSTATE note for thread tid of process pid.
|
||||||
@ -544,7 +616,7 @@ class coredump_generator:
|
|||||||
# FIXME zeroify everything for now
|
# FIXME zeroify everything for now
|
||||||
ctypes.memset(ctypes.addressof(siginfo), 0, ctypes.sizeof(siginfo))
|
ctypes.memset(ctypes.addressof(siginfo), 0, ctypes.sizeof(siginfo))
|
||||||
|
|
||||||
nhdr = elf.Elf64_Nhdr()
|
nhdr = self.nhdr[self.bits]()
|
||||||
nhdr.n_namesz = 5
|
nhdr.n_namesz = 5
|
||||||
nhdr.n_descsz = ctypes.sizeof(elf.siginfo_t())
|
nhdr.n_descsz = ctypes.sizeof(elf.siginfo_t())
|
||||||
nhdr.n_type = elf.NT_SIGINFO
|
nhdr.n_type = elf.NT_SIGINFO
|
||||||
@ -563,17 +635,22 @@ class coredump_generator:
|
|||||||
mm = self.mms[pid]
|
mm = self.mms[pid]
|
||||||
num_auxv = len(mm["mm_saved_auxv"]) // 2
|
num_auxv = len(mm["mm_saved_auxv"]) // 2
|
||||||
|
|
||||||
class elf_auxv(ctypes.Structure):
|
class elf32_auxv(ctypes.Structure):
|
||||||
|
_fields_ = [("auxv", elf.Elf32_auxv_t * num_auxv)]
|
||||||
|
|
||||||
|
class elf64_auxv(ctypes.Structure):
|
||||||
_fields_ = [("auxv", elf.Elf64_auxv_t * num_auxv)]
|
_fields_ = [("auxv", elf.Elf64_auxv_t * num_auxv)]
|
||||||
|
|
||||||
auxv = elf_auxv()
|
elf_auxv = {"32bit": elf32_auxv(), "64bit": elf64_auxv()}
|
||||||
|
|
||||||
|
auxv = elf_auxv[self.bits]
|
||||||
for i in range(num_auxv):
|
for i in range(num_auxv):
|
||||||
auxv.auxv[i].a_type = mm["mm_saved_auxv"][i]
|
auxv.auxv[i].a_type = mm["mm_saved_auxv"][i]
|
||||||
auxv.auxv[i].a_val = mm["mm_saved_auxv"][i + 1]
|
auxv.auxv[i].a_val = mm["mm_saved_auxv"][i + 1]
|
||||||
|
|
||||||
nhdr = elf.Elf64_Nhdr()
|
nhdr = self.nhdr[self.bits]()
|
||||||
nhdr.n_namesz = 5
|
nhdr.n_namesz = 5
|
||||||
nhdr.n_descsz = ctypes.sizeof(elf_auxv())
|
nhdr.n_descsz = ctypes.sizeof(elf_auxv[self.bits])
|
||||||
nhdr.n_type = elf.NT_AUXV
|
nhdr.n_type = elf.NT_AUXV
|
||||||
|
|
||||||
note = elf_note()
|
note = elf_note()
|
||||||
@ -650,7 +727,7 @@ class coredump_generator:
|
|||||||
setattr(data, "file_ofs" + str(i), info.file_ofs)
|
setattr(data, "file_ofs" + str(i), info.file_ofs)
|
||||||
setattr(data, "name" + str(i), info.name.encode())
|
setattr(data, "name" + str(i), info.name.encode())
|
||||||
|
|
||||||
nhdr = elf.Elf64_Nhdr()
|
nhdr = self.nhdr[self.bits]()
|
||||||
|
|
||||||
nhdr.n_namesz = 5 # strlen + 1
|
nhdr.n_namesz = 5 # strlen + 1
|
||||||
nhdr.n_descsz = ctypes.sizeof(elf_files())
|
nhdr.n_descsz = ctypes.sizeof(elf_files())
|
||||||
@ -667,10 +744,13 @@ class coredump_generator:
|
|||||||
notes = []
|
notes = []
|
||||||
|
|
||||||
notes.append(self._gen_prstatus(pid, tid))
|
notes.append(self._gen_prstatus(pid, tid))
|
||||||
|
if self.machine != "armv7l":
|
||||||
notes.append(self._gen_fpregset(pid, tid))
|
notes.append(self._gen_fpregset(pid, tid))
|
||||||
notes.append(self._gen_siginfo(pid, tid))
|
notes.append(self._gen_siginfo(pid, tid))
|
||||||
if self.machine == "aarch64":
|
if self.machine == "aarch64":
|
||||||
notes.append(self._gen_arm_tls(tid))
|
notes.append(self._gen_arm_tls(tid))
|
||||||
|
elif self.machine == "armv7l":
|
||||||
|
notes.append(self._gen_arm_vfp(tid))
|
||||||
elif self.machine == "x86_64":
|
elif self.machine == "x86_64":
|
||||||
notes.append(self._gen_x86_xstate(pid, tid))
|
notes.append(self._gen_x86_xstate(pid, tid))
|
||||||
|
|
||||||
|
@ -4,13 +4,19 @@ import platform
|
|||||||
|
|
||||||
MACHINE = platform.machine()
|
MACHINE = platform.machine()
|
||||||
|
|
||||||
|
Elf32_Half = ctypes.c_uint16 # typedef uint16_t Elf32_Half;
|
||||||
|
Elf32_Word = ctypes.c_uint32 # typedef uint32_t Elf32_Word;
|
||||||
|
Elf32_Addr = ctypes.c_uint32 # typedef uint32_t Elf32_Addr;
|
||||||
|
Elf32_Off = ctypes.c_uint32 # typedef uint32_t Elf32_Off;
|
||||||
|
Elf32_Xword = ctypes.c_uint64 # typedef uint64_t Elf32_Xword;
|
||||||
|
|
||||||
Elf64_Half = ctypes.c_uint16 # typedef uint16_t Elf64_Half;
|
Elf64_Half = ctypes.c_uint16 # typedef uint16_t Elf64_Half;
|
||||||
Elf64_Word = ctypes.c_uint32 # typedef uint32_t Elf64_Word;
|
Elf64_Word = ctypes.c_uint32 # typedef uint32_t Elf64_Word;
|
||||||
Elf64_Addr = ctypes.c_uint64 # typedef uint64_t Elf64_Addr;
|
Elf64_Addr = ctypes.c_uint64 # typedef uint64_t Elf64_Addr;
|
||||||
Elf64_Off = ctypes.c_uint64 # typedef uint64_t Elf64_Off;
|
Elf64_Off = ctypes.c_uint64 # typedef uint64_t Elf64_Off;
|
||||||
Elf64_Xword = ctypes.c_uint64 # typedef uint64_t Elf64_Xword;
|
Elf64_Xword = ctypes.c_uint64 # typedef uint64_t Elf64_Xword;
|
||||||
|
|
||||||
# Elf64_Ehdr related constants.
|
# Elf_Ehdr related constants.
|
||||||
|
|
||||||
# e_ident size.
|
# e_ident size.
|
||||||
EI_NIDENT = 16 # #define EI_NIDENT (16)
|
EI_NIDENT = 16 # #define EI_NIDENT (16)
|
||||||
@ -31,22 +37,50 @@ EI_CLASS = 4 # #define EI_CLASS 4 /* File class byte index
|
|||||||
|
|
||||||
EI_DATA = 5 # #define EI_DATA 5 /* Data encoding byte index */
|
EI_DATA = 5 # #define EI_DATA 5 /* Data encoding byte index */
|
||||||
|
|
||||||
|
EI_OSABI = 7 # #define EI_OSABI 7 /* OS ABI identification */
|
||||||
|
|
||||||
EI_VERSION = 6 # #define EI_VERSION 6 /* File version byte index */
|
EI_VERSION = 6 # #define EI_VERSION 6 /* File version byte index */
|
||||||
|
|
||||||
ELFDATA2LSB = 1 # #define ELFDATA2LSB 1 /* 2's complement, little endian */
|
ELFDATA2LSB = 1 # #define ELFDATA2LSB 1 /* 2's complement, little endian */
|
||||||
|
|
||||||
|
ELFCLASS32 = 1 # #define ELFCLASS32 1 /* 32-bit objects */
|
||||||
ELFCLASS64 = 2 # #define ELFCLASS64 2 /* 64-bit objects */
|
ELFCLASS64 = 2 # #define ELFCLASS64 2 /* 64-bit objects */
|
||||||
|
|
||||||
# Legal values for e_type (object file type).
|
# Legal values for e_type (object file type).
|
||||||
ET_CORE = 4 # #define ET_CORE 4 /* Core file */
|
ET_CORE = 4 # #define ET_CORE 4 /* Core file */
|
||||||
|
|
||||||
# Legal values for e_machine (architecture).
|
# Legal values for e_machine (architecture).
|
||||||
|
EM_ARM = 40 # #define EM_ARM 40 /* ARM */
|
||||||
EM_X86_64 = 62 # #define EM_X86_64 62 /* AMD x86-64 architecture */
|
EM_X86_64 = 62 # #define EM_X86_64 62 /* AMD x86-64 architecture */
|
||||||
EM_AARCH64 = 183 # #define EM_AARCH64 183 /* ARM AARCH64 */
|
EM_AARCH64 = 183 # #define EM_AARCH64 183 /* ARM AARCH64 */
|
||||||
|
|
||||||
# Legal values for e_version (version).
|
# Legal values for e_version (version).
|
||||||
EV_CURRENT = 1 # #define EV_CURRENT 1 /* Current version */
|
EV_CURRENT = 1 # #define EV_CURRENT 1 /* Current version */
|
||||||
|
|
||||||
|
# Legal values for e_osabi
|
||||||
|
ELFOSABI_NONE = 0 # #define ELFOSABI_NONE 0 /* UNIX System V ABI */
|
||||||
|
ELFOSABI_ARM = 97 # #define ELFOSABI_ARM 97 /* ARM */
|
||||||
|
|
||||||
|
|
||||||
|
class Elf32_Ehdr(ctypes.Structure): # typedef struct
|
||||||
|
_fields_ = [
|
||||||
|
("e_ident",
|
||||||
|
ctypes.c_ubyte * EI_NIDENT), # unsigned char e_ident[EI_NIDENT];
|
||||||
|
("e_type", Elf32_Half), # Elf32_Half e_type;
|
||||||
|
("e_machine", Elf32_Half), # Elf32_Half e_machine;
|
||||||
|
("e_version", Elf32_Word), # Elf32_Word e_version;
|
||||||
|
("e_entry", Elf32_Addr), # Elf32_Addr e_entry;
|
||||||
|
("e_phoff", Elf32_Off), # Elf32_Off e_phoff;
|
||||||
|
("e_shoff", Elf32_Off), # Elf32_Off e_shoff;
|
||||||
|
("e_flags", Elf32_Word), # Elf32_Word e_flags;
|
||||||
|
("e_ehsize", Elf32_Half), # Elf32_Half e_ehsize;
|
||||||
|
("e_phentsize", Elf32_Half), # Elf32_Half e_phentsize;
|
||||||
|
("e_phnum", Elf32_Half), # Elf32_Half e_phnum;
|
||||||
|
("e_shentsize", Elf32_Half), # Elf32_Half e_shentsize;
|
||||||
|
("e_shnum", Elf32_Half), # Elf32_Half e_shnum;
|
||||||
|
("e_shstrndx", Elf32_Half) # Elf32_Half e_shstrndx;
|
||||||
|
] # } Elf32_Ehdr;
|
||||||
|
|
||||||
|
|
||||||
class Elf64_Ehdr(ctypes.Structure): # typedef struct
|
class Elf64_Ehdr(ctypes.Structure): # typedef struct
|
||||||
_fields_ = [
|
_fields_ = [
|
||||||
@ -68,7 +102,7 @@ class Elf64_Ehdr(ctypes.Structure): # typedef struct
|
|||||||
] # } Elf64_Ehdr;
|
] # } Elf64_Ehdr;
|
||||||
|
|
||||||
|
|
||||||
# Elf64_Phdr related constants.
|
# Elf_Phdr related constants.
|
||||||
|
|
||||||
# Legal values for p_type (segment type).
|
# Legal values for p_type (segment type).
|
||||||
PT_LOAD = 1 # #define PT_LOAD 1 /* Loadable program segment */
|
PT_LOAD = 1 # #define PT_LOAD 1 /* Loadable program segment */
|
||||||
@ -80,6 +114,19 @@ PF_W = 1 << 1 # #define PF_W (1 << 1) /* Segment is writable
|
|||||||
PF_R = 1 << 2 # #define PF_R (1 << 2) /* Segment is readable */
|
PF_R = 1 << 2 # #define PF_R (1 << 2) /* Segment is readable */
|
||||||
|
|
||||||
|
|
||||||
|
class Elf32_Phdr(ctypes.Structure): # typedef struct
|
||||||
|
_fields_ = [
|
||||||
|
("p_type", Elf32_Word), # Elf32_Word p_type;
|
||||||
|
("p_offset", Elf32_Off), # Elf32_Off p_offset;
|
||||||
|
("p_vaddr", Elf32_Addr), # Elf32_Addr p_vaddr;
|
||||||
|
("p_paddr", Elf32_Addr), # Elf32_Addr p_paddr;
|
||||||
|
("p_filesz", Elf32_Word), # Elf32_Word p_filesz;
|
||||||
|
("p_memsz", Elf32_Word), # Elf32_Word p_memsz;
|
||||||
|
("p_flags", Elf32_Word), # Elf32_Word p_flags;
|
||||||
|
("p_align", Elf32_Word), # Elf32_Word p_align;
|
||||||
|
] # } Elf32_Phdr;
|
||||||
|
|
||||||
|
|
||||||
class Elf64_Phdr(ctypes.Structure): # typedef struct
|
class Elf64_Phdr(ctypes.Structure): # typedef struct
|
||||||
_fields_ = [
|
_fields_ = [
|
||||||
("p_type", Elf64_Word), # Elf64_Word p_type;
|
("p_type", Elf64_Word), # Elf64_Word p_type;
|
||||||
@ -93,7 +140,25 @@ class Elf64_Phdr(ctypes.Structure): # typedef struct
|
|||||||
] # } Elf64_Phdr;
|
] # } Elf64_Phdr;
|
||||||
|
|
||||||
|
|
||||||
# Elf64_auxv_t related constants.
|
# Elf_auxv_t related constants.
|
||||||
|
|
||||||
|
|
||||||
|
class _Elf32_auxv_t_U(ctypes.Union):
|
||||||
|
_fields_ = [("a_val", ctypes.c_uint32)]
|
||||||
|
|
||||||
|
|
||||||
|
class Elf32_auxv_t(ctypes.Structure): # typedef struct
|
||||||
|
_fields_ = [
|
||||||
|
("a_type",
|
||||||
|
ctypes.c_uint32), # uint32_t a_type; /* Entry type */
|
||||||
|
("a_un", _Elf32_auxv_t_U) # union
|
||||||
|
|
||||||
|
# uint32_t a_val; /* Integer value */
|
||||||
|
# /* We use to have pointer elements added here. We cannot do that,
|
||||||
|
# though, since it does not work when using 32-bit definitions
|
||||||
|
# on 64-bit platforms and vice versa. */
|
||||||
|
# } a_un;
|
||||||
|
] # } Elf32_auxv_t;
|
||||||
|
|
||||||
|
|
||||||
class _Elf64_auxv_t_U(ctypes.Union):
|
class _Elf64_auxv_t_U(ctypes.Union):
|
||||||
@ -114,7 +179,7 @@ class Elf64_auxv_t(ctypes.Structure): # typedef struct
|
|||||||
] # } Elf64_auxv_t;
|
] # } Elf64_auxv_t;
|
||||||
|
|
||||||
|
|
||||||
# Elf64_Nhdr related constants.
|
# Elf_Nhdr related constants.
|
||||||
|
|
||||||
NT_PRSTATUS = 1 # #define NT_PRSTATUS 1 /* Contains copy of prstatus struct */
|
NT_PRSTATUS = 1 # #define NT_PRSTATUS 1 /* Contains copy of prstatus struct */
|
||||||
NT_FPREGSET = 2 # #define NT_FPREGSET 2 /* Contains copy of fpregset struct */
|
NT_FPREGSET = 2 # #define NT_FPREGSET 2 /* Contains copy of fpregset struct */
|
||||||
@ -123,9 +188,24 @@ NT_AUXV = 6 # #define NT_AUXV 6 /* Contains copy of auxv array */
|
|||||||
NT_SIGINFO = 0x53494749 # #define NT_SIGINFO 0x53494749 /* Contains copy of siginfo_t, size might increase */
|
NT_SIGINFO = 0x53494749 # #define NT_SIGINFO 0x53494749 /* Contains copy of siginfo_t, size might increase */
|
||||||
NT_FILE = 0x46494c45 # #define NT_FILE 0x46494c45 /* Contains information about mapped files */
|
NT_FILE = 0x46494c45 # #define NT_FILE 0x46494c45 /* Contains information about mapped files */
|
||||||
NT_X86_XSTATE = 0x202 # #define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */
|
NT_X86_XSTATE = 0x202 # #define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */
|
||||||
|
NT_ARM_VFP = 0x400 # #define NT_ARM_VFP 0x400 /* ARM VFP/NEON registers */
|
||||||
NT_ARM_TLS = 0x401 # #define NT_ARM_TLS 0x401 /* ARM TLS register */
|
NT_ARM_TLS = 0x401 # #define NT_ARM_TLS 0x401 /* ARM TLS register */
|
||||||
|
|
||||||
|
|
||||||
|
class Elf32_Nhdr(ctypes.Structure): # typedef struct
|
||||||
|
_fields_ = [
|
||||||
|
(
|
||||||
|
"n_namesz", Elf32_Word
|
||||||
|
), # Elf32_Word n_namesz; /* Length of the note's name. */
|
||||||
|
(
|
||||||
|
"n_descsz", Elf32_Word
|
||||||
|
), # Elf32_Word n_descsz; /* Length of the note's descriptor. */
|
||||||
|
(
|
||||||
|
"n_type", Elf32_Word
|
||||||
|
), # Elf32_Word n_type; /* Type of the note. */
|
||||||
|
] # } Elf32_Nhdr;
|
||||||
|
|
||||||
|
|
||||||
class Elf64_Nhdr(ctypes.Structure): # typedef struct
|
class Elf64_Nhdr(ctypes.Structure): # typedef struct
|
||||||
_fields_ = [
|
_fields_ = [
|
||||||
(
|
(
|
||||||
@ -139,7 +219,52 @@ class Elf64_Nhdr(ctypes.Structure): # typedef struct
|
|||||||
] # } Elf64_Nhdr;
|
] # } Elf64_Nhdr;
|
||||||
|
|
||||||
|
|
||||||
# Elf64_Shdr related constants.
|
# Elf_Shdr related constants.
|
||||||
|
|
||||||
|
|
||||||
|
class Elf32_Shdr(ctypes.Structure):
|
||||||
|
_fields_ = [
|
||||||
|
(
|
||||||
|
# Section name (string tbl index)
|
||||||
|
"sh_name", Elf32_Word
|
||||||
|
),
|
||||||
|
(
|
||||||
|
# Section type
|
||||||
|
"sh_type", Elf32_Word
|
||||||
|
),
|
||||||
|
(
|
||||||
|
# Section flags
|
||||||
|
"sh_flags", Elf32_Word
|
||||||
|
),
|
||||||
|
(
|
||||||
|
# Section virtual addr at execution
|
||||||
|
"sh_addr", Elf32_Addr
|
||||||
|
),
|
||||||
|
(
|
||||||
|
# Section file offset
|
||||||
|
"sh_offset", Elf32_Off
|
||||||
|
),
|
||||||
|
(
|
||||||
|
# Section size in bytes
|
||||||
|
"sh_size", Elf32_Word
|
||||||
|
),
|
||||||
|
(
|
||||||
|
# Link to another section
|
||||||
|
"sh_link", Elf32_Word
|
||||||
|
),
|
||||||
|
(
|
||||||
|
# Additional section information
|
||||||
|
"sh_info", Elf32_Word
|
||||||
|
),
|
||||||
|
(
|
||||||
|
# Section alignment
|
||||||
|
"sh_addralign", Elf32_Word
|
||||||
|
),
|
||||||
|
(
|
||||||
|
# Entry size if section holds table
|
||||||
|
"sh_entsize", Elf32_Word
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class Elf64_Shdr(ctypes.Structure):
|
class Elf64_Shdr(ctypes.Structure):
|
||||||
@ -295,11 +420,53 @@ class aarch64_user_regs_struct(ctypes.Structure): # struct aarch64_user_regs_st
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class arm_user_regs_struct(ctypes.Structure): # struct arm_user_regs_struct
|
||||||
|
_fields_ = [
|
||||||
|
("r0",
|
||||||
|
ctypes.c_ulong), # unsigned ulong int r0;
|
||||||
|
("r1",
|
||||||
|
ctypes.c_ulong), # unsigned ulong int r1;
|
||||||
|
("r2",
|
||||||
|
ctypes.c_ulong), # unsigned ulong int r2;
|
||||||
|
("r3",
|
||||||
|
ctypes.c_ulong), # unsigned ulong int r3;
|
||||||
|
("r4",
|
||||||
|
ctypes.c_ulong), # unsigned ulong int r4;
|
||||||
|
("r5",
|
||||||
|
ctypes.c_ulong), # unsigned ulong int r5;
|
||||||
|
("r6",
|
||||||
|
ctypes.c_ulong), # unsigned ulong int r6;
|
||||||
|
("r7",
|
||||||
|
ctypes.c_ulong), # unsigned ulong int r7;
|
||||||
|
("r8",
|
||||||
|
ctypes.c_ulong), # unsigned ulong int r8;
|
||||||
|
("r9",
|
||||||
|
ctypes.c_ulong), # unsigned ulong int r9;
|
||||||
|
("r10",
|
||||||
|
ctypes.c_ulong), # unsigned ulong int r10;
|
||||||
|
("fp",
|
||||||
|
ctypes.c_ulong), # unsigned ulong int fp;
|
||||||
|
("ip",
|
||||||
|
ctypes.c_ulong), # unsigned ulong int ip;
|
||||||
|
("sp",
|
||||||
|
ctypes.c_ulong), # unsigned ulong int sp;
|
||||||
|
("lr",
|
||||||
|
ctypes.c_ulong), # unsigned ulong int lr;
|
||||||
|
("pc",
|
||||||
|
ctypes.c_ulong), # unsigned ulong int pc;
|
||||||
|
("cpsr",
|
||||||
|
ctypes.c_ulong), # unsigned ulong int cpsr;
|
||||||
|
("orig_r0",
|
||||||
|
ctypes.c_ulong), # unsigned ulong int orig_r0;
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
# elf_greg_t = ctypes.c_ulonglong
|
# elf_greg_t = ctypes.c_ulonglong
|
||||||
# ELF_NGREG = ctypes.sizeof(user_regs_struct)/ctypes.sizeof(elf_greg_t)
|
# ELF_NGREG = ctypes.sizeof(user_regs_struct)/ctypes.sizeof(elf_greg_t)
|
||||||
# elf_gregset_t = elf_greg_t*ELF_NGREG
|
# elf_gregset_t = elf_greg_t*ELF_NGREG
|
||||||
user_regs_dict = {
|
user_regs_dict = {
|
||||||
"aarch64": aarch64_user_regs_struct,
|
"aarch64": aarch64_user_regs_struct,
|
||||||
|
"armv7l": arm_user_regs_struct,
|
||||||
"x86_64": x86_64_user_regs_struct,
|
"x86_64": x86_64_user_regs_struct,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -488,6 +655,7 @@ class aarch64_user_fpregs_struct(ctypes.Structure): # struct aarch64_user_fpreg
|
|||||||
|
|
||||||
user_fpregs_dict = {
|
user_fpregs_dict = {
|
||||||
"aarch64": aarch64_user_fpregs_struct,
|
"aarch64": aarch64_user_fpregs_struct,
|
||||||
|
"armv7l": None,
|
||||||
"x86_64": x86_64_user_fpregs_struct,
|
"x86_64": x86_64_user_fpregs_struct,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -889,3 +1057,13 @@ class elf_xsave_struct(ctypes.Structure): # struct xsave_struct {
|
|||||||
# struct ymmh_struct ymmh;
|
# struct ymmh_struct ymmh;
|
||||||
("ymmh", ymmh_struct)
|
("ymmh", ymmh_struct)
|
||||||
] # } __aligned(FP_MIN_ALIGN_BYTES) __packed;
|
] # } __aligned(FP_MIN_ALIGN_BYTES) __packed;
|
||||||
|
|
||||||
|
|
||||||
|
class vfp_hard_struct(ctypes.Structure): # struct vfp_hard_struct {
|
||||||
|
_fields_ = [
|
||||||
|
("vfp_regs", ctypes.c_ulonglong * 32), # __u64 fpregs[32];
|
||||||
|
("fpexc", ctypes.c_ulong), # __u32 fpexc;
|
||||||
|
("fpscr", ctypes.c_ulong), # __u32 fpscr;
|
||||||
|
("fpinst", ctypes.c_ulong), # __u32 fpinst;
|
||||||
|
("fpinst2", ctypes.c_ulong), # __u32 fpinst2;
|
||||||
|
] # };
|
||||||
|
@ -45,8 +45,8 @@ function run_test {
|
|||||||
|
|
||||||
UNAME_M=$(uname -m)
|
UNAME_M=$(uname -m)
|
||||||
|
|
||||||
if [[ "$UNAME_M" != "aarch64" && "$UNAME_M" != "x86_64" ]]; then
|
if [[ "$UNAME_M" != "aarch64" && "$UNAME_M" != "armv7l" &&"$UNAME_M" != "x86_64" ]]; then
|
||||||
echo "criu-coredump only supports aarch64 and x86_64. skipping."
|
echo "criu-coredump only supports aarch64 armv7l, and x86_64. skipping."
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user