int context_read_mem(Context * ctx, ContextAddress address, void * buf, size_t size) { ContextAddress word_addr; unsigned word_size = context_word_size(ctx); assert(is_dispatch_thread()); assert(!ctx->exited); trace(LOG_CONTEXT, "context: read memory ctx %#lx, id %s, address %#lx, size %zu", ctx, ctx->id, address, size); assert(word_size <= sizeof(unsigned long)); for (word_addr = address & ~((ContextAddress)word_size - 1); word_addr < address + size; word_addr += word_size) { unsigned long word = 0; errno = 0; word = ptrace(PTRACE_PEEKDATA, EXT(ctx)->pid, (char *)word_addr, 0); if (errno != 0) { int err = errno; trace(LOG_CONTEXT, "error: ptrace(PTRACE_PEEKDATA, ...) failed: ctx %#lx, id %s, addr %#lx, error %d %s", ctx, ctx->id, word_addr, err, errno_to_str(err)); errno = err; return -1; } if (word_addr < address || word_addr + word_size > address + size) { size_t i; for (i = 0; i < word_size; i++) { if (word_addr + i >= address && word_addr + i < address + size) { ((char *)buf)[word_addr + i - address] = ((char *)&word)[i]; } } } else { memcpy((char *)buf + (word_addr - address), &word, word_size); } } return check_breakpoints_on_memory_read(ctx, address, buf, size); }
static void write_context(OutputStream * out, Context * ctx) { assert(!ctx->exited); write_stream(out, '{'); json_write_string(out, "ID"); write_stream(out, ':'); json_write_string(out, ctx->id); if (ctx->parent != NULL) { write_stream(out, ','); json_write_string(out, "ParentID"); write_stream(out, ':'); json_write_string(out, ctx->parent->id); } write_stream(out, ','); json_write_string(out, "ProcessID"); write_stream(out, ':'); json_write_string(out, context_get_group(ctx, CONTEXT_GROUP_PROCESS)->id); if (ctx->name != NULL) { write_stream(out, ','); json_write_string(out, "Name"); write_stream(out, ':'); json_write_string(out, ctx->name); } write_stream(out, ','); json_write_string(out, "BigEndian"); write_stream(out, ':'); json_write_boolean(out, ctx->big_endian); if (ctx->mem_access) { int cnt = 0; write_stream(out, ','); json_write_string(out, "AddressSize"); write_stream(out, ':'); json_write_ulong(out, context_word_size(ctx)); write_stream(out, ','); json_write_string(out, "AccessTypes"); write_stream(out, ':'); write_stream(out, '['); if (ctx->mem_access & MEM_ACCESS_INSTRUCTION) { if (cnt++) write_stream(out, ','); json_write_string(out, "instruction"); } if (ctx->mem_access & MEM_ACCESS_DATA) { if (cnt++) write_stream(out, ','); json_write_string(out, "data"); } if (ctx->mem_access & MEM_ACCESS_IO) { if (cnt++) write_stream(out, ','); json_write_string(out, "io"); } if (ctx->mem_access & MEM_ACCESS_USER) { if (cnt++) write_stream(out, ','); json_write_string(out, "user"); } if (ctx->mem_access & MEM_ACCESS_SUPERVISOR) { if (cnt++) write_stream(out, ','); json_write_string(out, "supervisor"); } if (ctx->mem_access & MEM_ACCESS_HYPERVISOR) { if (cnt++) write_stream(out, ','); json_write_string(out, "hypervisor"); } if (ctx->mem_access & MEM_ACCESS_VIRTUAL) { if (cnt++) write_stream(out, ','); json_write_string(out, "virtual"); } if (ctx->mem_access & MEM_ACCESS_PHYSICAL) { if (cnt++) write_stream(out, ','); json_write_string(out, "physical"); } if (ctx->mem_access & MEM_ACCESS_CACHE) { if (cnt++) write_stream(out, ','); json_write_string(out, "cache"); } if (ctx->mem_access & MEM_ACCESS_TLB) { if (cnt++) write_stream(out, ','); json_write_string(out, "tlb"); } write_stream(out, ']'); } write_stream(out, '}'); }