static cma__t_int_tcb * find_tcb (ptid_t ptid) { cma__t_known_object queue_header; cma__t_queue *queue_ptr; int thread = ptid_get_tid (ptid); if (thread == cached_thread) return &cached_tcb; read_memory ((CORE_ADDR) P_cma__g_known_threads, (char *) &queue_header, sizeof queue_header); for (queue_ptr = queue_header.queue.flink; queue_ptr != (cma__t_queue *) P_cma__g_known_threads; queue_ptr = cached_tcb.threads.flink) { cma__t_int_tcb *tcb_ptr; tcb_ptr = cma__base (queue_ptr, threads, cma__t_int_tcb); read_memory ((CORE_ADDR) tcb_ptr, (char *) &cached_tcb, sizeof cached_tcb); if (cached_tcb.header.type == cma__c_obj_tcb) if (cma_thread_get_unique (&cached_tcb.prolog.client_thread) == thread) { cached_thread = thread; return &cached_tcb; } } error (_("Can't find TCB %d"), thread); return NULL; }
static int ppcnbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb) { struct switchframe sf; struct callframe cf; struct gdbarch *gdbarch = get_regcache_arch (regcache); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); int i; /* The stack pointer shouldn't be zero. */ if (pcb->pcb_sp == 0) return 0; read_memory (pcb->pcb_sp, (gdb_byte *)&sf, sizeof sf); regcache_raw_supply (regcache, tdep->ppc_cr_regnum, &sf.cr); regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 2, &sf.fixreg2); for (i = 0 ; i < 19 ; i++) regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 13 + i, &sf.fixreg[i]); read_memory(sf.sp, (gdb_byte *)&cf, sizeof(cf)); regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 30, &cf.r30); regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 31, &cf.r31); regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 1, &cf.sp); read_memory(cf.sp, (gdb_byte *)&cf, sizeof(cf)); regcache_raw_supply (regcache, tdep->ppc_lr_regnum, &cf.lr); regcache_raw_supply (regcache, gdbarch_pc_regnum (gdbarch), &cf.lr); return 1; }
static int ppcobsd_supply_pcb (struct regcache *regcache, struct pcb *pcb) { struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache)); struct switchframe sf; struct callframe cf; int i, regnum; /* The following is true for OpenBSD 3.7: The pcb contains %r1 (the stack pointer) at the point of the context switch in cpu_switch(). At that point we have a stack frame as described by `struct switchframe', and below that a call frame as described by `struct callframe'. From this information we reconstruct the register state as it would look when we are in cpu_switch(). */ /* The stack pointer shouldn't be zero. */ if (pcb->pcb_sp == 0) return 0; read_memory (pcb->pcb_sp, (gdb_byte *)&sf, sizeof sf); regcache_raw_supply (regcache, SP_REGNUM, &sf.sp); regcache_raw_supply (regcache, tdep->ppc_cr_regnum, &sf.cr); regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 2, &sf.fixreg2); for (i = 0, regnum = tdep->ppc_gp0_regnum + 13; i < 19; i++, regnum++) regcache_raw_supply (regcache, regnum, &sf.fixreg[i]); read_memory (sf.sp, (gdb_byte *)&cf, sizeof cf); regcache_raw_supply (regcache, PC_REGNUM, &cf.lr); regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 30, &cf.r30); regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 31, &cf.r31); return 1; }
CORE_ADDR NEXT_PROLOGUE_INSN (CORE_ADDR addr, CORE_ADDR lim, char *pword1) { if (addr < lim + 8) { read_memory (addr, pword1, 1); read_memory (addr, pword1 + 1, 1); return 1; } return 0; }
static ptid_t find_active_thread (void) { static cma__t_int_tcb tcb; CORE_ADDR tcb_ptr; read_memory ((CORE_ADDR) P_cma__g_current_thread, (char *) &tcb_ptr, sizeof tcb_ptr); read_memory (tcb_ptr, (char *) &tcb, sizeof tcb); return (ptid_build (PIDGET (main_ptid), 0, cma_thread_get_unique (&tcb.prolog.client_thread))); }
static i32 process_checks (pid_t pid, DynMemEntry *dynmem, list<CheckEntry> *chk_lp, ptr_t mem_offs) { list<CheckEntry>::iterator it; CheckEntry *chk_en; value_t __chk_buf, *chk_buf = &__chk_buf; ptr_t mem_addr; i32 ret = 0; list_for_each (chk_lp, it) { chk_en = &(*it); if (chk_en->cfg_ref) { ret = handle_cfg_ref(chk_en->cfg_ref, chk_buf); if (ret) continue; } else if (chk_en->check_obj_num) { if (!dynmem) continue; chk_buf->u32 = dynmem->obj_idx; } else { mem_addr = mem_offs + chk_en->addr; ret = read_memory(pid, mem_addr, chk_buf, "MEMORY"); if (ret) goto out; } ret = or_check_memory(chk_en, chk_buf); if (ret) { // Parser must ensure (dynmem != NULL) if (chk_en->is_objcheck) dynmem->v_maddr[dynmem->obj_idx] = 0; goto out; } }
static int cartridge_ram_transform(usb_dev_handle *handle, const uint8_t *firmware, enum request w, enum request r, long address, long length, bool dump) { uint8_t *compare; compare = malloc(length); write_memory(handle, w, INDEX_IMPLIED, address, length, firmware); read_memory(handle, r, INDEX_IMPLIED, address, length, compare); int ret = memcmp(firmware, compare, length); if(dump == true){ int i; uint8_t *t = compare; for(i = 0; i < length; i += 0x10){ int j; printf("%06x:", i); for(j = 0; j < 0x10; j++){ const char *safix; switch(j){ case 7: safix = "-"; break; case 0x0f: safix = "\n"; break; default: safix = " "; break; } printf("%02x%s", *t, safix); t++; } } } free(compare); return ret; }
static void firmware_verify(usb_dev_handle *handle, const char *file) { uint8_t *firmware, *compare; const int firmsize = 0x3800; assert(firmsize <= 0x3800); firmware = malloc(firmsize); compare = malloc(firmsize); memset(compare, 0xff, firmsize); // if(buf_load(compare, file, firmsize) == false){ if(hex_load(file, firmsize, compare) == false){ puts("image open error!"); goto end; } read_memory(handle, REQUEST_FIRMWARE_DOWNLOAD, INDEX_IMPLIED, 0, firmsize, firmware); if(memcmp(firmware, compare, firmsize) == 0){ puts("firmware compare ok!"); }else{ puts("firmware compare ng!"); printf("hex: %s\n", compare + FIRM_VERSION_OFFSET); printf("avr: %s\n", firmware + FIRM_VERSION_OFFSET); } end: free(firmware); free(compare); }
EXPORT int add_breakpoint(mach_port_t task, vm_address_t patch_addr, int cont, callback handler) { kern_return_t kret; char *tmp; mach_vm_size_t len = 1; // number of bytes to write uint8_t opcode = 0xcc; // the CC byte to write interface *face; face = find_interface(task); if(face->registered_exception_handler == 0) { DEBUG_PRINT("[+add_breakpoint] HERE IN ADD BREAK\n %d", 0); register_(task); } kret = mach_vm_protect(task, patch_addr, len, FALSE, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE); RETURN_ON_MACH_ERROR("[-add_breakpoint] mach_vm_protect()", kret); if (patch_addr <= MAX_BREAKS) { DEBUG_PRINT("[-add_breakpoint] INVALID BREAKPOINT ADDRESS %lx\n", patch_addr); return -1; } else if(face->current_break >= MAX_BREAKS) { DEBUG_PRINT("[-add_breakpoint] Max %d breaks reached!\n", MAX_BREAKS); return -1; } DEBUG_PRINT("[+add_breakpoint] Breakpoint %u: %lx added\n", face->current_break, patch_addr); tmp = (char*) read_memory(task, patch_addr, 1); breakpoint_struct *new_break = safe_malloc(sizeof(breakpoint_struct)); new_break->address = patch_addr; new_break->original = tmp[0] & 0xff; new_break->handler = handler; if(face->single_step) { new_break->index = face->single_step_index; } else { new_break->index = face->current_break == 0 ? 0 : face->breaks[face->current_break-1]->index + 1; } new_break->flags = cont; if(face->max_break == 0) { face->max_break = 1; } if(face->current_break >= (face->max_break - 1)) { DEBUG_PRINT("[+add_breakpoint] ALLOCATING MORE BP! CURRENTLY: %d\n", face->current_break); face->breaks = safe_realloc(face->breaks, sizeof(breakpoint_struct*) *(face->max_break*2)); face->max_break *= 2; } // face->breaks = safe_realloc(face->breaks, sizeof(breakpoint_struct*) *(face->current_break+1)); face->breaks[face->current_break++] = new_break; write_memory(task, patch_addr, opcode, len); // write the byte kret = mach_vm_protect(task, patch_addr, (mach_vm_size_t)1, FALSE, VM_PROT_READ | VM_PROT_EXECUTE); RETURN_ON_MACH_ERROR("[-add_breakpoint] RESTORE mach_vm_protect()", kret); return 1; }
// TIME CRITICAL! Process all activated config entries from pointer static void process_ptrmem (pid_t pid, CfgEntry *cfg_en, value_t *buf, u32 mem_idx) { ptr_t mem_addr; PtrMemEntry *ptrtgt = cfg_en->ptrtgt; list<CfgEntry*> *cfg_act = &ptrtgt->cfg_act; list<CfgEntry*>::iterator it; vector<value_t> *vvec = &cfg_en->v_oldval; value_t *value = &vvec->at(mem_idx); if (buf->ptr == 0 || ptrtgt->v_state[mem_idx] == PTR_DONE) return; if (buf->ptr == value->ptr) { if (cfg_en->dynval == DYN_VAL_PTR_ONCE) ptrtgt->v_state[mem_idx] = PTR_DONE; else ptrtgt->v_state[mem_idx] = PTR_SETTLED; ptrtgt->v_offs[mem_idx] = buf->ptr; list_for_each (cfg_act, it) { PtrMemEntry *ptrmem; cfg_en = *it; ptrmem = cfg_en->ptrmem; mem_addr = ptrmem->v_offs[mem_idx] + cfg_en->addr; if (read_memory(pid, mem_addr, buf, "PTR MEMORY")) continue; change_memory(pid, cfg_en, buf, ptrmem->v_offs[mem_idx], &cfg_en->v_oldval[mem_idx]); } } else {
/** * Determines the argument to the exit function, given the context at which the exit breakpoint * was hit * * @param context the current context * @param errmsg the error message populated by the memory access * * @return the exit result */ exit_result get_exit_argument(const ucontext_t *context, udi_errmsg *errmsg) { exit_result ret; ret.failure = 0; if (__WORDSIZE == 64) { // The exit argument is passed in rax ret.status = (int)context->uc_mcontext.gregs[X86_64_RAX_OFFSET]; }else{ // The exit argument is the first parameter on the stack // Get the stack pointer unsigned long sp; sp = (unsigned long)context->uc_mcontext.gregs[X86_ESP_OFFSET]; int word_length = sizeof(unsigned long); // skip return address sp += word_length; int read_result = read_memory(&(ret.status), (const void *)sp, sizeof(int), errmsg); if ( read_result != 0 ) { udi_printf("failed to retrieve exit status off of the stack at 0x%lx\n", sp); snprintf(errmsg->msg, errmsg->size, "failed to retrieve exit status off of the stack at 0x%lx: %s", sp, get_mem_errstr()); ret.failure = read_result; } } return ret; }
static enum return_value_convention m68k_return_value (struct gdbarch *gdbarch, struct type *type, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf) { enum type_code code = TYPE_CODE (type); /* GCC returns a `long double' in memory too. */ if (((code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION) && !m68k_reg_struct_return_p (gdbarch, type)) || (code == TYPE_CODE_FLT && TYPE_LENGTH (type) == 12)) { /* The default on m68k is to return structures in static memory. Consequently a function must return the address where we can find the return value. */ if (readbuf) { ULONGEST addr; regcache_raw_read_unsigned (regcache, M68K_D0_REGNUM, &addr); read_memory (addr, readbuf, TYPE_LENGTH (type)); } return RETURN_VALUE_ABI_RETURNS_ADDRESS; } if (readbuf) m68k_extract_return_value (type, regcache, readbuf); if (writebuf) m68k_store_return_value (type, regcache, writebuf); return RETURN_VALUE_REGISTER_CONVENTION; }
CORE_ADDR read_memory_typed_address(CORE_ADDR addr, struct type *type) { char *buf = (char *)alloca(TYPE_LENGTH(type)); read_memory(addr, (gdb_byte *)buf, TYPE_LENGTH(type)); return extract_typed_address((const gdb_byte *)buf, type); }
static int amd64_darwin_sstep_at_sigreturn (x86_thread_state_t *regs) { enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); static const gdb_byte darwin_syscall[] = { 0x0f, 0x05 }; /* syscall */ gdb_byte buf[sizeof (darwin_syscall)]; /* Check if PC is at a sigreturn system call. */ if (target_read_memory (regs->uts.ts64.__rip, buf, sizeof (buf)) == 0 && memcmp (buf, darwin_syscall, sizeof (darwin_syscall)) == 0 && (regs->uts.ts64.__rax & 0xffffffff) == 0x20000b8 /* SYS_sigreturn */) { ULONGEST mctx_addr; ULONGEST flags_addr; unsigned int rflags; mctx_addr = read_memory_unsigned_integer (regs->uts.ts64.__rdi + 48, 8, byte_order); flags_addr = mctx_addr + 16 + 17 * 8; /* AMD64 is little endian. */ read_memory (flags_addr, (gdb_byte *) &rflags, 4); rflags |= X86_EFLAGS_T; write_memory (flags_addr, (gdb_byte *) &rflags, 4); return 1; } return 0; }
EXPORT BOOL ReadProcessMemory(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead){ short sts; sts = read_memory(hProcess, (unsigned int) lpBaseAddress, nSize, lpBuffer); *lpNumberOfBytesRead = nSize; return sts; }
static enum return_value_convention sparc32_return_value (struct gdbarch *gdbarch, struct type *type, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf) { /* The psABI says that "...every stack frame reserves the word at %fp+64. If a function returns a structure, union, or quad-precision value, this word should hold the address of the object into which the return value should be copied." This guarantees that we can always find the return value, not just before the function returns. */ if (sparc_structure_or_union_p (type) || (sparc_floating_p (type) && TYPE_LENGTH (type) == 16)) { if (readbuf) { ULONGEST sp; CORE_ADDR addr; regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM, &sp); addr = read_memory_unsigned_integer (sp + 64, 4); read_memory (addr, readbuf, TYPE_LENGTH (type)); } return RETURN_VALUE_ABI_PRESERVES_ADDRESS; } if (readbuf) sparc32_extract_return_value (type, regcache, readbuf); if (writebuf) sparc32_store_return_value (type, regcache, writebuf); return RETURN_VALUE_REGISTER_CONVENTION; }
static int m68kbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb) { int regnum, tmp; int i = 0; /* The following is true for NetBSD 1.6.2: The pcb contains %d2...%d7, %a2...%a7 and %ps. This accounts for all callee-saved registers. From this information we reconstruct the register state as it would look when we just returned from cpu_switch(). */ /* The stack pointer shouldn't be zero. */ if (pcb->pcb_regs[PCB_REGS_SP] == 0) return 0; for (regnum = M68K_D2_REGNUM; regnum <= M68K_D7_REGNUM; regnum++) regcache_raw_supply (regcache, regnum, &pcb->pcb_regs[i++]); for (regnum = M68K_A2_REGNUM; regnum <= M68K_SP_REGNUM; regnum++) regcache_raw_supply (regcache, regnum, &pcb->pcb_regs[i++]); tmp = pcb->pcb_ps & 0xffff; regcache_raw_supply (regcache, M68K_PS_REGNUM, &tmp); read_memory (pcb->pcb_regs[PCB_REGS_FP] + 4, (char *) &tmp, sizeof tmp); regcache_raw_supply (regcache, M68K_PC_REGNUM, &tmp); return 1; }
static void lm32_extract_return_value (struct type *type, struct regcache *regcache, gdb_byte *valbuf) { struct gdbarch *gdbarch = get_regcache_arch (regcache); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); int offset; ULONGEST l; CORE_ADDR return_buffer; if (TYPE_CODE (type) != TYPE_CODE_STRUCT && TYPE_CODE (type) != TYPE_CODE_UNION && TYPE_CODE (type) != TYPE_CODE_ARRAY && TYPE_LENGTH (type) <= 4) { /* Return value is returned in a single register. */ regcache_cooked_read_unsigned (regcache, SIM_LM32_R1_REGNUM, &l); store_unsigned_integer (valbuf, TYPE_LENGTH (type), byte_order, l); } else if ((TYPE_CODE (type) == TYPE_CODE_INT) && (TYPE_LENGTH (type) == 8)) { /* 64-bit values are returned in a register pair. */ regcache_cooked_read_unsigned (regcache, SIM_LM32_R1_REGNUM, &l); memcpy (valbuf, &l, 4); regcache_cooked_read_unsigned (regcache, SIM_LM32_R2_REGNUM, &l); memcpy (valbuf + 4, &l, 4); } else { /* Aggregate types greater than a single register are returned in memory. FIXME: Unless they are only 2 regs?. */ regcache_cooked_read_unsigned (regcache, SIM_LM32_R1_REGNUM, &l); return_buffer = l; read_memory (return_buffer, valbuf, TYPE_LENGTH (type)); } }
/* APPLE LOCAL begin Darwin */ enum return_value_convention ppc_darwin_abi_return_value (struct gdbarch *gdbarch, struct type *valtype, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); if (TYPE_CODE (valtype) == TYPE_CODE_STRUCT || TYPE_CODE (valtype) == TYPE_CODE_UNION) { if (readbuf != NULL) { /* CORE_ADDR is more logical, but ULONGEST finesses the situation of G5 registers in 32-bit mode. */ ULONGEST addr; regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3, (gdb_byte *) &addr); read_memory (addr, readbuf, TYPE_LENGTH (valtype)); } return RETURN_VALUE_ABI_RETURNS_ADDRESS; } else return do_ppc_sysv_return_value (gdbarch, valtype, regcache, readbuf, writebuf, 0); }
static int sparc64nbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb) { u_int64_t state; int regnum; /* The following is true for NetBSD 1.6.2: The pcb contains %sp and %pc, %pstate and %cwp. From this information we reconstruct the register state as it would look when we just returned from cpu_switch(). */ /* The stack pointer shouldn't be zero. */ if (pcb->pcb_sp == 0) return 0; /* If the program counter is zero, this is probably a core dump, and we can get %pc from the stack. */ if (pcb->pcb_pc == 0) read_memory(pcb->pcb_sp + BIAS - 176 + (11 * 8), (gdb_byte *)&pcb->pcb_pc, sizeof pcb->pcb_pc); regcache_raw_supply (regcache, SPARC_SP_REGNUM, &pcb->pcb_sp); regcache_raw_supply (regcache, SPARC64_PC_REGNUM, &pcb->pcb_pc); state = pcb->pcb_pstate << 8 | pcb->pcb_cwp; regcache_raw_supply (regcache, SPARC64_STATE_REGNUM, &state); sparc_supply_rwindow (regcache, pcb->pcb_sp, -1); return 1; }
static int i386_darwin_sstep_at_sigreturn (x86_thread_state_t *regs) { enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); static const gdb_byte darwin_syscall[] = { 0xcd, 0x80 }; /* int 0x80 */ gdb_byte buf[sizeof (darwin_syscall)]; /* Check if PC is at a sigreturn system call. */ if (target_read_memory (regs->uts.ts32.__eip, buf, sizeof (buf)) == 0 && memcmp (buf, darwin_syscall, sizeof (darwin_syscall)) == 0 && regs->uts.ts32.__eax == 0xb8 /* SYS_sigreturn */) { ULONGEST uctx_addr; ULONGEST mctx_addr; ULONGEST flags_addr; unsigned int eflags; uctx_addr = read_memory_unsigned_integer (regs->uts.ts32.__esp + 4, 4, byte_order); mctx_addr = read_memory_unsigned_integer (uctx_addr + 28, 4, byte_order); flags_addr = mctx_addr + 12 + 9 * 4; read_memory (flags_addr, (gdb_byte *) &eflags, 4); eflags |= X86_EFLAGS_T; write_memory (flags_addr, (gdb_byte *) &eflags, 4); return 1; } return 0; }
void read_memory_string(CORE_ADDR memaddr, char *buffer, int max_len) { char *cp; int i; int cnt; cp = buffer; while (1) { if ((cp - buffer) >= max_len) { buffer[max_len - 1] = '\0'; break; } cnt = (max_len - (cp - buffer)); if (cnt > 8) cnt = 8; read_memory(memaddr + (int)(cp - buffer), (gdb_byte *)cp, cnt); for (i = 0; (i < cnt) && *cp; i++, cp++) ; /* null body */ if ((i < cnt) && !*cp) break; } }
/* Attach to PID `pid', take a snapshot, modify its state to have it call * `dlopen()', restore the previously saved snapshot and detach. */ static int inject(pid_t pid, char *filename, char all_thrs) { regs_t regs; char buf[PAGE_SIZE]; ssize_t size; int r = -1; if(attach(pid, all_thrs) != 0) goto ret; if(read_registers(pid, ®s) != 0) goto ret; if((size = read_memory(pid, (void *)SP(regs), buf, sizeof(buf))) < 0) goto ret; r = 0; if(force_dlopen(pid, filename) != 0) r = -1; if(write_memory(pid, (void *)SP(regs), buf, size) != size) r = -1; if(write_registers(pid, ®s) != 0) r = -1; if(detach(pid, all_thrs) != 0) r = -1; ret: return r; }
static int amd64obsd_supply_pcb (struct regcache *regcache, struct pcb *pcb) { struct switchframe sf; int regnum; /* The following is true for OpenBSD 3.5: The pcb contains the stack pointer at the point of the context switch in cpu_switch(). At that point we have a stack frame as described by `struct switchframe', which for OpenBSD 3.5 has the following layout: interrupt level %r15 %r14 %r13 %r12 %rbp %rbx return address Together with %rsp in the pcb, this accounts for all callee-saved registers specified by the psABI. From this information we reconstruct the register state as it would look when we just returned from cpu_switch(). For core dumps the pcb is saved by savectx(). In that case the stack frame only contains the return address, and there is no way to recover the other registers. */ /* The stack pointer shouldn't be zero. */ if (pcb->pcb_rsp == 0) return 0; /* Read the stack frame, and check its validity. */ read_memory (pcb->pcb_rsp, (gdb_byte *) &sf, sizeof sf); if (sf.sf_rbp == pcb->pcb_rbp) { /* Yes, we have a frame that matches cpu_switch(). */ pcb->pcb_rsp += sizeof (struct switchframe); regcache_raw_supply (regcache, 12, &sf.sf_r12); regcache_raw_supply (regcache, 13, &sf.sf_r13); regcache_raw_supply (regcache, 14, &sf.sf_r14); regcache_raw_supply (regcache, 15, &sf.sf_r15); regcache_raw_supply (regcache, AMD64_RBX_REGNUM, &sf.sf_rbx); regcache_raw_supply (regcache, AMD64_RIP_REGNUM, &sf.sf_rip); } else { /* No, the pcb must have been last updated by savectx(). */ pcb->pcb_rsp += 8; regcache_raw_supply (regcache, AMD64_RIP_REGNUM, &sf); } regcache_raw_supply (regcache, AMD64_RSP_REGNUM, &pcb->pcb_rsp); regcache_raw_supply (regcache, AMD64_RBP_REGNUM, &pcb->pcb_rbp); return 1; }
ULONGEST read_memory_unsigned_integer(CORE_ADDR memaddr, int len) { char buf[sizeof(ULONGEST)]; read_memory(memaddr, (gdb_byte *)buf, len); return extract_unsigned_integer((const gdb_byte *)buf, len); }
LONGEST scm_get_field (LONGEST svalue, int index) { char buffer[20]; read_memory (SCM2PTR (svalue) + index * TYPE_LENGTH (builtin_type_scm), buffer, TYPE_LENGTH (builtin_type_scm)); return extract_signed_integer (buffer, TYPE_LENGTH (builtin_type_scm)); }
/* Read a PPC instruction from memory. PPC instructions are always big-endian, no matter what endianness the program is running in, so we can't use read_memory_integer or one of its friends here. */ static unsigned int read_insn (CORE_ADDR pc) { unsigned char buf[4]; read_memory (pc, buf, 4); return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; }
static void i386_linux_resume (ptid_t ptid, int step, enum target_signal signal) { int pid = PIDGET (ptid); int request = PTRACE_CONT; if (pid == -1) /* Resume all threads. */ /* I think this only gets used in the non-threaded case, where "resume all threads" and "resume inferior_ptid" are the same. */ pid = PIDGET (inferior_ptid); if (step) { CORE_ADDR pc = read_pc_pid (pid_to_ptid (pid)); gdb_byte buf[LINUX_SYSCALL_LEN]; request = PTRACE_SINGLESTEP; /* Returning from a signal trampoline is done by calling a special system call (sigreturn or rt_sigreturn, see i386-linux-tdep.c for more information). This system call restores the registers that were saved when the signal was raised, including %eflags. That means that single-stepping won't work. Instead, we'll have to modify the signal context that's about to be restored, and set the trace flag there. */ /* First check if PC is at a system call. */ if (deprecated_read_memory_nobpt (pc, buf, LINUX_SYSCALL_LEN) == 0 && memcmp (buf, linux_syscall, LINUX_SYSCALL_LEN) == 0) { int syscall = read_register_pid (LINUX_SYSCALL_REGNUM, pid_to_ptid (pid)); /* Then check the system call number. */ if (syscall == SYS_sigreturn || syscall == SYS_rt_sigreturn) { CORE_ADDR sp = read_register (I386_ESP_REGNUM); CORE_ADDR addr = sp; unsigned long int eflags; if (syscall == SYS_rt_sigreturn) addr = read_memory_integer (sp + 8, 4) + 20; /* Set the trace flag in the context that's about to be restored. */ addr += LINUX_SIGCONTEXT_EFLAGS_OFFSET; read_memory (addr, (gdb_byte *) &eflags, 4); eflags |= 0x0100; write_memory (addr, (gdb_byte *) &eflags, 4); } } } if (ptrace (request, pid, 0, target_signal_to_host (signal)) == -1) perror_with_name (("ptrace")); }
static void firmware_download(usb_dev_handle *handle, const char *file) { const int firmsize = 0x4000; uint8_t *firmware = malloc(firmsize); read_memory(handle, REQUEST_FIRMWARE_DOWNLOAD, INDEX_IMPLIED, 0, firmsize, firmware); buf_save(firmware, file, firmsize); puts(firmware + FIRM_VERSION_OFFSET); free(firmware); }
static int i386obsd_supply_pcb (struct regcache *regcache, struct pcb *pcb) { struct gdbarch *gdbarch = regcache->arch (); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct switchframe sf; /* The following is true for OpenBSD 3.6: The pcb contains %esp and %ebp at the point of the context switch in cpu_switch(). At that point we have a stack frame as described by `struct switchframe', which for OpenBSD 3.6 has the following layout: interrupt level %edi %esi %ebx %eip we reconstruct the register state as it would look when we just returned from cpu_switch(). */ /* The stack pointer shouldn't be zero. */ if (pcb->pcb_esp == 0) return 0; /* Read the stack frame, and check its validity. We do this by checking if the saved interrupt priority level in the stack frame looks reasonable.. */ #ifdef PCB_SAVECTX if ((pcb->pcb_flags & PCB_SAVECTX) == 0) { /* Yes, we have a frame that matches cpu_switch(). */ read_memory (pcb->pcb_esp, (gdb_byte *) &sf, sizeof sf); pcb->pcb_esp += sizeof (struct switchframe); regcache->raw_supply (I386_EDI_REGNUM, &sf.sf_edi); regcache->raw_supply (I386_ESI_REGNUM, &sf.sf_esi); regcache->raw_supply (I386_EBX_REGNUM, &sf.sf_ebx); regcache->raw_supply (I386_EIP_REGNUM, &sf.sf_eip); } else #endif { /* No, the pcb must have been last updated by savectx(). */ pcb->pcb_esp = pcb->pcb_ebp; pcb->pcb_ebp = read_memory_integer(pcb->pcb_esp, 4, byte_order); sf.sf_eip = read_memory_integer(pcb->pcb_esp + 4, 4, byte_order); regcache->raw_supply (I386_EIP_REGNUM, &sf.sf_eip); } regcache->raw_supply (I386_EBP_REGNUM, &pcb->pcb_ebp); regcache->raw_supply (I386_ESP_REGNUM, &pcb->pcb_esp); return 1; }