Browse Source

Rework things such that staticly linked applications can use
dlopen and have it be successful. This required moving some
things out of ldso.c into readelflib1.c, and directly including
hash.c and readelflib1.c into dlib.c when building the static
version of the library.
-Erik

Eric Andersen 23 years ago
parent
commit
26ac73a7de
8 changed files with 337 additions and 144 deletions
  1. 124 0
      ldso/ldso/dl-elf.c
  2. 1 1
      ldso/ldso/dl-hash.c
  3. 1 1
      ldso/ldso/hash.c
  4. 0 119
      ldso/ldso/ldso.c
  5. 124 0
      ldso/ldso/readelflib1.c
  6. 21 11
      ldso/libdl/Makefile
  7. 33 6
      ldso/libdl/dlib.c
  8. 33 6
      ldso/libdl/libdl.c

+ 124 - 0
ldso/ldso/dl-elf.c

@@ -128,6 +128,9 @@ search_for_named_library(char *name, int secure, const char *path_list,
 	char *path, *path_n;
 	char *path, *path_n;
 	char mylibname[2050];
 	char mylibname[2050];
 	struct elf_resolve *tpnt1;
 	struct elf_resolve *tpnt1;
+	
+	if (path_list==NULL)
+		return NULL;
 
 
 	/* We need a writable copy of this string */
 	/* We need a writable copy of this string */
 	path = _dl_strdup(path_list);
 	path = _dl_strdup(path_list);
@@ -666,3 +669,124 @@ int _dl_copy_fixups(struct dyn_elf *rpnt)
 #endif    
 #endif    
 	return goof;
 	return goof;
 }
 }
