void write_child_data_n(pid_t tid, const size_t size, long int addr, void* data) { int start_offset = addr & 0x3; int end_offset = (addr + size) & 0x3; size_t write_size = size; void* write_data = sys_malloc(size + 2 * READ_SIZE); void* write_addr = (void*) addr; if (start_offset) { long int word = read_child_data_word(tid, addr & ~0x3); memcpy(write_data, &word, READ_SIZE); write_size += start_offset; write_addr = (void*) (addr & ~0x3); } if (end_offset) { long int word = read_child_data_word(tid, (addr + size) & ~0x3); write_size += READ_SIZE - end_offset; unsigned long buffer_addr = ((unsigned long) write_data + start_offset + size) & ~0x3; memcpy((void*) buffer_addr, &word, READ_SIZE); } assert(write_size % 4 == 0); memcpy(write_data + start_offset, data, size); int i; for (i = 0; i < write_size; i += READ_SIZE) { uint32_t word = *(uint32_t*) (write_data + i); write_child_data_word(tid, write_addr + i, (void*) word); } free(write_data); }
void* read_child_data_tid(pid_t tid, size_t size, long int addr) { int i, offset, padding = 0; long tmp; void* data = sys_malloc(size); offset = addr & 0x3; if (offset) { tmp = read_child_data_word(tid, addr & ~0x3); padding = READ_SIZE - offset; memcpy(data, ((void*) (&tmp)) + offset, padding); } for (i = padding; i < size; i += READ_SIZE) { tmp = read_child_data_word(tid, addr + i); memcpy(data + i, &tmp, READ_SIZE); } /* make sure we no not return more than required */ return data; }