diff options
author | Eric Andersen <andersen@codepoet.org> | 2002-12-12 22:22:03 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2002-12-12 22:22:03 +0000 |
commit | 26ac73a7de1ba347046f7d23400439e682e79ed5 (patch) | |
tree | e5d8c117f4610cb987bbed7a62f4b6e00a247be7 /ldso/ldso/readelflib1.c | |
parent | 774a6c5c91078aed0e926cc6817aa10a2f5d2281 (diff) |
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
Diffstat (limited to 'ldso/ldso/readelflib1.c')
-rw-r--r-- | ldso/ldso/readelflib1.c | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/ldso/ldso/readelflib1.c b/ldso/ldso/readelflib1.c index ea6650968..62c84679c 100644 --- a/ldso/ldso/readelflib1.c +++ b/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 mylibname[2050]; struct elf_resolve *tpnt1; + + if (path_list==NULL) + return NULL; /* We need a writable copy of this string */ path = _dl_strdup(path_list); @@ -666,3 +669,124 @@ int _dl_copy_fixups(struct dyn_elf *rpnt) #endif 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; +} + + |