metadata.stderr.exp metadata.stdout.exp metadata.vgtest \
threadederrno.stderr.exp threadederrno.stdout.exp \
threadederrno.vgtest \
+ vgtest_ume.stderr.exp vgtest_ume.vgtest \
writev.stderr.exp writev.vgtest \
zeropage.stderr.exp zeropage.stderr.exp2 zeropage.vgtest
badloop badrw brk brk2 buflen_check \
clientperm custom_alloc \
doublefree error_counts errs1 exitprog execve execve2 \
- fpeflags fprw fwrite inits inline \
+ fpeflags fprw fwrite hello inits inline \
malloc1 malloc2 malloc3 manuel1 manuel2 manuel3 \
memalign_test memalign2 memcmptest mempool mmaptest \
nanoleak new_nothrow \
null_socket overlap pushfpopf \
realloc1 realloc2 realloc3 sigaltstack signal2 supp1 supp2 suppfree \
trivialleak tronical weirdioctl \
- mismatches new_override metadata threadederrno writev zeropage
+ mismatches new_override metadata threadederrno \
+ vgtest_ume \
+ writev zeropage
+
AM_CPPFLAGS = -I$(top_srcdir)/include
AM_CFLAGS = $(WERROR) -Winline -Wall -Wshadow -g
metadata_SOURCES = metadata.c
threadederrno_SOURCES = threadederrno.c
threadederrno_LDADD = -lpthread
+vgtest_ume_SOURCES = vgtest_ume.c
writev_SOURCES = writev.c
zeropage_SOURCES = zeropage.c
new_nothrow_SOURCES = new_nothrow.cpp
new_override_SOURCES = new_override.cpp
+# Valgrind unit self-tests
+hello_SOURCES = hello.c
+hello_LDFLAGS = -Wl,-defsym,kickstart_base=0x50000000 \
+ -Wl,-T,../../coregrind/${VG_ARCH}/stage2.lds
+vgtest_ume_LDADD = ../../coregrind/ume.o \
+ ../../coregrind/ume_entry.o \
+ ../../coregrind/jmp_with_stack.o
+
# must be built with these flags -- bug only occurred with them
fpeflags.o: CFLAGS += -march=i686
--- /dev/null
+#define ELFSZ 32
+
+// This file is a unit self-test for ume.c, ume_entry.c, jmp_with_stack.c
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <elf.h>
+#include "../../coregrind/ume.h"
+
+#define STKSZ (64*1024)
+
+static void push_auxv(unsigned char **espp, int type, void *val)
+{
+ struct ume_auxv *auxp = (struct ume_auxv *)*espp;
+ auxp--;
+ auxp->a_type = type;
+ auxp->u.a_ptr = val;
+ *espp = (unsigned char *)auxp;
+}
+
+static void push(unsigned char **espp, void *v)
+{
+ void **vp = *(void ***)espp;
+ *--vp = v;
+ *espp = (unsigned char *)vp;
+}
+
+
+int main(void)
+{
+ struct exeinfo info;
+ int err;
+ unsigned char* newstack;
+ unsigned char *esp;
+
+ info.argv = NULL;
+ info.exe_base = 0x50000000;
+ info.exe_end = 0x50ffffff;
+ info.map_base = 0x51000000;
+
+ err = do_exec("hello", &info);
+ assert(0 == err);
+
+// printf("info.exe_base=%p exe_end=%p\n",
+// (void*)info.exe_base, (void*)info.exe_end);
+
+ newstack = malloc(STKSZ);
+ assert(0 != newstack);
+
+ esp = newstack+STKSZ;
+
+ /*
+ Set the new executable's stack up like the kernel would after
+ exec.
+
+ These are being pushed onto the stack, towards decreasing
+ addresses.
+ */
+ push_auxv(&esp, AT_NULL, 0); // auxv terminator
+ push_auxv(&esp, AT_ENTRY, (void *)info.entry); // entrypoint of the main executable */
+ push_auxv(&esp, AT_BASE, (void *)info.interp_base); // base address of ld-linux.so
+ push_auxv(&esp, AT_PHDR, (void *)info.phdr); // where the ELF PHDRs are mapped
+ push_auxv(&esp, AT_PHNUM, (void*)info.phnum); // and how many of them
+
+ push(&esp, 0); /* no env */
+ push(&esp, 0); /* no argv */
+ push(&esp, 0); /* argc=0 */
+
+// fprintf(stderr, "ume_go: %p %p\n", (void*)info.init_eip, (void*)esp);
+
+ jmp_with_stack(info.init_eip, (addr_t)esp);
+
+ return 0;
+}