diff --git a/sysdeps/README b/sysdeps/README
index 1ec4935..001a13e 100644
--- a/sysdeps/README
+++ b/sysdeps/README
@@ -23,8 +23,9 @@ void * get_instruction_pointer(pid_t pid
 void * get_stack_pointer(pid_t pid);
 void * get_return_addr(pid_t pid, void * stack_pointer);
 long gimme_arg(enum tof type, struct process * proc, int arg_num);
-int umovestr(struct process * proc, void * addr, int len, void * laddr);
 int umovelong(struct process * proc, void * addr, long * result);
+int umovestr(struct process * proc, void * addr, int len, void * laddr);
+int umove(struct process * proc, void * addr, int len, void * laddr);
 char * pid2name(pid_t pid);
 void trace_me(void);
 int trace_pid(pid_t pid);
diff --git a/sysdeps/linux-gnu/trace.c b/sysdeps/linux-gnu/trace.c
index a1af202..5a8d29e 100644
--- a/sysdeps/linux-gnu/trace.c
+++ b/sysdeps/linux-gnu/trace.c
@@ -193,3 +193,26 @@ int umovestr(struct process *proc, void 
 	*(char *)(laddr + offset) = '\0';
 	return 0;
 }
+
+/* Read a series of 'len' bytes starting at the process's memory
+   address 'addr'.
+*/
+int umove(struct process *proc, void *addr, int len, void *laddr)
+{
+	union {
+		long a;
+		char c[sizeof(long)];
+	} a;
+	int i;
+	int offset = 0;
+
+	while (offset < len) {
+		a.a = ptrace(PTRACE_PEEKTEXT, proc->pid, addr + offset, 0);
+		if (len - offset >= sizeof(long))
+			memcpy(laddr + offset, &a.c[0], sizeof(long));
+		else
+			memcpy(laddr + offset, &a.c[0], len - offset);
+		offset += sizeof(long);
+	}
+	return 0;
+}
