diff options
Diffstat (limited to 'ldso/ldso/dl-elf.c')
-rw-r--r-- | ldso/ldso/dl-elf.c | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c index ea6650968..62c84679c 100644 --- a/ldso/ldso/dl-elf.c +++ b/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 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; +} + + |