Index: uspace/lib/c/arch/ia32/src/rtld/reloc.c
===================================================================
--- uspace/lib/c/arch/ia32/src/rtld/reloc.c	(revision 3b0f1b9a04083e5b48162443937d5e8d8303e4d0)
+++ uspace/lib/c/arch/ia32/src/rtld/reloc.c	(revision 0f792c28c69f695fd1956a86e0489bd2ea27cc3f)
@@ -69,5 +69,5 @@
 	uint32_t sym_size;
 	char *str_tab;
-	
+
 	elf_symbol_t *sym_def;
 	module_t *dest;
@@ -80,5 +80,5 @@
 
 	DPRINTF("address: 0x%x, entries: %d\n", (uintptr_t)rt, rt_entries);
-	
+
 	for (i = 0; i < rt_entries; ++i) {
 //		DPRINTF("symbol %d: ", i);
@@ -100,5 +100,5 @@
 //			DPRINTF("rel_type: %x, rel_offset: 0x%x\n", rel_type, r_offset);
 			sym_def = symbol_def_find(str_tab + sym->st_name,
-			    m, &dest);
+			    m, ssf_none, &dest);
 //			DPRINTF("dest name: '%s'\n", dest->dyn.soname);
 //			DPRINTF("dest bias: 0x%x\n", dest->bias);
@@ -137,7 +137,22 @@
 			/*
 			 * Copy symbol data from shared object to specified
-			 * location.
+			 * location. Need to find the 'source', i.e. the
+			 * other instance of the object than the one in the
+			 * executable program.
 			 */
 			DPRINTF("fixup R_386_COPY (s)\n");
+
+			sym_def = symbol_def_find(str_tab + sym->st_name,
+			    m, ssf_noroot, &dest);
+
+			if (sym_def) {
+				sym_addr = (uint32_t)
+				    symbol_get_addr(sym_def, dest);
+			} else {
+				printf("Source definition of '%s' not found.\n",
+				    str_tab + sym->st_name);
+				continue;
+			}
+
 			sym_size = sym->st_size;
 			if (sym_size != sym_def->st_size) {
@@ -147,7 +162,8 @@
 					sym_size = sym_def->st_size;
 			}
+
 			memcpy(r_ptr, (const void *)sym_addr, sym_size);
 			break;
-			
+
 		case R_386_RELATIVE:
 			DPRINTF("fixup R_386_RELATIVE (b+a)\n");
Index: uspace/lib/c/generic/dlfcn.c
===================================================================
--- uspace/lib/c/generic/dlfcn.c	(revision 3b0f1b9a04083e5b48162443937d5e8d8303e4d0)
+++ uspace/lib/c/generic/dlfcn.c	(revision 0f792c28c69f695fd1956a86e0489bd2ea27cc3f)
@@ -81,5 +81,5 @@
 
 	printf("dlsym(0x%lx, \"%s\")\n", (long)mod, sym_name);
-	sd = symbol_bfs_find(sym_name, (module_t *) mod, &sm);
+	sd = symbol_bfs_find(sym_name, (module_t *) mod, ssf_none, &sm);
 	if (sd != NULL) {
 		return symbol_get_addr(sd, sm);
Index: uspace/lib/c/generic/rtld/symbol.c
===================================================================
--- uspace/lib/c/generic/rtld/symbol.c	(revision 3b0f1b9a04083e5b48162443937d5e8d8303e4d0)
+++ uspace/lib/c/generic/rtld/symbol.c	(revision 0f792c28c69f695fd1956a86e0489bd2ea27cc3f)
@@ -111,8 +111,11 @@
  * @param name		Name of the symbol to search for.
  * @param start		Module in which to start the search..
+ * @param flags		@c ssf_none or @c ssf_noroot to not look for the symbol
+ *			in @a start
  * @param mod		(output) Will be filled with a pointer to the module 
  *			that contains the symbol.
  */
-elf_symbol_t *symbol_bfs_find(const char *name, module_t *start, module_t **mod)
+elf_symbol_t *symbol_bfs_find(const char *name, module_t *start,
+    symbol_search_flags_t flags, module_t **mod)
 {
 	module_t *m, *dm;
@@ -145,10 +148,13 @@
 		list_remove(&m->queue_link);
 
-		s = def_find_in_module(name, m);
-		if (s != NULL) {
-			/* Symbol found */
-			sym = s;
-			*mod = m;
-			break;
+		/* If ssf_noroot is specified, do not look in start module */
+		if (m != start || (flags & ssf_noroot) == 0) { 
+			s = def_find_in_module(name, m);
+			if (s != NULL) {
+				/* Symbol found */
+				sym = s;
+				*mod = m;
+				break;
+			}
 		}
 
@@ -179,5 +185,5 @@
 
 
-/** Find the definition of a symbol..
+/** Find the definition of a symbol.
  *
  * By definition in System V ABI, if module origin has the flag DT_SYMBOLIC,
@@ -188,8 +194,11 @@
  * @param name		Name of the symbol to search for.
  * @param origin	Module in which the dependency originates.
+ * @param flags		@c ssf_none or @c ssf_noroot to not look for the symbol
+ *			in the executable program.
  * @param mod		(output) Will be filled with a pointer to the module 
  *			that contains the symbol.
  */
-elf_symbol_t *symbol_def_find(const char *name, module_t *origin, module_t **mod)
+elf_symbol_t *symbol_def_find(const char *name, module_t *origin,
+    symbol_search_flags_t flags, module_t **mod)
 {
 	elf_symbol_t *s;
@@ -212,8 +221,8 @@
 	if (runtime_env->program) {
 		/* Program is dynamic -- start with program as root. */
-		return symbol_bfs_find(name, runtime_env->program, mod);
+		return symbol_bfs_find(name, runtime_env->program, flags, mod);
 	} else {
 		/* Program is static -- start with @a origin as root. */
-		return symbol_bfs_find(name, origin, mod);
+		return symbol_bfs_find(name, origin, ssf_none, mod);
 	}
 }
Index: uspace/lib/c/include/rtld/symbol.h
===================================================================
--- uspace/lib/c/include/rtld/symbol.h	(revision 3b0f1b9a04083e5b48162443937d5e8d8303e4d0)
+++ uspace/lib/c/include/rtld/symbol.h	(revision 0f792c28c69f695fd1956a86e0489bd2ea27cc3f)
@@ -39,7 +39,17 @@
 #include <rtld/rtld.h>
 
-elf_symbol_t *symbol_bfs_find(const char *name, module_t *start, module_t **mod);
-elf_symbol_t *symbol_def_find(const char *name, module_t *origin, module_t **mod);
-void *symbol_get_addr(elf_symbol_t *sym, module_t *m);
+/** Symbol search flags */
+typedef enum {
+	/** No flags */
+	ssf_none = 0,
+	/** Do not search tree root */
+	ssf_noroot = 0x1
+} symbol_search_flags_t;
+
+extern elf_symbol_t *symbol_bfs_find(const char *, module_t *,
+    symbol_search_flags_t, module_t **);
+extern elf_symbol_t *symbol_def_find(const char *, module_t *,
+    symbol_search_flags_t, module_t **);
+extern void *symbol_get_addr(elf_symbol_t *, module_t *);
 
 #endif
