=== modified file 'uspace/lib/c/arch/ia32/src/rtld/reloc.c'
--- uspace/lib/c/arch/ia32/src/rtld/reloc.c	2012-04-02 15:52:07 +0000
+++ uspace/lib/c/arch/ia32/src/rtld/reloc.c	2016-04-11 09:25:15 +0000
@@ -70,6 +70,7 @@
 	char *str_tab;
 	
 	elf_symbol_t *sym_def;
+	module_t *src;
 	module_t *dest;
 
 	DPRINTF("parse relocation table\n");
@@ -99,7 +100,7 @@
 		if (sym->st_name != 0) {
 //			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, &dest, NULL);
 //			DPRINTF("dest name: '%s'\n", dest->dyn.soname);
 //			DPRINTF("dest bias: 0x%x\n", dest->bias);
 			if (sym_def) {
@@ -138,7 +139,6 @@
 			 * Copy symbol data from shared object to specified
 			 * location.
 			 */
-			DPRINTF("fixup R_386_COPY (s)\n");
 			sym_size = sym->st_size;
 			if (sym_size != sym_def->st_size) {
 				printf("Warning: Mismatched symbol sizes.\n");
@@ -146,7 +146,23 @@
 				if (sym_size > sym_def->st_size)
 					sym_size = sym_def->st_size;
 			}
-			memcpy(r_ptr, (const void *)sym_addr, sym_size);
+
+			/*
+			 * Look for the source symbol definition in all other
+			 * modules.
+			 */
+			elf_symbol_t *sdef; 
+			sdef = symbol_def_find(str_tab + sym->st_name, m, &src, m);
+			if (sdef) {
+				uint32_t saddr;
+
+				saddr = (uint32_t) symbol_get_addr(sdef, src);
+				memcpy(r_ptr, (const void *) saddr, sym_size);
+			} else {
+				printf("Source definition of '%s' not found.\n",
+				    str_tab + sym->st_name);
+			}
+
 			break;
 			
 		case R_386_RELATIVE:

=== modified file 'uspace/lib/c/generic/dlfcn.c'
--- uspace/lib/c/generic/dlfcn.c	2012-10-20 20:13:10 +0000
+++ uspace/lib/c/generic/dlfcn.c	2016-04-10 19:58:13 +0000
@@ -80,7 +80,7 @@
 	module_t *sm;
 
 	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, &sm, NULL);
 	if (sd != NULL) {
 		return symbol_get_addr(sd, sm);
 	}

=== modified file 'uspace/lib/c/generic/rtld/symbol.c'
--- uspace/lib/c/generic/rtld/symbol.c	2012-04-02 15:52:07 +0000
+++ uspace/lib/c/generic/rtld/symbol.c	2016-04-11 09:09:39 +0000
@@ -112,8 +112,11 @@
  * @param start		Module in which to start the search..
  * @param mod		(output) Will be filled with a pointer to the module 
  *			that contains the symbol.
+ * @param avoid		Module to exclude from the symbol search or NULL.
  */
-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, module_t **mod,
+    module_t *avoid)
 {
 	module_t *m, *dm;
 	elf_symbol_t *sym, *s;
@@ -144,12 +147,14 @@
 		m = list_get_instance(list_first(&queue), module_t, queue_link);
 		list_remove(&m->queue_link);
 
-		s = def_find_in_module(name, m);
-		if (s != NULL) {
-			/* Symbol found */
-			sym = s;
-			*mod = m;
-			break;
+		if (m != avoid) {
+			s = def_find_in_module(name, m);
+			if (s != NULL) {
+				/* Symbol found */
+				sym = s;
+				*mod = m;
+				break;
+			}
 		}
 
 		/*
@@ -178,7 +183,7 @@
 }
 
 
-/** 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,
  * origin is searched first. Otherwise, or if the symbol hasn't been found,
@@ -189,12 +194,15 @@
  * @param origin	Module in which the dependency originates.
  * @param mod		(output) Will be filled with a pointer to the module 
  *			that contains the symbol.
+ * @param avoid		Module to exclude from the symbol search or NULL.
  */
-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, module_t **mod,
+    module_t *avoid)
 {
 	elf_symbol_t *s;
 
-	if (origin->dyn.symbolic) {
+	if ((origin != avoid) && origin->dyn.symbolic) {
 		/* 
 		 * Origin module has a DT_SYMBOLIC flag.
 		 * Try this module first
@@ -211,10 +219,10 @@
 
 	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, mod, avoid);
 	} else {
 		/* Program is static -- start with @a origin as root. */
-		return symbol_bfs_find(name, origin, mod);
+		return symbol_bfs_find(name, origin, mod, avoid);
 	}
 }
 

=== modified file 'uspace/lib/c/include/rtld/symbol.h'
--- uspace/lib/c/include/rtld/symbol.h	2012-04-02 15:52:07 +0000
+++ uspace/lib/c/include/rtld/symbol.h	2016-04-11 09:10:29 +0000
@@ -38,8 +38,10 @@
 #include <elf/elf.h>
 #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);
+elf_symbol_t *symbol_bfs_find(const char *name, module_t *start, module_t **mod,
+    module_t *avoid);
+elf_symbol_t *symbol_def_find(const char *name, module_t *origin, module_t **mod,
+    module_t *avoid);
 void *symbol_get_addr(elf_symbol_t *sym, module_t *m);
 
 #endif