+
+/* Minimal printf which handles only %s, %d, and %x */
+void _dl_dprintf(int fd, const char *fmt, ...)
+{
+	int num;
+	va_list args;
+	char *start, *ptr, *string;
+	char buf[2048];
+
+	start = ptr = buf;
+
+	if (!fmt)
+		return;
+
+	if (_dl_strlen(fmt) >= (sizeof(buf) - 1))
+		_dl_write(fd, "(overflow)\n", 10);
+
+	_dl_strcpy(buf, fmt);
+	va_start(args, fmt);
+
+	while (start) {
+		while (*ptr != '%' && *ptr) {
+			ptr++;
+		}
+
+		if (*ptr == '%') {
+			*ptr++ = '\0';
+			_dl_write(fd, start, _dl_strlen(start));
+
+			switch (*ptr++) {
+			case 's':
+				string = va_arg(args, char *);
+
+				if (!string)
+					_dl_write(fd, "(null)", 6);
+				else
+					_dl_write(fd, string, _dl_strlen(string));
+				break;
+
+			case 'i':
+			case 'd':
+			{
+				char tmp[22];
+				num = va_arg(args, int);
+
+				string = _dl_simple_ltoa(tmp, num);
+				_dl_write(fd, string, _dl_strlen(string));
+				break;
+			}
+			case 'x':
+			case 'X':
+			{
+				char tmp[22];
+				num = va_arg(args, int);
+
+				string = _dl_simple_ltoahex(tmp, num);
+				_dl_write(fd, string, _dl_strlen(string));
+				break;
+			}
+			default:
+				_dl_write(fd, "(null)", 6);
+				break;
+			}
+
+			start = ptr;
+		} else {
+			_dl_write(fd, start, _dl_strlen(start));
+			start = NULL;
+		}
+	}
+	return;
+}
+
+void *(*_dl_malloc_function) (size_t size) = NULL;
+char *_dl_strdup(const char *string)
+{
+	char *retval;
+	int len;
+
+	len = _dl_strlen(string);
+	retval = _dl_malloc(len + 1);
+	_dl_strcpy(retval, string);
+	return retval;
+}
+
+void *_dl_malloc(int size)
+{
+	void *retval;
+
+#if 0
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+	_dl_dprintf(_dl_debug_file, "malloc: request for %d bytes\n", size);
+#endif
+#endif
+
+	if (_dl_malloc_function)
+		return (*_dl_malloc_function) (size);
+
+	if (_dl_malloc_addr - _dl_mmap_zero + size > 4096) {
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+		_dl_dprintf(_dl_debug_file, "malloc: mmapping more memory\n");
+#endif
+		_dl_mmap_zero = _dl_malloc_addr = _dl_mmap((void *) 0, size, 
+				PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+		if (_dl_mmap_check_error(_dl_mmap_zero)) {
+			_dl_dprintf(2, "%s: mmap of a spare page failed!\n", _dl_progname);
+			_dl_exit(20);
+		}
+	}
+	retval = _dl_malloc_addr;
+	_dl_malloc_addr += size;
+
+	/*
+	 * Align memory to 4 byte boundary.  Some platforms require this, others
+	 * simply get better performance.
+	 */
+	_dl_malloc_addr = (char *) (((unsigned long) _dl_malloc_addr + 3) & ~(3));
+	return retval;
+}
+
+

+ 1 - 1
ldso/ldso/dl-hash.c

@@ -185,7 +185,7 @@ char *_dl_find_hash(const char *name, struct dyn_elf *rpnt1,
 	   that any shared library data symbols referenced in the executable
 	   that any shared library data symbols referenced in the executable
 	   will be seen at the same address by the executable, shared libraries
 	   will be seen at the same address by the executable, shared libraries
 	   and dynamically loaded code. -Rob Ryan (robr@cmu.edu) */
 	   and dynamically loaded code. -Rob Ryan (robr@cmu.edu) */
-	if (!caller_type && rpnt1) {
+	if (_dl_symbol_tables && !caller_type && rpnt1) {
 		first = (*_dl_symbol_tables);
 		first = (*_dl_symbol_tables);
 		first.next = rpnt1;
 		first.next = rpnt1;
 		rpnt1 = (&first);
 		rpnt1 = (&first);

+ 1 - 1
ldso/ldso/hash.c

@@ -185,7 +185,7 @@ char *_dl_find_hash(const char *name, struct dyn_elf *rpnt1,
 	   that any shared library data symbols referenced in the executable
 	   that any shared library data symbols referenced in the executable
 	   will be seen at the same address by the executable, shared libraries
 	   will be seen at the same address by the executable, shared libraries
 	   and dynamically loaded code. -Rob Ryan (robr@cmu.edu) */
 	   and dynamically loaded code. -Rob Ryan (robr@cmu.edu) */
-	if (!caller_type && rpnt1) {
+	if (_dl_symbol_tables && !caller_type && rpnt1) {
 		first = (*_dl_symbol_tables);
 		first = (*_dl_symbol_tables);
 		first.next = rpnt1;
 		first.next = rpnt1;
 		rpnt1 = (&first);
 		rpnt1 = (&first);

+ 0 - 119
ldso/ldso/ldso.c

@@ -147,7 +147,6 @@ static char *_dl_malloc_addr, *_dl_mmap_zero;
 static char *_dl_trace_loaded_objects = 0;
 static char *_dl_trace_loaded_objects = 0;
 static int (*_dl_elf_main) (int, char **, char **);
 static int (*_dl_elf_main) (int, char **, char **);
 static int (*_dl_elf_init) (void);
 static int (*_dl_elf_init) (void);
-void *(*_dl_malloc_function) (int size) = NULL;
 struct r_debug *_dl_debug_addr = NULL;
 struct r_debug *_dl_debug_addr = NULL;
 unsigned long *_dl_brkp;
 unsigned long *_dl_brkp;
 unsigned long *_dl_envp;
 unsigned long *_dl_envp;
@@ -1339,41 +1338,6 @@ int _dl_fixup(struct elf_resolve *tpnt)
 	return goof;
 	return goof;
 }
 }
 
 
-void *_dl_malloc(int size)
-{
-	void *retval;
-
-#if 0
-#ifdef __SUPPORT_LD_DEBUG_EARLY__
-	_dl_dprintf(_dl_debug_file, "malloc: request for %d bytes\n", size);
-#endif
-#endif
-
-	if (_dl_malloc_function)
-		return (*_dl_malloc_function) (size);
-
-	if (_dl_malloc_addr - _dl_mmap_zero + size > 4096) {
-#ifdef __SUPPORT_LD_DEBUG_EARLY__
-		_dl_dprintf(_dl_debug_file, "malloc: mmapping more memory\n");
-#endif
-		_dl_mmap_zero = _dl_malloc_addr = _dl_mmap((void *) 0, size, 
-				PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
-		if (_dl_mmap_check_error(_dl_mmap_zero)) {
-			_dl_dprintf(2, "%s: mmap of a spare page failed!\n", _dl_progname);
-			_dl_exit(20);
-		}
-	}
-	retval = _dl_malloc_addr;
-	_dl_malloc_addr += size;
-
-	/*
-	 * Align memory to 4 byte boundary.  Some platforms require this, others
-	 * simply get better performance.
-	 */
-	_dl_malloc_addr = (char *) (((unsigned long) _dl_malloc_addr + 3) & ~(3));
-	return retval;
-}
-
 char *_dl_getenv(const char *symbol, char **envp)
 char *_dl_getenv(const char *symbol, char **envp)
 {
 {
 	char *pnt;
 	char *pnt;
@@ -1407,88 +1371,5 @@ void _dl_unsetenv(const char *symbol, char **envp)
 	return;
 	return;
 }
 }
 
 
-char *_dl_strdup(const char *string)
-{
-	char *retval;
-	int len;
-
-	len = _dl_strlen(string);
-	retval = _dl_malloc(len + 1);
-	_dl_strcpy(retval, string);
-	return retval;
-}
-
-/* Minimal printf which handles only %s, %d, and %x */
-void _dl_dprintf(int fd, const char *fmt, ...)
-{
-	int num;
-	va_list args;
-	char *start, *ptr, *string;
-	char buf[2048];
-
-	start = ptr = buf;
-
-	if (!fmt)
-		return;
-
-	if (_dl_strlen(fmt) >= (sizeof(buf) - 1))
-		_dl_write(fd, "(overflow)\n", 10);
-
-	_dl_strcpy(buf, fmt);
-	va_start(args, fmt);
-
-	while (start) {
-		while (*ptr != '%' && *ptr) {
-			ptr++;
-		}
-
-		if (*ptr == '%') {
-			*ptr++ = '\0';
-			_dl_write(fd, start, _dl_strlen(start));
-
-			switch (*ptr++) {
-			case 's':
-				string = va_arg(args, char *);
-
-				if (!string)
-					_dl_write(fd, "(null)", 6);
-				else
-					_dl_write(fd, string, _dl_strlen(string));
-				break;
-
-			case 'i':
-			case 'd':
-			{
-				char tmp[22];
-				num = va_arg(args, int);
-
-				string = _dl_simple_ltoa(tmp, num);
-				_dl_write(fd, string, _dl_strlen(string));
-				break;
-			}
-			case 'x':
-			case 'X':
-			{
-				char tmp[22];
-				num = va_arg(args, int);
-
-				string = _dl_simple_ltoahex(tmp, num);
-				_dl_write(fd, string, _dl_strlen(string));
-				break;
-			}
-			default:
-				_dl_write(fd, "(null)", 6);
-				break;
-			}
-
-			start = ptr;
-		} else {
-			_dl_write(fd, start, _dl_strlen(start));
-			start = NULL;
-		}
-	}
-	return;
-}
-
 #include "hash.c"
 #include "hash.c"
 #include "readelflib1.c"
 #include "readelflib1.c"

+ 124 - 0
ldso/ldso/readelflib1.c

@@ -128,6 +128,9 @@ search_for_named_library(char *name, int secure, const char *path_list,
 	char *path, *path_n;
 	char *path, *path_n;
 	char mylibname[2050];
 	char mylibname[2050];
 	struct elf_resolve *tpnt1;
 	struct elf_resolve *tpnt1;
+	
+	if (path_list==NULL)
+		return NULL;
 
 
 	/* We need a writable copy of this string */
 	/* We need a writable copy of this string */
 	path = _dl_strdup(path_list);
 	path = _dl_strdup(path_list);
@@ -666,3 +669,124 @@ int _dl_copy_fixups(struct dyn_elf *rpnt)
 #endif    
 #endif    
 	return goof;
 	return goof;
 }
 }
+
+/* Minimal printf which handles only %s, %d, and %x */
+void _dl_dprintf(int fd, const char *fmt, ...)
+{
+	int num;
+	va_list args;
+	char *start, *ptr, *string;
+	char buf[2048];
+
+	start = ptr = buf;
+
+	if (!fmt)
+		return;
+
+	if (_dl_strlen(fmt) >= (sizeof(buf) - 1))
+		_dl_write(fd, "(overflow)\n", 10);
+
+	_dl_strcpy(buf, fmt);
+	va_start(args, fmt);
+
+	while (start) {
+		while (*ptr != '%' && *ptr) {
+			ptr++;
+		}
+
+		if (*ptr == '%') {
+			*ptr++ = '\0';
+			_dl_write(fd, start, _dl_strlen(start));
+
+			switch (*ptr++) {
+			case 's':
+				string = va_arg(args, char *);
+
+				if (!string)
+					_dl_write(fd, "(null)", 6);
+				else
+					_dl_write(fd, string, _dl_strlen(string));
+				break;
+
+			case 'i':
+			case 'd':
+			{
+				char tmp[22];
+				num = va_arg(args, int);
+
+				string = _dl_simple_ltoa(tmp, num);
+				_dl_write(fd, string, _dl_strlen(string));
+				break;
+			}
+			case 'x':
+			case 'X':
+			{
+				char tmp[22];
+				num = va_arg(args, int);
+
+				string = _dl_simple_ltoahex(tmp, num);
+				_dl_write(fd, string, _dl_strlen(string));
+				break;
+			}
+			default:
+				_dl_write(fd, "(null)", 6);
+				break;
+			}
+
+			start = ptr;
+		} else {
+			_dl_write(fd, start, _dl_strlen(start));
+			start = NULL;
+		}
+	}
+	return;
+}
+
+void *(*_dl_malloc_function) (size_t size) = NULL;
+char *_dl_strdup(const char *string)
+{
+	char *retval;
+	int len;
+
+	len = _dl_strlen(string);
+	retval = _dl_malloc(len + 1);
+	_dl_strcpy(retval, string);
+	return retval;
+}
+
+void *_dl_malloc(int size)
+{
+	void *retval;
+
+#if 0
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+	_dl_dprintf(_dl_debug_file, "malloc: request for %d bytes\n", size);
+#endif
+#endif
+
+	if (_dl_malloc_function)
+		return (*_dl_malloc_function) (size);
+
+	if (_dl_malloc_addr - _dl_mmap_zero + size > 4096) {
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+		_dl_dprintf(_dl_debug_file, "malloc: mmapping more memory\n");
+#endif
+		_dl_mmap_zero = _dl_malloc_addr = _dl_mmap((void *) 0, size, 
+				PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+		if (_dl_mmap_check_error(_dl_mmap_zero)) {
+			_dl_dprintf(2, "%s: mmap of a spare page failed!\n", _dl_progname);
+			_dl_exit(20);
+		}
+	}
+	retval = _dl_malloc_addr;
+	_dl_malloc_addr += size;
+
+	/*
+	 * Align memory to 4 byte boundary.  Some platforms require this, others
+	 * simply get better performance.
+	 */
+	_dl_malloc_addr = (char *) (((unsigned long) _dl_malloc_addr + 3) & ~(3));
+	return retval;
+}
+
+

+ 21 - 11
ldso/libdl/Makefile

@@ -16,42 +16,52 @@
 # You should have received a copy of the GNU Library General Public License
 # You should have received a copy of the GNU Library General Public License
 # along with this program; if not, write to the Free Software Foundation, Inc.,
 # along with this program; if not, write to the Free Software Foundation, Inc.,
 # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# Derived in part from the Linux-8086 C library, the GNU C Library, and several
-# other sundry sources.  Files within this library are copyright by their
-# respective copyright holders.
 
 
 
 
 TOPDIR=../../
 TOPDIR=../../
 include $(TOPDIR)Rules.mak
 include $(TOPDIR)Rules.mak
 
 
+XXFLAGS+=-DUCLIBC_TARGET_PREFIX=\"$(TARGET_PREFIX)\" \
+	-DUCLIBC_DEVEL_PREFIX=\"$(DEVEL_PREFIX)\" \
+	-DUCLIBC_BUILD_DIR=\"$(shell cd $(TOPDIR) && pwd)\"
+ifeq ($(strip $(SUPPORT_LD_DEBUG)),y)
+XXFLAGS+=-D__SUPPORT_LD_DEBUG__
+endif
+
 LIBDL=libdl.a
 LIBDL=libdl.a
+LIBDL_PIC=libdl_pic.a
 LIBDL_SHARED=libdl.so
 LIBDL_SHARED=libdl.so
 LIBDL_SHARED_FULLNAME=libdl-$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBLEVEL).so
 LIBDL_SHARED_FULLNAME=libdl-$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBLEVEL).so
 
 
-CSRC= dlib.c
-OBJS=$(patsubst %.c,%.o, $(CSRC))
+CSRC=dlib.c
+OBJS=dlib.o
+PIC_OBJS=dlib_pic.o
 
 
 all: $(OBJS) $(LIBDL) shared
 all: $(OBJS) $(LIBDL) shared
 
 
 $(LIBDL): ar-target
 $(LIBDL): ar-target
 
 
-ar-target: $(OBJS)
-	$(AR) $(ARFLAGS) $(LIBDL) $(OBJS)
+ar-target: $(OBJS) $(PIC_OBJS)
+	$(AR) $(ARFLAGS) $(LIBDL) ../ldso/$(TARGET_ARCH)/resolve.o $(OBJS)
+	$(AR) $(ARFLAGS) $(LIBDL_PIC) $(PIC_OBJS)
 	install -d $(TOPDIR)lib
 	install -d $(TOPDIR)lib
 	rm -f $(TOPDIR)lib/$(LIBDL)
 	rm -f $(TOPDIR)lib/$(LIBDL)
 	install -m 644 $(LIBDL) $(TOPDIR)lib
 	install -m 644 $(LIBDL) $(TOPDIR)lib
 
 
 
 
-$(OBJS): %.o : %.c
-	$(CC) -I../ldso -I../ldso/$(TARGET_ARCH) $(CFLAGS) -c $< -o $@
+dlib.o: dlib.c
+	$(CC) -I../ldso -I../ldso/$(TARGET_ARCH) $(CFLAGS_NOPIC) $(XXFLAGS) -c dlib.c -o dlib.o
+	$(STRIPTOOL) -x -R .note -R .comment $*.o
+
+dlib_pic.o: dlib.c
+	$(CC) -I../ldso -I../ldso/$(TARGET_ARCH) $(CFLAGS) -c dlib.c -o dlib_pic.o
 	$(STRIPTOOL) -x -R .note -R .comment $*.o
 	$(STRIPTOOL) -x -R .note -R .comment $*.o
 
 
 $(OBJ): Makefile
 $(OBJ): Makefile
 
 
 shared:
 shared:
 	$(LD) $(LDFLAGS) -soname=$(LIBDL_SHARED).$(MAJOR_VERSION) \
 	$(LD) $(LDFLAGS) -soname=$(LIBDL_SHARED).$(MAJOR_VERSION) \
-		-o $(LIBDL_SHARED_FULLNAME) --whole-archive $(LIBDL) \
+		-o $(LIBDL_SHARED_FULLNAME) --whole-archive $(LIBDL_PIC) \
 		--no-whole-archive $(TOPDIR)/libc/misc/internals/interp.o \
 		--no-whole-archive $(TOPDIR)/libc/misc/internals/interp.o \
 		-L$(TOPDIR)/lib -lc;
 		-L$(TOPDIR)/lib -lc;
 	install -d $(TOPDIR)lib
 	install -d $(TOPDIR)lib

+ 33 - 6
ldso/libdl/dlib.c

@@ -12,7 +12,6 @@
 #include "ld_hash.h"
 #include "ld_hash.h"
 #include "ld_string.h"
 #include "ld_string.h"
 
 
-extern int _dl_error_number;
 extern struct r_debug *_dl_debug_addr;
 extern struct r_debug *_dl_debug_addr;
 
 
 extern void *(*_dl_malloc_function) (size_t size);
 extern void *(*_dl_malloc_function) (size_t size);
@@ -26,6 +25,7 @@ void *dlsym(void *, const char *) __attribute__ ((__weak__, __alias__ ("_dlsym")
 int dlclose(void *) __attribute__ ((__weak__, __alias__ ("_dlclose")));
 int dlclose(void *) __attribute__ ((__weak__, __alias__ ("_dlclose")));
 int dladdr(void *, Dl_info *) __attribute__ ((__weak__, __alias__ ("_dladdr")));
 int dladdr(void *, Dl_info *) __attribute__ ((__weak__, __alias__ ("_dladdr")));
 
 
+#ifdef __PIC__
 /* This is a real hack.  We need access to the dynamic linker, but we
 /* This is a real hack.  We need access to the dynamic linker, but we
 also need to make it possible to link against this library without any
 also need to make it possible to link against this library without any
 unresolved externals.  We provide these weak symbols to make the link
 unresolved externals.  We provide these weak symbols to make the link
@@ -60,8 +60,27 @@ extern struct dyn_elf *_dl_symbol_tables __attribute__ ((__weak__, __alias__ ("f
 extern struct dyn_elf *_dl_handles __attribute__ ((__weak__, __alias__ ("foobar1")));
 extern struct dyn_elf *_dl_handles __attribute__ ((__weak__, __alias__ ("foobar1")));
 extern struct elf_resolve *_dl_loaded_modules __attribute__ ((__weak__, __alias__ ("foobar1")));
 extern struct elf_resolve *_dl_loaded_modules __attribute__ ((__weak__, __alias__ ("foobar1")));
 extern struct r_debug *_dl_debug_addr __attribute__ ((__weak__, __alias__ ("foobar1")));
 extern struct r_debug *_dl_debug_addr __attribute__ ((__weak__, __alias__ ("foobar1")));
-extern int _dl_error_number __attribute__ ((__weak__, __alias__ ("foobar1")));
+extern unsigned long _dl_error_number __attribute__ ((__weak__, __alias__ ("foobar1")));
 extern void *(*_dl_malloc_function)(size_t) __attribute__ ((__weak__, __alias__ ("foobar1")));
 extern void *(*_dl_malloc_function)(size_t) __attribute__ ((__weak__, __alias__ ("foobar1")));
+#else
+#ifdef __SUPPORT_LD_DEBUG__
+static char *_dl_debug  = 0;
+static char *_dl_debug_symbols = 0;
+static char *_dl_debug_move    = 0;
+static char *_dl_debug_reloc   = 0;
+static char *_dl_debug_detail  = 0;
+static char *_dl_debug_nofixups  = 0;
+static char *_dl_debug_bindings  = 0;
+static int   _dl_debug_file = 2;
+#endif
+char *_dl_library_path = 0;
+char *_dl_ldsopath = 0;
+struct r_debug *_dl_debug_addr = NULL;
+static char *_dl_malloc_addr, *_dl_mmap_zero;
+#include "../ldso/ldso.h"               /* Pull in the name of ld.so */
+#include "../ldso/hash.c"
+#include "../ldso/readelflib1.c"
+#endif
 
 
 static const char *dl_error_names[] = {
 static const char *dl_error_names[] = {
 	"",
 	"",
@@ -109,7 +128,9 @@ void *_dlopen(const char *libname, int flag)
 	static int dl_init = 0;
 	static int dl_init = 0;
 	char *from;
 	char *from;
 	void (*dl_brk) (void);
 	void (*dl_brk) (void);
+#ifdef __PIC__
 	int (*dl_elf_init) (void);
 	int (*dl_elf_init) (void);
+#endif
 
 
 	from = __builtin_return_address(0);
 	from = __builtin_return_address(0);
 
 
@@ -213,15 +234,18 @@ void *_dlopen(const char *libname, int flag)
 		goto oops;
 		goto oops;
 	}
 	}
 
 
-	dl_brk = (void (*)(void)) _dl_debug_addr->r_brk;
-	if (dl_brk != NULL) {
+	if (_dl_debug_addr) {
+	    dl_brk = (void (*)(void)) _dl_debug_addr->r_brk;
+	    if (dl_brk != NULL) {
 		_dl_debug_addr->r_state = RT_ADD;
 		_dl_debug_addr->r_state = RT_ADD;
 		(*dl_brk) ();
 		(*dl_brk) ();
 
 
 		_dl_debug_addr->r_state = RT_CONSISTENT;
 		_dl_debug_addr->r_state = RT_CONSISTENT;
 		(*dl_brk) ();
 		(*dl_brk) ();
+	    }
 	}
 	}
 
 
+#ifdef __PIC__
 	for (rpnt = dyn_chain; rpnt; rpnt = rpnt->next) {
 	for (rpnt = dyn_chain; rpnt; rpnt = rpnt->next) {
 		tpnt = rpnt->dyn;
 		tpnt = rpnt->dyn;
 		/* Apparently crt1 for the application is responsible for handling this.
 		/* Apparently crt1 for the application is responsible for handling this.
@@ -244,6 +268,7 @@ void *_dlopen(const char *libname, int flag)
 		}
 		}
 
 
 	}
 	}
+#endif
 
 
 #ifdef USE_CACHE
 #ifdef USE_CACHE
 	_dl_unmap_cache();
 	_dl_unmap_cache();
@@ -476,13 +501,15 @@ static int do_dlclose(void *vhandle, int need_fini)
 	}
 	}
 
 
 
 
-	dl_brk = (void (*)(void)) _dl_debug_addr->r_brk;
-	if (dl_brk != NULL) {
+	if (_dl_debug_addr) {
+	    dl_brk = (void (*)(void)) _dl_debug_addr->r_brk;
+	    if (dl_brk != NULL) {
 		_dl_debug_addr->r_state = RT_DELETE;
 		_dl_debug_addr->r_state = RT_DELETE;
 		(*dl_brk) ();
 		(*dl_brk) ();
 
 
 		_dl_debug_addr->r_state = RT_CONSISTENT;
 		_dl_debug_addr->r_state = RT_CONSISTENT;
 		(*dl_brk) ();
 		(*dl_brk) ();
+	    }
 	}
 	}
 
 
 	return 0;
 	return 0;

+ 33 - 6
ldso/libdl/libdl.c

@@ -12,7 +12,6 @@
 #include "ld_hash.h"
 #include "ld_hash.h"
 #include "ld_string.h"
 #include "ld_string.h"
 
 
-extern int _dl_error_number;
 extern struct r_debug *_dl_debug_addr;
 extern struct r_debug *_dl_debug_addr;
 
 
 extern void *(*_dl_malloc_function) (size_t size);
 extern void *(*_dl_malloc_function) (size_t size);
@@ -26,6 +25,7 @@ void *dlsym(void *, const char *) __attribute__ ((__weak__, __alias__ ("_dlsym")
 int dlclose(void *) __attribute__ ((__weak__, __alias__ ("_dlclose")));
 int dlclose(void *) __attribute__ ((__weak__, __alias__ ("_dlclose")));
 int dladdr(void *, Dl_info *) __attribute__ ((__weak__, __alias__ ("_dladdr")));
 int dladdr(void *, Dl_info *) __attribute__ ((__weak__, __alias__ ("_dladdr")));
 
 
+#ifdef __PIC__
 /* This is a real hack.  We need access to the dynamic linker, but we
 /* This is a real hack.  We need access to the dynamic linker, but we
 also need to make it possible to link against this library without any
 also need to make it possible to link against this library without any
 unresolved externals.  We provide these weak symbols to make the link
 unresolved externals.  We provide these weak symbols to make the link
@@ -60,8 +60,27 @@ extern struct dyn_elf *_dl_symbol_tables __attribute__ ((__weak__, __alias__ ("f
 extern struct dyn_elf *_dl_handles __attribute__ ((__weak__, __alias__ ("foobar1")));
 extern struct dyn_elf *_dl_handles __attribute__ ((__weak__, __alias__ ("foobar1")));
 extern struct elf_resolve *_dl_loaded_modules __attribute__ ((__weak__, __alias__ ("foobar1")));
 extern struct elf_resolve *_dl_loaded_modules __attribute__ ((__weak__, __alias__ ("foobar1")));
 extern struct r_debug *_dl_debug_addr __attribute__ ((__weak__, __alias__ ("foobar1")));
 extern struct r_debug *_dl_debug_addr __attribute__ ((__weak__, __alias__ ("foobar1")));
-extern int _dl_error_number __attribute__ ((__weak__, __alias__ ("foobar1")));
+extern unsigned long _dl_error_number __attribute__ ((__weak__, __alias__ ("foobar1")));
 extern void *(*_dl_malloc_function)(size_t) __attribute__ ((__weak__, __alias__ ("foobar1")));
 extern void *(*_dl_malloc_function)(size_t) __attribute__ ((__weak__, __alias__ ("foobar1")));
+#else
+#ifdef __SUPPORT_LD_DEBUG__
+static char *_dl_debug  = 0;
+static char *_dl_debug_symbols = 0;
+static char *_dl_debug_move    = 0;
+static char *_dl_debug_reloc   = 0;
+static char *_dl_debug_detail  = 0;
+static char *_dl_debug_nofixups  = 0;
+static char *_dl_debug_bindings  = 0;
+static int   _dl_debug_file = 2;
+#endif
+char *_dl_library_path = 0;
+char *_dl_ldsopath = 0;
+struct r_debug *_dl_debug_addr = NULL;
+static char *_dl_malloc_addr, *_dl_mmap_zero;
+#include "../ldso/ldso.h"               /* Pull in the name of ld.so */
+#include "../ldso/hash.c"
+#include "../ldso/readelflib1.c"
+#endif
 
 
 static const char *dl_error_names[] = {
 static const char *dl_error_names[] = {
 	"",
 	"",
@@ -109,7 +128,9 @@ void *_dlopen(const char *libname, int flag)
 	static int dl_init = 0;
 	static int dl_init = 0;
 	char *from;
 	char *from;
 	void (*dl_brk) (void);
 	void (*dl_brk) (void);
+#ifdef __PIC__
 	int (*dl_elf_init) (void);
 	int (*dl_elf_init) (void);
+#endif
 
 
 	from = __builtin_return_address(0);
 	from = __builtin_return_address(0);
 
 
@@ -213,15 +234,18 @@ void *_dlopen(const char *libname, int flag)
 		goto oops;
 		goto oops;
 	}
 	}
 
 
-	dl_brk = (void (*)(void)) _dl_debug_addr->r_brk;
-	if (dl_brk != NULL) {
+	if (_dl_debug_addr) {
+	    dl_brk = (void (*)(void)) _dl_debug_addr->r_brk;
+	    if (dl_brk != NULL) {
 		_dl_debug_addr->r_state = RT_ADD;
 		_dl_debug_addr->r_state = RT_ADD;
 		(*dl_brk) ();
 		(*dl_brk) ();
 
 
 		_dl_debug_addr->r_state = RT_CONSISTENT;
 		_dl_debug_addr->r_state = RT_CONSISTENT;
 		(*dl_brk) ();
 		(*dl_brk) ();
+	    }
 	}
 	}
 
 
+#ifdef __PIC__
 	for (rpnt = dyn_chain; rpnt; rpnt = rpnt->next) {
 	for (rpnt = dyn_chain; rpnt; rpnt = rpnt->next) {
 		tpnt = rpnt->dyn;
 		tpnt = rpnt->dyn;
 		/* Apparently crt1 for the application is responsible for handling this.
 		/* Apparently crt1 for the application is responsible for handling this.
@@ -244,6 +268,7 @@ void *_dlopen(const char *libname, int flag)
 		}
 		}
 
 
 	}
 	}
+#endif
 
 
 #ifdef USE_CACHE
 #ifdef USE_CACHE
 	_dl_unmap_cache();
 	_dl_unmap_cache();
@@ -476,13 +501,15 @@ static int do_dlclose(void *vhandle, int need_fini)
 	}
 	}
 
 
 
 
-	dl_brk = (void (*)(void)) _dl_debug_addr->r_brk;
-	if (dl_brk != NULL) {
+	if (_dl_debug_addr) {
+	    dl_brk = (void (*)(void)) _dl_debug_addr->r_brk;
+	    if (dl_brk != NULL) {
 		_dl_debug_addr->r_state = RT_DELETE;
 		_dl_debug_addr->r_state = RT_DELETE;
 		(*dl_brk) ();
 		(*dl_brk) ();
 
 
 		_dl_debug_addr->r_state = RT_CONSISTENT;
 		_dl_debug_addr->r_state = RT_CONSISTENT;
 		(*dl_brk) ();
 		(*dl_brk) ();
+	    }
 	}
 	}
 
 
 	return 0;
 	return 0;