regs_t *proc_get_registers(proc_obj_t* proc) { regs_t* regs; ttstate_t* tts; if (proc->luse == NULL) return (-1); tts = (ttstate_t *)proc->luse; regs = malloc(sizeof(regs_t)); if (ttrace(TT_LWP_RUREGS, proc->pid, tts->tts_lwpid, (uint64_t)__reason, (uint64_t)8, (uint64_t)®s->reason) == -1 || ttrace(TT_LWP_RUREGS, proc->pid, tts->tts_lwpid, (uint64_t)__ip, (uint64_t)8, (uint64_t)®s->ip) == -1 || ttrace(TT_LWP_RUREGS, proc->pid, tts->tts_lwpid, (uint64_t)__r12, (uint64_t)8, (uint64_t)®s->sp) == -1 || ttrace(TT_LWP_RUREGS, proc->pid, tts->tts_lwpid, (uint64_t)__ar_bsp, (uint64_t)8, (uint64_t)®s->bsp) == -1 || ttrace(TT_LWP_RUREGS, proc->pid, tts->tts_lwpid, (uint64_t)__ar_pfs, (uint64_t)8, (uint64_t)®s->pfs) == -1) { free(regs); return (NULL); } return (regs); }
static void inf_ttrace_enable_syscall_events (pid_t pid) { ttevent_t tte; ttstate_t tts; gdb_assert (inf_ttrace_num_lwps_in_syscall == 0); if (ttrace (TT_PROC_GET_EVENT_MASK, pid, 0, (uintptr_t)&tte, sizeof tte, 0) == -1) perror_with_name (("ttrace")); tte.tte_events |= (TTEVT_SYSCALL_ENTRY | TTEVT_SYSCALL_RETURN); if (ttrace (TT_PROC_SET_EVENT_MASK, pid, 0, (uintptr_t)&tte, sizeof tte, 0) == -1) perror_with_name (("ttrace")); if (ttrace (TT_PROC_GET_FIRST_LWP_STATE, pid, 0, (uintptr_t)&tts, sizeof tts, 0) == -1) perror_with_name (("ttrace")); if (tts.tts_flags & TTS_INSYSCALL) inf_ttrace_num_lwps_in_syscall++; /* FIXME: Handle multiple threads. */ }
static struct inf_ttrace_page * inf_ttrace_add_page (pid_t pid, CORE_ADDR addr) { const int num_buckets = ARRAY_SIZE (inf_ttrace_page_dict.buckets); const int pagesize = inf_ttrace_page_dict.pagesize; int bucket; struct inf_ttrace_page *page; struct inf_ttrace_page *prev = NULL; bucket = (addr / pagesize) % num_buckets; page = &inf_ttrace_page_dict.buckets[bucket]; while (page) { if (page->addr == addr) break; prev = page; page = page->next; } if (!page) { int prot; if (ttrace (TT_PROC_GET_MPROTECT, pid, 0, addr, 0, (uintptr_t)&prot) == -1) perror_with_name (("ttrace")); page = XMALLOC (struct inf_ttrace_page); page->addr = addr; page->prot = prot; page->refcount = 0; page->next = NULL; page->prev = prev; prev->next = page; inf_ttrace_page_dict.count++; if (inf_ttrace_page_dict.count == 1) inf_ttrace_enable_syscall_events (pid); if (inf_ttrace_num_lwps_in_syscall == 0) { if (ttrace (TT_PROC_SET_MPROTECT, pid, 0, addr, pagesize, prot & ~PROT_WRITE) == -1) perror_with_name (("ttrace")); } }
static int ia64_hpux_read_memory_bs (gdb_byte *buf, CORE_ADDR addr, int len) { gdb_byte tmp_buf[8]; CORE_ADDR tmp_addr = addr & ~0x7; while (tmp_addr < addr + len) { int status; int skip_lo = 0; int skip_hi = 0; status = ttrace (TT_LWP_RDRSEBS, ptid_get_pid (inferior_ptid), ptid_get_lwp (inferior_ptid), tmp_addr, sizeof (tmp_buf), (uintptr_t) tmp_buf); if (status < 0) return 0; if (tmp_addr < addr) skip_lo = addr - tmp_addr; if (tmp_addr + sizeof (tmp_buf) > addr + len) skip_hi = (tmp_addr + sizeof (tmp_buf)) - (addr + len); memcpy (buf + (tmp_addr + skip_lo - addr), tmp_buf + skip_lo, sizeof (tmp_buf) - skip_lo - skip_hi); tmp_addr += sizeof (tmp_buf); } return 1; }
static void hppa_hpux_fetch_register (struct regcache *regcache, int regnum) { struct gdbarch *gdbarch = get_regcache_arch (regcache); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR addr; size_t size; PTRACE_TYPE_RET *buf; pid_t pid; int i; pid = ptid_get_pid (inferior_ptid); /* This isn't really an address, but ptrace thinks of it as one. */ addr = hppa_hpux_save_state_offset (regcache, regnum); size = register_size (gdbarch, regnum); gdb_assert (size == 4 || size == 8); buf = alloca (size); #ifdef HAVE_TTRACE { lwpid_t lwp = ptid_get_lwp (inferior_ptid); if (ttrace (TT_LWP_RUREGS, pid, lwp, addr, size, (uintptr_t)buf) == -1) error (_("Couldn't read register %s (#%d): %s"), gdbarch_register_name (gdbarch, regnum), regnum, safe_strerror (errno)); } #else { int i; /* Read the register contents from the inferior a chuck at the time. */ for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++) { errno = 0; buf[i] = ptrace (PT_RUREGS, pid, (PTRACE_TYPE_ARG3) addr, 0, 0); if (errno != 0) error (_("Couldn't read register %s (#%d): %s"), gdbarch_register_name (gdbarch, regnum), regnum, safe_strerror (errno)); addr += sizeof (PTRACE_TYPE_RET); } } #endif /* Take care with the "flags" register. It's stored as an `int' in `struct save_state', even for 64-bit code. */ if (regnum == HPPA_FLAGS_REGNUM && size == 8) { ULONGEST flags; flags = extract_unsigned_integer ((gdb_byte *)buf, 4, byte_order); store_unsigned_integer ((gdb_byte *)buf, 8, byte_order, flags); } regcache_raw_supply (regcache, regnum, buf); }
static int ia64_hpux_read_register_from_save_state_t (int offset, gdb_byte *buf, int len) { int status; status = ttrace (TT_LWP_RUREGS, ptid_get_pid (inferior_ptid), ptid_get_lwp (inferior_ptid), offset, len, (uintptr_t) buf); return status; }
static void inf_ttrace_disable_syscall_events (pid_t pid) { ttevent_t tte; gdb_assert (inf_ttrace_page_dict.count == 0); if (ttrace (TT_PROC_GET_EVENT_MASK, pid, 0, (uintptr_t)&tte, sizeof tte, 0) == -1) perror_with_name (("ttrace")); tte.tte_events &= ~(TTEVT_SYSCALL_ENTRY | TTEVT_SYSCALL_RETURN); if (ttrace (TT_PROC_SET_EVENT_MASK, pid, 0, (uintptr_t)&tte, sizeof tte, 0) == -1) perror_with_name (("ttrace")); inf_ttrace_num_lwps_in_syscall = 0; }
static void hppa_hpux_store_register (int regnum) { CORE_ADDR addr; size_t size; PTRACE_TYPE_RET *buf; pid_t pid; pid = ptid_get_pid (inferior_ptid); /* This isn't really an address, but ptrace thinks of it as one. */ addr = hppa_hpux_save_state_offset(current_regcache, regnum); size = register_size (current_gdbarch, regnum); gdb_assert (size == 4 || size == 8); buf = alloca (size); regcache_raw_collect (current_regcache, regnum, buf); /* Take care with the "flags" register. It's stored as an `int' in `struct save_state', even for 64-bit code. */ if (regnum == HPPA_FLAGS_REGNUM && size == 8) { ULONGEST flags = extract_unsigned_integer ((gdb_byte *)buf, 8); store_unsigned_integer ((gdb_byte *)buf, 4, flags); size = 4; } #ifdef HAVE_TTRACE { lwpid_t lwp = ptid_get_lwp (inferior_ptid); if (ttrace (TT_LWP_WUREGS, pid, lwp, addr, size, (uintptr_t)buf) == -1) error (_("Couldn't write register %s (#%d): %s"), REGISTER_NAME (regnum), regnum, safe_strerror (errno)); } #else { int i; /* Write the register contents into the inferior a chunk at the time. */ for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++) { errno = 0; ptrace (PT_WUREGS, pid, (PTRACE_TYPE_ARG3) addr, buf[i], 0); if (errno != 0) error (_("Couldn't write register %s (#%d): %s"), REGISTER_NAME (regnum), regnum, safe_strerror (errno)); addr += sizeof (PTRACE_TYPE_RET); } } #endif }
int proc_attach(proc_obj_t* proc, pid_t pid) { ttevent_t ev; siginfo_t si; ev.tte_events = TTEVT_SYSCALL_ENTRY|TTEVT_SYSCALL_RESTART|TTEVT_SYSCALL_RETURN| TTEVT_EXEC|TTEVT_EXIT|TTEVT_BPT_SSTEP|TTEVT_SIGNAL; ev.tte_opts = TTEO_NONE; proc->pid = -1; if (ttrace(TT_PROC_ATTACH, pid, 0, TT_DETACH_ON_EXIT, TT_VERSION, 0) == -1) return -1; proc->pid = pid; if (waitid(P_PID, pid, &si, WEXITED|WSTOPPED) < 0 || si.si_pid != pid || si.si_code != CLD_STOPPED) return (-1); if (ttrace(TT_PROC_SET_EVENT_MASK, pid, 0, (uint64_t)&ev, sizeof ev, 0) == -1) return -1; return (pid); }
static void ia64_hpux_mourn_inferior (struct target_ops *ops) { const int pid = ptid_get_pid (inferior_ptid); int status; super_mourn_inferior (ops); /* On this platform, the process still exists even after we received an exit event. Detaching from the process isn't sufficient either, as it only turns the process into a zombie. So the only solution we found is to kill it. */ ttrace (TT_PROC_EXIT, pid, 0, 0, 0, 0); wait (&status); }
int proc_ttrace(proc_obj_t* proc, int signal, ttreq_t request, pid_t pid, lwpid_t lwpid, uint64_t addr, uint64_t data, uint64_t addr2) { ttstate_t tts; if (proc->luse == NULL) return (-1); tts = *((ttstate_t *)proc->luse); if (signal == 0 && tts.tts_u.tts_signal.tts_signo != 0) { printf("Signal: %d -- %d\n", signal, tts.tts_u.tts_signal.tts_signo); signal = tts.tts_u.tts_signal.tts_signo; if (signal == 9) signal = 0; data = signal; } return (ttrace(request, pid, lwpid, addr, data, addr2)); }
static void ia64_hpux_fetch_rnat_register (struct regcache *regcache) { CORE_ADDR addr; gdb_byte buf[8]; int status; /* The value of RNAT is stored at bsp|0x1f8, and must be read using TT_LWP_RDRSEBS. */ regcache_raw_read_unsigned (regcache, IA64_BSP_REGNUM, &addr); addr |= 0x1f8; status = ttrace (TT_LWP_RDRSEBS, ptid_get_pid (inferior_ptid), ptid_get_lwp (inferior_ptid), addr, sizeof (buf), (uintptr_t) buf); if (status < 0) error (_("failed to read RNAT register at %s"), paddress (get_regcache_arch(regcache), addr)); regcache_raw_supply (regcache, IA64_RNAT_REGNUM, buf); }
static int ia64_hpux_write_memory_bs (const gdb_byte *buf, CORE_ADDR addr, int len) { gdb_byte tmp_buf[8]; CORE_ADDR tmp_addr = addr & ~0x7; while (tmp_addr < addr + len) { int status; int lo = 0; int hi = 7; if (tmp_addr < addr || tmp_addr + sizeof (tmp_buf) > addr + len) /* Part of the 8byte region pointed by tmp_addr needs to be preserved. So read it in before we copy the data that needs to be changed. */ if (!ia64_hpux_read_memory_bs (tmp_buf, tmp_addr, sizeof (tmp_buf))) return 0; if (tmp_addr < addr) lo = addr - tmp_addr; if (tmp_addr + sizeof (tmp_buf) > addr + len) hi = addr - tmp_addr + len - 1; memcpy (tmp_buf + lo, buf + tmp_addr - addr + lo, hi - lo + 1); status = ttrace (TT_LWP_WRRSEBS, ptid_get_pid (inferior_ptid), ptid_get_lwp (inferior_ptid), tmp_addr, sizeof (tmp_buf), (uintptr_t) tmp_buf); if (status < 0) return 0; tmp_addr += sizeof (tmp_buf); } return 1; }
void PartionedManualMPSimExecutor::simulate() { try { PartionedMRTKernel kern("PartionedKern"); TextTrace ttrace("run_log.txt"); JSONTrace jtrace("run_trace.json"); createSimCPUScheduler(); createSimTaskCPU(); createSimVMCPU(); GUI_CONTEXT.addPeriodicTasks(); GUI_CONTEXT.addVMs(); addCPUs2Kernel(kern); addVMs2Kernel(kern, jtrace, ttrace); addTasks2Kernel(kern, jtrace, ttrace); SIMUL.run(_simulTime + 1); } catch (BaseExc &e) { GUI_CONTEXT.showMessageBox(e.what()); GUI_CONTEXT.erasePeriodicTask(); GUI_CONTEXT.erasePeriodicServerVM(); cleanExecutionData(); return; } showResult(); GUI_CONTEXT.erasePeriodicTask(); GUI_CONTEXT.erasePeriodicServerVM(); cleanExecutionData(); }
int proc_stop(proc_obj_t* proc) { return (ttrace(TT_PROC_STOP, proc->pid, 0, 0, 0, 0)); }
int proc_kill(proc_obj_t* proc) { return (ttrace(TT_PROC_EXIT, proc->pid, 0, 0, 0, 0)); }
int proc_create(proc_obj_t* proc, char* bin_path, char** args) { pid_t child; int pfd1[2], pfd2[2]; char c; ttevent_t ev; ev.tte_events = TTEVT_SYSCALL|TTEVT_EXEC|TTEVT_EXIT| TTEVT_BPT_SSTEP|TTEVT_SIGNAL; ev.tte_opts = TTEO_NONE; /* ** Technique de Roumain avec des pipes ** pour synchoniser les deux process */ if (pipe(pfd1) < 0 || pipe(pfd2) < 0) return (-1); switch ((child = fork())) { case -1: return (-1); /* ** Child Process */ case 0: if (setpgid(0, 0) == -1) return (-1); if (ttrace(TT_PROC_SETTRC, 0, 0, 0, TT_VERSION, 0) == -1) return -1; /* tell parent we are SETTRC'ed */ if (write(pfd2[1], (void *)&c, sizeof c) != sizeof c) return (-1); /* wait for exec event to be set*/ if (read(pfd1[0], (void *)&c, sizeof c) != sizeof c) return (-1); close(pfd1[0]); close(pfd1[1]); close(pfd2[0]); close(pfd2[1]); if (execvp(bin_path, args) == -1) return (-1); return (-1); } /* ** Ftrace process */ if (read(pfd2[0], (void *)&c, sizeof c) != sizeof c) return (-1); proc->pid = child; if (ttrace(TT_PROC_SET_EVENT_MASK, proc->pid, 0, (uint64_t)&ev, sizeof ev, 0) == -1) return (-1); /* tell the child to exec */ if (write(pfd1[1], (void *)&c, sizeof c) != sizeof c) return (-1); close(pfd1[0]); close(pfd1[1]); close(pfd2[0]); close(pfd2[1]); /* ** TODO: ** Attendre la fin de l'exec() ** set des breakpoints */ proc->luse = NULL; if (proc_wait_debug_event(proc, NULL) == -1) return (-1); return child; }
static int ia64_hpux_write_register_to_saved_state_t (int offset, gdb_byte *buf, int len) { return ttrace (TT_LWP_WUREGS, ptid_get_pid (inferior_ptid), ptid_get_lwp (inferior_ptid), offset, len, (uintptr_t) buf); }
int proc_detach(proc_obj_t* proc) { return (ttrace(TT_PROC_DETACH, proc->pid, 0, 0, 0, 0)); }