Browse Source

Blackfin FD-PIC patch 2/6.
Add the necessary changes in ld.so and libdl to deal with targets that
prepend an underscore to symbol names.

Bernd Schmidt 16 years ago
parent
commit
3d2a55e7a3
3 changed files with 33 additions and 6 deletions
  1. 6 0
      ldso/include/dl-defs.h
  2. 3 3
      ldso/ldso/ldso.c
  3. 24 3
      ldso/libdl/libdl.c

+ 6 - 0
ldso/include/dl-defs.h

@@ -175,4 +175,10 @@ typedef struct {
 # define DL_MALLOC_ALIGN (__WORDSIZE / 8)
 #endif
 
+#ifdef __UCLIBC_NO_UNDERSCORES__
+#define __C_SYMBOL_PREFIX__ ""
+#else
+#define __C_SYMBOL_PREFIX__ "_"
+#endif
+
 #endif	/* _LD_DEFS_H */

+ 3 - 3
ldso/ldso/ldso.c

@@ -773,7 +773,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
 	 * ld.so.1, so we have to look up each symbol individually.
 	 */
 
-	_dl_envp = (unsigned long *) (intptr_t) _dl_find_hash("__environ", _dl_symbol_tables, NULL, 0);
+	_dl_envp = (unsigned long *) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "__environ", _dl_symbol_tables, NULL, 0);
 	if (_dl_envp)
 		*_dl_envp = (unsigned long) envp;
 
@@ -828,8 +828,8 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
 	}
 
 	/* Find the real malloc function and make ldso functions use that from now on */
-	 _dl_malloc_function = (void* (*)(size_t)) (intptr_t) _dl_find_hash("malloc",
-			 _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT);
+	_dl_malloc_function = (void* (*)(size_t)) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "malloc",
+			_dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT);
 
 	/* Notify the debugger that all objects are now mapped in.  */
 	_dl_debug_addr->r_state = RT_CONSISTENT;

+ 24 - 3
ldso/libdl/libdl.c

@@ -446,7 +446,22 @@ void *dlsym(void *vhandle, const char *name)
 	ElfW(Addr) from;
 	struct dyn_elf *rpnt;
 	void *ret;
-
+	/* Nastiness to support underscore prefixes.  */
+	char tmp_buf[80];
+#ifndef __UCLIBC_NO_UNDERSCORES__
+	char *name2 = tmp_buf;
+	size_t nlen = strlen (name) + 1;
+	if (nlen + 1 > sizeof (tmp_buf))
+	    name2 = malloc (nlen + 1);
+	if (name2 == 0) {
+	    _dl_error_number = LD_ERROR_MMAP_FAILED;
+	    return 0;
+	}
+	name2[0] = '_';
+	memcpy (name2 + 1, name, nlen);
+#else
+	const char *name2 = name;
+#endif
 	handle = (struct dyn_elf *) vhandle;
 
 	/* First of all verify that we have a real handle
@@ -460,7 +475,8 @@ void *dlsym(void *vhandle, const char *name)
 				break;
 		if (!rpnt) {
 			_dl_error_number = LD_BAD_HANDLE;
-			return NULL;
+			ret = NULL;
+			goto out;
 		}
 	} else if (handle == RTLD_NEXT) {
 		/*
@@ -484,13 +500,18 @@ void *dlsym(void *vhandle, const char *name)
 	tpnt = NULL;
 	if (handle == _dl_symbol_tables)
 	   tpnt = handle->dyn; /* Only search RTLD_GLOBAL objs if global object */
-	ret = _dl_find_hash((char*)name, handle, tpnt, 0);
+	ret = _dl_find_hash(name2, handle, tpnt, 0);
 
 	/*
 	 * Nothing found.
 	 */
 	if (!ret)
 		_dl_error_number = LD_NO_SYMBOL;
+out:
+#ifndef __UCLIBC_NO_UNDERSCORES__
+	if (name2 != tmp_buf)
+		free (name2);
+#endif
 	return ret;
 }