summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ldso/ldso/dl-elf.c131
-rw-r--r--ldso/ldso/readelflib1.c131
2 files changed, 262 insertions, 0 deletions
diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c
index cef44965e..5a1c89230 100644
--- a/ldso/ldso/dl-elf.c
+++ b/ldso/ldso/dl-elf.c
@@ -793,3 +793,134 @@ int _dl_fixup(struct dyn_elf *rpnt, int flag)
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;
+ static char *buf;
+
+ buf = _dl_mmap((void *) 0, PAGE_SIZE, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+ if (_dl_mmap_check_error(buf)) {
+ _dl_write(fd, "mmap of a spare page failed!\n", 29);
+ _dl_exit(20);
+ }
+
+ start = ptr = buf;
+
+ if (!fmt)
+ return;
+
+ if (_dl_strlen(fmt) >= (PAGE_SIZE - 1)) {
+ _dl_write(fd, "overflow\n", 11);
+ _dl_exit(20);
+ }
+
+ _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;
+ }
+ }
+ _dl_munmap(buf, PAGE_SIZE);
+ 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;
+}
+
+void *(*_dl_malloc_function) (size_t size) = NULL;
+void *_dl_malloc(int size)
+{
+ void *retval;
+
+#if 0
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+ _dl_dprintf(2, "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 > PAGE_SIZE) {
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+ _dl_dprintf(2, "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 = (unsigned char *) (((unsigned long) _dl_malloc_addr + 3) & ~(3));
+ return retval;
+}
+
+
+
diff --git a/ldso/ldso/readelflib1.c b/ldso/ldso/readelflib1.c
index cef44965e..5a1c89230 100644
--- a/ldso/ldso/readelflib1.c
+++ b/ldso/ldso/readelflib1.c
@@ -793,3 +793,134 @@ int _dl_fixup(struct dyn_elf *rpnt, int flag)
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;
+ static char *buf;
+
+ buf = _dl_mmap((void *) 0, PAGE_SIZE, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+ if (_dl_mmap_check_error(buf)) {
+ _dl_write(fd, "mmap of a spare page failed!\n", 29);
+ _dl_exit(20);
+ }
+
+ start = ptr = buf;
+
+ if (!fmt)
+ return;
+
+ if (_dl_strlen(fmt) >= (PAGE_SIZE - 1)) {
+ _dl_write(fd, "overflow\n", 11);
+ _dl_exit(20);
+ }
+
+ _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;
+ }
+ }
+ _dl_munmap(buf, PAGE_SIZE);
+ 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;
+}
+
+void *(*_dl_malloc_function) (size_t size) = NULL;
+void *_dl_malloc(int size)
+{
+ void *retval;
+
+#if 0
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+ _dl_dprintf(2, "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 > PAGE_SIZE) {
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+ _dl_dprintf(2, "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 = (unsigned char *) (((unsigned long) _dl_malloc_addr + 3) & ~(3));
+ return retval;
+}
+
+
+