def _gen_fpregset(self, pid, tid): """ Generate NT_FPREGSET note for thread tid of process pid. """ core = self.cores[tid] regs = core["thread_info"]["fpregs"] fpregset = elf.elf_fpregset_t() ctypes.memset(ctypes.addressof(fpregset), 0, ctypes.sizeof(fpregset)) fpregset.cwd = regs["cwd"] fpregset.swd = regs["swd"] fpregset.ftw = regs["twd"] fpregset.fop = regs["fop"] fpregset.rip = regs["rip"] fpregset.rdp = regs["rdp"] fpregset.mxcsr = regs["mxcsr"] fpregset.mxcr_mask = regs["mxcsr_mask"] fpregset.st_space = (ctypes.c_uint * len(regs["st_space"]))(*regs["st_space"]) fpregset.xmm_space = (ctypes.c_uint * len(regs["xmm_space"]))(*regs["xmm_space"]) #fpregset.padding = regs["padding"] unused nhdr = elf.Elf64_Nhdr() nhdr.n_namesz = 5 nhdr.n_descsz = ctypes.sizeof(elf.elf_fpregset_t()) nhdr.n_type = elf.NT_FPREGSET note = elf_note() note.data = fpregset note.owner = "CORE" note.nhdr = nhdr return note
def _gen_auxv(self, pid): """ Generate NT_AUXV note for thread tid of process pid. """ mm = self.mms[pid] num_auxv = len(mm["mm_saved_auxv"])/2 class elf_auxv(ctypes.Structure): _fields_ = [("auxv", elf.Elf64_auxv_t*num_auxv)] auxv = elf_auxv() for i in range(num_auxv): auxv.auxv[i].a_type = mm["mm_saved_auxv"][i] auxv.auxv[i].a_val = mm["mm_saved_auxv"][i+1] nhdr = elf.Elf64_Nhdr() nhdr.n_namesz = 5 nhdr.n_descsz = ctypes.sizeof(elf_auxv()) nhdr.n_type = elf.NT_AUXV note = elf_note() note.data = auxv note.owner = "CORE" note.nhdr = nhdr return note
def _gen_prstatus(self, pid, tid): """ Generate NT_PRSTATUS note for thread tid of process pid. """ core = self.cores[tid] regs = core["thread_info"]["gpregs"] pstree = self.pstree[pid] prstatus = elf.elf_prstatus() ctypes.memset(ctypes.addressof(prstatus), 0, ctypes.sizeof(prstatus)) #FIXME setting only some of the fields for now. Revisit later. prstatus.pr_pid = tid prstatus.pr_ppid = pstree["ppid"] prstatus.pr_pgrp = pstree["pgid"] prstatus.pr_sid = pstree["sid"] prstatus.pr_reg.r15 = regs["r15"] prstatus.pr_reg.r14 = regs["r14"] prstatus.pr_reg.r13 = regs["r13"] prstatus.pr_reg.r12 = regs["r12"] prstatus.pr_reg.rbp = regs["bp"] prstatus.pr_reg.rbx = regs["bx"] prstatus.pr_reg.r11 = regs["r11"] prstatus.pr_reg.r10 = regs["r10"] prstatus.pr_reg.r9 = regs["r9"] prstatus.pr_reg.r8 = regs["r8"] prstatus.pr_reg.rax = regs["ax"] prstatus.pr_reg.rcx = regs["cx"] prstatus.pr_reg.rdx = regs["dx"] prstatus.pr_reg.rsi = regs["si"] prstatus.pr_reg.rdi = regs["di"] prstatus.pr_reg.orig_rax = regs["orig_ax"] prstatus.pr_reg.rip = regs["ip"] prstatus.pr_reg.cs = regs["cs"] prstatus.pr_reg.eflags = regs["flags"] prstatus.pr_reg.rsp = regs["sp"] prstatus.pr_reg.ss = regs["ss"] prstatus.pr_reg.fs_base = regs["fs_base"] prstatus.pr_reg.gs_base = regs["gs_base"] prstatus.pr_reg.ds = regs["ds"] prstatus.pr_reg.es = regs["es"] prstatus.pr_reg.fs = regs["fs"] prstatus.pr_reg.gs = regs["gs"] nhdr = elf.Elf64_Nhdr() nhdr.n_namesz = 5 nhdr.n_descsz = ctypes.sizeof(elf.elf_prstatus()) nhdr.n_type = elf.NT_PRSTATUS note = elf_note() note.data = prstatus note.owner = "CORE" note.nhdr = nhdr return note
def gen_prpsinfo(self): """ Generate NT_PRPSINFO note for process pid. """ if self.x86 is True: prpsinfo = elf.elf_prpsinfo32() else: prpsinfo = elf.elf_prpsinfo() ctypes.memset(ctypes.addressof(prpsinfo), 0, ctypes.sizeof(prpsinfo)) TASK_ALIVE = 0x1 TASK_DEAD = 0x2 TASK_STOPPED = 0x3 if self.task.state == TASK_ALIVE: prpsinfo.pr_state = 0 if self.task.state == TASK_DEAD: prpsinfo.pr_state = 4 if self.task.state == TASK_STOPPED: prpsinfo.pr_state = 3 prpsinfo.pr_sname = '.' if prpsinfo.pr_state > 5 else "RSDTZW"[ prpsinfo.pr_state] prpsinfo.pr_zomb = 1 if prpsinfo.pr_state == 4 else 0 prpsinfo.pr_nice = 0 #default prpsinfo.pr_flag = 0 #default prpsinfo.pr_uid = self.task.uid prpsinfo.pr_gid = self.task.gid prpsinfo.pr_pid = self.task.pid prpsinfo.pr_ppid = self.task.parent.pid prpsinfo.pr_pgrp = self.task.parent.gid prpsinfo.pr_sid = 0 #default prpsinfo.pr_fname = self.task.comm prpsinfo.pr_psargs = self.task.get_commandline() if self.x86 is True: nhdr = elf.Elf32_Nhdr() nhdr.n_namesz = 5 nhdr.n_descsz = ctypes.sizeof(elf.elf_prpsinfo32()) nhdr.n_type = elf.NT_PRPSINFO else: nhdr = elf.Elf64_Nhdr() nhdr.n_namesz = 5 nhdr.n_descsz = ctypes.sizeof(elf.elf_prpsinfo()) nhdr.n_type = elf.NT_PRPSINFO note = elf_note() note.data = prpsinfo note.owner = "CORE" note.nhdr = nhdr return note
def gen_prstatus(self, thread): """ Generate NT_PRSTATUS note for thread tid of process pid. """ regs = self.threads_registers[str(thread.pid)] prstatus = elf.elf_prstatus() ctypes.memset(ctypes.addressof(prstatus), 0, ctypes.sizeof(prstatus)) prstatus.pr_pid = thread.pid prstatus.pr_ppid = thread.parent.pid prstatus.pr_pgrp = thread.parent.gid prstatus.pr_sid = 0 #default prstatus.pr_reg.r15 = regs["r15"] prstatus.pr_reg.r14 = regs["r14"] prstatus.pr_reg.r13 = regs["r13"] prstatus.pr_reg.r12 = regs["r12"] prstatus.pr_reg.rbp = regs["rbp"] prstatus.pr_reg.rbx = regs["rbx"] prstatus.pr_reg.r11 = regs["r11"] prstatus.pr_reg.r10 = regs["r10"] prstatus.pr_reg.r9 = regs["r9"] prstatus.pr_reg.r8 = regs["r8"] prstatus.pr_reg.rax = regs["rax"] prstatus.pr_reg.rcx = regs["rcx"] prstatus.pr_reg.rdx = regs["rdx"] prstatus.pr_reg.rsi = regs["rsi"] prstatus.pr_reg.rdi = regs["rdi"] #prstatus.pr_reg.orig_rax = regs["unknown?"] prstatus.pr_reg.rip = regs["rip"] prstatus.pr_reg.cs = regs["cs"] prstatus.pr_reg.eflags = regs["eflags"] prstatus.pr_reg.rsp = regs["rsp"] prstatus.pr_reg.ss = regs["ss"] # prstatus.pr_reg.fs_base = regs["fs_base"] # prstatus.pr_reg.gs_base = regs["gs_base"] # prstatus.pr_reg.ds = regs["ds"] MISSING # prstatus.pr_reg.es = regs["es"] # prstatus.pr_reg.fs = regs["fs"] # prstatus.pr_reg.gs = regs["gs"] nhdr = elf.Elf64_Nhdr() nhdr.n_namesz = 5 nhdr.n_descsz = ctypes.sizeof(elf.elf_prstatus()) nhdr.n_type = elf.NT_PRSTATUS note = elf_note() note.data = prstatus note.owner = "CORE" note.nhdr = nhdr return note
def _gen_prpsinfo(self, pid): """ Generate NT_PRPSINFO note for process pid. """ pstree = self.pstree[pid] creds = self.creds[pid] core = self.cores[pid] prpsinfo = elf.elf_prpsinfo() ctypes.memset(ctypes.addressof(prpsinfo), 0, ctypes.sizeof(prpsinfo)) # FIXME TASK_ALIVE means that it is either running or sleeping, need to # teach criu to distinguish them. TASK_ALIVE = 0x1 # XXX A bit of confusion here, as in ps "dead" and "zombie" # state are two separate states, and we use TASK_DEAD for zombies. TASK_DEAD = 0x2 TASK_STOPPED = 0x3 if core["tc"]["task_state"] == TASK_ALIVE: prpsinfo.pr_state = 0 if core["tc"]["task_state"] == TASK_DEAD: prpsinfo.pr_state = 4 if core["tc"]["task_state"] == TASK_STOPPED: prpsinfo.pr_state = 3 # Don't even ask me why it is so, just borrowed from linux # source and made pr_state match. prpsinfo.pr_sname = '.' if prpsinfo.pr_state > 5 else "RSDTZW"[ prpsinfo.pr_state] prpsinfo.pr_zomb = 1 if prpsinfo.pr_state == 4 else 0 prpsinfo.pr_nice = core["thread_core"][ "sched_prio"] if "sched_prio" in core["thread_core"] else 0 prpsinfo.pr_flag = core["tc"]["flags"] prpsinfo.pr_uid = creds["uid"] prpsinfo.pr_gid = creds["gid"] prpsinfo.pr_pid = pid prpsinfo.pr_ppid = pstree["ppid"] prpsinfo.pr_pgrp = pstree["pgid"] prpsinfo.pr_sid = pstree["sid"] prpsinfo.pr_fname = core["tc"]["comm"] prpsinfo.pr_psargs = self._gen_cmdline(pid) nhdr = elf.Elf64_Nhdr() nhdr.n_namesz = 5 nhdr.n_descsz = ctypes.sizeof(elf.elf_prpsinfo()) nhdr.n_type = elf.NT_PRPSINFO note = elf_note() note.data = prpsinfo note.owner = "CORE" note.nhdr = nhdr return note
def _gen_siginfo(self, pid, tid): """ Generate NT_SIGINFO note for thread tid of process pid. """ siginfo = elf.siginfo_t() # FIXME zeroify everything for now ctypes.memset(ctypes.addressof(siginfo), 0, ctypes.sizeof(siginfo)) nhdr = elf.Elf64_Nhdr() nhdr.n_namesz = 5 nhdr.n_descsz = ctypes.sizeof(elf.siginfo_t()) nhdr.n_type = elf.NT_SIGINFO note = elf_note() note.data = siginfo note.owner = "CORE" note.nhdr = nhdr return note
def _gen_x86_xstate(self, pid, tid): """ Generate NT_X86_XSTATE note for thread tid of process pid. """ core = self.cores[tid] fpregs = core["thread_info"]["fpregs"] data = elf.elf_xsave_struct() ctypes.memset(ctypes.addressof(data), 0, ctypes.sizeof(data)) data.i387.cwd = fpregs["cwd"] data.i387.swd = fpregs["swd"] data.i387.twd = fpregs["twd"] data.i387.fop = fpregs["fop"] data.i387.rip = fpregs["rip"] data.i387.rdp = fpregs["rdp"] data.i387.mxcsr = fpregs["mxcsr"] data.i387.mxcsr_mask = fpregs["mxcsr_mask"] data.i387.st_space = (ctypes.c_uint * len(fpregs["st_space"]))(*fpregs["st_space"]) data.i387.xmm_space = (ctypes.c_uint * len(fpregs["xmm_space"]))(*fpregs["xmm_space"]) if "xsave" in fpregs: data.xsave_hdr.xstate_bv = fpregs["xsave"]["xstate_bv"] data.ymmh.ymmh_space = (ctypes.c_uint * len(fpregs["xsave"]["ymmh_space"]))( *fpregs["xsave"]["ymmh_space"]) nhdr = elf.Elf64_Nhdr() nhdr.n_namesz = 6 nhdr.n_descsz = ctypes.sizeof(data) nhdr.n_type = elf.NT_X86_XSTATE note = elf_note() note.data = data note.owner = "LINUX" note.nhdr = nhdr return note
def _gen_files(self, pid): """ Generate NT_FILE note for process pid. """ mm = self.mms[pid] class mmaped_file_info: start = None end = None file_ofs = None name = None infos = [] for vma in mm["vmas"]: if vma["shmid"] == 0: # shmid == 0 means that it is not a file continue shmid = vma["shmid"] size = vma["end"] - vma["start"] off = vma["pgoff"]/PAGESIZE files = self.reg_files fname = filter(lambda x: x["id"] == shmid, files)[0]["name"] info = mmaped_file_info() info.start = vma["start"] info.end = vma["end"] info.file_ofs = off info.name = fname infos.append(info) # /* # * Format of NT_FILE note: # * # * long count -- how many files are mapped # * long page_size -- units for file_ofs # * array of [COUNT] elements of # * long start # * long end # * long file_ofs # * followed by COUNT filenames in ASCII: "FILE1" NUL "FILE2" NUL... # */ fields = [] fields.append(("count", ctypes.c_long)) fields.append(("page_size", ctypes.c_long)) for i in range(len(infos)): fields.append(("start"+str(i), ctypes.c_long)) fields.append(("end"+str(i), ctypes.c_long)) fields.append(("file_ofs"+str(i), ctypes.c_long)) for i in range(len(infos)): fields.append(("name"+str(i), ctypes.c_char*(len(infos[i].name)+1))) class elf_files(ctypes.Structure): _fields_ = fields data = elf_files() data.count = len(infos) data.page_size = PAGESIZE for i in range(len(infos)): info = infos[i] setattr(data, "start"+str(i), info.start) setattr(data, "end"+str(i), info.end) setattr(data, "file_ofs"+str(i), info.file_ofs) setattr(data, "name"+str(i), info.name) nhdr = elf.Elf64_Nhdr() nhdr.n_namesz = 5#XXX strlen + 1 nhdr.n_descsz = ctypes.sizeof(elf_files()) nhdr.n_type = elf.NT_FILE note = elf_note() note.nhdr = nhdr note.owner = "CORE" note.data = data return note
def _gen_files(self): """ Generate NT_FILE note for process pid. """ class mmaped_file_info: start = None end = None file_ofs = None name = None infos = [] for vma in self.vma_list: (fname, major, minor, ino, pgoff) = vma.info(self.task) if fname.startswith('/') == False: continue off = pgoff info = mmaped_file_info() info.start = vma.vm_start info.end = vma.vm_end info.file_ofs = off info.name = fname infos.append(info) # /* # * Format of NT_FILE note: # * # * long count -- how many files are mapped # * long page_size -- units for file_ofs # * array of [COUNT] elements of # * long start # * long end # * long file_ofs # * followed by COUNT filenames in ASCII: "FILE1" NUL "FILE2" NUL... # */ fields = [] fields.append(("count", ctypes.c_long)) fields.append(("page_size", ctypes.c_long)) for i in range(len(infos)): fields.append(("start" + str(i), ctypes.c_long)) fields.append(("end" + str(i), ctypes.c_long)) fields.append(("file_ofs" + str(i), ctypes.c_long)) for i in range(len(infos)): fields.append( ("name" + str(i), ctypes.c_char * (len(infos[i].name) + 1))) class elf_files(ctypes.Structure): _fields_ = fields data = elf_files() data.count = len(infos) data.page_size = PAGESIZE for i in range(len(infos)): info = infos[i] setattr(data, "start" + str(i), info.start) setattr(data, "end" + str(i), info.end) setattr(data, "file_ofs" + str(i), info.file_ofs) setattr(data, "name" + str(i), info.name) nhdr = elf.Elf64_Nhdr() nhdr.n_namesz = 5 #XXX strlen + 1 nhdr.n_descsz = ctypes.sizeof(elf_files()) nhdr.n_type = elf.NT_FILE note = elf_note() note.nhdr = nhdr note.owner = "CORE" note.data = data return note