diff --git a/libc/bionic/stubs.cpp b/libc/bionic/stubs.cpp
new file mode 100644
index 0000000..652e522
--- /dev/null
+++ b/libc/bionic/stubs.cpp
@@ -0,0 +1,461 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <ctype.h>
+#include <errno.h>
+#include <grp.h>
+#include <mntent.h>
+#include <netdb.h>
+#include <private/android_filesystem_config.h>
+#include <private/logd.h>
+#include <pthread.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+// Thread-specific state for the non-reentrant functions.
+static pthread_once_t stubs_once = PTHREAD_ONCE_INIT;
+static pthread_key_t stubs_key;
+struct stubs_state_t {
+  passwd passwd_;
+  group group_;
+  char* group_members_[2];
+  char app_name_buffer_[32];
+  char group_name_buffer_[32];
+  char dir_buffer_[32];
+  char sh_buffer_[32];
+};
+
+static int do_getpw_r(int by_name, const char* name, uid_t uid,
+                      passwd* dst, char* buf, size_t byte_count,
+                      passwd** result) {
+  // getpwnam_r and getpwuid_r don't modify errno, but library calls we
+  // make might.
+  int old_errno = errno;
+  *result = NULL;
+
+  // Our implementation of getpwnam(3) and getpwuid(3) use thread-local
+  // storage, so we can call them as long as we copy everything out
+  // before returning.
+  const passwd* src = by_name ? getpwnam(name) : getpwuid(uid); // NOLINT: see above.
+
+  // POSIX allows failure to find a match to be considered a non-error.
+  // Reporting success (0) but with *result NULL is glibc's behavior.
+  if (src == NULL) {
+    int rc = (errno == ENOENT) ? 0 : errno;
+    errno = old_errno;
+    return rc;
+  }
+
+  // Work out where our strings will go in 'buf', and whether we've got
+  // enough space.
+  size_t required_byte_count = 0;
+  dst->pw_name = buf;
+  required_byte_count += strlen(src->pw_name) + 1;
+  dst->pw_dir = buf + required_byte_count;
+  required_byte_count += strlen(src->pw_dir) + 1;
+  dst->pw_shell = buf + required_byte_count;
+  required_byte_count += strlen(src->pw_shell) + 1;
+  if (byte_count < required_byte_count) {
+    errno = old_errno;
+    return ERANGE;
+  }
+
+  // Copy the strings.
+  snprintf(buf, byte_count, "%s%c%s%c%s",
+           src->pw_name, 0, src->pw_dir, 0, src->pw_shell);
+
+  // pw_passwd is non-POSIX and unused (always NULL) in bionic.
+  // pw_gecos is non-POSIX and missing in bionic.
+  dst->pw_passwd = NULL;
+
+  // Copy the integral fields.
+  dst->pw_gid = src->pw_gid;
+  dst->pw_uid = src->pw_uid;
+
+  *result = dst;
+  errno = old_errno;
+  return 0;
+}
+
+int getpwnam_r(const char* name, passwd* pwd,
+               char* buf, size_t byte_count, passwd** result) {
+  return do_getpw_r(1, name, -1, pwd, buf, byte_count, result);
+}
+
+int getpwuid_r(uid_t uid, passwd* pwd,
+               char* buf, size_t byte_count, passwd** result) {
+  return do_getpw_r(0, NULL, uid, pwd, buf, byte_count, result);
+}
+
+static stubs_state_t* stubs_state_alloc() {
+  stubs_state_t*  s = reinterpret_cast<stubs_state_t*>(calloc(1, sizeof(*s)));
+  if (s != NULL) {
+    s->group_.gr_mem = s->group_members_;
+  }
+  return s;
+}
+
+static void stubs_state_free(void* ptr) {
+  stubs_state_t* state = reinterpret_cast<stubs_state_t*>(ptr);
+  free(state);
+}
+
+static void __stubs_key_init() {
+  pthread_key_create(&stubs_key, stubs_state_free);
+}
+
+static stubs_state_t* __stubs_state() {
+  pthread_once(&stubs_once, __stubs_key_init);
+  stubs_state_t* s =
+      reinterpret_cast<stubs_state_t*>(pthread_getspecific(stubs_key));
+  if (s == NULL) {
+    s = stubs_state_alloc();
+    if (s == NULL) {
+      errno = ENOMEM;  // Just in case.
+    } else {
+      if (pthread_setspecific(stubs_key, s) != 0) {
+        stubs_state_free(s);
+        errno = ENOMEM;
+        s = NULL;
+      }
+    }
+  }
+  return s;
+}
+
+static passwd* android_iinfo_to_passwd(stubs_state_t* state,
+                                       const android_id_info* iinfo) {
+  snprintf(state->dir_buffer_, sizeof(state->dir_buffer_), "/");
+  snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/system/bin/sh");
+
+  passwd* pw = &state->passwd_;
+  pw->pw_name  = (char*) iinfo->name;
+  pw->pw_uid   = iinfo->aid;
+  pw->pw_gid   = iinfo->aid;
+  pw->pw_dir   = state->dir_buffer_;
+  pw->pw_shell = state->sh_buffer_;
+  return pw;
+}
+
+static group* android_iinfo_to_group(group* gr,
+                                     const android_id_info* iinfo) {
+  gr->gr_name   = (char*) iinfo->name;
+  gr->gr_gid    = iinfo->aid;
+  gr->gr_mem[0] = gr->gr_name;
+  gr->gr_mem[1] = NULL;
+  return gr;
+}
+
+static passwd* android_id_to_passwd(stubs_state_t* state, unsigned id) {
+  for (size_t n = 0; n < android_id_count; ++n) {
+    if (android_ids[n].aid == id) {
+      return android_iinfo_to_passwd(state, android_ids + n);
+    }
+  }
+  return NULL;
+}
+
+static passwd* android_name_to_passwd(stubs_state_t* state, const char* name) {
+  for (size_t n = 0; n < android_id_count; ++n) {
+    if (!strcmp(android_ids[n].name, name)) {
+      return android_iinfo_to_passwd(state, android_ids + n);
+    }
+  }
+  return NULL;
+}
+
+static group* android_id_to_group(group* gr, unsigned id) {
+  for (size_t n = 0; n < android_id_count; ++n) {
+    if (android_ids[n].aid == id) {
+      return android_iinfo_to_group(gr, android_ids + n);
+    }
+  }
+  return NULL;
+}
+
+static group* android_name_to_group(group* gr, const char* name) {
+  for (size_t n = 0; n < android_id_count; ++n) {
+    if (!strcmp(android_ids[n].name, name)) {
+      return android_iinfo_to_group(gr, android_ids + n);
+    }
+  }
+  return NULL;
+}
+
+// Translate a user/group name to the corresponding user/group id.
+// u0_a1234 -> 0 * AID_USER + AID_APP + 1234
+// u2_i1000 -> 2 * AID_USER + AID_ISOLATED_START + 1000
+// u1_system -> 1 * AID_USER + android_ids['system']
+// returns 0 and sets errno to ENOENT in case of error
+static unsigned app_id_from_name(const char* name) {
+  if (name[0] != 'u' || !isdigit(name[1])) {
+    errno = ENOENT;
+    return 0;
+  }
+
+  char* end;
+  unsigned long userid = strtoul(name+1, &end, 10);
+  if (end[0] != '_' || end[1] == 0) {
+    errno = ENOENT;
+    return 0;
+  }
+
+  unsigned long appid = 0;
+  if (end[1] == 'a' && isdigit(end[2])) {
+    // end will point to \0 if the strtoul below succeeds.
+    appid = strtoul(end+2, &end, 10) + AID_APP;
+  } else if (end[1] == 'i' && isdigit(end[2])) {
+    // end will point to \0 if the strtoul below succeeds.
+    appid = strtoul(end+2, &end, 10) + AID_ISOLATED_START;
+  } else {
+    for (size_t n = 0; n < android_id_count; n++) {
+      if (!strcmp(android_ids[n].name, end + 1)) {
+        appid = android_ids[n].aid;
+        // Move the end pointer to the null terminator.
+        end += strlen(android_ids[n].name) + 1;
+      }
+    }
+  }
+
+  // Check that the entire string was consumed by one of the 3 cases above.
+  if (end[0] != 0) {
+    errno = ENOENT;
+    return 0;
+  }
+
+  // Check that user id won't overflow.
+  if (userid > 1000) {
+    errno = ENOENT;
+    return 0;
+  }
+
+  // Check that app id is within range.
+  if (appid >= AID_USER) {
+    errno = ENOENT;
+    return 0;
+  }
+
+  return (unsigned)(appid + userid*AID_USER);
+}
+
+static void print_app_uid_name(uid_t  uid, char* buffer, int bufferlen) {
+  uid_t appid = uid % AID_USER;
+  uid_t userid = uid / AID_USER;
+
+  if (appid < AID_ISOLATED_START) {
+    if (appid < AID_APP) {
+      for (size_t n = 0; n < android_id_count; n++) {
+        if (android_ids[n].aid == appid) {
+          snprintf(buffer, bufferlen, "u%u_%s", userid, android_ids[n].name);
+          return;
+        }
+      }
+    }
+    snprintf(buffer, bufferlen, "u%u_a%u", userid, appid - AID_APP);
+  } else {
+    snprintf(buffer, bufferlen, "u%u_i%u", userid, appid - AID_ISOLATED_START);
+  }
+}
+
+// Translate a uid into the corresponding name.
+// 0 to AID_APP-1                   -> "system", "radio", etc.
+// AID_APP to AID_ISOLATED_START-1  -> u0_a1234
+// AID_ISOLATED_START to AID_USER-1 -> u0_i1234
+// AID_USER+                        -> u1_radio, u1_a1234, u2_i1234, etc.
+// returns a passwd structure (sets errno to ENOENT on failure).
+static passwd* app_id_to_passwd(uid_t uid, stubs_state_t* state) {
+  passwd* pw = &state->passwd_;
+
+  if (uid < AID_APP) {
+    errno = ENOENT;
+    return NULL;
+  }
+
+  print_app_uid_name(uid, state->app_name_buffer_,
+                     sizeof(state->app_name_buffer_));
+
+  snprintf(state->dir_buffer_, sizeof(state->dir_buffer_), "/data");
+  snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/system/bin/sh");
+
+  pw->pw_name  = state->app_name_buffer_;
+  pw->pw_dir   = state->dir_buffer_;
+  pw->pw_shell = state->sh_buffer_;
+  pw->pw_uid   = uid;
+  pw->pw_gid   = uid;
+
+  return pw;
+}
+
+// Translate a gid into the corresponding app_<gid>
+// group structure (sets errno to ENOENT on failure).
+static group* app_id_to_group(gid_t gid, stubs_state_t* state) {
+  if (gid < AID_APP) {
+    errno = ENOENT;
+    return NULL;
+  }
+
+  print_app_uid_name(gid, state->group_name_buffer_,
+                     sizeof(state->group_name_buffer_));
+
+  group* gr = &state->group_;
+  gr->gr_name   = state->group_name_buffer_;
+  gr->gr_gid    = gid;
+  gr->gr_mem[0] = gr->gr_name;
+  gr->gr_mem[1] = NULL;
+  return gr;
+}
+
+
+passwd* getpwuid(uid_t uid) { // NOLINT: implementing bad function.
+  stubs_state_t* state = __stubs_state();
+  if (state == NULL) {
+    return NULL;
+  }
+
+  passwd* pw = android_id_to_passwd(state, uid);
+  if (pw != NULL) {
+    return pw;
+  }
+  return app_id_to_passwd(uid, state);
+}
+
+passwd* getpwnam(const char* login) { // NOLINT: implementing bad function.
+  stubs_state_t* state = __stubs_state();
+  if (state == NULL) {
+    return NULL;
+  }
+
+  passwd* pw = android_name_to_passwd(state, login);
+  if (pw != NULL) {
+    return pw;
+  }
+  return app_id_to_passwd(app_id_from_name(login), state);
+}
+
+int getgrouplist(const char* user, gid_t group, gid_t* groups, int* ngroups) {
+    if (*ngroups < 1) {
+        *ngroups = 1;
+        return -1;
+    }
+    groups[0] = group;
+    return (*ngroups = 1);
+}
+
+char* getlogin() { // NOLINT: implementing bad function.
+  passwd *pw = getpwuid(getuid()); // NOLINT: implementing bad function in terms of bad function.
+  return (pw != NULL) ? pw->pw_name : NULL;
+}
+
+group* getgrgid(gid_t gid) { // NOLINT: implementing bad function.
+  stubs_state_t* state = __stubs_state();
+  if (state == NULL) {
+    return NULL;
+  }
+
+  group* gr = android_id_to_group(&state->group_, gid);
+  if (gr != NULL) {
+    return gr;
+  }
+
+  return app_id_to_group(gid, state);
+}
+
+group* getgrnam(const char* name) { // NOLINT: implementing bad function.
+  stubs_state_t* state = __stubs_state();
+  if (state == NULL) {
+    return NULL;
+  }
+
+  if (android_name_to_group(&state->group_, name) != 0) {
+    return &state->group_;
+  }
+
+  return app_id_to_group(app_id_from_name(name), state);
+}
+
+static void unimplemented_stub(const char* function) {
+  const char* fmt = "%s(3) is not implemented on Android\n";
+  __libc_android_log_print(ANDROID_LOG_WARN, "libc", fmt, function);
+  fprintf(stderr, fmt, function);
+}
+
+#define UNIMPLEMENTED unimplemented_stub(__PRETTY_FUNCTION__)
+
+netent* getnetbyname(const char* name) {
+  UNIMPLEMENTED;
+  return NULL;
+}
+
+void endpwent() {
+  UNIMPLEMENTED;
+}
+
+mntent* getmntent(FILE* f) {
+  UNIMPLEMENTED;
+  return NULL;
+}
+
+char* ttyname(int fd) { // NOLINT: implementing bad function.
+  UNIMPLEMENTED;
+  return NULL;
+}
+
+int ttyname_r(int fd, char* buf, size_t buflen) {
+  UNIMPLEMENTED;
+  return -ERANGE;
+}
+
+netent* getnetbyaddr(uint32_t net, int type) {
+  UNIMPLEMENTED;
+  return NULL;
+}
+
+protoent* getprotobyname(const char* name) {
+  UNIMPLEMENTED;
+  return NULL;
+}
+
+protoent* getprotobynumber(int proto) {
+  UNIMPLEMENTED;
+  return NULL;
+}
+
+char* getusershell() {
+  UNIMPLEMENTED;
+  return NULL;
+}
+
+void setusershell() {
+  UNIMPLEMENTED;
+}
+
+void endusershell() {
+  UNIMPLEMENTED;
+}
