Merge "Change stdatomic.h check from defined(_USING_LIBCXX) to __has_include(<atomic>)"
diff --git a/libc/Android.bp b/libc/Android.bp
index 21ac02e..52a7aca 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1710,6 +1710,19 @@
     cmd: "$(location :bionic-generate-version-script) x86_64 $(in) $(out)",
 }
 
+// Makes bionic_tls.h available for art to use in its implementation of Thread::Current().
+cc_library_headers {
+    name: "bionic_libc_private_headers",
+    visibility: [
+        "//art:__subpackages__",
+    ],
+    host_supported: true,
+    export_include_dirs: [
+        "private",
+    ],
+    sdk_version: "current",
+}
+
 // libc_headers for libasync_safe and libpropertyinfoparser
 cc_library_headers {
     name: "libc_headers",
diff --git a/libc/bionic/grp_pwd.cpp b/libc/bionic/grp_pwd.cpp
index d37fadd..6f8c07e 100644
--- a/libc/bionic/grp_pwd.cpp
+++ b/libc/bionic/grp_pwd.cpp
@@ -50,8 +50,21 @@
 #include "generated_android_ids.h"
 #include "grp_pwd_file.h"
 
-static PasswdFile vendor_passwd("/vendor/etc/passwd", "vendor_");
-static GroupFile vendor_group("/vendor/etc/group", "vendor_");
+static PasswdFile passwd_files[] = {
+  { "/system/etc/passwd", "system_" },
+  { "/vendor/etc/passwd", "vendor_" },
+  { "/odm/etc/passwd", "odm_" },
+  { "/product/etc/passwd", "product_" },
+  { "/system_ext/etc/passwd", "system_ext_" },
+};
+
+static GroupFile group_files[] = {
+  { "/system/etc/group", "system_" },
+  { "/vendor/etc/group", "vendor_" },
+  { "/odm/etc/group", "odm_" },
+  { "/product/etc/group", "product_" },
+  { "/system_ext/etc/group", "system_ext_" },
+};
 
 // POSIX seems to envisage an implementation where the <pwd.h> functions are
 // implemented by brute-force searching with getpwent(3), and the <grp.h>
@@ -91,7 +104,7 @@
                                        const android_id_info* iinfo) {
   snprintf(state->name_buffer_, sizeof(state->name_buffer_), "%s", iinfo->name);
   snprintf(state->dir_buffer_, sizeof(state->dir_buffer_), "/");
-  snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/system/bin/sh");
+  snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/bin/sh");
 
   passwd* pw = &state->passwd_;
   pw->pw_uid   = iinfo->aid;
@@ -421,17 +434,19 @@
 }
 
 static passwd* oem_id_to_passwd(uid_t uid, passwd_state_t* state) {
+  for (auto& passwd_file : passwd_files) {
+    if (passwd_file.FindById(uid, state)) {
+      return &state->passwd_;
+    }
+  }
+
   if (!is_oem_id(uid)) {
     return nullptr;
   }
 
-  if (vendor_passwd.FindById(uid, state)) {
-    return &state->passwd_;
-  }
-
   snprintf(state->name_buffer_, sizeof(state->name_buffer_), "oem_%u", uid);
   snprintf(state->dir_buffer_, sizeof(state->dir_buffer_), "/");
-  snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/vendor/bin/sh");
+  snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/bin/sh");
 
   passwd* pw = &state->passwd_;
   pw->pw_uid   = uid;
@@ -440,12 +455,14 @@
 }
 
 static group* oem_id_to_group(gid_t gid, group_state_t* state) {
-  if (!is_oem_id(gid)) {
-    return nullptr;
+  for (auto& group_file : group_files) {
+    if (group_file.FindById(gid, state)) {
+      return &state->group_;
+    }
   }
 
-  if (vendor_group.FindById(gid, state)) {
-    return &state->group_;
+  if (!is_oem_id(gid)) {
+    return nullptr;
   }
 
   snprintf(state->group_name_buffer_, sizeof(state->group_name_buffer_),
@@ -477,7 +494,7 @@
       snprintf(state->dir_buffer_, sizeof(state->dir_buffer_), "/data");
   }
 
-  snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/system/bin/sh");
+  snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/bin/sh");
 
   passwd* pw = &state->passwd_;
   pw->pw_uid   = uid;
@@ -523,8 +540,8 @@
     return android_iinfo_to_passwd(state, android_id_info);
   }
 
-  if (vendor_passwd.FindByName(login, state)) {
-    if (is_oem_id(state->passwd_.pw_uid)) {
+  for (auto& passwd_file : passwd_files) {
+    if (passwd_file.FindByName(login, state)) {
       return &state->passwd_;
     }
   }
@@ -633,6 +650,22 @@
         state->getpwent_idx++ - start + AID_OEM_RESERVED_2_START, state);
   }
 
+  start = end;
+  end += AID_SYSTEM_EXT_RESERVED_END - AID_SYSTEM_RESERVED_START + 1;
+
+  if (state->getpwent_idx < end) {
+    // No one calls this enough to worry about how inefficient the below is.
+    auto* oem_passwd =
+        oem_id_to_passwd(state->getpwent_idx++ - start + AID_SYSTEM_RESERVED_START, state);
+    while (oem_passwd == nullptr && state->getpwent_idx < end) {
+      oem_passwd =
+          oem_id_to_passwd(state->getpwent_idx++ - start + AID_SYSTEM_RESERVED_START, state);
+    }
+    if (oem_passwd != nullptr) {
+      return oem_passwd;
+    }
+  }
+
   state->getpwent_idx = get_next_app_id(state->getpwent_idx, false);
 
   if (state->getpwent_idx != -1) {
@@ -666,8 +699,8 @@
     return android_iinfo_to_group(state, android_id_info);
   }
 
-  if (vendor_group.FindByName(name, state)) {
-    if (is_oem_id(state->group_.gr_gid)) {
+  for (auto& group_file : group_files) {
+    if (group_file.FindByName(name, state)) {
       return &state->group_;
     }
   }
@@ -754,6 +787,22 @@
   }
 
   start = end;
+  end += AID_SYSTEM_EXT_RESERVED_END - AID_SYSTEM_RESERVED_START + 1;
+
+  if (state->getgrent_idx < end) {
+    // No one calls this enough to worry about how inefficient the below is.
+    init_group_state(state);
+    auto* oem_group =
+        oem_id_to_group(state->getgrent_idx++ - start + AID_SYSTEM_RESERVED_START, state);
+    while (oem_group == nullptr && state->getgrent_idx < end) {
+      oem_group = oem_id_to_group(state->getgrent_idx++ - start + AID_SYSTEM_RESERVED_START, state);
+    }
+    if (oem_group != nullptr) {
+      return oem_group;
+    }
+  }
+
+  start = end;
   end += AID_USER_OFFSET - AID_APP_START; // Do not expose higher groups
 
   state->getgrent_idx = get_next_app_id(state->getgrent_idx, true);
diff --git a/libc/bionic/grp_pwd_file.cpp b/libc/bionic/grp_pwd_file.cpp
index 201c9d0..e13604e 100644
--- a/libc/bionic/grp_pwd_file.cpp
+++ b/libc/bionic/grp_pwd_file.cpp
@@ -270,8 +270,8 @@
 
   while (line_beginning < end) {
     line_beginning = ParseLine(line_beginning, end, line->fields, line->kNumFields);
-    // To comply with Treble, users/groups from the vendor partition need to be prefixed with
-    // vendor_.
+    // To comply with Treble, users/groups from each partition need to be prefixed with
+    // the partition name.
     if (required_prefix_ != nullptr) {
       if (strncmp(line->fields[0], required_prefix_, strlen(required_prefix_)) != 0) {
         char name[kGrpPwdBufferSize];
diff --git a/libc/malloc_debug/Android.bp b/libc/malloc_debug/Android.bp
index aae16f1..d6b8531 100644
--- a/libc/malloc_debug/Android.bp
+++ b/libc/malloc_debug/Android.bp
@@ -16,7 +16,6 @@
     whole_static_libs: [
         "libbase",
         "libasync_safe",
-        "libdemangle",
     ],
 
     include_dirs: ["bionic/libc"],
@@ -66,7 +65,6 @@
     static_libs: [
         "libasync_safe",
         "libbase",
-        "libdemangle",
         "libc_malloc_debug_backtrace",
     ],
 
@@ -122,7 +120,6 @@
 
     static_libs: [
         "libc_malloc_debug",
-        "libdemangle",
         "libtinyxml2",
     ],
 
diff --git a/libc/malloc_debug/PointerData.cpp b/libc/malloc_debug/PointerData.cpp
index 617d128..ec7e42d 100644
--- a/libc/malloc_debug/PointerData.cpp
+++ b/libc/malloc_debug/PointerData.cpp
@@ -43,7 +43,6 @@
 
 #include <android-base/stringprintf.h>
 #include <android-base/thread_annotations.h>
-#include <demangle.h>
 #include <private/bionic_macros.h>
 
 #include "Config.h"
@@ -54,6 +53,8 @@
 #include "malloc_debug.h"
 #include "UnwindBacktrace.h"
 
+extern "C" char* __cxa_demangle(const char*, char*, size_t*, int*);
+
 std::atomic_uint8_t PointerData::backtrace_enabled_;
 std::atomic_bool PointerData::backtrace_dump_;
 
@@ -596,7 +597,16 @@
         if (frame.function_name.empty()) {
           fprintf(fp, " \"\" 0}");
         } else {
-          fprintf(fp, " \"%s\" %" PRIx64 "}", demangle(frame.function_name.c_str()).c_str(), frame.function_offset);
+          char* demangled_name = __cxa_demangle(frame.function_name.c_str(), nullptr, nullptr,
+                                                nullptr);
+          const char* name;
+          if (demangled_name != nullptr) {
+            name = demangled_name;
+          } else {
+            name = frame.function_name.c_str();
+          }
+          fprintf(fp, " \"%s\" %" PRIx64 "}", name, frame.function_offset);
+          free(demangled_name);
         }
       }
       fprintf(fp, "\n");
diff --git a/libc/malloc_debug/UnwindBacktrace.cpp b/libc/malloc_debug/UnwindBacktrace.cpp
index ddafc73..92fb3fa 100644
--- a/libc/malloc_debug/UnwindBacktrace.cpp
+++ b/libc/malloc_debug/UnwindBacktrace.cpp
@@ -36,7 +36,6 @@
 #include <vector>
 
 #include <android-base/stringprintf.h>
-#include <demangle.h>
 #include <unwindstack/LocalUnwinder.h>
 #include <unwindstack/MapInfo.h>
 
@@ -49,6 +48,8 @@
 #define PAD_PTR "08" PRIx64
 #endif
 
+extern "C" char* __cxa_demangle(const char*, char*, size_t*, int*);
+
 static pthread_once_t g_setup_once = PTHREAD_ONCE_INIT;
 
 static unwindstack::LocalUnwinder* g_unwinder;
@@ -100,7 +101,14 @@
     }
 
     if (!info->function_name.empty()) {
-      line += " (" + demangle(info->function_name.c_str());
+      line += " (";
+      char* demangled_name = __cxa_demangle(info->function_name.c_str(), nullptr, nullptr, nullptr);
+      if (demangled_name != nullptr) {
+        line += demangled_name;
+        free(demangled_name);
+      } else {
+        line += info->function_name;
+      }
       if (info->function_offset != 0) {
         line += "+" + std::to_string(info->function_offset);
       }
diff --git a/libc/malloc_debug/backtrace.cpp b/libc/malloc_debug/backtrace.cpp
index 0e3a53f..ab5c505 100644
--- a/libc/malloc_debug/backtrace.cpp
+++ b/libc/malloc_debug/backtrace.cpp
@@ -36,8 +36,6 @@
 #include <unistd.h>
 #include <unwind.h>
 
-#include <demangle.h>
-
 #include "MapData.h"
 #include "backtrace.h"
 #include "debug_log.h"
@@ -164,10 +162,18 @@
 
     char buf[1024];
     if (symbol != nullptr) {
+      char* demangled_name = __cxa_demangle(symbol, nullptr, nullptr, nullptr);
+      const char* name;
+      if (demangled_name != nullptr) {
+        name = demangled_name;
+      } else {
+        name = symbol;
+      }
       async_safe_format_buffer(buf, sizeof(buf),
                                "          #%02zd  pc %" PAD_PTR "  %s%s (%s+%" PRIuPTR ")\n",
-                               frame_num, rel_pc, soname, offset_buf, demangle(symbol).c_str(),
+                               frame_num, rel_pc, soname, offset_buf, name,
                                frames[frame_num] - offset);
+      free(demangled_name);
     } else {
       async_safe_format_buffer(buf, sizeof(buf), "          #%02zd  pc %" PAD_PTR "  %s%s\n",
                                frame_num, rel_pc, soname, offset_buf);
diff --git a/libc/symbol_ordering b/libc/symbol_ordering
index c04692b..679d461 100644
--- a/libc/symbol_ordering
+++ b/libc/symbol_ordering
@@ -176,8 +176,6 @@
 __sym_ntop.unname
 __sym_ntos.unname
 _ZL10gFunctions
-_ZL12vendor_group
-_ZL13vendor_passwd
 freelist
 __p_option.nbuf
 __p_time.nbuf
diff --git a/tests/grp_pwd_test.cpp b/tests/grp_pwd_test.cpp
index 5b6eed8..6b49e29 100644
--- a/tests/grp_pwd_test.cpp
+++ b/tests/grp_pwd_test.cpp
@@ -75,11 +75,7 @@
     EXPECT_STREQ("/", pwd->pw_dir);
   }
 
-  if (uid_type == TYPE_VENDOR) {
-    EXPECT_STREQ("/vendor/bin/sh", pwd->pw_shell);
-  } else {
-    EXPECT_STREQ("/system/bin/sh", pwd->pw_shell);
-  }
+  EXPECT_STREQ("/bin/sh", pwd->pw_shell);
 }
 
 static void check_getpwuid(const char* username, uid_t uid, uid_type_t uid_type,
@@ -382,7 +378,7 @@
 
 #if defined(__BIONIC__)
 template <typename T>
-static void expect_ids(const T& ids, bool is_group) {
+static void expect_ids(T ids, bool is_group) {
   std::set<typename T::key_type> expected_ids;
   // Ensure that all android_ids are iterated through.
   for (size_t n = 0; n < android_id_count; ++n) {
@@ -415,6 +411,14 @@
     return;
   }
 
+  auto allow_range = [&ids](uid_t start, uid_t end) {
+    for (size_t n = start; n <= end; ++n) {
+      ids.erase(n);
+    }
+  };
+
+  allow_range(AID_SYSTEM_RESERVED_START, AID_SYSTEM_EXT_RESERVED_END);
+
   // Ensure that no other ids were returned.
   auto return_differences = [&ids, &expected_ids] {
     std::vector<typename T::key_type> missing_from_ids;