diff --git a/libc/libc.cc b/libc/libc.cc
index 6599d84a8795f342492d179d2160a6c11c499eca..d3711e5bdac16a3d26db482041838dcb4d7aac40 100644
--- a/libc/libc.cc
+++ b/libc/libc.cc
@@ -7,6 +7,7 @@
 #include <limits>
 #include <sys/resource.h>
 #include <pwd.h>
+#include <sys/utsname.h>
 
 int libc_error(int err)
 {
@@ -59,6 +60,11 @@ char* getenv(const char* name)
     return NULL;
 }
 
+int putenv(char* string)
+{
+    return 0; // no environent
+}
+
 template <typename N>
 N strtoN(const char* s, char** e, int base)
 {
@@ -179,3 +185,29 @@ int getpwuid_r(uid_t uid, struct passwd *pwd,
     *result = pwd;
     return 0;
 }
+
+struct passwd* getpwuid(uid_t uid)
+{
+    static struct passwd ret;
+    static char buf[300];
+    struct passwd *p;
+    int e;
+
+    e = getpwuid_r(uid, &ret, buf, sizeof(buf), &p);
+    if (e == 0) {
+        return &ret;
+    } else {
+        return libc_error_ptr<passwd>(e);
+    }
+}
+
+int uname(struct utsname* u)
+{
+    // lie, to avoid confusing the payload.
+    strcpy(u->sysname, "Linux");
+    strcpy(u->nodename, "home");
+    strcpy(u->release, "3.7");
+    strcpy(u->version, "#1 SMP");
+    strcpy(u->machine, "x86_64");
+    return 0;
+}
diff --git a/libc/pthread.cc b/libc/pthread.cc
index 88a1d933b6d185f22f51a89a550044674305d285..2dbd146186a7d861211a659dd7f1940705c3a5ec 100644
--- a/libc/pthread.cc
+++ b/libc/pthread.cc
@@ -15,6 +15,7 @@ namespace pthread_private {
     const unsigned tsd_nkeys = 100;
 
     __thread void* tsd[tsd_nkeys];
+    pthread_t current_pthread;
 
     mutex tsd_key_mutex;
     std::vector<bool> tsd_used_keys(tsd_nkeys);
@@ -49,6 +50,7 @@ namespace pthread_private {
     pthread::pthread(void *(*start)(void *arg), void *arg, sigset_t sigset)
         : _stack(allocate_stack())
         , _thread([=] {
+                current_pthread = to_libc();
                 sigprocmask(SIG_SETMASK, &sigset, nullptr);
                 _retval = start(arg);
             }, _stack)
@@ -57,7 +59,7 @@ namespace pthread_private {
 
     sched::thread::stack_info pthread::allocate_stack()
     {
-        size_t size = 64*1024;
+        size_t size = 1024*1024;
         return { new char[size], size };
     }
 
@@ -123,7 +125,7 @@ int pthread_setspecific(pthread_key_t key, const void* value)
 
 pthread_t pthread_self()
 {
-    return reinterpret_cast<pthread_t>(sched::thread::current());
+    return current_pthread;
 }
 
 mutex* from_libc(pthread_mutex_t* m)
diff --git a/loader.cc b/loader.cc
index cb4b667dfbdce205d006687bb5793bbb360bddc6..19cba81cfb230c15fd10e2268892d20d55827e9e 100644
--- a/loader.cc
+++ b/loader.cc
@@ -264,8 +264,9 @@ void start_jvm(elf::program& prog)
     debug(fmt("JNI_CreateJavaVM() returned %1%") % ret);
 }
 
-void main_thread(elf::program& prog)
+void* do_main_thread(void* pprog)
 {
+    auto& prog = *static_cast<elf::program*>(pprog);
     test_threads();
     test_clock_events();
 
@@ -293,4 +294,13 @@ void main_thread(elf::program& prog)
 
     while (true)
 	;
+    return nullptr;
+}
+
+void main_thread(elf::program& prog)
+{
+    pthread_t pthread;
+    // run the payload in a pthread, so pthread_self() etc. work
+    pthread_create(&pthread, nullptr, do_main_thread, &prog);
+    sched::thread::wait_until([] { return false; });
 }