Merge "Rename # vndk tag to # llndk"
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 375207b..51d5755 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -22,6 +22,9 @@
       "name": "libpackagelistparser_test"
     },
     {
+      "name": "libcutils_test"
+    },
+    {
       "name": "libprocinfo_test"
     },
     {
diff --git a/adb/client/fastdeploy.cpp b/adb/client/fastdeploy.cpp
index bdc9e56..5fa0edb 100644
--- a/adb/client/fastdeploy.cpp
+++ b/adb/client/fastdeploy.cpp
@@ -101,17 +101,12 @@
 
 static void push_to_device(const void* data, size_t byte_count, const char* dst, bool sync) {
     std::vector<const char*> srcs;
-    {
-        TemporaryFile temp;
-        android::base::WriteFully(temp.fd, data, byte_count);
-        srcs.push_back(temp.path);
-
-        // On Windows, the file needs to be flushed before pushing to device.
-        // closing the file flushes its content, but we still need to remove it after push.
-        // FileDeleter does exactly that.
-        temp.DoNotRemove();
-    }
-    FileDeleter temp_deleter(srcs.back());
+    TemporaryFile tf;
+    android::base::WriteFully(tf.fd, data, byte_count);
+    srcs.push_back(tf.path);
+    // On Windows, the file needs to be flushed before pushing to device,
+    // but can't be removed until after the push.
+    unix_close(tf.release());
 
     if (!do_sync_push(srcs, dst, sync)) {
         error_exit("Failed to push fastdeploy agent to device.");
diff --git a/adb/fastdeploy/deployagent/test/com/android/fastdeploy/FastDeployTest.java b/adb/fastdeploy/deployagent/test/com/android/fastdeploy/FastDeployTest.java
index ef6ccae..4aa2f79 100644
--- a/adb/fastdeploy/deployagent/test/com/android/fastdeploy/FastDeployTest.java
+++ b/adb/fastdeploy/deployagent/test/com/android/fastdeploy/FastDeployTest.java
@@ -20,7 +20,9 @@
 import static org.junit.Assert.assertTrue;
 
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.ddmlib.Log.LogLevel;
 import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.log.LogUtil.CLog;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 
@@ -68,17 +70,19 @@
     }
 
     private boolean isAppInstalled(String packageName) throws DeviceNotAvailableException {
-        final String commandResult = getDevice().executeShellCommand("pm list packages");
+        final String result = getDevice().executeShellCommand("pm list packages");
+        CLog.logAndDisplay(LogLevel.INFO, result);
         final int prefixLength = "package:".length();
-        return Arrays.stream(commandResult.split("\\r?\\n"))
+        return Arrays.stream(result.split("\\r?\\n"))
                 .anyMatch(line -> line.substring(prefixLength).equals(packageName));
     }
 
     // Mostly copied from PkgInstallSignatureVerificationTest.java.
-    private String fastInstallPackage(String apkPath)
+    private void fastInstallPackage(String apkPath)
             throws IOException, DeviceNotAvailableException {
-        return getDevice().executeAdbCommand("install", "-t", "--fastdeploy", "--force-agent",
+        String result = getDevice().executeAdbCommand("install", "-t", "--fastdeploy", "--force-agent",
                 apkPath);
+        CLog.logAndDisplay(LogLevel.INFO, result);
     }
 }
 
diff --git a/base/README.md b/base/README.md
new file mode 100644
index 0000000..2ef5c10
--- /dev/null
+++ b/base/README.md
@@ -0,0 +1,42 @@
+# libbase
+
+## Who is this library for?
+
+This library is a collection of convenience functions to make common tasks
+easier and less error-prone.
+
+In this context, "error-prone" covers both "hard to do correctly" and
+"hard to do with good performance", but as a general purpose library,
+libbase's primary focus is on making it easier to do things easily and
+correctly when a compromise has to be made between "simplest API" on the
+one hand and "fastest implementation" on the other. Though obviously
+the ideal is to have both.
+
+## Should my routine be added?
+
+The intention is to cover the 80% use cases, not be all things to all users.
+
+If you have a routine that's really useful in your project,
+congratulations. But that doesn't mean it should be here rather than
+just in your project.
+
+The question for libbase is "should everyone be doing this?"/"does this
+make everyone's code cleaner/safer?". Historically we've considered the
+bar for inclusion to be "are there at least three *unrelated* projects
+that would be cleaned up by doing so".
+
+If your routine is actually something from a future C++ standard (that
+isn't yet in libc++), or it's widely used in another library, that helps
+show that there's precedent. Being able to say "so-and-so has used this
+API for n years" is a good way to reduce concerns about API choices.
+
+## Any other restrictions?
+
+Unlike most Android code, code in libbase has to build for Mac and
+Windows too.
+
+Code here is also expected to have good test coverage.
+
+By its nature, it's difficult to change libbase API. It's often best
+to start using your routine just in your project, and let it "graduate"
+after you're certain that the API is solid.
diff --git a/code_coverage/Android.mk b/code_coverage/Android.mk
new file mode 100644
index 0000000..80ab36b
--- /dev/null
+++ b/code_coverage/Android.mk
@@ -0,0 +1,37 @@
+# policies to allow processes inside minijail to dump code coverage information
+#
+
+LOCAL_PATH := $(call my-dir)
+
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := code_coverage.policy
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MULTILIB := both
+
+ifeq ($(TARGET_ARCH), $(filter $(TARGET_ARCH), arm arm64))
+LOCAL_MODULE_STEM_32 := code_coverage.arm.policy
+LOCAL_MODULE_STEM_64 := code_coverage.arm64.policy
+endif
+
+ifeq ($(TARGET_ARCH), $(filter $(TARGET_ARCH), x86 x86_64))
+LOCAL_MODULE_STEM_32 := code_coverage.x86.policy
+LOCAL_MODULE_STEM_64 := code_coverage.x86_64.policy
+endif
+
+# different files for different configurations
+ifeq ($(NATIVE_COVERAGE),true)
+LOCAL_SRC_FILES_arm := seccomp_policy/code_coverage.arm.policy
+LOCAL_SRC_FILES_arm64 := seccomp_policy/code_coverage.arm64.policy
+LOCAL_SRC_FILES_x86 := seccomp_policy/code_coverage.x86.policy
+LOCAL_SRC_FILES_x86_64 := seccomp_policy/code_coverage.x86_64.policy
+else
+LOCAL_SRC_FILES_arm := empty_policy/code_coverage.arm.policy
+LOCAL_SRC_FILES_arm64 := empty_policy/code_coverage.arm64.policy
+LOCAL_SRC_FILES_x86 := empty_policy/code_coverage.x86.policy
+LOCAL_SRC_FILES_x86_64 := empty_policy/code_coverage.x86_64.policy
+endif
+
+LOCAL_MODULE_TARGET_ARCH := arm arm64 x86 x86_64
+LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/seccomp_policy
+include $(BUILD_PREBUILT)
diff --git a/code_coverage/empty_policy/code_coverage.arm.policy b/code_coverage/empty_policy/code_coverage.arm.policy
new file mode 100644
index 0000000..4c9132b
--- /dev/null
+++ b/code_coverage/empty_policy/code_coverage.arm.policy
@@ -0,0 +1,2 @@
+# empty unless code_coverage is enabled.
+# code_coverage.arm.policy
diff --git a/code_coverage/empty_policy/code_coverage.arm64.policy b/code_coverage/empty_policy/code_coverage.arm64.policy
new file mode 100644
index 0000000..dc5c35a
--- /dev/null
+++ b/code_coverage/empty_policy/code_coverage.arm64.policy
@@ -0,0 +1,2 @@
+# empty unless code_coverage is enabled.
+# code_coverage.arm64.policy
diff --git a/code_coverage/empty_policy/code_coverage.x86.policy b/code_coverage/empty_policy/code_coverage.x86.policy
new file mode 100644
index 0000000..044f34c
--- /dev/null
+++ b/code_coverage/empty_policy/code_coverage.x86.policy
@@ -0,0 +1,2 @@
+# empty unless code_coverage is enabled.
+# code_coverage.x86.policy
diff --git a/code_coverage/empty_policy/code_coverage.x86_64.policy b/code_coverage/empty_policy/code_coverage.x86_64.policy
new file mode 100644
index 0000000..6dcd22d
--- /dev/null
+++ b/code_coverage/empty_policy/code_coverage.x86_64.policy
@@ -0,0 +1,2 @@
+# empty unless code_coverage is enabled.
+# code_coverage.x86_64.policy
diff --git a/code_coverage/seccomp_policy/code_coverage.arm.policy b/code_coverage/seccomp_policy/code_coverage.arm.policy
new file mode 100644
index 0000000..d6784e3
--- /dev/null
+++ b/code_coverage/seccomp_policy/code_coverage.arm.policy
@@ -0,0 +1,14 @@
+close: 1
+mkdirat: 1
+msync: 1
+munmap: 1
+openat: 1
+write: 1
+fcntl64: 1
+fstat64: 1
+geteuid32: 1
+_llseek: 1
+mmap2: 1
+sigreturn: 1
+gettimeofday: 1
+prctl: 1
diff --git a/code_coverage/seccomp_policy/code_coverage.arm64.policy b/code_coverage/seccomp_policy/code_coverage.arm64.policy
new file mode 100644
index 0000000..4c3dd26
--- /dev/null
+++ b/code_coverage/seccomp_policy/code_coverage.arm64.policy
@@ -0,0 +1,13 @@
+close: 1
+mkdirat: 1
+msync: 1
+munmap: 1
+openat: 1
+write: 1
+fcntl: 1
+fstat: 1
+geteuid: 1
+lseek: 1
+mmap: 1
+rt_sigreturn: 1
+prctl: 1
diff --git a/code_coverage/seccomp_policy/code_coverage.policy.def b/code_coverage/seccomp_policy/code_coverage.policy.def
new file mode 100644
index 0000000..f136084
--- /dev/null
+++ b/code_coverage/seccomp_policy/code_coverage.policy.def
@@ -0,0 +1,51 @@
+// SECCOMP_MODE_STRICT
+//
+// minijail allowances for code coverage
+// this is processed with generate.sh, so we can use appropriate directives
+// size specific: __LP64__ for 64 bit, else 32 bit
+// arch specific: __arm__, __aarch64__, __i386__, __x86_64__
+
+// includes *all* syscalls used during the coverage dumping
+// no skipping just because they might have been in another policy file.
+
+// coverage tool uses different operations on different passes
+// 1st: uses write() to fill the file
+// 2nd-Nth: uses mmap() to update in place
+
+close: 1
+mkdirat: 1
+msync: 1
+munmap: 1
+openat: 1
+write: 1
+
+#if     defined(__LP64__)
+fcntl: 1
+fstat: 1
+geteuid: 1
+lseek: 1
+mmap: 1
+rt_sigreturn: 1
+#else
+fcntl64: 1
+fstat64: 1
+geteuid32: 1
+_llseek: 1
+mmap2: 1
+sigreturn: 1
+#endif
+
+#if     defined(__arm__)
+gettimeofday: 1
+#endif
+
+#if     defined(__i386__)
+madvise: 1
+#endif
+
+#if     defined(__arm__)
+prctl: 1
+#elif   defined(__aarch64__)
+prctl: 1
+#endif
+
diff --git a/code_coverage/seccomp_policy/code_coverage.x86.policy b/code_coverage/seccomp_policy/code_coverage.x86.policy
new file mode 100644
index 0000000..24ff8b9
--- /dev/null
+++ b/code_coverage/seccomp_policy/code_coverage.x86.policy
@@ -0,0 +1,13 @@
+close: 1
+mkdirat: 1
+msync: 1
+munmap: 1
+openat: 1
+write: 1
+fcntl64: 1
+fstat64: 1
+geteuid32: 1
+_llseek: 1
+mmap2: 1
+sigreturn: 1
+madvise: 1
diff --git a/code_coverage/seccomp_policy/code_coverage.x86_64.policy b/code_coverage/seccomp_policy/code_coverage.x86_64.policy
new file mode 100644
index 0000000..3081036
--- /dev/null
+++ b/code_coverage/seccomp_policy/code_coverage.x86_64.policy
@@ -0,0 +1,12 @@
+close: 1
+mkdirat: 1
+msync: 1
+munmap: 1
+openat: 1
+write: 1
+fcntl: 1
+fstat: 1
+geteuid: 1
+lseek: 1
+mmap: 1
+rt_sigreturn: 1
diff --git a/code_coverage/seccomp_policy/generate.sh b/code_coverage/seccomp_policy/generate.sh
new file mode 100755
index 0000000..ae582c6
--- /dev/null
+++ b/code_coverage/seccomp_policy/generate.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+# generate the arch-specific files from the generic one
+
+set -ex
+
+cd "$(dirname "$0")"
+CPP='cpp -undef -E -P code_coverage.policy.def'
+$CPP -D__arm__ -o code_coverage.arm.policy
+$CPP -D__aarch64__ -D__LP64__ -o code_coverage.arm64.policy
+$CPP -D__i386__ -o code_coverage.x86.policy
+$CPP -D__x86_64__ -D__LP64__ -o code_coverage.x86_64.policy
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index b93872b..ce1f9ef 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -1407,9 +1407,8 @@
             return -1;
         }
     } else {
-        // TODO(b/135984674): support remounting for ext4.
-        LERROR << "Remounting in checkpointing mode is not yet supported for ext4";
-        return -1;
+        // STOPSHIP(b/143970043): support remounting for ext4.
+        LWARNING << "Remounting into checkpointing is not supported for ex4. Proceed with caution";
     }
     return 0;
 }
diff --git a/fs_mgr/libsnapshot/snapshot_metadata_updater_test.cpp b/fs_mgr/libsnapshot/snapshot_metadata_updater_test.cpp
index 7d96a67..4fd8759 100644
--- a/fs_mgr/libsnapshot/snapshot_metadata_updater_test.cpp
+++ b/fs_mgr/libsnapshot/snapshot_metadata_updater_test.cpp
@@ -325,7 +325,7 @@
     EXPECT_TRUE(CheckGroupName("product", "another_group"));
 }
 
-INSTANTIATE_TEST_SUITE_P(, SnapshotMetadataUpdaterTest, testing::Values(0, 1));
+INSTANTIATE_TEST_SUITE_P(Snapshot, SnapshotMetadataUpdaterTest, testing::Values(0, 1));
 
 }  // namespace snapshot
 }  // namespace android
diff --git a/fs_mgr/libsnapshot/snapshot_test.cpp b/fs_mgr/libsnapshot/snapshot_test.cpp
index 3c3d9a6..af268f9 100644
--- a/fs_mgr/libsnapshot/snapshot_test.cpp
+++ b/fs_mgr/libsnapshot/snapshot_test.cpp
@@ -1338,7 +1338,7 @@
     ASSERT_TRUE(new_sm->CancelUpdate());
 }
 
-INSTANTIATE_TEST_SUITE_P(, FlashAfterUpdateTest, Combine(Values(0, 1), Bool()),
+INSTANTIATE_TEST_SUITE_P(Snapshot, FlashAfterUpdateTest, Combine(Values(0, 1), Bool()),
                          [](const TestParamInfo<FlashAfterUpdateTest::ParamType>& info) {
                              return "Flash"s + (std::get<0>(info.param) ? "New"s : "Old"s) +
                                     "Slot"s + (std::get<1>(info.param) ? "After"s : "Before"s) +
diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp
index 9e168e9..bdf4aac 100644
--- a/healthd/BatteryMonitor.cpp
+++ b/healthd/BatteryMonitor.cpp
@@ -73,12 +73,25 @@
     return std::nullopt;
 }
 
+static void initHealthInfo(HealthInfo_2_1* health_info_2_1) {
+    *health_info_2_1 = HealthInfo_2_1{};
+
+    // HIDL enum values are zero initialized, so they need to be initialized
+    // properly.
+    health_info_2_1->batteryCapacityLevel = BatteryCapacityLevel::UNKNOWN;
+    auto* props = &health_info_2_1->legacy.legacy;
+    props->batteryStatus = BatteryStatus::UNKNOWN;
+    props->batteryHealth = BatteryHealth::UNKNOWN;
+}
+
 BatteryMonitor::BatteryMonitor()
     : mHealthdConfig(nullptr),
       mBatteryDevicePresent(false),
       mBatteryFixedCapacity(0),
       mBatteryFixedTemperature(0),
-      mHealthInfo(std::make_unique<HealthInfo_2_1>()) {}
+      mHealthInfo(std::make_unique<HealthInfo_2_1>()) {
+    initHealthInfo(mHealthInfo.get());
+}
 
 BatteryMonitor::~BatteryMonitor() {}
 
@@ -168,7 +181,7 @@
         return ANDROID_POWER_SUPPLY_TYPE_UNKNOWN;
 
     auto ret = mapSysfsString(buf.c_str(), supplyTypeMap);
-    if (ret < 0) {
+    if (!ret) {
         KLOG_WARNING(LOG_TAG, "Unknown power supply type '%s'\n", buf.c_str());
         *ret = ANDROID_POWER_SUPPLY_TYPE_UNKNOWN;
     }
@@ -198,7 +211,7 @@
 }
 
 void BatteryMonitor::updateValues(void) {
-    *mHealthInfo = HealthInfo_2_1{};
+    initHealthInfo(mHealthInfo.get());
 
     HealthInfo_1_0& props = mHealthInfo->legacy.legacy;
 
diff --git a/init/Android.bp b/init/Android.bp
index 776a3a6..6ee9132 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -65,6 +65,7 @@
         "libavb",
         "libc++fs",
         "libcgrouprc_format",
+        "liblmkd_utils",
         "libmodprobe",
         "libprotobuf-cpp-lite",
         "libpropertyinfoserializer",
@@ -118,6 +119,7 @@
         "init.cpp",
         "interface_utils.cpp",
         "keychords.cpp",
+        "lmkd_service.cpp",
         "modalias_handler.cpp",
         "mount_handler.cpp",
         "mount_namespace.cpp",
@@ -183,9 +185,11 @@
     static_libs: ["libinit"],
     required: [
         "e2fsdroid",
+        "init.rc",
         "mke2fs",
         "sload_f2fs",
         "make_f2fs",
+        "ueventd.rc",
     ],
     srcs: ["main.cpp"],
     symlinks: ["ueventd"],
diff --git a/init/AndroidTest.xml b/init/AndroidTest.xml
index 94a02e6..667911d 100644
--- a/init/AndroidTest.xml
+++ b/init/AndroidTest.xml
@@ -17,7 +17,7 @@
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="systems" />
     <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
-    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
         <option name="cleanup" value="true" />
         <option name="push" value="CtsInitTestCases->/data/local/tmp/CtsInitTestCases" />
diff --git a/init/README.md b/init/README.md
index cdf3487..e8df4ec 100644
--- a/init/README.md
+++ b/init/README.md
@@ -505,12 +505,23 @@
 > Used to mark the point right after /data is mounted. Used to implement the
   `class_reset_post_data` and `class_start_post_data` commands.
 
-`mkdir <path> [mode] [owner] [group]`
+`mkdir <path> [<mode>] [<owner>] [<group>] [encryption=<action>] [key=<key>]`
 > Create a directory at _path_, optionally with the given mode, owner, and
   group. If not provided, the directory is created with permissions 755 and
   owned by the root user and root group. If provided, the mode, owner and group
   will be updated if the directory exists already.
 
+ > _action_ can be one of:
+  * `None`: take no encryption action; directory will be encrypted if parent is.
+  * `Require`: encrypt directory, abort boot process if encryption fails
+  * `Attempt`: try to set an encryption policy, but continue if it fails
+  * `DeleteIfNecessary`: recursively delete directory if necessary to set
+  encryption policy.
+
+  > _key_ can be one of:
+  * `ref`: use the systemwide DE key
+  * `per_boot_ref`: use the key freshly generated on each boot.
+
 `mount_all <fstab> [ <path> ]\* [--<option>]`
 > Calls fs\_mgr\_mount\_all on the given fs\_mgr-format fstab with optional
   options "early" and "late".
diff --git a/init/builtins.cpp b/init/builtins.cpp
index b2c6461..5ee928e 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -364,67 +364,52 @@
     return {};
 }
 
-// mkdir <path> [mode] [owner] [group]
+// mkdir <path> [mode] [owner] [group] [<option> ...]
 static Result<void> do_mkdir(const BuiltinArguments& args) {
-    mode_t mode = 0755;
-    Result<uid_t> uid = -1;
-    Result<gid_t> gid = -1;
-
-    switch (args.size()) {
-        case 5:
-            gid = DecodeUid(args[4]);
-            if (!gid) {
-                return Error() << "Unable to decode GID for '" << args[4] << "': " << gid.error();
-            }
-            FALLTHROUGH_INTENDED;
-        case 4:
-            uid = DecodeUid(args[3]);
-            if (!uid) {
-                return Error() << "Unable to decode UID for '" << args[3] << "': " << uid.error();
-            }
-            FALLTHROUGH_INTENDED;
-        case 3:
-            mode = std::strtoul(args[2].c_str(), 0, 8);
-            FALLTHROUGH_INTENDED;
-        case 2:
-            break;
-        default:
-            return Error() << "Unexpected argument count: " << args.size();
+    auto options = ParseMkdir(args.args);
+    if (!options) return options.error();
+    std::string ref_basename;
+    if (options->ref_option == "ref") {
+        ref_basename = fscrypt_key_ref;
+    } else if (options->ref_option == "per_boot_ref") {
+        ref_basename = fscrypt_key_per_boot_ref;
+    } else {
+        return Error() << "Unknown key option: '" << options->ref_option << "'";
     }
-    std::string target = args[1];
+
     struct stat mstat;
-    if (lstat(target.c_str(), &mstat) != 0) {
+    if (lstat(options->target.c_str(), &mstat) != 0) {
         if (errno != ENOENT) {
-            return ErrnoError() << "lstat() failed on " << target;
+            return ErrnoError() << "lstat() failed on " << options->target;
         }
-        if (!make_dir(target, mode)) {
-            return ErrnoErrorIgnoreEnoent() << "mkdir() failed on " << target;
+        if (!make_dir(options->target, options->mode)) {
+            return ErrnoErrorIgnoreEnoent() << "mkdir() failed on " << options->target;
         }
-        if (lstat(target.c_str(), &mstat) != 0) {
-            return ErrnoError() << "lstat() failed on new " << target;
+        if (lstat(options->target.c_str(), &mstat) != 0) {
+            return ErrnoError() << "lstat() failed on new " << options->target;
         }
     }
     if (!S_ISDIR(mstat.st_mode)) {
-        return Error() << "Not a directory on " << target;
+        return Error() << "Not a directory on " << options->target;
     }
-    bool needs_chmod = (mstat.st_mode & ~S_IFMT) != mode;
-    if ((*uid != static_cast<uid_t>(-1) && *uid != mstat.st_uid) ||
-        (*gid != static_cast<gid_t>(-1) && *gid != mstat.st_gid)) {
-        if (lchown(target.c_str(), *uid, *gid) == -1) {
-            return ErrnoError() << "lchown failed on " << target;
+    bool needs_chmod = (mstat.st_mode & ~S_IFMT) != options->mode;
+    if ((options->uid != static_cast<uid_t>(-1) && options->uid != mstat.st_uid) ||
+        (options->gid != static_cast<gid_t>(-1) && options->gid != mstat.st_gid)) {
+        if (lchown(options->target.c_str(), options->uid, options->gid) == -1) {
+            return ErrnoError() << "lchown failed on " << options->target;
         }
         // chown may have cleared S_ISUID and S_ISGID, chmod again
         needs_chmod = true;
     }
     if (needs_chmod) {
-        if (fchmodat(AT_FDCWD, target.c_str(), mode, AT_SYMLINK_NOFOLLOW) == -1) {
-            return ErrnoError() << "fchmodat() failed on " << target;
+        if (fchmodat(AT_FDCWD, options->target.c_str(), options->mode, AT_SYMLINK_NOFOLLOW) == -1) {
+            return ErrnoError() << "fchmodat() failed on " << options->target;
         }
     }
     if (fscrypt_is_native()) {
-        if (fscrypt_set_directory_policy(target)) {
+        if (!FscryptSetDirectoryPolicy(ref_basename, options->fscrypt_action, options->target)) {
             return reboot_into_recovery(
-                    {"--prompt_and_wipe_data", "--reason=set_policy_failed:"s + target});
+                    {"--prompt_and_wipe_data", "--reason=set_policy_failed:"s + options->target});
         }
     }
     return {};
@@ -562,11 +547,25 @@
  *
  * return code is processed based on input code
  */
-static Result<void> queue_fs_event(int code) {
+static Result<void> queue_fs_event(int code, bool userdata_remount) {
     if (code == FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION) {
+        if (userdata_remount) {
+            // FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION should only happen on FDE devices. Since we don't
+            // support userdata remount on FDE devices, this should never been triggered. Time to
+            // panic!
+            LOG(ERROR) << "Userdata remount is not supported on FDE devices. How did you get here?";
+            TriggerShutdown("reboot,requested-userdata-remount-on-fde-device");
+        }
         ActionManager::GetInstance().QueueEventTrigger("encrypt");
         return {};
     } else if (code == FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED) {
+        if (userdata_remount) {
+            // FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED should only happen on FDE devices. Since we
+            // don't support userdata remount on FDE devices, this should never been triggered.
+            // Time to panic!
+            LOG(ERROR) << "Userdata remount is not supported on FDE devices. How did you get here?";
+            TriggerShutdown("reboot,requested-userdata-remount-on-fde-device");
+        }
         property_set("ro.crypto.state", "encrypted");
         property_set("ro.crypto.type", "block");
         ActionManager::GetInstance().QueueEventTrigger("defaultcrypto");
@@ -589,8 +588,8 @@
         return reboot_into_recovery(options);
         /* If reboot worked, there is no return. */
     } else if (code == FS_MGR_MNTALL_DEV_FILE_ENCRYPTED) {
-        if (fscrypt_install_keyring()) {
-            return Error() << "fscrypt_install_keyring() failed";
+        if (!userdata_remount && !FscryptInstallKeyring()) {
+            return Error() << "FscryptInstallKeyring() failed";
         }
         property_set("ro.crypto.state", "encrypted");
         property_set("ro.crypto.type", "file");
@@ -600,8 +599,8 @@
         ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
         return {};
     } else if (code == FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED) {
-        if (fscrypt_install_keyring()) {
-            return Error() << "fscrypt_install_keyring() failed";
+        if (!userdata_remount && !FscryptInstallKeyring()) {
+            return Error() << "FscryptInstallKeyring() failed";
         }
         property_set("ro.crypto.state", "encrypted");
         property_set("ro.crypto.type", "file");
@@ -611,8 +610,8 @@
         ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
         return {};
     } else if (code == FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION) {
-        if (fscrypt_install_keyring()) {
-            return Error() << "fscrypt_install_keyring() failed";
+        if (!userdata_remount && !FscryptInstallKeyring()) {
+            return Error() << "FscryptInstallKeyring() failed";
         }
         property_set("ro.crypto.state", "encrypted");
         property_set("ro.crypto.type", "file");
@@ -679,7 +678,7 @@
         /* queue_fs_event will queue event based on mount_fstab return code
          * and return processed return code*/
         initial_mount_fstab_return_code = mount_fstab_return_code;
-        auto queue_fs_result = queue_fs_event(mount_fstab_return_code);
+        auto queue_fs_result = queue_fs_event(mount_fstab_return_code, false);
         if (!queue_fs_result) {
             return Error() << "queue_fs_event() failed: " << queue_fs_result.error();
         }
@@ -1151,7 +1150,7 @@
     if (auto rc = fs_mgr_remount_userdata_into_checkpointing(&fstab); rc < 0) {
         TriggerShutdown("reboot,mount-userdata-failed");
     }
-    if (auto result = queue_fs_event(initial_mount_fstab_return_code); !result) {
+    if (auto result = queue_fs_event(initial_mount_fstab_return_code, true); !result) {
         return Error() << "queue_fs_event() failed: " << result.error();
     }
     return {};
@@ -1257,7 +1256,7 @@
         {"load_system_props",       {0,     0,    {false,  do_load_system_props}}},
         {"loglevel",                {1,     1,    {false,  do_loglevel}}},
         {"mark_post_data",          {0,     0,    {false,  do_mark_post_data}}},
-        {"mkdir",                   {1,     4,    {true,   do_mkdir}}},
+        {"mkdir",                   {1,     6,    {true,   do_mkdir}}},
         // TODO: Do mount operations in vendor_init.
         // mount_all is currently too complex to run in vendor_init as it queues action triggers,
         // imports rc scripts, etc.  It should be simplified and run in vendor_init context.
diff --git a/init/check_builtins.cpp b/init/check_builtins.cpp
index 2efaeea..9d23921 100644
--- a/init/check_builtins.cpp
+++ b/init/check_builtins.cpp
@@ -121,22 +121,10 @@
 }
 
 Result<void> check_mkdir(const BuiltinArguments& args) {
-    if (args.size() >= 4) {
-        if (!args[3].empty()) {
-            auto uid = DecodeUid(args[3]);
-            if (!uid) {
-                return Error() << "Unable to decode UID for '" << args[3] << "': " << uid.error();
-            }
-        }
-
-        if (args.size() == 5 && !args[4].empty()) {
-            auto gid = DecodeUid(args[4]);
-            if (!gid) {
-                return Error() << "Unable to decode GID for '" << args[4] << "': " << gid.error();
-            }
-        }
+    auto options = ParseMkdir(args.args);
+    if (!options) {
+        return options.error();
     }
-
     return {};
 }
 
diff --git a/init/fscrypt_init_extensions.cpp b/init/fscrypt_init_extensions.cpp
index 5fa07dd..7820f3d 100644
--- a/init/fscrypt_init_extensions.cpp
+++ b/init/fscrypt_init_extensions.cpp
@@ -41,19 +41,15 @@
 
 using namespace android::fscrypt;
 
-static int set_policy_on(const std::string& ref_basename, const std::string& dir);
-
-int fscrypt_install_keyring() {
+bool FscryptInstallKeyring() {
     key_serial_t device_keyring = add_key("keyring", "fscrypt", 0, 0, KEY_SPEC_SESSION_KEYRING);
 
     if (device_keyring == -1) {
         PLOG(ERROR) << "Failed to create keyring";
-        return -1;
+        return false;
     }
-
     LOG(INFO) << "Keyring created with id " << device_keyring << " in process " << getpid();
-
-    return 0;
+    return true;
 }
 
 // TODO(b/139378601): use a single central implementation of this.
@@ -97,102 +93,57 @@
     }
 }
 
-int fscrypt_set_directory_policy(const std::string& dir) {
-    const std::string prefix = "/data/";
-
-    if (!android::base::StartsWith(dir, prefix)) {
-        return 0;
-    }
-
-    // Special-case /data/media/obb per b/64566063
-    if (dir == "/data/media/obb") {
-        // Try to set policy on this directory, but if it is non-empty this may fail.
-        set_policy_on(fscrypt_key_ref, dir);
-        return 0;
-    }
-
-    // Only set policy on first level /data directories
-    // To make this less restrictive, consider using a policy file.
-    // However this is overkill for as long as the policy is simply
-    // to apply a global policy to all /data folders created via makedir
-    if (dir.find_first_of('/', prefix.size()) != std::string::npos) {
-        return 0;
-    }
-
-    // Special case various directories that must not be encrypted,
-    // often because their subdirectories must be encrypted.
-    // This isn't a nice way to do this, see b/26641735
-    std::vector<std::string> directories_to_exclude = {
-        "lost+found",
-        "system_ce", "system_de",
-        "misc_ce", "misc_de",
-        "vendor_ce", "vendor_de",
-        "media",
-        "data", "user", "user_de",
-        "apex", "preloads", "app-staging",
-        "gsi",
-    };
-    for (const auto& d : directories_to_exclude) {
-        if ((prefix + d) == dir) {
-            LOG(INFO) << "Not setting policy on " << dir;
-            return 0;
-        }
-    }
-    std::vector<std::string> per_boot_directories = {
-            "per_boot",
-    };
-    for (const auto& d : per_boot_directories) {
-        if ((prefix + d) == dir) {
-            LOG(INFO) << "Setting per_boot key on " << dir;
-            return set_policy_on(fscrypt_key_per_boot_ref, dir);
-        }
-    }
-    int err = set_policy_on(fscrypt_key_ref, dir);
-    if (err == 0) {
-        return 0;
-    }
-    // Empty these directories if policy setting fails.
-    std::vector<std::string> wipe_on_failure = {
-            "rollback", "rollback-observer",  // b/139193659
-    };
-    for (const auto& d : wipe_on_failure) {
-        if ((prefix + d) == dir) {
-            LOG(ERROR) << "Setting policy failed, deleting: " << dir;
-            delete_dir_contents(dir);
-            err = set_policy_on(fscrypt_key_ref, dir);
-            break;
-        }
-    }
-    return err;
-}
-
-// Set an encryption policy on the given directory.  The policy (key reference
+// Look up an encryption policy  The policy (key reference
 // and encryption options) to use is read from files that were written by vold.
-static int set_policy_on(const std::string& ref_basename, const std::string& dir) {
-    EncryptionPolicy policy;
+static bool LookupPolicy(const std::string& ref_basename, EncryptionPolicy* policy) {
     std::string ref_filename = std::string("/data") + ref_basename;
-    if (!android::base::ReadFileToString(ref_filename, &policy.key_raw_ref)) {
-        LOG(ERROR) << "Unable to read system policy to set on " << dir;
-        return -1;
+    if (!android::base::ReadFileToString(ref_filename, &policy->key_raw_ref)) {
+        LOG(ERROR) << "Unable to read system policy with name " << ref_filename;
+        return false;
     }
 
     auto options_filename = std::string("/data") + fscrypt_key_mode;
     std::string options_string;
     if (!android::base::ReadFileToString(options_filename, &options_string)) {
         LOG(ERROR) << "Cannot read encryption options string";
-        return -1;
+        return false;
     }
-    if (!ParseOptions(options_string, &policy.options)) {
+    if (!ParseOptions(options_string, &policy->options)) {
         LOG(ERROR) << "Invalid encryption options string: " << options_string;
-        return -1;
+        return false;
     }
+    return true;
+}
 
+static bool EnsurePolicyOrLog(const EncryptionPolicy& policy, const std::string& dir) {
     if (!EnsurePolicy(policy, dir)) {
         std::string ref_hex;
         BytesToHex(policy.key_raw_ref, &ref_hex);
         LOG(ERROR) << "Setting " << ref_hex << " policy on " << dir << " failed!";
-        return -1;
+        return false;
     }
+    return true;
+}
 
-    return 0;
+static bool SetPolicyOn(const std::string& ref_basename, const std::string& dir) {
+    EncryptionPolicy policy;
+    if (!LookupPolicy(ref_basename, &policy)) return false;
+    if (!EnsurePolicyOrLog(policy, dir)) return false;
+    return true;
+}
+
+bool FscryptSetDirectoryPolicy(const std::string& ref_basename, FscryptAction action,
+                               const std::string& dir) {
+    if (action == FscryptAction::kNone) {
+        return true;
+    }
+    if (SetPolicyOn(ref_basename, dir) || action == FscryptAction::kAttempt) {
+        return true;
+    }
+    if (action == FscryptAction::kDeleteIfNecessary) {
+        LOG(ERROR) << "Setting policy failed, deleting: " << dir;
+        delete_dir_contents(dir);
+        return SetPolicyOn(ref_basename, dir);
+    }
+    return false;
 }
diff --git a/init/fscrypt_init_extensions.h b/init/fscrypt_init_extensions.h
index 2163ef6..d357bb2 100644
--- a/init/fscrypt_init_extensions.h
+++ b/init/fscrypt_init_extensions.h
@@ -18,5 +18,13 @@
 
 #include <string>
 
-int fscrypt_install_keyring();
-int fscrypt_set_directory_policy(const std::string& dir);
+enum class FscryptAction {
+    kNone,
+    kAttempt,
+    kRequire,
+    kDeleteIfNecessary,
+};
+
+bool FscryptInstallKeyring();
+bool FscryptSetDirectoryPolicy(const std::string& ref_basename, FscryptAction action,
+                               const std::string& dir);
diff --git a/init/init.cpp b/init/init.cpp
index f775d8f..ff86f8d 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -59,6 +59,7 @@
 #include "first_stage_mount.h"
 #include "import_parser.h"
 #include "keychords.h"
+#include "lmkd_service.h"
 #include "mount_handler.h"
 #include "mount_namespace.h"
 #include "property_service.h"
@@ -135,7 +136,7 @@
 
     std::string bootscript = GetProperty("ro.boot.init_rc", "");
     if (bootscript.empty()) {
-        parser.ParseConfig("/init.rc");
+        parser.ParseConfig("/system/etc/init/hw/init.rc");
         if (!parser.ParseConfig("/system/etc/init")) {
             late_import_paths.emplace_back("/system/etc/init");
         }
@@ -684,9 +685,15 @@
     InitKernelLogging(argv);
     LOG(INFO) << "init second stage started!";
 
+    // Will handle EPIPE at the time of write by checking the errno
+    signal(SIGPIPE, SIG_IGN);
+
     // Set init and its forked children's oom_adj.
-    if (auto result = WriteFile("/proc/1/oom_score_adj", "-1000"); !result) {
-        LOG(ERROR) << "Unable to write -1000 to /proc/1/oom_score_adj: " << result.error();
+    if (auto result =
+                WriteFile("/proc/1/oom_score_adj", StringPrintf("%d", DEFAULT_OOM_SCORE_ADJUST));
+        !result) {
+        LOG(ERROR) << "Unable to write " << DEFAULT_OOM_SCORE_ADJUST
+                   << " to /proc/1/oom_score_adj: " << result.error();
     }
 
     // Set up a session keyring that all processes will have access to. It
diff --git a/init/lmkd_service.cpp b/init/lmkd_service.cpp
new file mode 100644
index 0000000..dd1ab4d
--- /dev/null
+++ b/init/lmkd_service.cpp
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "lmkd_service.h"
+
+#include <errno.h>
+
+#include <android-base/logging.h>
+#include <liblmkd_utils.h>
+
+#include "service_list.h"
+
+namespace android {
+namespace init {
+
+enum LmkdRegistrationResult {
+    LMKD_REG_SUCCESS,
+    LMKD_CONN_FAILED,
+    LMKD_REG_FAILED,
+};
+
+static int lmkd_socket = -1;
+
+static LmkdRegistrationResult RegisterProcess(uid_t uid, pid_t pid, int oom_score_adjust) {
+    // connect to lmkd if not already connected
+    if (lmkd_socket < 0) {
+        lmkd_socket = lmkd_connect();
+        if (lmkd_socket < 0) {
+            return LMKD_CONN_FAILED;
+        }
+    }
+
+    // register service with lmkd
+    struct lmk_procprio params;
+    params.pid = pid;
+    params.uid = uid;
+    params.oomadj = oom_score_adjust;
+    params.ptype = PROC_TYPE_SERVICE;
+    if (lmkd_register_proc(lmkd_socket, &params) != 0) {
+        // data transfer failed, reset the connection
+        close(lmkd_socket);
+        lmkd_socket = -1;
+        return LMKD_REG_FAILED;
+    }
+
+    return LMKD_REG_SUCCESS;
+}
+
+static bool UnregisterProcess(pid_t pid) {
+    if (lmkd_socket < 0) {
+        // no connection or it was lost, no need to unregister
+        return false;
+    }
+
+    // unregister service
+    struct lmk_procremove params;
+    params.pid = pid;
+    if (lmkd_unregister_proc(lmkd_socket, &params) != 0) {
+        // data transfer failed, reset the connection
+        close(lmkd_socket);
+        lmkd_socket = -1;
+        return false;
+    }
+
+    return true;
+}
+
+static void RegisterServices(pid_t exclude_pid) {
+    for (const auto& service : ServiceList::GetInstance().services()) {
+        auto svc = service.get();
+        if (svc->oom_score_adjust() != DEFAULT_OOM_SCORE_ADJUST) {
+            // skip if process is excluded or not yet forked (pid==0)
+            if (svc->pid() == exclude_pid || svc->pid() == 0) {
+                continue;
+            }
+            if (RegisterProcess(svc->uid(), svc->pid(), svc->oom_score_adjust()) !=
+                LMKD_REG_SUCCESS) {
+                // a failure here resets the connection, will retry during next registration
+                break;
+            }
+        }
+    }
+}
+
+void LmkdRegister(const std::string& name, uid_t uid, pid_t pid, int oom_score_adjust) {
+    bool new_connection = lmkd_socket == -1;
+    LmkdRegistrationResult result;
+
+    result = RegisterProcess(uid, pid, oom_score_adjust);
+    if (result == LMKD_REG_FAILED) {
+        // retry one time if connection to lmkd was lost
+        result = RegisterProcess(uid, pid, oom_score_adjust);
+        new_connection = result == LMKD_REG_SUCCESS;
+    }
+    switch (result) {
+        case LMKD_REG_SUCCESS:
+            // register existing services once new connection is established
+            if (new_connection) {
+                RegisterServices(pid);
+            }
+            break;
+        case LMKD_CONN_FAILED:
+            PLOG(ERROR) << "lmkd connection failed when " << name << " process got started";
+            break;
+        case LMKD_REG_FAILED:
+            PLOG(ERROR) << "lmkd failed to register " << name << " process";
+            break;
+    }
+}
+
+void LmkdUnregister(const std::string& name, pid_t pid) {
+    if (!UnregisterProcess(pid)) {
+        PLOG(ERROR) << "lmkd failed to unregister " << name << " process";
+    }
+}
+
+}  // namespace init
+}  // namespace android
diff --git a/init/lmkd_service.h b/init/lmkd_service.h
new file mode 100644
index 0000000..5b51d52
--- /dev/null
+++ b/init/lmkd_service.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <sys/types.h>
+
+#include <string>
+
+namespace android {
+namespace init {
+
+static const int MIN_OOM_SCORE_ADJUST = -1000;
+static const int MAX_OOM_SCORE_ADJUST = 1000;
+// service with default score is unkillable
+static const int DEFAULT_OOM_SCORE_ADJUST = MIN_OOM_SCORE_ADJUST;
+
+#if defined(__ANDROID__)
+
+void LmkdRegister(const std::string& name, uid_t uid, pid_t pid, int oom_score_adjust);
+void LmkdUnregister(const std::string& name, pid_t pid);
+
+#else  // defined(__ANDROID__)
+
+static inline void LmkdRegister(const std::string&, uid_t, pid_t, int) {}
+static inline void LmkdUnregister(const std::string&, pid_t) {}
+
+#endif  // defined(__ANDROID__)
+
+}  // namespace init
+}  // namespace android
diff --git a/init/reboot.cpp b/init/reboot.cpp
index fc18ecb..4a16969 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -57,6 +57,7 @@
 #include "action_manager.h"
 #include "builtin_arguments.h"
 #include "init.h"
+#include "mount_namespace.h"
 #include "property_service.h"
 #include "reboot_utils.h"
 #include "service.h"
@@ -713,6 +714,18 @@
     SendStartSendingMessagesMessage();
 }
 
+static Result<void> UnmountAllApexes() {
+    const char* args[] = {"/system/bin/apexd", "--unmount-all"};
+    int status;
+    if (logwrap_fork_execvp(arraysize(args), args, &status, false, LOG_KLOG, true, nullptr) != 0) {
+        return ErrnoError() << "Failed to call '/system/bin/apexd --unmount-all'";
+    }
+    if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
+        return {};
+    }
+    return Error() << "'/system/bin/apexd --unmount-all' failed : " << status;
+}
+
 static Result<void> DoUserspaceReboot() {
     LOG(INFO) << "Userspace reboot initiated";
     auto guard = android::base::make_scope_guard([] {
@@ -746,30 +759,20 @@
         // TODO(b/135984674): store information about offending services for debugging.
         return Error() << r << " post-data services are still running";
     }
-    // We only really need to restart vold if userdata is ext4 filesystem.
-    // TODO(b/135984674): get userdata fs type here, and do nothing in case of f2fs.
-    // First shutdown volumes managed by vold. They will be recreated by
-    // system_server.
-    Service* vold_service = ServiceList::GetInstance().FindService("vold");
-    if (vold_service != nullptr && vold_service->IsRunning()) {
-        if (auto result = ShutdownVold(); !result) {
-            return result;
-        }
-        LOG(INFO) << "Restarting vold";
-        vold_service->Restart();
-    }
-    // Again, we only need to kill zram backing device in case of ext4 userdata.
-    // TODO(b/135984674): get userdata fs type here, and do nothing in case of f2fs.
-    if (auto result = KillZramBackingDevice(); !result) {
-        return result;
-    }
+    // TODO(b/143970043): in case of ext4 we probably we will need to restart vold and kill zram
+    //  backing device.
     if (int r = StopServicesAndLogViolations(GetDebuggingServices(true /* only_post_data */), 5s,
                                              false /* SIGKILL */);
         r > 0) {
         // TODO(b/135984674): store information about offending services for debugging.
         return Error() << r << " debugging services are still running";
     }
-    // TODO(b/135984674): deactivate APEX modules and switch back to bootstrap namespace.
+    if (auto result = UnmountAllApexes(); !result) {
+        return result;
+    }
+    if (!SwitchToBootstrapMountNamespaceIfNeeded()) {
+        return Error() << "Failed to switch to bootstrap namespace";
+    }
     // Re-enable services
     for (const auto& s : were_enabled) {
         LOG(INFO) << "Re-enabling service '" << s->name() << "'";
diff --git a/init/selinux.cpp b/init/selinux.cpp
index a15d136..a9cd290 100644
--- a/init/selinux.cpp
+++ b/init/selinux.cpp
@@ -514,9 +514,6 @@
 
 }  // namespace
 
-// The files and directories that were created before initial sepolicy load or
-// files on ramdisk need to have their security context restored to the proper
-// value. This must happen before /dev is populated by ueventd.
 void SelinuxRestoreContext() {
     LOG(INFO) << "Running restorecon...";
     selinux_android_restorecon("/dev", 0);
@@ -560,15 +557,12 @@
     return 0;
 }
 
-// This function sets up SELinux logging to be written to kmsg, to match init's logging.
 void SelinuxSetupKernelLogging() {
     selinux_callback cb;
     cb.func_log = SelinuxKlogCallback;
     selinux_set_callback(SELINUX_CB_LOG, cb);
 }
 
-// This function returns the Android version with which the vendor SEPolicy was compiled.
-// It is used for version checks such as whether or not vendor_init should be used
 int SelinuxGetVendorAndroidVersion() {
     static int vendor_android_version = [] {
         if (!IsSplitPolicyDevice()) {
@@ -594,7 +588,6 @@
     return vendor_android_version;
 }
 
-// This function initializes SELinux then execs init to run in the init SELinux context.
 int SetupSelinux(char** argv) {
     SetStdioToDevNull(argv);
     InitKernelLogging(argv);
diff --git a/init/selinux.h b/init/selinux.h
index 63ad470..1a41bfd 100644
--- a/init/selinux.h
+++ b/init/selinux.h
@@ -19,10 +19,19 @@
 namespace android {
 namespace init {
 
+// Initialize SELinux, then exec init to run in the init SELinux context.
 int SetupSelinux(char** argv);
+
+// Restore the proper security context to files and directories on ramdisk, and
+// those that were created before initial sepolicy load.
+// This must happen before /dev is populated by ueventd.
 void SelinuxRestoreContext();
 
+// Set up SELinux logging to be written to kmsg, to match init's logging.
 void SelinuxSetupKernelLogging();
+
+// Return the Android API level with which the vendor SEPolicy was compiled.
+// Used for version checks such as whether or not vendor_init should be used.
 int SelinuxGetVendorAndroidVersion();
 
 static constexpr char kEnvSelinuxStartedAt[] = "SELINUX_STARTED_AT";
diff --git a/init/service.cpp b/init/service.cpp
index c8568a0..f8e98a2 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -36,6 +36,7 @@
 #include <processgroup/processgroup.h>
 #include <selinux/selinux.h>
 
+#include "lmkd_service.h"
 #include "service_list.h"
 #include "util.h"
 
@@ -151,7 +152,7 @@
       seclabel_(seclabel),
       onrestart_(false, subcontext_for_restart_commands, "<Service '" + name + "' onrestart>", 0,
                  "onrestart", {}),
-      oom_score_adjust_(-1000),
+      oom_score_adjust_(DEFAULT_OOM_SCORE_ADJUST),
       start_order_(0),
       args_(args) {}
 
@@ -199,6 +200,10 @@
 
         if (r == 0) process_cgroup_empty_ = true;
     }
+
+    if (oom_score_adjust_ != DEFAULT_OOM_SCORE_ADJUST) {
+        LmkdUnregister(name_, pid_);
+    }
 }
 
 void Service::SetProcessAttributesAndCaps() {
@@ -502,7 +507,7 @@
         return ErrnoError() << "Failed to fork";
     }
 
-    if (oom_score_adjust_ != -1000) {
+    if (oom_score_adjust_ != DEFAULT_OOM_SCORE_ADJUST) {
         std::string oom_str = std::to_string(oom_score_adjust_);
         std::string oom_file = StringPrintf("/proc/%d/oom_score_adj", pid);
         if (!WriteStringToFile(oom_str, oom_file)) {
@@ -563,6 +568,10 @@
         }
     }
 
+    if (oom_score_adjust_ != DEFAULT_OOM_SCORE_ADJUST) {
+        LmkdRegister(name_, proc_attr_.uid, pid_, oom_score_adjust_);
+    }
+
     NotifyStateChange("running");
     reboot_on_failure.Disable();
     return {};
diff --git a/init/service_parser.cpp b/init/service_parser.cpp
index e6a341d..154d1dd 100644
--- a/init/service_parser.cpp
+++ b/init/service_parser.cpp
@@ -29,6 +29,7 @@
 #include <hidl-util/FQName.h>
 #include <system/thread_defs.h>
 
+#include "lmkd_service.h"
 #include "rlimit_parser.h"
 #include "service_utils.h"
 #include "util.h"
@@ -261,8 +262,10 @@
 }
 
 Result<void> ServiceParser::ParseOomScoreAdjust(std::vector<std::string>&& args) {
-    if (!ParseInt(args[1], &service_->oom_score_adjust_, -1000, 1000)) {
-        return Error() << "oom_score_adjust value must be in range -1000 - +1000";
+    if (!ParseInt(args[1], &service_->oom_score_adjust_, MIN_OOM_SCORE_ADJUST,
+                  MAX_OOM_SCORE_ADJUST)) {
+        return Error() << "oom_score_adjust value must be in range " << MIN_OOM_SCORE_ADJUST
+                       << " - +" << MAX_OOM_SCORE_ADJUST;
     }
     return {};
 }
diff --git a/init/service_test.cpp b/init/service_test.cpp
index c9cc7bd..c158b0a 100644
--- a/init/service_test.cpp
+++ b/init/service_test.cpp
@@ -23,6 +23,7 @@
 
 #include <gtest/gtest.h>
 
+#include "lmkd_service.h"
 #include "util.h"
 
 namespace android {
@@ -49,7 +50,7 @@
     EXPECT_EQ(IoSchedClass_NONE, service_in_old_memory->ioprio_class());
     EXPECT_EQ(0, service_in_old_memory->ioprio_pri());
     EXPECT_EQ(0, service_in_old_memory->priority());
-    EXPECT_EQ(-1000, service_in_old_memory->oom_score_adjust());
+    EXPECT_EQ(DEFAULT_OOM_SCORE_ADJUST, service_in_old_memory->oom_score_adjust());
     EXPECT_FALSE(service_in_old_memory->process_cgroup_empty());
 
     for (std::size_t i = 0; i < memory_size; ++i) {
@@ -68,7 +69,7 @@
     EXPECT_EQ(IoSchedClass_NONE, service_in_old_memory2->ioprio_class());
     EXPECT_EQ(0, service_in_old_memory2->ioprio_pri());
     EXPECT_EQ(0, service_in_old_memory2->priority());
-    EXPECT_EQ(-1000, service_in_old_memory2->oom_score_adjust());
+    EXPECT_EQ(DEFAULT_OOM_SCORE_ADJUST, service_in_old_memory2->oom_score_adjust());
     EXPECT_FALSE(service_in_old_memory->process_cgroup_empty());
 }
 
diff --git a/init/ueventd.cpp b/init/ueventd.cpp
index 59f91ee..d2b503b 100644
--- a/init/ueventd.cpp
+++ b/init/ueventd.cpp
@@ -288,7 +288,7 @@
     // TODO: cleanup platform ueventd.rc to remove vendor specific device node entries (b/34968103)
     auto hardware = android::base::GetProperty("ro.hardware", "");
 
-    auto ueventd_configuration = ParseConfig({"/ueventd.rc", "/vendor/ueventd.rc",
+    auto ueventd_configuration = ParseConfig({"/system/etc/ueventd.rc", "/vendor/ueventd.rc",
                                               "/odm/ueventd.rc", "/ueventd." + hardware + ".rc"});
 
     uevent_handlers.emplace_back(std::make_unique<DeviceHandler>(
diff --git a/init/util.cpp b/init/util.cpp
index 40db838..ada9e78 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -434,6 +434,142 @@
     return {};
 }
 
+static FscryptAction FscryptInferAction(const std::string& dir) {
+    const std::string prefix = "/data/";
+
+    if (!android::base::StartsWith(dir, prefix)) {
+        return FscryptAction::kNone;
+    }
+
+    // Special-case /data/media/obb per b/64566063
+    if (dir == "/data/media/obb") {
+        // Try to set policy on this directory, but if it is non-empty this may fail.
+        return FscryptAction::kAttempt;
+    }
+
+    // Only set policy on first level /data directories
+    // To make this less restrictive, consider using a policy file.
+    // However this is overkill for as long as the policy is simply
+    // to apply a global policy to all /data folders created via makedir
+    if (dir.find_first_of('/', prefix.size()) != std::string::npos) {
+        return FscryptAction::kNone;
+    }
+
+    // Special case various directories that must not be encrypted,
+    // often because their subdirectories must be encrypted.
+    // This isn't a nice way to do this, see b/26641735
+    std::vector<std::string> directories_to_exclude = {
+            "lost+found", "system_ce", "system_de", "misc_ce",     "misc_de",
+            "vendor_ce",  "vendor_de", "media",     "data",        "user",
+            "user_de",    "apex",      "preloads",  "app-staging", "gsi",
+    };
+    for (const auto& d : directories_to_exclude) {
+        if ((prefix + d) == dir) {
+            return FscryptAction::kNone;
+        }
+    }
+    // Empty these directories if policy setting fails.
+    std::vector<std::string> wipe_on_failure = {
+            "rollback", "rollback-observer",  // b/139193659
+    };
+    for (const auto& d : wipe_on_failure) {
+        if ((prefix + d) == dir) {
+            return FscryptAction::kDeleteIfNecessary;
+        }
+    }
+    return FscryptAction::kRequire;
+}
+
+Result<MkdirOptions> ParseMkdir(const std::vector<std::string>& args) {
+    mode_t mode = 0755;
+    Result<uid_t> uid = -1;
+    Result<gid_t> gid = -1;
+    FscryptAction fscrypt_inferred_action = FscryptInferAction(args[1]);
+    FscryptAction fscrypt_action = fscrypt_inferred_action;
+    std::string ref_option = "ref";
+    bool set_option_encryption = false;
+    bool set_option_key = false;
+
+    for (size_t i = 2; i < args.size(); i++) {
+        switch (i) {
+            case 2:
+                mode = std::strtoul(args[2].c_str(), 0, 8);
+                break;
+            case 3:
+                uid = DecodeUid(args[3]);
+                if (!uid) {
+                    return Error()
+                           << "Unable to decode UID for '" << args[3] << "': " << uid.error();
+                }
+                break;
+            case 4:
+                gid = DecodeUid(args[4]);
+                if (!gid) {
+                    return Error()
+                           << "Unable to decode GID for '" << args[4] << "': " << gid.error();
+                }
+                break;
+            default:
+                auto parts = android::base::Split(args[i], "=");
+                if (parts.size() != 2) {
+                    return Error() << "Can't parse option: '" << args[i] << "'";
+                }
+                auto optname = parts[0];
+                auto optval = parts[1];
+                if (optname == "encryption") {
+                    if (set_option_encryption) {
+                        return Error() << "Duplicated option: '" << optname << "'";
+                    }
+                    if (optval == "Require") {
+                        fscrypt_action = FscryptAction::kRequire;
+                    } else if (optval == "None") {
+                        fscrypt_action = FscryptAction::kNone;
+                    } else if (optval == "Attempt") {
+                        fscrypt_action = FscryptAction::kAttempt;
+                    } else if (optval == "DeleteIfNecessary") {
+                        fscrypt_action = FscryptAction::kDeleteIfNecessary;
+                    } else {
+                        return Error() << "Unknown encryption option: '" << optval << "'";
+                    }
+                    set_option_encryption = true;
+                } else if (optname == "key") {
+                    if (set_option_key) {
+                        return Error() << "Duplicated option: '" << optname << "'";
+                    }
+                    if (optval == "ref" || optval == "per_boot_ref") {
+                        ref_option = optval;
+                    } else {
+                        return Error() << "Unknown key option: '" << optval << "'";
+                    }
+                    set_option_key = true;
+                } else {
+                    return Error() << "Unknown option: '" << args[i] << "'";
+                }
+        }
+    }
+    if (set_option_key && fscrypt_action == FscryptAction::kNone) {
+        return Error() << "Key option set but encryption action is none";
+    }
+    const std::string prefix = "/data/";
+    if (StartsWith(args[1], prefix) &&
+        args[1].find_first_of('/', prefix.size()) == std::string::npos) {
+        if (!set_option_encryption) {
+            LOG(WARNING) << "Top-level directory needs encryption action, eg mkdir " << args[1]
+                         << " <mode> <uid> <gid> encryption=Require";
+        }
+        if (fscrypt_action == FscryptAction::kNone) {
+            LOG(INFO) << "Not setting encryption policy on: " << args[1];
+        }
+    }
+    if (fscrypt_action != fscrypt_inferred_action) {
+        LOG(WARNING) << "Inferred action different from explicit one, expected "
+                     << static_cast<int>(fscrypt_inferred_action) << " but got "
+                     << static_cast<int>(fscrypt_action);
+    }
+
+    return MkdirOptions{args[1], mode, *uid, *gid, fscrypt_action, ref_option};
+}
+
 Result<std::pair<int, std::vector<std::string>>> ParseRestorecon(
         const std::vector<std::string>& args) {
     struct flag_type {
diff --git a/init/util.h b/init/util.h
index 4cccefe..3d81d72 100644
--- a/init/util.h
+++ b/init/util.h
@@ -25,6 +25,7 @@
 
 #include <android-base/chrono_utils.h>
 
+#include "fscrypt_init_extensions.h"
 #include "result.h"
 
 using android::base::boot_clock;
@@ -60,6 +61,17 @@
 bool IsLegalPropertyName(const std::string& name);
 Result<void> IsLegalPropertyValue(const std::string& name, const std::string& value);
 
+struct MkdirOptions {
+    std::string target;
+    mode_t mode;
+    uid_t uid;
+    gid_t gid;
+    FscryptAction fscrypt_action;
+    std::string ref_option;
+};
+
+Result<MkdirOptions> ParseMkdir(const std::vector<std::string>& args);
+
 Result<std::pair<int, std::vector<std::string>>> ParseRestorecon(
         const std::vector<std::string>& args);
 
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index b9420d4..1255896 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -114,36 +114,17 @@
         },
 
         android_arm: {
-            srcs: ["arch-arm/memset32.S"],
             sanitize: {
                 misc_undefined: ["integer"],
             },
         },
         android_arm64: {
-            srcs: ["arch-arm64/android_memset.S"],
-            sanitize: {
-                misc_undefined: ["integer"],
-            },
-        },
-
-        android_mips: {
-            srcs: ["arch-mips/android_memset.c"],
-            sanitize: {
-                misc_undefined: ["integer"],
-            },
-        },
-        android_mips64: {
-            srcs: ["arch-mips/android_memset.c"],
             sanitize: {
                 misc_undefined: ["integer"],
             },
         },
 
         android_x86: {
-            srcs: [
-                "arch-x86/android_memset16.S",
-                "arch-x86/android_memset32.S",
-            ],
             // TODO: This is to work around b/29412086.
             // Remove once __mulodi4 is available and move the "sanitize" block
             // to the android target.
@@ -153,10 +134,6 @@
         },
 
         android_x86_64: {
-            srcs: [
-                "arch-x86_64/android_memset16.S",
-                "arch-x86_64/android_memset32.S",
-            ],
             sanitize: {
                 misc_undefined: ["integer"],
             },
@@ -206,7 +183,6 @@
                 "android_get_control_socket_test.cpp",
                 "ashmem_test.cpp",
                 "fs_config_test.cpp",
-                "memset_test.cpp",
                 "multiuser_test.cpp",
                 "properties_test.cpp",
                 "sched_policy_test.cpp",
@@ -244,6 +220,7 @@
     defaults: ["libcutils_test_default"],
     host_supported: true,
     shared_libs: test_libraries,
+    require_root: true,
 }
 
 cc_test {
@@ -255,6 +232,7 @@
         "libcgrouprc_format",
     ] + test_libraries,
     stl: "libc++_static",
+    require_root: true,
 
     target: {
         android: {
diff --git a/libcutils/arch-arm/memset32.S b/libcutils/arch-arm/memset32.S
deleted file mode 100644
index 1e89636..0000000
--- a/libcutils/arch-arm/memset32.S
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- *  memset32.S
- *
- */
-
-    .syntax unified
-
-    .text
-    .align
-
-    .global android_memset32
-    .type   android_memset32, %function
-    .global android_memset16
-    .type   android_memset16, %function
-
-        /*
-         * Optimized memset32 and memset16 for ARM.
-         *
-         * void android_memset16(uint16_t* dst, uint16_t value, size_t size);
-         * void android_memset32(uint32_t* dst, uint32_t value, size_t size);
-         *
-         */
-
-android_memset16:
-        .fnstart
-        cmp         r2, #1
-        bxle        lr
-
-        /* expand the data to 32 bits */
-        mov         r1, r1, lsl #16
-        orr         r1, r1, r1, lsr #16
-
-        /* align to 32 bits */
-        tst         r0, #2
-        strhne      r1, [r0], #2
-        subne       r2, r2, #2
-        .fnend
-
-android_memset32:
-        .fnstart
-        .cfi_startproc
-        str         lr, [sp, #-4]!
-        .cfi_def_cfa_offset 4
-        .cfi_rel_offset lr, 0
-
-        /* align the destination to a cache-line */
-        mov         r12, r1
-        mov         lr, r1
-        rsb         r3, r0, #0
-        ands        r3, r3, #0x1C
-        beq         .Laligned32
-        cmp         r3, r2
-        andhi       r3, r2, #0x1C
-        sub         r2, r2, r3
-
-        /* conditionally writes 0 to 7 words (length in r3) */
-        movs        r3, r3, lsl #28
-        stmiacs     r0!, {r1, lr}
-        stmiacs     r0!, {r1, lr}
-        stmiami     r0!, {r1, lr}
-        movs        r3, r3, lsl #2
-        strcs       r1, [r0], #4
-
-.Laligned32:
-        mov         r3, r1
-1:      subs        r2, r2, #32
-        stmiahs     r0!, {r1,r3,r12,lr}
-        stmiahs     r0!, {r1,r3,r12,lr}
-        bhs         1b
-        add         r2, r2, #32
-
-        /* conditionally stores 0 to 30 bytes */
-        movs        r2, r2, lsl #28
-        stmiacs     r0!, {r1,r3,r12,lr}
-        stmiami     r0!, {r1,lr}
-        movs        r2, r2, lsl #2
-        strcs       r1, [r0], #4
-        strhmi      lr, [r0], #2
-
-        ldr         lr, [sp], #4
-        .cfi_def_cfa_offset 0
-        .cfi_restore lr
-        bx          lr
-        .cfi_endproc
-        .fnend
diff --git a/libcutils/arch-arm64/android_memset.S b/libcutils/arch-arm64/android_memset.S
deleted file mode 100644
index 9a83a68..0000000
--- a/libcutils/arch-arm64/android_memset.S
+++ /dev/null
@@ -1,211 +0,0 @@
-/* Copyright (c) 2012, Linaro Limited
-   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.
-       * Neither the name of the Linaro nor the
-         names of its contributors may be used to endorse or promote products
-         derived from this software without specific prior written permission.
-
-   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
-   HOLDER 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.
-*/
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64
- * Unaligned accesses
- *
- */
-
-/* By default we assume that the DC instruction can be used to zero
-   data blocks more efficiently.  In some circumstances this might be
-   unsafe, for example in an asymmetric multiprocessor environment with
-   different DC clear lengths (neither the upper nor lower lengths are
-   safe to use). */
-
-#define dst  		x0
-#define count		x2
-#define tmp1		x3
-#define tmp1w		w3
-#define tmp2		x4
-#define tmp2w		w4
-#define zva_len_x	x5
-#define zva_len		w5
-#define zva_bits_x	x6
-
-#define A_l		x1
-#define A_lw		w1
-#define tmp3w		w9
-
-#define ENTRY(f) \
-  .text; \
-  .globl f; \
-  .align 0; \
-  .type f, %function; \
-  f: \
-  .cfi_startproc \
-
-#define END(f) \
-  .cfi_endproc; \
-  .size f, .-f; \
-
-ENTRY(android_memset16)
-	ands   A_lw, A_lw, #0xffff
-	b.eq	.Lzero_mem
-	orr	A_lw, A_lw, A_lw, lsl #16
-	b .Lexpand_to_64
-END(android_memset16)
-
-ENTRY(android_memset32)
-	cmp	    A_lw, #0
-	b.eq	.Lzero_mem
-.Lexpand_to_64:
-	orr	A_l, A_l, A_l, lsl #32
-.Ltail_maybe_long:
-	cmp	count, #64
-	b.ge	.Lnot_short
-.Ltail_maybe_tiny:
-	cmp	count, #15
-	b.le	.Ltail15tiny
-.Ltail63:
-	ands	tmp1, count, #0x30
-	b.eq	.Ltail15
-	add	dst, dst, tmp1
-	cmp	tmp1w, #0x20
-	b.eq	1f
-	b.lt	2f
-	stp	A_l, A_l, [dst, #-48]
-1:
-	stp	A_l, A_l, [dst, #-32]
-2:
-	stp	A_l, A_l, [dst, #-16]
-
-.Ltail15:
-	and	count, count, #15
-	add	dst, dst, count
-	stp	A_l, A_l, [dst, #-16]	/* Repeat some/all of last store. */
-	ret
-
-.Ltail15tiny:
-	/* Set up to 15 bytes.  Does not assume earlier memory
-	   being set.  */
-	tbz	count, #3, 1f
-	str	A_l, [dst], #8
-1:
-	tbz	count, #2, 1f
-	str	A_lw, [dst], #4
-1:
-	tbz	count, #1, 1f
-	strh	A_lw, [dst], #2
-1:
-	ret
-
-	/* Critical loop.  Start at a new cache line boundary.  Assuming
-	 * 64 bytes per line, this ensures the entire loop is in one line.  */
-	.p2align 6
-.Lnot_short:
-	neg	tmp2, dst
-	ands	tmp2, tmp2, #15
-	b.eq	2f
-	/* Bring DST to 128-bit (16-byte) alignment.  We know that there's
-	 * more than that to set, so we simply store 16 bytes and advance by
-	 * the amount required to reach alignment.  */
-	sub	count, count, tmp2
-	stp	A_l, A_l, [dst]
-	add	dst, dst, tmp2
-	/* There may be less than 63 bytes to go now.  */
-	cmp	count, #63
-	b.le	.Ltail63
-2:
-	sub	dst, dst, #16		/* Pre-bias.  */
-	sub	count, count, #64
-1:
-	stp	A_l, A_l, [dst, #16]
-	stp	A_l, A_l, [dst, #32]
-	stp	A_l, A_l, [dst, #48]
-	stp	A_l, A_l, [dst, #64]!
-	subs	count, count, #64
-	b.ge	1b
-	tst	count, #0x3f
-	add	dst, dst, #16
-	b.ne	.Ltail63
-	ret
-
-	/* For zeroing memory, check to see if we can use the ZVA feature to
-	 * zero entire 'cache' lines.  */
-.Lzero_mem:
-	mov	A_l, #0
-	cmp	count, #63
-	b.le	.Ltail_maybe_tiny
-	neg	tmp2, dst
-	ands	tmp2, tmp2, #15
-	b.eq	1f
-	sub	count, count, tmp2
-	stp	A_l, A_l, [dst]
-	add	dst, dst, tmp2
-	cmp	count, #63
-	b.le	.Ltail63
-1:
-	/* For zeroing small amounts of memory, it's not worth setting up
-	 * the line-clear code.  */
-	cmp	count, #128
-	b.lt	.Lnot_short
-	mrs	tmp1, dczid_el0
-	tbnz	tmp1, #4, .Lnot_short
-	mov	tmp3w, #4
-	and	zva_len, tmp1w, #15	/* Safety: other bits reserved.  */
-	lsl	zva_len, tmp3w, zva_len
-
-.Lzero_by_line:
-	/* Compute how far we need to go to become suitably aligned.  We're
-	 * already at quad-word alignment.  */
-	cmp	count, zva_len_x
-	b.lt	.Lnot_short		/* Not enough to reach alignment.  */
-	sub	zva_bits_x, zva_len_x, #1
-	neg	tmp2, dst
-	ands	tmp2, tmp2, zva_bits_x
-	b.eq	1f			/* Already aligned.  */
-	/* Not aligned, check that there's enough to copy after alignment.  */
-	sub	tmp1, count, tmp2
-	cmp	tmp1, #64
-	ccmp	tmp1, zva_len_x, #8, ge	/* NZCV=0b1000 */
-	b.lt	.Lnot_short
-	/* We know that there's at least 64 bytes to zero and that it's safe
-	 * to overrun by 64 bytes.  */
-	mov	count, tmp1
-2:
-	stp	A_l, A_l, [dst]
-	stp	A_l, A_l, [dst, #16]
-	stp	A_l, A_l, [dst, #32]
-	subs	tmp2, tmp2, #64
-	stp	A_l, A_l, [dst, #48]
-	add	dst, dst, #64
-	b.ge	2b
-	/* We've overrun a bit, so adjust dst downwards.  */
-	add	dst, dst, tmp2
-1:
-	sub	count, count, zva_len_x
-3:
-	dc	zva, dst
-	add	dst, dst, zva_len_x
-	subs	count, count, zva_len_x
-	b.ge	3b
-	ands	count, count, zva_bits_x
-	b.ne	.Ltail_maybe_long
-	ret
-END(android_memset32)
diff --git a/libcutils/arch-mips/android_memset.c b/libcutils/arch-mips/android_memset.c
deleted file mode 100644
index c0fe3d1..0000000
--- a/libcutils/arch-mips/android_memset.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-
-/* generic C version for any machine */
-
-#include <cutils/memory.h>
-
-#ifdef __clang__
-__attribute__((no_sanitize("integer")))
-#endif
-void android_memset16(uint16_t* dst, uint16_t value, size_t size)
-{
-   /* optimized version of
-      size >>= 1;
-      while (size--)
-        *dst++ = value;
-   */
-
-   size >>= 1;
-   if (((uintptr_t)dst & 2) && size) {
-      /* fill unpaired first elem separately */
-      *dst++ = value;
-      size--;
-   }
-   /* dst is now 32-bit-aligned */
-   /* fill body with 32-bit pairs */
-   uint32_t value32 = (((uint32_t)value) << 16) | ((uint32_t)value);
-   android_memset32((uint32_t*) dst, value32, size<<1);
-   if (size & 1) {
-      dst[size-1] = value;  /* fill unpaired last elem */
-   }
-}
-
-
-#ifdef __clang__
-__attribute__((no_sanitize("integer")))
-#endif
-void android_memset32(uint32_t* dst, uint32_t value, size_t size)
-{
-   /* optimized version of
-      size >>= 2;
-      while (size--)
-         *dst++ = value;
-   */
-
-   size >>= 2;
-   if (((uintptr_t)dst & 4) && size) {
-      /* fill unpaired first 32-bit elem separately */
-      *dst++ = value;
-      size--;
-   }
-   /* dst is now 64-bit aligned */
-   /* fill body with 64-bit pairs */
-   uint64_t value64 = (((uint64_t)value) << 32) | ((uint64_t)value);
-   uint64_t* dst64 = (uint64_t*)dst;
-
-   while (size >= 12) {
-      dst64[0] = value64;
-      dst64[1] = value64;
-      dst64[2] = value64;
-      dst64[3] = value64;
-      dst64[4] = value64;
-      dst64[5] = value64;
-      size  -= 12;
-      dst64 += 6;
-   }
-
-   /* fill remainder with original 32-bit single-elem loop */
-   dst = (uint32_t*) dst64;
-   while (size != 0) {
-       size--;
-      *dst++ = value;
-   }
-
-}
diff --git a/libcutils/arch-x86/android_memset16.S b/libcutils/arch-x86/android_memset16.S
deleted file mode 100755
index cb2ff14..0000000
--- a/libcutils/arch-x86/android_memset16.S
+++ /dev/null
@@ -1,719 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "cache.h"
-
-#ifndef MEMSET
-# define MEMSET		android_memset16
-#endif
-
-#ifndef L
-# define L(label)	.L##label
-#endif
-
-#ifndef ALIGN
-# define ALIGN(n)	.p2align n
-#endif
-
-#ifndef cfi_startproc
-# define cfi_startproc			.cfi_startproc
-#endif
-
-#ifndef cfi_endproc
-# define cfi_endproc			.cfi_endproc
-#endif
-
-#ifndef cfi_rel_offset
-# define cfi_rel_offset(reg, off)	.cfi_rel_offset reg, off
-#endif
-
-#ifndef cfi_restore
-# define cfi_restore(reg)		.cfi_restore reg
-#endif
-
-#ifndef cfi_adjust_cfa_offset
-# define cfi_adjust_cfa_offset(off)	.cfi_adjust_cfa_offset off
-#endif
-
-#ifndef ENTRY
-# define ENTRY(name)			\
-	.type name,  @function; 	\
-	.globl name;			\
-	.p2align 4;			\
-name:					\
-	cfi_startproc
-#endif
-
-#ifndef END
-# define END(name)			\
-	cfi_endproc;			\
-	.size name, .-name
-#endif
-
-#define CFI_PUSH(REG)						\
-  cfi_adjust_cfa_offset (4);					\
-  cfi_rel_offset (REG, 0)
-
-#define CFI_POP(REG)						\
-  cfi_adjust_cfa_offset (-4);					\
-  cfi_restore (REG)
-
-#define PUSH(REG)	pushl REG; CFI_PUSH (REG)
-#define POP(REG)	popl REG; CFI_POP (REG)
-
-#ifdef USE_AS_BZERO16
-# define DEST		PARMS
-# define LEN		DEST+4
-# define SETRTNVAL
-#else
-# define DEST		PARMS
-# define CHR		DEST+4
-# define LEN		CHR+4
-# define SETRTNVAL	movl DEST(%esp), %eax
-#endif
-
-#if (defined SHARED || defined __PIC__)
-# define ENTRANCE	PUSH (%ebx);
-# define RETURN_END	POP (%ebx); ret
-# define RETURN		RETURN_END; CFI_PUSH (%ebx)
-# define PARMS		8		/* Preserve EBX.  */
-# define JMPTBL(I, B)	I - B
-
-/* Load an entry in a jump table into EBX and branch to it.  TABLE is a
-   jump table with relative offsets.   */
-# define BRANCH_TO_JMPTBL_ENTRY(TABLE)				\
-    /* We first load PC into EBX.  */				\
-    call	__x86.get_pc_thunk.bx;				\
-    /* Get the address of the jump table.  */			\
-    add		$(TABLE - .), %ebx;				\
-    /* Get the entry and convert the relative offset to the	\
-       absolute address.  */					\
-    add		(%ebx,%ecx,4), %ebx;				\
-    /* We loaded the jump table and adjuested EDX. Go.  */	\
-    jmp		*%ebx
-
-	.section	.gnu.linkonce.t.__x86.get_pc_thunk.bx,"ax",@progbits
-	.globl	__x86.get_pc_thunk.bx
-	.hidden	__x86.get_pc_thunk.bx
-	ALIGN (4)
-	.type	__x86.get_pc_thunk.bx,@function
-__x86.get_pc_thunk.bx:
-	movl	(%esp), %ebx
-	ret
-#else
-# define ENTRANCE
-# define RETURN_END	ret
-# define RETURN		RETURN_END
-# define PARMS		4
-# define JMPTBL(I, B)	I
-
-/* Branch to an entry in a jump table.  TABLE is a jump table with
-   absolute offsets.  */
-# define BRANCH_TO_JMPTBL_ENTRY(TABLE)				\
-    jmp		*TABLE(,%ecx,4)
-#endif
-
-	.section .text.sse2,"ax",@progbits
-	ALIGN (4)
-ENTRY (MEMSET)
-	ENTRANCE
-
-	movl	LEN(%esp), %ecx
-	shr	$1, %ecx
-#ifdef USE_AS_BZERO16
-	xor	%eax, %eax
-#else
-	movzwl	CHR(%esp), %eax
-	mov	%eax, %edx
-	shl	$16, %eax
-	or	%edx, %eax
-#endif
-	movl	DEST(%esp), %edx
-	cmp	$32, %ecx
-	jae	L(32wordsormore)
-
-L(write_less32words):
-	lea	(%edx, %ecx, 2), %edx
-	BRANCH_TO_JMPTBL_ENTRY (L(table_less32words))
-
-
-	.pushsection .rodata.sse2,"a",@progbits
-	ALIGN (2)
-L(table_less32words):
-	.int	JMPTBL (L(write_0words), L(table_less32words))
-	.int	JMPTBL (L(write_1words), L(table_less32words))
-	.int	JMPTBL (L(write_2words), L(table_less32words))
-	.int	JMPTBL (L(write_3words), L(table_less32words))
-	.int	JMPTBL (L(write_4words), L(table_less32words))
-	.int	JMPTBL (L(write_5words), L(table_less32words))
-	.int	JMPTBL (L(write_6words), L(table_less32words))
-	.int	JMPTBL (L(write_7words), L(table_less32words))
-	.int	JMPTBL (L(write_8words), L(table_less32words))
-	.int	JMPTBL (L(write_9words), L(table_less32words))
-	.int	JMPTBL (L(write_10words), L(table_less32words))
-	.int	JMPTBL (L(write_11words), L(table_less32words))
-	.int	JMPTBL (L(write_12words), L(table_less32words))
-	.int	JMPTBL (L(write_13words), L(table_less32words))
-	.int	JMPTBL (L(write_14words), L(table_less32words))
-	.int	JMPTBL (L(write_15words), L(table_less32words))
-	.int	JMPTBL (L(write_16words), L(table_less32words))
-	.int	JMPTBL (L(write_17words), L(table_less32words))
-	.int	JMPTBL (L(write_18words), L(table_less32words))
-	.int	JMPTBL (L(write_19words), L(table_less32words))
-	.int	JMPTBL (L(write_20words), L(table_less32words))
-	.int	JMPTBL (L(write_21words), L(table_less32words))
-	.int	JMPTBL (L(write_22words), L(table_less32words))
-	.int	JMPTBL (L(write_23words), L(table_less32words))
-	.int	JMPTBL (L(write_24words), L(table_less32words))
-	.int	JMPTBL (L(write_25words), L(table_less32words))
-	.int	JMPTBL (L(write_26words), L(table_less32words))
-	.int	JMPTBL (L(write_27words), L(table_less32words))
-	.int	JMPTBL (L(write_28words), L(table_less32words))
-	.int	JMPTBL (L(write_29words), L(table_less32words))
-	.int	JMPTBL (L(write_30words), L(table_less32words))
-	.int	JMPTBL (L(write_31words), L(table_less32words))
-	.popsection
-
-	ALIGN (4)
-L(write_28words):
-	movl	%eax, -56(%edx)
-	movl	%eax, -52(%edx)
-L(write_24words):
-	movl	%eax, -48(%edx)
-	movl	%eax, -44(%edx)
-L(write_20words):
-	movl	%eax, -40(%edx)
-	movl	%eax, -36(%edx)
-L(write_16words):
-	movl	%eax, -32(%edx)
-	movl	%eax, -28(%edx)
-L(write_12words):
-	movl	%eax, -24(%edx)
-	movl	%eax, -20(%edx)
-L(write_8words):
-	movl	%eax, -16(%edx)
-	movl	%eax, -12(%edx)
-L(write_4words):
-	movl	%eax, -8(%edx)
-	movl	%eax, -4(%edx)
-L(write_0words):
-	SETRTNVAL
-	RETURN
-
-	ALIGN (4)
-L(write_29words):
-	movl	%eax, -58(%edx)
-	movl	%eax, -54(%edx)
-L(write_25words):
-	movl	%eax, -50(%edx)
-	movl	%eax, -46(%edx)
-L(write_21words):
-	movl	%eax, -42(%edx)
-	movl	%eax, -38(%edx)
-L(write_17words):
-	movl	%eax, -34(%edx)
-	movl	%eax, -30(%edx)
-L(write_13words):
-	movl	%eax, -26(%edx)
-	movl	%eax, -22(%edx)
-L(write_9words):
-	movl	%eax, -18(%edx)
-	movl	%eax, -14(%edx)
-L(write_5words):
-	movl	%eax, -10(%edx)
-	movl	%eax, -6(%edx)
-L(write_1words):
-	mov	%ax, -2(%edx)
-	SETRTNVAL
-	RETURN
-
-	ALIGN (4)
-L(write_30words):
-	movl	%eax, -60(%edx)
-	movl	%eax, -56(%edx)
-L(write_26words):
-	movl	%eax, -52(%edx)
-	movl	%eax, -48(%edx)
-L(write_22words):
-	movl	%eax, -44(%edx)
-	movl	%eax, -40(%edx)
-L(write_18words):
-	movl	%eax, -36(%edx)
-	movl	%eax, -32(%edx)
-L(write_14words):
-	movl	%eax, -28(%edx)
-	movl	%eax, -24(%edx)
-L(write_10words):
-	movl	%eax, -20(%edx)
-	movl	%eax, -16(%edx)
-L(write_6words):
-	movl	%eax, -12(%edx)
-	movl	%eax, -8(%edx)
-L(write_2words):
-	movl	%eax, -4(%edx)
-	SETRTNVAL
-	RETURN
-
-	ALIGN (4)
-L(write_31words):
-	movl	%eax, -62(%edx)
-	movl	%eax, -58(%edx)
-L(write_27words):
-	movl	%eax, -54(%edx)
-	movl	%eax, -50(%edx)
-L(write_23words):
-	movl	%eax, -46(%edx)
-	movl	%eax, -42(%edx)
-L(write_19words):
-	movl	%eax, -38(%edx)
-	movl	%eax, -34(%edx)
-L(write_15words):
-	movl	%eax, -30(%edx)
-	movl	%eax, -26(%edx)
-L(write_11words):
-	movl	%eax, -22(%edx)
-	movl	%eax, -18(%edx)
-L(write_7words):
-	movl	%eax, -14(%edx)
-	movl	%eax, -10(%edx)
-L(write_3words):
-	movl	%eax, -6(%edx)
-	movw	%ax, -2(%edx)
-	SETRTNVAL
-	RETURN
-
-	ALIGN (4)
-
-L(32wordsormore):
-	shl	$1, %ecx
-	test	$0x01, %edx
-	jz	L(aligned2bytes)
-	mov	%eax, (%edx)
-	mov	%eax, -4(%edx, %ecx)
-	sub	$2, %ecx
-	add	$1, %edx
-	rol	$8, %eax
-L(aligned2bytes):
-#ifdef USE_AS_BZERO16
-	pxor	%xmm0, %xmm0
-#else
-	movd	%eax, %xmm0
-	pshufd	$0, %xmm0, %xmm0
-#endif
-	testl	$0xf, %edx
-	jz	L(aligned_16)
-/* ECX > 32 and EDX is not 16 byte aligned.  */
-L(not_aligned_16):
-	movdqu	%xmm0, (%edx)
-	movl	%edx, %eax
-	and	$-16, %edx
-	add	$16, %edx
-	sub	%edx, %eax
-	add	%eax, %ecx
-	movd	%xmm0, %eax
-
-	ALIGN (4)
-L(aligned_16):
-	cmp	$128, %ecx
-	jae	L(128bytesormore)
-
-L(aligned_16_less128bytes):
-	add	%ecx, %edx
-	shr	$1, %ecx
-	BRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes))
-
-	ALIGN (4)
-L(128bytesormore):
-#ifdef SHARED_CACHE_SIZE
-	PUSH (%ebx)
-	mov	$SHARED_CACHE_SIZE, %ebx
-#else
-# if (defined SHARED || defined __PIC__)
-	call	__x86.get_pc_thunk.bx
-	add	$_GLOBAL_OFFSET_TABLE_, %ebx
-	mov	__x86_shared_cache_size@GOTOFF(%ebx), %ebx
-# else
-	PUSH (%ebx)
-	mov	__x86_shared_cache_size, %ebx
-# endif
-#endif
-	cmp	%ebx, %ecx
-	jae	L(128bytesormore_nt_start)
-
-
-#ifdef DATA_CACHE_SIZE
-	POP (%ebx)
-# define RESTORE_EBX_STATE CFI_PUSH (%ebx)
-	cmp	$DATA_CACHE_SIZE, %ecx
-#else
-# if (defined SHARED || defined __PIC__)
-#  define RESTORE_EBX_STATE
-	call	__x86.get_pc_thunk.bx
-	add	$_GLOBAL_OFFSET_TABLE_, %ebx
-	cmp	__x86_data_cache_size@GOTOFF(%ebx), %ecx
-# else
-	POP (%ebx)
-#  define RESTORE_EBX_STATE CFI_PUSH (%ebx)
-	cmp	__x86_data_cache_size, %ecx
-# endif
-#endif
-
-	jae	L(128bytes_L2_normal)
-	subl	$128, %ecx
-L(128bytesormore_normal):
-	sub	$128, %ecx
-	movdqa	%xmm0, (%edx)
-	movdqa	%xmm0, 0x10(%edx)
-	movdqa	%xmm0, 0x20(%edx)
-	movdqa	%xmm0, 0x30(%edx)
-	movdqa	%xmm0, 0x40(%edx)
-	movdqa	%xmm0, 0x50(%edx)
-	movdqa	%xmm0, 0x60(%edx)
-	movdqa	%xmm0, 0x70(%edx)
-	lea	128(%edx), %edx
-	jb	L(128bytesless_normal)
-
-
-	sub	$128, %ecx
-	movdqa	%xmm0, (%edx)
-	movdqa	%xmm0, 0x10(%edx)
-	movdqa	%xmm0, 0x20(%edx)
-	movdqa	%xmm0, 0x30(%edx)
-	movdqa	%xmm0, 0x40(%edx)
-	movdqa	%xmm0, 0x50(%edx)
-	movdqa	%xmm0, 0x60(%edx)
-	movdqa	%xmm0, 0x70(%edx)
-	lea	128(%edx), %edx
-	jae	L(128bytesormore_normal)
-
-L(128bytesless_normal):
-	lea	128(%ecx), %ecx
-	add	%ecx, %edx
-	shr	$1, %ecx
-	BRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes))
-
-	ALIGN (4)
-L(128bytes_L2_normal):
-	prefetcht0	0x380(%edx)
-	prefetcht0	0x3c0(%edx)
-	sub	$128, %ecx
-	movdqa	%xmm0, (%edx)
-	movaps	%xmm0, 0x10(%edx)
-	movaps	%xmm0, 0x20(%edx)
-	movaps	%xmm0, 0x30(%edx)
-	movaps	%xmm0, 0x40(%edx)
-	movaps	%xmm0, 0x50(%edx)
-	movaps	%xmm0, 0x60(%edx)
-	movaps	%xmm0, 0x70(%edx)
-	add	$128, %edx
-	cmp	$128, %ecx
-	jae	L(128bytes_L2_normal)
-
-L(128bytesless_L2_normal):
-	add	%ecx, %edx
-	shr	$1, %ecx
-	BRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes))
-
-	RESTORE_EBX_STATE
-L(128bytesormore_nt_start):
-	sub	%ebx, %ecx
-	mov	%ebx, %eax
-	and	$0x7f, %eax
-	add	%eax, %ecx
-	movd	%xmm0, %eax
-	ALIGN (4)
-L(128bytesormore_shared_cache_loop):
-	prefetcht0	0x3c0(%edx)
-	prefetcht0	0x380(%edx)
-	sub	$0x80, %ebx
-	movdqa	%xmm0, (%edx)
-	movdqa	%xmm0, 0x10(%edx)
-	movdqa	%xmm0, 0x20(%edx)
-	movdqa	%xmm0, 0x30(%edx)
-	movdqa	%xmm0, 0x40(%edx)
-	movdqa	%xmm0, 0x50(%edx)
-	movdqa	%xmm0, 0x60(%edx)
-	movdqa	%xmm0, 0x70(%edx)
-	add	$0x80, %edx
-	cmp	$0x80, %ebx
-	jae	L(128bytesormore_shared_cache_loop)
-	cmp	$0x80, %ecx
-	jb	L(shared_cache_loop_end)
-	ALIGN (4)
-L(128bytesormore_nt):
-	sub	$0x80, %ecx
-	movntdq	%xmm0, (%edx)
-	movntdq	%xmm0, 0x10(%edx)
-	movntdq	%xmm0, 0x20(%edx)
-	movntdq	%xmm0, 0x30(%edx)
-	movntdq	%xmm0, 0x40(%edx)
-	movntdq	%xmm0, 0x50(%edx)
-	movntdq	%xmm0, 0x60(%edx)
-	movntdq	%xmm0, 0x70(%edx)
-	add	$0x80, %edx
-	cmp	$0x80, %ecx
-	jae	L(128bytesormore_nt)
-	sfence
-L(shared_cache_loop_end):
-#if defined DATA_CACHE_SIZE || !(defined SHARED || defined __PIC__)
-	POP (%ebx)
-#endif
-	add	%ecx, %edx
-	shr	$1, %ecx
-	BRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes))
-
-
-	.pushsection .rodata.sse2,"a",@progbits
-	ALIGN (2)
-L(table_16_128bytes):
-	.int	JMPTBL (L(aligned_16_0bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_2bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_4bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_6bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_8bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_10bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_12bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_14bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_16bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_18bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_20bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_22bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_24bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_26bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_28bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_30bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_32bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_34bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_36bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_38bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_40bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_42bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_44bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_46bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_48bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_50bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_52bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_54bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_56bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_58bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_60bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_62bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_64bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_66bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_68bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_70bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_72bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_74bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_76bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_78bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_80bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_82bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_84bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_86bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_88bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_90bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_92bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_94bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_96bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_98bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_100bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_102bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_104bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_106bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_108bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_110bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_112bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_114bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_116bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_118bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_120bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_122bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_124bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_126bytes), L(table_16_128bytes))
-	.popsection
-
-
-	ALIGN (4)
-L(aligned_16_112bytes):
-	movdqa	%xmm0, -112(%edx)
-L(aligned_16_96bytes):
-	movdqa	%xmm0, -96(%edx)
-L(aligned_16_80bytes):
-	movdqa	%xmm0, -80(%edx)
-L(aligned_16_64bytes):
-	movdqa	%xmm0, -64(%edx)
-L(aligned_16_48bytes):
-	movdqa	%xmm0, -48(%edx)
-L(aligned_16_32bytes):
-	movdqa	%xmm0, -32(%edx)
-L(aligned_16_16bytes):
-	movdqa	%xmm0, -16(%edx)
-L(aligned_16_0bytes):
-	SETRTNVAL
-	RETURN
-
-
-	ALIGN (4)
-L(aligned_16_114bytes):
-	movdqa	%xmm0, -114(%edx)
-L(aligned_16_98bytes):
-	movdqa	%xmm0, -98(%edx)
-L(aligned_16_82bytes):
-	movdqa	%xmm0, -82(%edx)
-L(aligned_16_66bytes):
-	movdqa	%xmm0, -66(%edx)
-L(aligned_16_50bytes):
-	movdqa	%xmm0, -50(%edx)
-L(aligned_16_34bytes):
-	movdqa	%xmm0, -34(%edx)
-L(aligned_16_18bytes):
-	movdqa	%xmm0, -18(%edx)
-L(aligned_16_2bytes):
-	movw	%ax, -2(%edx)
-	SETRTNVAL
-	RETURN
-
-	ALIGN (4)
-L(aligned_16_116bytes):
-	movdqa	%xmm0, -116(%edx)
-L(aligned_16_100bytes):
-	movdqa	%xmm0, -100(%edx)
-L(aligned_16_84bytes):
-	movdqa	%xmm0, -84(%edx)
-L(aligned_16_68bytes):
-	movdqa	%xmm0, -68(%edx)
-L(aligned_16_52bytes):
-	movdqa	%xmm0, -52(%edx)
-L(aligned_16_36bytes):
-	movdqa	%xmm0, -36(%edx)
-L(aligned_16_20bytes):
-	movdqa	%xmm0, -20(%edx)
-L(aligned_16_4bytes):
-	movl	%eax, -4(%edx)
-	SETRTNVAL
-	RETURN
-
-
-	ALIGN (4)
-L(aligned_16_118bytes):
-	movdqa	%xmm0, -118(%edx)
-L(aligned_16_102bytes):
-	movdqa	%xmm0, -102(%edx)
-L(aligned_16_86bytes):
-	movdqa	%xmm0, -86(%edx)
-L(aligned_16_70bytes):
-	movdqa	%xmm0, -70(%edx)
-L(aligned_16_54bytes):
-	movdqa	%xmm0, -54(%edx)
-L(aligned_16_38bytes):
-	movdqa	%xmm0, -38(%edx)
-L(aligned_16_22bytes):
-	movdqa	%xmm0, -22(%edx)
-L(aligned_16_6bytes):
-	movl	%eax, -6(%edx)
-	movw	%ax, -2(%edx)
-	SETRTNVAL
-	RETURN
-
-
-	ALIGN (4)
-L(aligned_16_120bytes):
-	movdqa	%xmm0, -120(%edx)
-L(aligned_16_104bytes):
-	movdqa	%xmm0, -104(%edx)
-L(aligned_16_88bytes):
-	movdqa	%xmm0, -88(%edx)
-L(aligned_16_72bytes):
-	movdqa	%xmm0, -72(%edx)
-L(aligned_16_56bytes):
-	movdqa	%xmm0, -56(%edx)
-L(aligned_16_40bytes):
-	movdqa	%xmm0, -40(%edx)
-L(aligned_16_24bytes):
-	movdqa	%xmm0, -24(%edx)
-L(aligned_16_8bytes):
-	movq	%xmm0, -8(%edx)
-	SETRTNVAL
-	RETURN
-
-
-	ALIGN (4)
-L(aligned_16_122bytes):
-	movdqa	%xmm0, -122(%edx)
-L(aligned_16_106bytes):
-	movdqa	%xmm0, -106(%edx)
-L(aligned_16_90bytes):
-	movdqa	%xmm0, -90(%edx)
-L(aligned_16_74bytes):
-	movdqa	%xmm0, -74(%edx)
-L(aligned_16_58bytes):
-	movdqa	%xmm0, -58(%edx)
-L(aligned_16_42bytes):
-	movdqa	%xmm0, -42(%edx)
-L(aligned_16_26bytes):
-	movdqa	%xmm0, -26(%edx)
-L(aligned_16_10bytes):
-	movq	%xmm0, -10(%edx)
-	movw	%ax, -2(%edx)
-	SETRTNVAL
-	RETURN
-
-
-	ALIGN (4)
-L(aligned_16_124bytes):
-	movdqa	%xmm0, -124(%edx)
-L(aligned_16_108bytes):
-	movdqa	%xmm0, -108(%edx)
-L(aligned_16_92bytes):
-	movdqa	%xmm0, -92(%edx)
-L(aligned_16_76bytes):
-	movdqa	%xmm0, -76(%edx)
-L(aligned_16_60bytes):
-	movdqa	%xmm0, -60(%edx)
-L(aligned_16_44bytes):
-	movdqa	%xmm0, -44(%edx)
-L(aligned_16_28bytes):
-	movdqa	%xmm0, -28(%edx)
-L(aligned_16_12bytes):
-	movq	%xmm0, -12(%edx)
-	movl	%eax, -4(%edx)
-	SETRTNVAL
-	RETURN
-
-
-	ALIGN (4)
-L(aligned_16_126bytes):
-	movdqa	%xmm0, -126(%edx)
-L(aligned_16_110bytes):
-	movdqa	%xmm0, -110(%edx)
-L(aligned_16_94bytes):
-	movdqa	%xmm0, -94(%edx)
-L(aligned_16_78bytes):
-	movdqa	%xmm0, -78(%edx)
-L(aligned_16_62bytes):
-	movdqa	%xmm0, -62(%edx)
-L(aligned_16_46bytes):
-	movdqa	%xmm0, -46(%edx)
-L(aligned_16_30bytes):
-	movdqa	%xmm0, -30(%edx)
-L(aligned_16_14bytes):
-	movq	%xmm0, -14(%edx)
-	movl	%eax, -6(%edx)
-	movw	%ax, -2(%edx)
-	SETRTNVAL
-	RETURN
-
-END (MEMSET)
diff --git a/libcutils/arch-x86/android_memset32.S b/libcutils/arch-x86/android_memset32.S
deleted file mode 100755
index f4326dc..0000000
--- a/libcutils/arch-x86/android_memset32.S
+++ /dev/null
@@ -1,510 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "cache.h"
-
-#ifndef MEMSET
-# define MEMSET 	android_memset32
-#endif
-
-#ifndef L
-# define L(label)	.L##label
-#endif
-
-#ifndef ALIGN
-# define ALIGN(n)	.p2align n
-#endif
-
-#ifndef cfi_startproc
-# define cfi_startproc			.cfi_startproc
-#endif
-
-#ifndef cfi_endproc
-# define cfi_endproc			.cfi_endproc
-#endif
-
-#ifndef cfi_rel_offset
-# define cfi_rel_offset(reg, off)	.cfi_rel_offset reg, off
-#endif
-
-#ifndef cfi_restore
-# define cfi_restore(reg)		.cfi_restore reg
-#endif
-
-#ifndef cfi_adjust_cfa_offset
-# define cfi_adjust_cfa_offset(off)	.cfi_adjust_cfa_offset off
-#endif
-
-#ifndef ENTRY
-# define ENTRY(name)			\
-	.type name,  @function; 	\
-	.globl name;			\
-	.p2align 4;			\
-name:					\
-	cfi_startproc
-#endif
-
-#ifndef END
-# define END(name)			\
-	cfi_endproc;			\
-	.size name, .-name
-#endif
-
-#define CFI_PUSH(REG)						\
-  cfi_adjust_cfa_offset (4);					\
-  cfi_rel_offset (REG, 0)
-
-#define CFI_POP(REG)						\
-  cfi_adjust_cfa_offset (-4);					\
-  cfi_restore (REG)
-
-#define PUSH(REG)	pushl REG; CFI_PUSH (REG)
-#define POP(REG)	popl REG; CFI_POP (REG)
-
-#ifdef USE_AS_BZERO32
-# define DEST		PARMS
-# define LEN		DEST+4
-# define SETRTNVAL
-#else
-# define DEST		PARMS
-# define DWDS		DEST+4
-# define LEN		DWDS+4
-# define SETRTNVAL	movl DEST(%esp), %eax
-#endif
-
-#if (defined SHARED || defined __PIC__)
-# define ENTRANCE	PUSH (%ebx);
-# define RETURN_END	POP (%ebx); ret
-# define RETURN		RETURN_END; CFI_PUSH (%ebx)
-# define PARMS		8		/* Preserve EBX.  */
-# define JMPTBL(I, B)	I - B
-
-/* Load an entry in a jump table into EBX and branch to it.  TABLE is a
-   jump table with relative offsets.   */
-# define BRANCH_TO_JMPTBL_ENTRY(TABLE)				\
-    /* We first load PC into EBX.  */				\
-    call	__x86.get_pc_thunk.bx;				\
-    /* Get the address of the jump table.  */			\
-    add		$(TABLE - .), %ebx;				\
-    /* Get the entry and convert the relative offset to the	\
-       absolute address.  */					\
-    add		(%ebx,%ecx,4), %ebx;				\
-    /* We loaded the jump table and adjuested EDX. Go.  */	\
-    jmp		*%ebx
-
-	.section	.gnu.linkonce.t.__x86.get_pc_thunk.bx,"ax",@progbits
-	.globl	__x86.get_pc_thunk.bx
-	.hidden	__x86.get_pc_thunk.bx
-	ALIGN (4)
-	.type	__x86.get_pc_thunk.bx,@function
-__x86.get_pc_thunk.bx:
-	movl	(%esp), %ebx
-	ret
-#else
-# define ENTRANCE
-# define RETURN_END	ret
-# define RETURN		RETURN_END
-# define PARMS		4
-# define JMPTBL(I, B)	I
-
-/* Branch to an entry in a jump table.  TABLE is a jump table with
-   absolute offsets.  */
-# define BRANCH_TO_JMPTBL_ENTRY(TABLE)				\
-    jmp		*TABLE(,%ecx,4)
-#endif
-
-	.section .text.sse2,"ax",@progbits
-	ALIGN (4)
-ENTRY (MEMSET)
-	ENTRANCE
-
-	movl	LEN(%esp), %ecx
-	shr     $2, %ecx
-#ifdef USE_AS_BZERO32
-	xor	%eax, %eax
-#else
-	mov	DWDS(%esp), %eax
-	mov	%eax, %edx
-#endif
-	movl	DEST(%esp), %edx
-	cmp	$16, %ecx
-	jae	L(16dbwordsormore)
-
-L(write_less16dbwords):
-	lea	(%edx, %ecx, 4), %edx
-	BRANCH_TO_JMPTBL_ENTRY (L(table_less16dbwords))
-
-	.pushsection .rodata.sse2,"a",@progbits
-	ALIGN (2)
-L(table_less16dbwords):
-	.int	JMPTBL (L(write_0dbwords), L(table_less16dbwords))
-	.int	JMPTBL (L(write_1dbwords), L(table_less16dbwords))
-	.int	JMPTBL (L(write_2dbwords), L(table_less16dbwords))
-	.int	JMPTBL (L(write_3dbwords), L(table_less16dbwords))
-	.int	JMPTBL (L(write_4dbwords), L(table_less16dbwords))
-	.int	JMPTBL (L(write_5dbwords), L(table_less16dbwords))
-	.int	JMPTBL (L(write_6dbwords), L(table_less16dbwords))
-	.int	JMPTBL (L(write_7dbwords), L(table_less16dbwords))
-	.int	JMPTBL (L(write_8dbwords), L(table_less16dbwords))
-	.int	JMPTBL (L(write_9dbwords), L(table_less16dbwords))
-	.int	JMPTBL (L(write_10dbwords), L(table_less16dbwords))
-	.int	JMPTBL (L(write_11dbwords), L(table_less16dbwords))
-	.int	JMPTBL (L(write_12dbwords), L(table_less16dbwords))
-	.int	JMPTBL (L(write_13dbwords), L(table_less16dbwords))
-	.int	JMPTBL (L(write_14dbwords), L(table_less16dbwords))
-	.int	JMPTBL (L(write_15dbwords), L(table_less16dbwords))
-	.popsection
-
-	ALIGN (4)
-L(write_15dbwords):
-	movl	%eax, -60(%edx)
-L(write_14dbwords):
-	movl	%eax, -56(%edx)
-L(write_13dbwords):
-	movl	%eax, -52(%edx)
-L(write_12dbwords):
-	movl	%eax, -48(%edx)
-L(write_11dbwords):
-	movl	%eax, -44(%edx)
-L(write_10dbwords):
-	movl	%eax, -40(%edx)
-L(write_9dbwords):
-	movl	%eax, -36(%edx)
-L(write_8dbwords):
-	movl	%eax, -32(%edx)
-L(write_7dbwords):
-	movl	%eax, -28(%edx)
-L(write_6dbwords):
-	movl	%eax, -24(%edx)
-L(write_5dbwords):
-	movl	%eax, -20(%edx)
-L(write_4dbwords):
-	movl	%eax, -16(%edx)
-L(write_3dbwords):
-	movl	%eax, -12(%edx)
-L(write_2dbwords):
-	movl	%eax, -8(%edx)
-L(write_1dbwords):
-	movl	%eax, -4(%edx)
-L(write_0dbwords):
-	SETRTNVAL
-	RETURN
-
-	ALIGN (4)
-L(16dbwordsormore):
-	test	$3, %edx
-	jz	L(aligned4bytes)
-	mov	%eax, (%edx)
-	mov	%eax, -4(%edx, %ecx, 4)
-	sub	$1, %ecx
-	rol	$24, %eax
-	add	$1, %edx
-	test	$3, %edx
-	jz	L(aligned4bytes)
-	ror	$8, %eax
-	add	$1, %edx
-	test	$3, %edx
-	jz	L(aligned4bytes)
-	ror	$8, %eax
-	add	$1, %edx
-L(aligned4bytes):
-	shl	$2, %ecx
-
-#ifdef USE_AS_BZERO32
-	pxor	%xmm0, %xmm0
-#else
-	movd	%eax, %xmm0
-	pshufd	$0, %xmm0, %xmm0
-#endif
-	testl	$0xf, %edx
-	jz	L(aligned_16)
-/* ECX > 32 and EDX is not 16 byte aligned.  */
-L(not_aligned_16):
-	movdqu	%xmm0, (%edx)
-	movl	%edx, %eax
-	and	$-16, %edx
-	add	$16, %edx
-	sub	%edx, %eax
-	add	%eax, %ecx
-	movd	%xmm0, %eax
-	ALIGN (4)
-L(aligned_16):
-	cmp	$128, %ecx
-	jae	L(128bytesormore)
-
-L(aligned_16_less128bytes):
-	add	%ecx, %edx
-	shr	$2, %ecx
-	BRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes))
-
-	ALIGN (4)
-L(128bytesormore):
-#ifdef SHARED_CACHE_SIZE
-	PUSH (%ebx)
-	mov	$SHARED_CACHE_SIZE, %ebx
-#else
-# if (defined SHARED || defined __PIC__)
-	call	__x86.get_pc_thunk.bx
-	add	$_GLOBAL_OFFSET_TABLE_, %ebx
-	mov	__x86_shared_cache_size@GOTOFF(%ebx), %ebx
-# else
-	PUSH (%ebx)
-	mov	__x86_shared_cache_size, %ebx
-# endif
-#endif
-	cmp	%ebx, %ecx
-	jae	L(128bytesormore_nt_start)
-
-#ifdef DATA_CACHE_SIZE
-	POP (%ebx)
-# define RESTORE_EBX_STATE CFI_PUSH (%ebx)
-	cmp	$DATA_CACHE_SIZE, %ecx
-#else
-# if (defined SHARED || defined __PIC__)
-#  define RESTORE_EBX_STATE
-	call	__x86.get_pc_thunk.bx
-	add	$_GLOBAL_OFFSET_TABLE_, %ebx
-	cmp	__x86_data_cache_size@GOTOFF(%ebx), %ecx
-# else
-	POP (%ebx)
-#  define RESTORE_EBX_STATE CFI_PUSH (%ebx)
-	cmp	__x86_data_cache_size, %ecx
-# endif
-#endif
-
-	jae	L(128bytes_L2_normal)
-	subl	$128, %ecx
-L(128bytesormore_normal):
-	sub	$128, %ecx
-	movdqa	%xmm0, (%edx)
-	movdqa	%xmm0, 0x10(%edx)
-	movdqa	%xmm0, 0x20(%edx)
-	movdqa	%xmm0, 0x30(%edx)
-	movdqa	%xmm0, 0x40(%edx)
-	movdqa	%xmm0, 0x50(%edx)
-	movdqa	%xmm0, 0x60(%edx)
-	movdqa	%xmm0, 0x70(%edx)
-	lea	128(%edx), %edx
-	jb	L(128bytesless_normal)
-
-
-	sub	$128, %ecx
-	movdqa	%xmm0, (%edx)
-	movdqa	%xmm0, 0x10(%edx)
-	movdqa	%xmm0, 0x20(%edx)
-	movdqa	%xmm0, 0x30(%edx)
-	movdqa	%xmm0, 0x40(%edx)
-	movdqa	%xmm0, 0x50(%edx)
-	movdqa	%xmm0, 0x60(%edx)
-	movdqa	%xmm0, 0x70(%edx)
-	lea	128(%edx), %edx
-	jae	L(128bytesormore_normal)
-
-L(128bytesless_normal):
-	lea	128(%ecx), %ecx
-	add	%ecx, %edx
-	shr	$2, %ecx
-	BRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes))
-
-	ALIGN (4)
-L(128bytes_L2_normal):
-	prefetcht0	0x380(%edx)
-	prefetcht0	0x3c0(%edx)
-	sub	$128, %ecx
-	movdqa	%xmm0, (%edx)
-	movaps	%xmm0, 0x10(%edx)
-	movaps	%xmm0, 0x20(%edx)
-	movaps	%xmm0, 0x30(%edx)
-	movaps	%xmm0, 0x40(%edx)
-	movaps	%xmm0, 0x50(%edx)
-	movaps	%xmm0, 0x60(%edx)
-	movaps	%xmm0, 0x70(%edx)
-	add	$128, %edx
-	cmp	$128, %ecx
-	jae	L(128bytes_L2_normal)
-
-L(128bytesless_L2_normal):
-	add	%ecx, %edx
-	shr	$2, %ecx
-	BRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes))
-
-	RESTORE_EBX_STATE
-L(128bytesormore_nt_start):
-	sub	%ebx, %ecx
-	mov	%ebx, %eax
-	and	$0x7f, %eax
-	add	%eax, %ecx
-	movd	%xmm0, %eax
-	ALIGN (4)
-L(128bytesormore_shared_cache_loop):
-	prefetcht0	0x3c0(%edx)
-	prefetcht0	0x380(%edx)
-	sub	$0x80, %ebx
-	movdqa	%xmm0, (%edx)
-	movdqa	%xmm0, 0x10(%edx)
-	movdqa	%xmm0, 0x20(%edx)
-	movdqa	%xmm0, 0x30(%edx)
-	movdqa	%xmm0, 0x40(%edx)
-	movdqa	%xmm0, 0x50(%edx)
-	movdqa	%xmm0, 0x60(%edx)
-	movdqa	%xmm0, 0x70(%edx)
-	add	$0x80, %edx
-	cmp	$0x80, %ebx
-	jae	L(128bytesormore_shared_cache_loop)
-	cmp	$0x80, %ecx
-	jb	L(shared_cache_loop_end)
-
-	ALIGN (4)
-L(128bytesormore_nt):
-	sub	$0x80, %ecx
-	movntdq	%xmm0, (%edx)
-	movntdq	%xmm0, 0x10(%edx)
-	movntdq	%xmm0, 0x20(%edx)
-	movntdq	%xmm0, 0x30(%edx)
-	movntdq	%xmm0, 0x40(%edx)
-	movntdq	%xmm0, 0x50(%edx)
-	movntdq	%xmm0, 0x60(%edx)
-	movntdq	%xmm0, 0x70(%edx)
-	add	$0x80, %edx
-	cmp	$0x80, %ecx
-	jae	L(128bytesormore_nt)
-	sfence
-L(shared_cache_loop_end):
-#if defined DATA_CACHE_SIZE || !(defined SHARED || defined __PIC__)
-	POP (%ebx)
-#endif
-	add	%ecx, %edx
-	shr	$2, %ecx
-	BRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes))
-
-	.pushsection .rodata.sse2,"a",@progbits
-	ALIGN (2)
-L(table_16_128bytes):
-	.int	JMPTBL (L(aligned_16_0bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_4bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_8bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_12bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_16bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_20bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_24bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_28bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_32bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_36bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_40bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_44bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_48bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_52bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_56bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_60bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_64bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_68bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_72bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_76bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_80bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_84bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_88bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_92bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_96bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_100bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_104bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_108bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_112bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_116bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_120bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_124bytes), L(table_16_128bytes))
-	.popsection
-
-	ALIGN (4)
-L(aligned_16_112bytes):
-	movdqa	%xmm0, -112(%edx)
-L(aligned_16_96bytes):
-	movdqa	%xmm0, -96(%edx)
-L(aligned_16_80bytes):
-	movdqa	%xmm0, -80(%edx)
-L(aligned_16_64bytes):
-	movdqa	%xmm0, -64(%edx)
-L(aligned_16_48bytes):
-	movdqa	%xmm0, -48(%edx)
-L(aligned_16_32bytes):
-	movdqa	%xmm0, -32(%edx)
-L(aligned_16_16bytes):
-	movdqa	%xmm0, -16(%edx)
-L(aligned_16_0bytes):
-	SETRTNVAL
-	RETURN
-
-	ALIGN (4)
-L(aligned_16_116bytes):
-	movdqa	%xmm0, -116(%edx)
-L(aligned_16_100bytes):
-	movdqa	%xmm0, -100(%edx)
-L(aligned_16_84bytes):
-	movdqa	%xmm0, -84(%edx)
-L(aligned_16_68bytes):
-	movdqa	%xmm0, -68(%edx)
-L(aligned_16_52bytes):
-	movdqa	%xmm0, -52(%edx)
-L(aligned_16_36bytes):
-	movdqa	%xmm0, -36(%edx)
-L(aligned_16_20bytes):
-	movdqa	%xmm0, -20(%edx)
-L(aligned_16_4bytes):
-	movl	%eax, -4(%edx)
-	SETRTNVAL
-	RETURN
-
-	ALIGN (4)
-L(aligned_16_120bytes):
-	movdqa	%xmm0, -120(%edx)
-L(aligned_16_104bytes):
-	movdqa	%xmm0, -104(%edx)
-L(aligned_16_88bytes):
-	movdqa	%xmm0, -88(%edx)
-L(aligned_16_72bytes):
-	movdqa	%xmm0, -72(%edx)
-L(aligned_16_56bytes):
-	movdqa	%xmm0, -56(%edx)
-L(aligned_16_40bytes):
-	movdqa	%xmm0, -40(%edx)
-L(aligned_16_24bytes):
-	movdqa	%xmm0, -24(%edx)
-L(aligned_16_8bytes):
-	movq	%xmm0, -8(%edx)
-	SETRTNVAL
-	RETURN
-
-	ALIGN (4)
-L(aligned_16_124bytes):
-	movdqa	%xmm0, -124(%edx)
-L(aligned_16_108bytes):
-	movdqa	%xmm0, -108(%edx)
-L(aligned_16_92bytes):
-	movdqa	%xmm0, -92(%edx)
-L(aligned_16_76bytes):
-	movdqa	%xmm0, -76(%edx)
-L(aligned_16_60bytes):
-	movdqa	%xmm0, -60(%edx)
-L(aligned_16_44bytes):
-	movdqa	%xmm0, -44(%edx)
-L(aligned_16_28bytes):
-	movdqa	%xmm0, -28(%edx)
-L(aligned_16_12bytes):
-	movq	%xmm0, -12(%edx)
-	movl	%eax, -4(%edx)
-	SETRTNVAL
-	RETURN
-
-END (MEMSET)
diff --git a/libcutils/arch-x86_64/android_memset16.S b/libcutils/arch-x86_64/android_memset16.S
deleted file mode 100644
index cb6d4a3..0000000
--- a/libcutils/arch-x86_64/android_memset16.S
+++ /dev/null
@@ -1,565 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "cache.h"
-
-#ifndef MEMSET
-# define MEMSET		android_memset16
-#endif
-
-#ifndef L
-# define L(label)	.L##label
-#endif
-
-#ifndef ALIGN
-# define ALIGN(n)	.p2align n
-#endif
-
-#ifndef cfi_startproc
-# define cfi_startproc			.cfi_startproc
-#endif
-
-#ifndef cfi_endproc
-# define cfi_endproc			.cfi_endproc
-#endif
-
-#ifndef ENTRY
-# define ENTRY(name)			\
-	.type name,  @function; 	\
-	.globl name;			\
-	.p2align 4;			\
-name:					\
-	cfi_startproc
-#endif
-
-#ifndef END
-# define END(name)			\
-	cfi_endproc;			\
-	.size name, .-name
-#endif
-
-#define JMPTBL(I, B)	I - B
-
-/* Branch to an entry in a jump table.  TABLE is a jump table with
-   relative offsets.  INDEX is a register contains the index into the
-   jump table.  SCALE is the scale of INDEX.  */
-#define BRANCH_TO_JMPTBL_ENTRY(TABLE, INDEX, SCALE) \
-	lea    TABLE(%rip), %r11;						\
-	movslq (%r11, INDEX, SCALE), INDEX;				\
-	lea    (%r11, INDEX), INDEX;					\
-	jmp    *INDEX
-
-	.section .text.sse2,"ax",@progbits
-	ALIGN (4)
-ENTRY (MEMSET)	// Address in rdi
-	shr    $1, %rdx			// Count in rdx
-	movzwl %si, %ecx
-	/* Fill the whole ECX with pattern.  */
-	shl    $16, %esi
-	or     %esi, %ecx		// Pattern in ecx
-
-	cmp    $32, %rdx
-	jae    L(32wordsormore)
-
-L(write_less32words):
-	lea    (%rdi, %rdx, 2), %rdi
-	BRANCH_TO_JMPTBL_ENTRY (L(table_less32words), %rdx, 4)
-
-	.pushsection .rodata.sse2,"a",@progbits
-	ALIGN (2)
-L(table_less32words):
-	.int	JMPTBL (L(write_0words), L(table_less32words))
-	.int	JMPTBL (L(write_1words), L(table_less32words))
-	.int	JMPTBL (L(write_2words), L(table_less32words))
-	.int	JMPTBL (L(write_3words), L(table_less32words))
-	.int	JMPTBL (L(write_4words), L(table_less32words))
-	.int	JMPTBL (L(write_5words), L(table_less32words))
-	.int	JMPTBL (L(write_6words), L(table_less32words))
-	.int	JMPTBL (L(write_7words), L(table_less32words))
-	.int	JMPTBL (L(write_8words), L(table_less32words))
-	.int	JMPTBL (L(write_9words), L(table_less32words))
-	.int	JMPTBL (L(write_10words), L(table_less32words))
-	.int	JMPTBL (L(write_11words), L(table_less32words))
-	.int	JMPTBL (L(write_12words), L(table_less32words))
-	.int	JMPTBL (L(write_13words), L(table_less32words))
-	.int	JMPTBL (L(write_14words), L(table_less32words))
-	.int	JMPTBL (L(write_15words), L(table_less32words))
-	.int	JMPTBL (L(write_16words), L(table_less32words))
-	.int	JMPTBL (L(write_17words), L(table_less32words))
-	.int	JMPTBL (L(write_18words), L(table_less32words))
-	.int	JMPTBL (L(write_19words), L(table_less32words))
-	.int	JMPTBL (L(write_20words), L(table_less32words))
-	.int	JMPTBL (L(write_21words), L(table_less32words))
-	.int	JMPTBL (L(write_22words), L(table_less32words))
-	.int	JMPTBL (L(write_23words), L(table_less32words))
-	.int	JMPTBL (L(write_24words), L(table_less32words))
-	.int	JMPTBL (L(write_25words), L(table_less32words))
-	.int	JMPTBL (L(write_26words), L(table_less32words))
-	.int	JMPTBL (L(write_27words), L(table_less32words))
-	.int	JMPTBL (L(write_28words), L(table_less32words))
-	.int	JMPTBL (L(write_29words), L(table_less32words))
-	.int	JMPTBL (L(write_30words), L(table_less32words))
-	.int	JMPTBL (L(write_31words), L(table_less32words))
-	.popsection
-
-	ALIGN (4)
-L(write_28words):
-	movl   %ecx, -56(%rdi)
-	movl   %ecx, -52(%rdi)
-L(write_24words):
-	movl   %ecx, -48(%rdi)
-	movl   %ecx, -44(%rdi)
-L(write_20words):
-	movl   %ecx, -40(%rdi)
-	movl   %ecx, -36(%rdi)
-L(write_16words):
-	movl   %ecx, -32(%rdi)
-	movl   %ecx, -28(%rdi)
-L(write_12words):
-	movl   %ecx, -24(%rdi)
-	movl   %ecx, -20(%rdi)
-L(write_8words):
-	movl   %ecx, -16(%rdi)
-	movl   %ecx, -12(%rdi)
-L(write_4words):
-	movl   %ecx, -8(%rdi)
-	movl   %ecx, -4(%rdi)
-L(write_0words):
-	ret
-
-	ALIGN (4)
-L(write_29words):
-	movl   %ecx, -58(%rdi)
-	movl   %ecx, -54(%rdi)
-L(write_25words):
-	movl   %ecx, -50(%rdi)
-	movl   %ecx, -46(%rdi)
-L(write_21words):
-	movl   %ecx, -42(%rdi)
-	movl   %ecx, -38(%rdi)
-L(write_17words):
-	movl   %ecx, -34(%rdi)
-	movl   %ecx, -30(%rdi)
-L(write_13words):
-	movl   %ecx, -26(%rdi)
-	movl   %ecx, -22(%rdi)
-L(write_9words):
-	movl   %ecx, -18(%rdi)
-	movl   %ecx, -14(%rdi)
-L(write_5words):
-	movl   %ecx, -10(%rdi)
-	movl   %ecx, -6(%rdi)
-L(write_1words):
-	mov	%cx, -2(%rdi)
-	ret
-
-	ALIGN (4)
-L(write_30words):
-	movl   %ecx, -60(%rdi)
-	movl   %ecx, -56(%rdi)
-L(write_26words):
-	movl   %ecx, -52(%rdi)
-	movl   %ecx, -48(%rdi)
-L(write_22words):
-	movl   %ecx, -44(%rdi)
-	movl   %ecx, -40(%rdi)
-L(write_18words):
-	movl   %ecx, -36(%rdi)
-	movl   %ecx, -32(%rdi)
-L(write_14words):
-	movl   %ecx, -28(%rdi)
-	movl   %ecx, -24(%rdi)
-L(write_10words):
-	movl   %ecx, -20(%rdi)
-	movl   %ecx, -16(%rdi)
-L(write_6words):
-	movl   %ecx, -12(%rdi)
-	movl   %ecx, -8(%rdi)
-L(write_2words):
-	movl   %ecx, -4(%rdi)
-	ret
-
-	ALIGN (4)
-L(write_31words):
-	movl   %ecx, -62(%rdi)
-	movl   %ecx, -58(%rdi)
-L(write_27words):
-	movl   %ecx, -54(%rdi)
-	movl   %ecx, -50(%rdi)
-L(write_23words):
-	movl   %ecx, -46(%rdi)
-	movl   %ecx, -42(%rdi)
-L(write_19words):
-	movl   %ecx, -38(%rdi)
-	movl   %ecx, -34(%rdi)
-L(write_15words):
-	movl   %ecx, -30(%rdi)
-	movl   %ecx, -26(%rdi)
-L(write_11words):
-	movl   %ecx, -22(%rdi)
-	movl   %ecx, -18(%rdi)
-L(write_7words):
-	movl   %ecx, -14(%rdi)
-	movl   %ecx, -10(%rdi)
-L(write_3words):
-	movl   %ecx, -6(%rdi)
-	movw   %cx, -2(%rdi)
-	ret
-
-	ALIGN (4)
-L(32wordsormore):
-	shl    $1, %rdx
-	test   $0x01, %edi
-	jz     L(aligned2bytes)
-	mov    %ecx, (%rdi)
-	mov    %ecx, -4(%rdi, %rdx)
-	sub    $2, %rdx
-	add    $1, %rdi
-	rol    $8, %ecx
-L(aligned2bytes):
-	/* Fill xmm0 with the pattern.  */
-	movd   %ecx, %xmm0
-	pshufd $0, %xmm0, %xmm0
-
-	testl  $0xf, %edi
-	jz     L(aligned_16)
-/* RDX > 32 and RDI is not 16 byte aligned.  */
-	movdqu %xmm0, (%rdi)
-	mov    %rdi, %rsi
-	and    $-16, %rdi
-	add    $16, %rdi
-	sub    %rdi, %rsi
-	add    %rsi, %rdx
-
-	ALIGN (4)
-L(aligned_16):
-	cmp    $128, %rdx
-	jge    L(128bytesormore)
-
-L(aligned_16_less128bytes):
-	add    %rdx, %rdi
-	shr    $1, %rdx
-	BRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes), %rdx, 4)
-
-	ALIGN (4)
-L(128bytesormore):
-	cmp    $SHARED_CACHE_SIZE, %rdx
-	jg     L(128bytesormore_nt)
-
-L(128bytesormore_normal):
-	sub    $128, %rdx
-	movdqa %xmm0, (%rdi)
-	movdqa %xmm0, 0x10(%rdi)
-	movdqa %xmm0, 0x20(%rdi)
-	movdqa %xmm0, 0x30(%rdi)
-	movdqa %xmm0, 0x40(%rdi)
-	movdqa %xmm0, 0x50(%rdi)
-	movdqa %xmm0, 0x60(%rdi)
-	movdqa %xmm0, 0x70(%rdi)
-	lea    128(%rdi), %rdi
-	cmp    $128, %rdx
-	jl     L(128bytesless_normal)
-
-	sub    $128, %rdx
-	movdqa %xmm0, (%rdi)
-	movdqa %xmm0, 0x10(%rdi)
-	movdqa %xmm0, 0x20(%rdi)
-	movdqa %xmm0, 0x30(%rdi)
-	movdqa %xmm0, 0x40(%rdi)
-	movdqa %xmm0, 0x50(%rdi)
-	movdqa %xmm0, 0x60(%rdi)
-	movdqa %xmm0, 0x70(%rdi)
-	lea    128(%rdi), %rdi
-	cmp    $128, %rdx
-	jl     L(128bytesless_normal)
-
-	sub    $128, %rdx
-	movdqa %xmm0, (%rdi)
-	movdqa %xmm0, 0x10(%rdi)
-	movdqa %xmm0, 0x20(%rdi)
-	movdqa %xmm0, 0x30(%rdi)
-	movdqa %xmm0, 0x40(%rdi)
-	movdqa %xmm0, 0x50(%rdi)
-	movdqa %xmm0, 0x60(%rdi)
-	movdqa %xmm0, 0x70(%rdi)
-	lea    128(%rdi), %rdi
-	cmp    $128, %rdx
-	jl     L(128bytesless_normal)
-
-	sub    $128, %rdx
-	movdqa %xmm0, (%rdi)
-	movdqa %xmm0, 0x10(%rdi)
-	movdqa %xmm0, 0x20(%rdi)
-	movdqa %xmm0, 0x30(%rdi)
-	movdqa %xmm0, 0x40(%rdi)
-	movdqa %xmm0, 0x50(%rdi)
-	movdqa %xmm0, 0x60(%rdi)
-	movdqa %xmm0, 0x70(%rdi)
-	lea    128(%rdi), %rdi
-	cmp    $128, %rdx
-	jge    L(128bytesormore_normal)
-
-L(128bytesless_normal):
-	add    %rdx, %rdi
-	shr    $1, %rdx
-	BRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes), %rdx, 4)
-
-	ALIGN (4)
-L(128bytesormore_nt):
-	sub    $128, %rdx
-	movntdq %xmm0, (%rdi)
-	movntdq %xmm0, 0x10(%rdi)
-	movntdq %xmm0, 0x20(%rdi)
-	movntdq %xmm0, 0x30(%rdi)
-	movntdq %xmm0, 0x40(%rdi)
-	movntdq %xmm0, 0x50(%rdi)
-	movntdq %xmm0, 0x60(%rdi)
-	movntdq %xmm0, 0x70(%rdi)
-	lea    128(%rdi), %rdi
-	cmp    $128, %rdx
-	jge    L(128bytesormore_nt)
-
-	sfence
-	add    %rdx, %rdi
-	shr    $1, %rdx
-	BRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes), %rdx, 4)
-
-	.pushsection .rodata.sse2,"a",@progbits
-	ALIGN (2)
-L(table_16_128bytes):
-	.int	JMPTBL (L(aligned_16_0bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_2bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_4bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_6bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_8bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_10bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_12bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_14bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_16bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_18bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_20bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_22bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_24bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_26bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_28bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_30bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_32bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_34bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_36bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_38bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_40bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_42bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_44bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_46bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_48bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_50bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_52bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_54bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_56bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_58bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_60bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_62bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_64bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_66bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_68bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_70bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_72bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_74bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_76bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_78bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_80bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_82bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_84bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_86bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_88bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_90bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_92bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_94bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_96bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_98bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_100bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_102bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_104bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_106bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_108bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_110bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_112bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_114bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_116bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_118bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_120bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_122bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_124bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_126bytes), L(table_16_128bytes))
-	.popsection
-
-	ALIGN (4)
-L(aligned_16_112bytes):
-	movdqa %xmm0, -112(%rdi)
-L(aligned_16_96bytes):
-	movdqa %xmm0, -96(%rdi)
-L(aligned_16_80bytes):
-	movdqa %xmm0, -80(%rdi)
-L(aligned_16_64bytes):
-	movdqa %xmm0, -64(%rdi)
-L(aligned_16_48bytes):
-	movdqa %xmm0, -48(%rdi)
-L(aligned_16_32bytes):
-	movdqa %xmm0, -32(%rdi)
-L(aligned_16_16bytes):
-	movdqa %xmm0, -16(%rdi)
-L(aligned_16_0bytes):
-	ret
-
-	ALIGN (4)
-L(aligned_16_114bytes):
-	movdqa %xmm0, -114(%rdi)
-L(aligned_16_98bytes):
-	movdqa %xmm0, -98(%rdi)
-L(aligned_16_82bytes):
-	movdqa %xmm0, -82(%rdi)
-L(aligned_16_66bytes):
-	movdqa %xmm0, -66(%rdi)
-L(aligned_16_50bytes):
-	movdqa %xmm0, -50(%rdi)
-L(aligned_16_34bytes):
-	movdqa %xmm0, -34(%rdi)
-L(aligned_16_18bytes):
-	movdqa %xmm0, -18(%rdi)
-L(aligned_16_2bytes):
-	movw   %cx, -2(%rdi)
-	ret
-
-	ALIGN (4)
-L(aligned_16_116bytes):
-	movdqa %xmm0, -116(%rdi)
-L(aligned_16_100bytes):
-	movdqa %xmm0, -100(%rdi)
-L(aligned_16_84bytes):
-	movdqa %xmm0, -84(%rdi)
-L(aligned_16_68bytes):
-	movdqa %xmm0, -68(%rdi)
-L(aligned_16_52bytes):
-	movdqa %xmm0, -52(%rdi)
-L(aligned_16_36bytes):
-	movdqa %xmm0, -36(%rdi)
-L(aligned_16_20bytes):
-	movdqa %xmm0, -20(%rdi)
-L(aligned_16_4bytes):
-	movl   %ecx, -4(%rdi)
-	ret
-
-	ALIGN (4)
-L(aligned_16_118bytes):
-	movdqa %xmm0, -118(%rdi)
-L(aligned_16_102bytes):
-	movdqa %xmm0, -102(%rdi)
-L(aligned_16_86bytes):
-	movdqa %xmm0, -86(%rdi)
-L(aligned_16_70bytes):
-	movdqa %xmm0, -70(%rdi)
-L(aligned_16_54bytes):
-	movdqa %xmm0, -54(%rdi)
-L(aligned_16_38bytes):
-	movdqa %xmm0, -38(%rdi)
-L(aligned_16_22bytes):
-	movdqa %xmm0, -22(%rdi)
-L(aligned_16_6bytes):
-	movl   %ecx, -6(%rdi)
-	movw   %cx, -2(%rdi)
-	ret
-
-	ALIGN (4)
-L(aligned_16_120bytes):
-	movdqa %xmm0, -120(%rdi)
-L(aligned_16_104bytes):
-	movdqa %xmm0, -104(%rdi)
-L(aligned_16_88bytes):
-	movdqa %xmm0, -88(%rdi)
-L(aligned_16_72bytes):
-	movdqa %xmm0, -72(%rdi)
-L(aligned_16_56bytes):
-	movdqa %xmm0, -56(%rdi)
-L(aligned_16_40bytes):
-	movdqa %xmm0, -40(%rdi)
-L(aligned_16_24bytes):
-	movdqa %xmm0, -24(%rdi)
-L(aligned_16_8bytes):
-	movq   %xmm0, -8(%rdi)
-	ret
-
-	ALIGN (4)
-L(aligned_16_122bytes):
-	movdqa %xmm0, -122(%rdi)
-L(aligned_16_106bytes):
-	movdqa %xmm0, -106(%rdi)
-L(aligned_16_90bytes):
-	movdqa %xmm0, -90(%rdi)
-L(aligned_16_74bytes):
-	movdqa %xmm0, -74(%rdi)
-L(aligned_16_58bytes):
-	movdqa %xmm0, -58(%rdi)
-L(aligned_16_42bytes):
-	movdqa %xmm0, -42(%rdi)
-L(aligned_16_26bytes):
-	movdqa %xmm0, -26(%rdi)
-L(aligned_16_10bytes):
-	movq   %xmm0, -10(%rdi)
-	movw   %cx, -2(%rdi)
-	ret
-
-	ALIGN (4)
-L(aligned_16_124bytes):
-	movdqa %xmm0, -124(%rdi)
-L(aligned_16_108bytes):
-	movdqa %xmm0, -108(%rdi)
-L(aligned_16_92bytes):
-	movdqa %xmm0, -92(%rdi)
-L(aligned_16_76bytes):
-	movdqa %xmm0, -76(%rdi)
-L(aligned_16_60bytes):
-	movdqa %xmm0, -60(%rdi)
-L(aligned_16_44bytes):
-	movdqa %xmm0, -44(%rdi)
-L(aligned_16_28bytes):
-	movdqa %xmm0, -28(%rdi)
-L(aligned_16_12bytes):
-	movq   %xmm0, -12(%rdi)
-	movl   %ecx, -4(%rdi)
-	ret
-
-	ALIGN (4)
-L(aligned_16_126bytes):
-	movdqa %xmm0, -126(%rdi)
-L(aligned_16_110bytes):
-	movdqa %xmm0, -110(%rdi)
-L(aligned_16_94bytes):
-	movdqa %xmm0, -94(%rdi)
-L(aligned_16_78bytes):
-	movdqa %xmm0, -78(%rdi)
-L(aligned_16_62bytes):
-	movdqa %xmm0, -62(%rdi)
-L(aligned_16_46bytes):
-	movdqa %xmm0, -46(%rdi)
-L(aligned_16_30bytes):
-	movdqa %xmm0, -30(%rdi)
-L(aligned_16_14bytes):
-	movq   %xmm0, -14(%rdi)
-	movl   %ecx, -6(%rdi)
-	movw   %cx, -2(%rdi)
-	ret
-
-END (MEMSET)
diff --git a/libcutils/arch-x86_64/android_memset32.S b/libcutils/arch-x86_64/android_memset32.S
deleted file mode 100644
index 1514aa2..0000000
--- a/libcutils/arch-x86_64/android_memset32.S
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "cache.h"
-
-#ifndef MEMSET
-# define MEMSET		android_memset32
-#endif
-
-#ifndef L
-# define L(label)	.L##label
-#endif
-
-#ifndef ALIGN
-# define ALIGN(n)	.p2align n
-#endif
-
-#ifndef cfi_startproc
-# define cfi_startproc			.cfi_startproc
-#endif
-
-#ifndef cfi_endproc
-# define cfi_endproc			.cfi_endproc
-#endif
-
-#ifndef ENTRY
-# define ENTRY(name)			\
-	.type name,  @function; 	\
-	.globl name;			\
-	.p2align 4;			\
-name:					\
-	cfi_startproc
-#endif
-
-#ifndef END
-# define END(name)			\
-	cfi_endproc;			\
-	.size name, .-name
-#endif
-
-#define JMPTBL(I, B)	I - B
-
-/* Branch to an entry in a jump table.  TABLE is a jump table with
-   relative offsets.  INDEX is a register contains the index into the
-   jump table.  SCALE is the scale of INDEX.  */
-#define BRANCH_TO_JMPTBL_ENTRY(TABLE, INDEX, SCALE) \
-	lea    TABLE(%rip), %r11;						\
-	movslq (%r11, INDEX, SCALE), INDEX;				\
-	lea    (%r11, INDEX), INDEX;					\
-	jmp    *INDEX
-
-	.section .text.sse2,"ax",@progbits
-	ALIGN (4)
-ENTRY (MEMSET)	// Address in rdi
-	shr    $2, %rdx			// Count in rdx
-	movl   %esi, %ecx		// Pattern in ecx
-
-	cmp    $16, %rdx
-	jae    L(16dbwordsormore)
-
-L(write_less16dbwords):
-	lea    (%rdi, %rdx, 4), %rdi
-	BRANCH_TO_JMPTBL_ENTRY (L(table_less16dbwords), %rdx, 4)
-
-	.pushsection .rodata.sse2,"a",@progbits
-	ALIGN (2)
-L(table_less16dbwords):
-	.int	JMPTBL (L(write_0dbwords), L(table_less16dbwords))
-	.int	JMPTBL (L(write_1dbwords), L(table_less16dbwords))
-	.int	JMPTBL (L(write_2dbwords), L(table_less16dbwords))
-	.int	JMPTBL (L(write_3dbwords), L(table_less16dbwords))
-	.int	JMPTBL (L(write_4dbwords), L(table_less16dbwords))
-	.int	JMPTBL (L(write_5dbwords), L(table_less16dbwords))
-	.int	JMPTBL (L(write_6dbwords), L(table_less16dbwords))
-	.int	JMPTBL (L(write_7dbwords), L(table_less16dbwords))
-	.int	JMPTBL (L(write_8dbwords), L(table_less16dbwords))
-	.int	JMPTBL (L(write_9dbwords), L(table_less16dbwords))
-	.int	JMPTBL (L(write_10dbwords), L(table_less16dbwords))
-	.int	JMPTBL (L(write_11dbwords), L(table_less16dbwords))
-	.int	JMPTBL (L(write_12dbwords), L(table_less16dbwords))
-	.int	JMPTBL (L(write_13dbwords), L(table_less16dbwords))
-	.int	JMPTBL (L(write_14dbwords), L(table_less16dbwords))
-	.int	JMPTBL (L(write_15dbwords), L(table_less16dbwords))
-	.popsection
-
-	ALIGN (4)
-L(write_15dbwords):
-	movl   %ecx, -60(%rdi)
-L(write_14dbwords):
-	movl   %ecx, -56(%rdi)
-L(write_13dbwords):
-	movl   %ecx, -52(%rdi)
-L(write_12dbwords):
-	movl   %ecx, -48(%rdi)
-L(write_11dbwords):
-	movl   %ecx, -44(%rdi)
-L(write_10dbwords):
-	movl   %ecx, -40(%rdi)
-L(write_9dbwords):
-	movl   %ecx, -36(%rdi)
-L(write_8dbwords):
-	movl   %ecx, -32(%rdi)
-L(write_7dbwords):
-	movl   %ecx, -28(%rdi)
-L(write_6dbwords):
-	movl   %ecx, -24(%rdi)
-L(write_5dbwords):
-	movl   %ecx, -20(%rdi)
-L(write_4dbwords):
-	movl   %ecx, -16(%rdi)
-L(write_3dbwords):
-	movl   %ecx, -12(%rdi)
-L(write_2dbwords):
-	movl   %ecx, -8(%rdi)
-L(write_1dbwords):
-	movl   %ecx, -4(%rdi)
-L(write_0dbwords):
-	ret
-
-	ALIGN (4)
-L(16dbwordsormore):
-	test   $3, %edi
-	jz     L(aligned4bytes)
-	mov    %ecx, (%rdi)
-	mov    %ecx, -4(%rdi, %rdx, 4)
-	sub    $1, %rdx
-	rol    $24, %ecx
-	add    $1, %rdi
-	test   $3, %edi
-	jz     L(aligned4bytes)
-	ror    $8, %ecx
-	add    $1, %rdi
-	test   $3, %edi
-	jz     L(aligned4bytes)
-	ror    $8, %ecx
-	add    $1, %rdi
-L(aligned4bytes):
-	shl    $2, %rdx
-
-	/* Fill xmm0 with the pattern.  */
-	movd   %ecx, %xmm0
-	pshufd $0, %xmm0, %xmm0
-
-	testl  $0xf, %edi
-	jz     L(aligned_16)
-/* RDX > 32 and RDI is not 16 byte aligned.  */
-	movdqu %xmm0, (%rdi)
-	mov    %rdi, %rsi
-	and    $-16, %rdi
-	add    $16, %rdi
-	sub    %rdi, %rsi
-	add    %rsi, %rdx
-
-	ALIGN (4)
-L(aligned_16):
-	cmp    $128, %rdx
-	jge    L(128bytesormore)
-
-L(aligned_16_less128bytes):
-	add    %rdx, %rdi
-	shr    $2, %rdx
-	BRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes), %rdx, 4)
-
-	ALIGN (4)
-L(128bytesormore):
-	cmp    $SHARED_CACHE_SIZE, %rdx
-	jg     L(128bytesormore_nt)
-
-L(128bytesormore_normal):
-	sub    $128, %rdx
-	movdqa %xmm0, (%rdi)
-	movdqa %xmm0, 0x10(%rdi)
-	movdqa %xmm0, 0x20(%rdi)
-	movdqa %xmm0, 0x30(%rdi)
-	movdqa %xmm0, 0x40(%rdi)
-	movdqa %xmm0, 0x50(%rdi)
-	movdqa %xmm0, 0x60(%rdi)
-	movdqa %xmm0, 0x70(%rdi)
-	lea    128(%rdi), %rdi
-	cmp    $128, %rdx
-	jl     L(128bytesless_normal)
-
-	sub    $128, %rdx
-	movdqa %xmm0, (%rdi)
-	movdqa %xmm0, 0x10(%rdi)
-	movdqa %xmm0, 0x20(%rdi)
-	movdqa %xmm0, 0x30(%rdi)
-	movdqa %xmm0, 0x40(%rdi)
-	movdqa %xmm0, 0x50(%rdi)
-	movdqa %xmm0, 0x60(%rdi)
-	movdqa %xmm0, 0x70(%rdi)
-	lea    128(%rdi), %rdi
-	cmp    $128, %rdx
-	jl     L(128bytesless_normal)
-
-	sub    $128, %rdx
-	movdqa %xmm0, (%rdi)
-	movdqa %xmm0, 0x10(%rdi)
-	movdqa %xmm0, 0x20(%rdi)
-	movdqa %xmm0, 0x30(%rdi)
-	movdqa %xmm0, 0x40(%rdi)
-	movdqa %xmm0, 0x50(%rdi)
-	movdqa %xmm0, 0x60(%rdi)
-	movdqa %xmm0, 0x70(%rdi)
-	lea    128(%rdi), %rdi
-	cmp    $128, %rdx
-	jl     L(128bytesless_normal)
-
-	sub    $128, %rdx
-	movdqa %xmm0, (%rdi)
-	movdqa %xmm0, 0x10(%rdi)
-	movdqa %xmm0, 0x20(%rdi)
-	movdqa %xmm0, 0x30(%rdi)
-	movdqa %xmm0, 0x40(%rdi)
-	movdqa %xmm0, 0x50(%rdi)
-	movdqa %xmm0, 0x60(%rdi)
-	movdqa %xmm0, 0x70(%rdi)
-	lea    128(%rdi), %rdi
-	cmp    $128, %rdx
-	jge    L(128bytesormore_normal)
-
-L(128bytesless_normal):
-	add    %rdx, %rdi
-	shr    $2, %rdx
-	BRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes), %rdx, 4)
-
-	ALIGN (4)
-L(128bytesormore_nt):
-	sub    $128, %rdx
-	movntdq %xmm0, (%rdi)
-	movntdq %xmm0, 0x10(%rdi)
-	movntdq %xmm0, 0x20(%rdi)
-	movntdq %xmm0, 0x30(%rdi)
-	movntdq %xmm0, 0x40(%rdi)
-	movntdq %xmm0, 0x50(%rdi)
-	movntdq %xmm0, 0x60(%rdi)
-	movntdq %xmm0, 0x70(%rdi)
-	lea    128(%rdi), %rdi
-	cmp    $128, %rdx
-	jge    L(128bytesormore_nt)
-
-	sfence
-	add    %rdx, %rdi
-	shr    $2, %rdx
-	BRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes), %rdx, 4)
-
-	.pushsection .rodata.sse2,"a",@progbits
-	ALIGN (2)
-L(table_16_128bytes):
-	.int	JMPTBL (L(aligned_16_0bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_4bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_8bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_12bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_16bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_20bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_24bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_28bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_32bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_36bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_40bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_44bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_48bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_52bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_56bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_60bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_64bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_68bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_72bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_76bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_80bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_84bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_88bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_92bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_96bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_100bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_104bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_108bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_112bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_116bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_120bytes), L(table_16_128bytes))
-	.int	JMPTBL (L(aligned_16_124bytes), L(table_16_128bytes))
-	.popsection
-
-	ALIGN (4)
-L(aligned_16_112bytes):
-	movdqa	%xmm0, -112(%rdi)
-L(aligned_16_96bytes):
-	movdqa	%xmm0, -96(%rdi)
-L(aligned_16_80bytes):
-	movdqa	%xmm0, -80(%rdi)
-L(aligned_16_64bytes):
-	movdqa	%xmm0, -64(%rdi)
-L(aligned_16_48bytes):
-	movdqa	%xmm0, -48(%rdi)
-L(aligned_16_32bytes):
-	movdqa	%xmm0, -32(%rdi)
-L(aligned_16_16bytes):
-	movdqa	%xmm0, -16(%rdi)
-L(aligned_16_0bytes):
-	ret
-
-	ALIGN (4)
-L(aligned_16_116bytes):
-	movdqa	%xmm0, -116(%rdi)
-L(aligned_16_100bytes):
-	movdqa	%xmm0, -100(%rdi)
-L(aligned_16_84bytes):
-	movdqa	%xmm0, -84(%rdi)
-L(aligned_16_68bytes):
-	movdqa	%xmm0, -68(%rdi)
-L(aligned_16_52bytes):
-	movdqa	%xmm0, -52(%rdi)
-L(aligned_16_36bytes):
-	movdqa	%xmm0, -36(%rdi)
-L(aligned_16_20bytes):
-	movdqa	%xmm0, -20(%rdi)
-L(aligned_16_4bytes):
-	movl	%ecx, -4(%rdi)
-	ret
-
-	ALIGN (4)
-L(aligned_16_120bytes):
-	movdqa	%xmm0, -120(%rdi)
-L(aligned_16_104bytes):
-	movdqa	%xmm0, -104(%rdi)
-L(aligned_16_88bytes):
-	movdqa	%xmm0, -88(%rdi)
-L(aligned_16_72bytes):
-	movdqa	%xmm0, -72(%rdi)
-L(aligned_16_56bytes):
-	movdqa	%xmm0, -56(%rdi)
-L(aligned_16_40bytes):
-	movdqa	%xmm0, -40(%rdi)
-L(aligned_16_24bytes):
-	movdqa	%xmm0, -24(%rdi)
-L(aligned_16_8bytes):
-	movq	%xmm0, -8(%rdi)
-	ret
-
-	ALIGN (4)
-L(aligned_16_124bytes):
-	movdqa	%xmm0, -124(%rdi)
-L(aligned_16_108bytes):
-	movdqa	%xmm0, -108(%rdi)
-L(aligned_16_92bytes):
-	movdqa	%xmm0, -92(%rdi)
-L(aligned_16_76bytes):
-	movdqa	%xmm0, -76(%rdi)
-L(aligned_16_60bytes):
-	movdqa	%xmm0, -60(%rdi)
-L(aligned_16_44bytes):
-	movdqa	%xmm0, -44(%rdi)
-L(aligned_16_28bytes):
-	movdqa	%xmm0, -28(%rdi)
-L(aligned_16_12bytes):
-	movq	%xmm0, -12(%rdi)
-	movl	%ecx, -4(%rdi)
-	ret
-
-END (MEMSET)
diff --git a/libcutils/fs_config.cpp b/libcutils/fs_config.cpp
index 5fb11a5..2b39ca6 100644
--- a/libcutils/fs_config.cpp
+++ b/libcutils/fs_config.cpp
@@ -85,6 +85,7 @@
     { 00755, AID_ROOT,         AID_SHELL,        0, "system/vendor" },
     { 00751, AID_ROOT,         AID_SHELL,        0, "system/xbin" },
     { 00751, AID_ROOT,         AID_SHELL,        0, "system/apex/*/bin" },
+    { 00751, AID_ROOT,         AID_SHELL,        0, "system_ext/bin" },
     { 00751, AID_ROOT,         AID_SHELL,        0, "vendor/bin" },
     { 00755, AID_ROOT,         AID_SHELL,        0, "vendor" },
     { 00755, AID_ROOT,         AID_ROOT,         0, 0 },
@@ -207,6 +208,7 @@
     { 00755, AID_ROOT,      AID_SHELL,     0, "system/bin/*" },
     { 00755, AID_ROOT,      AID_SHELL,     0, "system/xbin/*" },
     { 00755, AID_ROOT,      AID_SHELL,     0, "system/apex/*/bin/*" },
+    { 00755, AID_ROOT,      AID_SHELL,     0, "system_ext/bin/*" },
     { 00755, AID_ROOT,      AID_SHELL,     0, "vendor/bin/*" },
     { 00755, AID_ROOT,      AID_SHELL,     0, "vendor/xbin/*" },
     { 00644, AID_ROOT,      AID_ROOT,      0, 0 },
diff --git a/libcutils/fs_config_test.cpp b/libcutils/fs_config_test.cpp
index 9627152..c6684b4 100644
--- a/libcutils/fs_config_test.cpp
+++ b/libcutils/fs_config_test.cpp
@@ -46,7 +46,7 @@
         // clang-format off
     { true,  "system/lib",             "system/lib/hw",           true  },
     { true,  "vendor/lib",             "system/vendor/lib/hw",    true  },
-    { true,  "system/vendor/lib",      "vendor/lib/hw",           true  },
+    { true,  "system/vendor/lib",      "vendor/lib/hw",           false },
     { true,  "system/vendor/lib",      "system/vendor/lib/hw",    true  },
     { true,  "foo/*/bar/*",            "foo/1/bar/2",             true  },
     { true,  "foo/*/bar/*",            "foo/1/bar",               true  },
@@ -56,13 +56,14 @@
     { false, "vendor/bin/wifi",        "system/vendor/bin/wifi",  true  },
     { false, "vendor/bin/wifi",        "system/vendor/bin/wifi2", false },
     { false, "system/vendor/bin/wifi", "system/vendor/bin/wifi",  true, },
-    { false, "odm/bin/wifi",           "system/odm/bin/wifi",     true  },
-    { false, "oem/bin/wifi",           "system/oem/bin/wifi",     true  },
+    { false, "odm/bin/wifi",           "system/odm/bin/wifi",     false },
+    { false, "odm/bin/wifi",           "vendor/odm/bin/wifi",     true  },
+    { false, "oem/bin/wifi",           "system/oem/bin/wifi",     false },
     { false, "data/bin/wifi",          "system/data/bin/wifi",    false },
     { false, "system/bin/*",           "system/bin/wifi",         true  },
     { false, "vendor/bin/*",           "system/vendor/bin/wifi",  true  },
     { false, "system/bin/*",           "system/bin",              false },
-    { false, "system/vendor/bin/*",    "vendor/bin/wifi",         true  },
+    { false, "system/vendor/bin/*",    "vendor/bin/wifi",         false },
     { false, "foo/*/bar/*",            "foo/1/bar/2",             true  },
     { false, "foo/*/bar/*",            "foo/1/bar",               false },
     { false, "foo/*/bar/*",            "foo/1/bar/2/3",           true  },
diff --git a/libcutils/include/cutils/memory.h b/libcutils/include/cutils/memory.h
index 4d26882..c6476c1 100644
--- a/libcutils/include/cutils/memory.h
+++ b/libcutils/include/cutils/memory.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_CUTILS_MEMORY_H
-#define ANDROID_CUTILS_MEMORY_H
+#pragma once
 
 #include <stdint.h>
 #include <sys/types.h>
@@ -24,12 +23,6 @@
 extern "C" {
 #endif
 
-/* size is given in bytes and must be multiple of 2 */
-void android_memset16(uint16_t* dst, uint16_t value, size_t size);
-
-/* size is given in bytes and must be multiple of 4 */
-void android_memset32(uint32_t* dst, uint32_t value, size_t size);
-
 #if defined(__GLIBC__) || defined(_WIN32)
 /* Declaration of strlcpy() for platforms that don't already have it. */
 size_t strlcpy(char *dst, const char *src, size_t size);
@@ -38,5 +31,3 @@
 #ifdef __cplusplus
 } // extern "C"
 #endif
-
-#endif // ANDROID_CUTILS_MEMORY_H
diff --git a/libcutils/include/cutils/sockets.h b/libcutils/include/cutils/sockets.h
index 285f150..be21a8f 100644
--- a/libcutils/include/cutils/sockets.h
+++ b/libcutils/include/cutils/sockets.h
@@ -103,14 +103,6 @@
 int socket_close(cutils_socket_t sock);
 
 /*
- * Sets socket receive timeout using SO_RCVTIMEO. Setting |timeout_ms| to 0
- * disables receive timeouts.
- *
- * Return 0 on success.
- */
-int socket_set_receive_timeout(cutils_socket_t sock, int timeout_ms);
-
-/*
  * Returns the local port the socket is bound to or -1 on error.
  */
 int socket_get_local_port(cutils_socket_t sock);
diff --git a/libcutils/memset_test.cpp b/libcutils/memset_test.cpp
deleted file mode 100644
index a98485f..0000000
--- a/libcutils/memset_test.cpp
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-
-#include <memory>
-
-#include <cutils/memory.h>
-#include <gtest/gtest.h>
-
-#define FENCEPOST_LENGTH 8
-
-#define MAX_TEST_SIZE (64*1024)
-// Choose values that have no repeating byte values.
-#define MEMSET16_PATTERN 0xb139
-#define MEMSET32_PATTERN 0x48193a27
-
-enum test_e {
-  MEMSET16 = 0,
-  MEMSET32,
-};
-
-static int g_memset16_aligns[][2] = {
-  { 2, 0 },
-  { 4, 0 },
-  { 8, 0 },
-  { 16, 0 },
-  { 32, 0 },
-  { 64, 0 },
-  { 128, 0 },
-
-  { 4, 2 },
-
-  { 8, 2 },
-  { 8, 4 },
-  { 8, 6 },
-
-  { 128, 2 },
-  { 128, 4 },
-  { 128, 6 },
-  { 128, 8 },
-  { 128, 10 },
-  { 128, 12 },
-  { 128, 14 },
-  { 128, 16 },
-};
-
-static int g_memset32_aligns[][2] = {
-  { 4, 0 },
-  { 8, 0 },
-  { 16, 0 },
-  { 32, 0 },
-  { 64, 0 },
-  { 128, 0 },
-
-  { 8, 4 },
-
-  { 128, 4 },
-  { 128, 8 },
-  { 128, 12 },
-  { 128, 16 },
-};
-
-static size_t GetIncrement(size_t len, size_t min_incr) {
-  if (len >= 4096) {
-    return 1024;
-  } else if (len >= 1024) {
-    return 256;
-  }
-  return min_incr;
-}
-
-// Return a pointer into the current buffer with the specified alignment.
-static void *GetAlignedPtr(void *orig_ptr, int alignment, int or_mask) {
-  uint64_t ptr = reinterpret_cast<uint64_t>(orig_ptr);
-  if (alignment > 0) {
-      // When setting the alignment, set it to exactly the alignment chosen.
-      // The pointer returned will be guaranteed not to be aligned to anything
-      // more than that.
-      ptr += alignment - (ptr & (alignment - 1));
-      ptr |= alignment | or_mask;
-  }
-
-  return reinterpret_cast<void*>(ptr);
-}
-
-static void SetFencepost(uint8_t *buffer) {
-  for (int i = 0; i < FENCEPOST_LENGTH; i += 2) {
-    buffer[i] = 0xde;
-    buffer[i+1] = 0xad;
-  }
-}
-
-static void VerifyFencepost(uint8_t *buffer) {
-  for (int i = 0; i < FENCEPOST_LENGTH; i += 2) {
-    if (buffer[i] != 0xde || buffer[i+1] != 0xad) {
-      uint8_t expected_value;
-      if (buffer[i] == 0xde) {
-        i++;
-        expected_value = 0xad;
-      } else {
-        expected_value = 0xde;
-      }
-      ASSERT_EQ(expected_value, buffer[i]);
-    }
-  }
-}
-
-void RunMemsetTests(test_e test_type, uint32_t value, int align[][2], size_t num_aligns) {
-  size_t min_incr = 4;
-  if (test_type == MEMSET16) {
-    min_incr = 2;
-    value |= value << 16;
-  }
-  std::unique_ptr<uint32_t[]> expected_buf(new uint32_t[MAX_TEST_SIZE/sizeof(uint32_t)]);
-  for (size_t i = 0; i < MAX_TEST_SIZE/sizeof(uint32_t); i++) {
-    expected_buf[i] = value;
-  }
-
-  // Allocate one large buffer with lots of extra space so that we can
-  // guarantee that all possible alignments will fit.
-  std::unique_ptr<uint8_t[]> buf(new uint8_t[3*MAX_TEST_SIZE]);
-  uint8_t *buf_align;
-  for (size_t i = 0; i < num_aligns; i++) {
-    size_t incr = min_incr;
-    for (size_t len = incr; len <= MAX_TEST_SIZE; len += incr) {
-      incr = GetIncrement(len, min_incr);
-
-      buf_align = reinterpret_cast<uint8_t*>(GetAlignedPtr(
-          buf.get()+FENCEPOST_LENGTH, align[i][0], align[i][1]));
-
-      SetFencepost(&buf_align[-FENCEPOST_LENGTH]);
-      SetFencepost(&buf_align[len]);
-
-      memset(buf_align, 0xff, len);
-      if (test_type == MEMSET16) {
-        android_memset16(reinterpret_cast<uint16_t*>(buf_align), value, len);
-      } else {
-        android_memset32(reinterpret_cast<uint32_t*>(buf_align), value, len);
-      }
-      ASSERT_EQ(0, memcmp(expected_buf.get(), buf_align, len))
-          << "Failed size " << len << " align " << align[i][0] << " " << align[i][1] << "\n";
-
-      VerifyFencepost(&buf_align[-FENCEPOST_LENGTH]);
-      VerifyFencepost(&buf_align[len]);
-    }
-  }
-}
-
-TEST(libcutils, android_memset16_non_zero) {
-  RunMemsetTests(MEMSET16, MEMSET16_PATTERN, g_memset16_aligns, sizeof(g_memset16_aligns)/sizeof(int[2]));
-}
-
-TEST(libcutils, android_memset16_zero) {
-  RunMemsetTests(MEMSET16, 0, g_memset16_aligns, sizeof(g_memset16_aligns)/sizeof(int[2]));
-}
-
-TEST(libcutils, android_memset32_non_zero) {
-  RunMemsetTests(MEMSET32, MEMSET32_PATTERN, g_memset32_aligns, sizeof(g_memset32_aligns)/sizeof(int[2]));
-}
-
-TEST(libcutils, android_memset32_zero) {
-  RunMemsetTests(MEMSET32, 0, g_memset32_aligns, sizeof(g_memset32_aligns)/sizeof(int[2]));
-}
diff --git a/libcutils/sockets_test.cpp b/libcutils/sockets_test.cpp
index b762ac1..1fa40bc 100644
--- a/libcutils/sockets_test.cpp
+++ b/libcutils/sockets_test.cpp
@@ -73,25 +73,6 @@
     EXPECT_EQ(0, socket_close(client));
 }
 
-// Tests receive timeout. The timing verification logic must be very coarse to
-// make sure different systems can all pass these tests.
-void TestReceiveTimeout(cutils_socket_t sock) {
-    time_t start_time;
-    char buffer[32];
-
-    // Make sure a 20ms timeout completes in 1 second or less.
-    EXPECT_EQ(0, socket_set_receive_timeout(sock, 20));
-    start_time = time(nullptr);
-    EXPECT_EQ(-1, recv(sock, buffer, sizeof(buffer), 0));
-    EXPECT_LE(difftime(time(nullptr), start_time), 1.0);
-
-    // Make sure a 1250ms timeout takes 1 second or more.
-    EXPECT_EQ(0, socket_set_receive_timeout(sock, 1250));
-    start_time = time(nullptr);
-    EXPECT_EQ(-1, recv(sock, buffer, sizeof(buffer), 0));
-    EXPECT_LE(1.0, difftime(time(nullptr), start_time));
-}
-
 // Tests socket_get_local_port().
 TEST(SocketsTest, TestGetLocalPort) {
     cutils_socket_t server;
@@ -157,32 +138,6 @@
     TestConnectedSockets(handler, client, SOCK_STREAM);
 }
 
-// Tests setting a receive timeout for UDP sockets.
-TEST(SocketsTest, TestUdpReceiveTimeout) {
-    cutils_socket_t sock = socket_inaddr_any_server(0, SOCK_DGRAM);
-    ASSERT_NE(INVALID_SOCKET, sock);
-
-    TestReceiveTimeout(sock);
-
-    EXPECT_EQ(0, socket_close(sock));
-}
-
-// Tests setting a receive timeout for TCP sockets.
-TEST(SocketsTest, TestTcpReceiveTimeout) {
-    cutils_socket_t server = socket_inaddr_any_server(0, SOCK_STREAM);
-    ASSERT_NE(INVALID_SOCKET, server);
-
-    cutils_socket_t client = socket_network_client(
-            "localhost", socket_get_local_port(server), SOCK_STREAM);
-    cutils_socket_t handler = accept(server, nullptr, nullptr);
-    EXPECT_EQ(0, socket_close(server));
-
-    TestReceiveTimeout(handler);
-
-    EXPECT_EQ(0, socket_close(client));
-    EXPECT_EQ(0, socket_close(handler));
-}
-
 // Tests socket_send_buffers() failure.
 TEST(SocketsTest, TestSocketSendBuffersFailure) {
     EXPECT_EQ(-1, socket_send_buffers(INVALID_SOCKET, nullptr, 0));
diff --git a/libcutils/sockets_unix.cpp b/libcutils/sockets_unix.cpp
index 6acdcd8..84663e6 100644
--- a/libcutils/sockets_unix.cpp
+++ b/libcutils/sockets_unix.cpp
@@ -31,13 +31,6 @@
     return close(sock);
 }
 
-int socket_set_receive_timeout(cutils_socket_t sock, int timeout_ms) {
-    timeval tv;
-    tv.tv_sec = timeout_ms / 1000;
-    tv.tv_usec = (timeout_ms % 1000) * 1000;
-    return setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
-}
-
 ssize_t socket_send_buffers(cutils_socket_t sock,
                             const cutils_socket_buffer_t* buffers,
                             size_t num_buffers) {
diff --git a/libcutils/sockets_windows.cpp b/libcutils/sockets_windows.cpp
index df14712..4adb796 100644
--- a/libcutils/sockets_windows.cpp
+++ b/libcutils/sockets_windows.cpp
@@ -54,11 +54,6 @@
     return closesocket(sock);
 }
 
-int socket_set_receive_timeout(cutils_socket_t sock, int timeout_ms) {
-    return setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,
-                      reinterpret_cast<char*>(&timeout_ms), sizeof(timeout_ms));
-}
-
 ssize_t socket_send_buffers(cutils_socket_t sock,
                             const cutils_socket_buffer_t* buffers,
                             size_t num_buffers) {
diff --git a/libgrallocusage/Android.bp b/libgrallocusage/Android.bp
index d27feb9..ce0c3c8 100644
--- a/libgrallocusage/Android.bp
+++ b/libgrallocusage/Android.bp
@@ -20,12 +20,7 @@
         "-Werror",
     ],
     cppflags: [
-        "-Weverything",
-        "-Wno-c++98-compat-pedantic",
-        // Hide errors in headers we include
-        "-Wno-global-constructors",
-        "-Wno-exit-time-destructors",
-        "-Wno-padded",
+        "-Wextra",
     ],
     srcs: ["GrallocUsageConversion.cpp"],
     export_include_dirs: ["include"],
diff --git a/libprocessgroup/profiles/test.cpp b/libprocessgroup/profiles/test.cpp
index bc9aade..b37e3e6 100644
--- a/libprocessgroup/profiles/test.cpp
+++ b/libprocessgroup/profiles/test.cpp
@@ -33,14 +33,14 @@
 }
 
 // Test suite instantiations
-INSTANTIATE_TEST_SUITE_P(, JsonSchemaTest,
+INSTANTIATE_TEST_SUITE_P(Cgroups, JsonSchemaTest,
                          ::testing::Values(MakeTestParam<Cgroups>("/cgroups.json"),
                                            MakeTestParam<Cgroups>("/cgroups.recovery.json"),
                                            MakeTestParam<TaskProfiles>("/task_profiles.json")));
-INSTANTIATE_TEST_SUITE_P(, CgroupsTest,
+INSTANTIATE_TEST_SUITE_P(Cgroups, CgroupsTest,
                          ::testing::Values(MakeTestParam<Cgroups>("/cgroups.json"),
                                            MakeTestParam<Cgroups>("/cgroups.recovery.json")));
-INSTANTIATE_TEST_SUITE_P(, TaskProfilesTest,
+INSTANTIATE_TEST_SUITE_P(TaskProfiles, TaskProfilesTest,
                          ::testing::Values(MakeTestParam<TaskProfiles>("/task_profiles.json")));
 
 }  // namespace profiles
diff --git a/libstats/stats_event.h b/libstats/include/stats_event.h
similarity index 71%
rename from libstats/stats_event.h
rename to libstats/include/stats_event.h
index ee88628..2811f52 100644
--- a/libstats/stats_event.h
+++ b/libstats/include/stats_event.h
@@ -53,11 +53,26 @@
 #define ERROR_NO_ATOM_ID 0x2
 #define ERROR_OVERFLOW 0x4
 #define ERROR_ATTRIBUTION_CHAIN_TOO_LONG 0x8
-#define ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD 0x10
-#define ERROR_INVALID_ANNOTATION_ID 0x20
-#define ERROR_ANNOTATION_ID_TOO_LARGE 0x40
-#define ERROR_TOO_MANY_ANNOTATIONS 0x80
-#define ERROR_TOO_MANY_FIELDS 0x100
+#define ERROR_TOO_MANY_KEY_VALUE_PAIRS 0x10
+#define ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD 0x20
+#define ERROR_INVALID_ANNOTATION_ID 0x40
+#define ERROR_ANNOTATION_ID_TOO_LARGE 0x80
+#define ERROR_TOO_MANY_ANNOTATIONS 0x100
+#define ERROR_TOO_MANY_FIELDS 0x200
+#define ERROR_INVALID_VALUE_TYPE 0x400
+
+/* TYPE IDS */
+#define INT32_TYPE 0x00
+#define INT64_TYPE 0x01
+#define STRING_TYPE 0x02
+#define LIST_TYPE 0x03
+#define FLOAT_TYPE 0x04
+#define BOOL_TYPE 0x05
+#define BYTE_ARRAY_TYPE 0x06
+#define OBJECT_TYPE 0x07
+#define KEY_VALUE_PAIRS_TYPE 0x08
+#define ATTRIBUTION_CHAIN_TYPE 0x09
+#define ERROR_TYPE 0x0F
 
 /* SYSTEM API */
 struct stats_event* stats_event_obtain();
@@ -75,6 +90,30 @@
 void stats_event_write_attribution_chain(struct stats_event* event, uint32_t* uids, char** tags,
                                          uint32_t* tagLengths, uint32_t numNodes);
 
+/* key_value_pair struct can be constructed as follows:
+ *    struct key_value_pair pair;
+ *    pair.key = key;
+ *    pair.typeId = STRING_TYPE;
+ *    pair.stringValue = buf;
+ *    pair.stringBytes = strlen(buf);
+ */
+struct key_value_pair {
+    int32_t key;
+    uint8_t valueType;  // expected to be INT32_TYPE, INT64_TYPE, FLOAT_TYPE, or STRING_TYPE
+    union {
+        int32_t int32Value;
+        int64_t int64Value;
+        float floatValue;
+        struct {
+            char* stringValue;
+            uint32_t stringBytes;
+        };
+    };
+};
+
+void stats_event_add_key_value_pairs(struct stats_event* event, struct key_value_pair* pairs,
+                                     uint32_t numPairs);
+
 void stats_event_add_bool_annotation(struct stats_event* event, uint32_t annotationId, bool value);
 void stats_event_add_int32_annotation(struct stats_event* event, uint32_t annotationId,
                                       int32_t value);
diff --git a/libstats/stats_event.c b/libstats/stats_event.c
index 5bccd9b..5e41d72 100644
--- a/libstats/stats_event.c
+++ b/libstats/stats_event.c
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "stats_event.h"
+#include "include/stats_event.h"
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
@@ -34,24 +34,9 @@
 #define POS_ATOM_ID (POS_TIMESTAMP + sizeof(byte) + sizeof(uint64_t))
 #define POS_FIRST_FIELD (POS_ATOM_ID + sizeof(byte) + sizeof(uint32_t))
 
-/* TYPE IDS */
-#define INT32_TYPE 0x00
-#define INT64_TYPE 0x01
-#define STRING_TYPE 0x02
-#define LIST_TYPE 0x03
-#define FLOAT_TYPE 0x04
-#define BOOL_TYPE 0x05
-#define BYTE_ARRAY_TYPE 0x06
-#define OBJECT_TYPE 0x07
-#define KEY_VALUE_PAIR_TYPE 0x08
-#define ATTRIBUTION_CHAIN_TYPE 0x09
-#define ERROR_TYPE 0x0F
-
 /* LIMITS */
 #define MAX_ANNOTATION_COUNT 15
-#define MAX_ANNOTATION_ID 127
-#define MAX_ATTRIBUTION_NODES 127
-#define MAX_NUM_ELEMENTS 127
+#define MAX_BYTE_VALUE 127  // parsing side requires that lengths fit in 7 bits
 
 // The stats_event struct holds the serialized encoding of an event
 // within a buf. Also includes other required fields.
@@ -59,6 +44,7 @@
     byte buf[MAX_EVENT_PAYLOAD];
     size_t bufPos;        // current write position within the buf
     size_t lastFieldPos;  // location of last field within the buf
+    byte lastFieldType;   // type of last field
     size_t size;          // number of valid bytes within buffer
     uint32_t numElements;
     uint32_t atomId;
@@ -82,6 +68,7 @@
 
     event->bufPos = POS_FIRST_FIELD;
     event->lastFieldPos = 0;
+    event->lastFieldType = OBJECT_TYPE;
     event->size = 0;
     event->numElements = 0;
     event->atomId = 0;
@@ -157,81 +144,69 @@
     return 0;
 }
 
+static void start_field(struct stats_event* event, byte typeId) {
+    event->lastFieldPos = event->bufPos;
+    event->lastFieldType = typeId;
+    event->bufPos += put_byte(event, typeId);
+    event->numElements++;
+}
+
 void stats_event_write_int32(struct stats_event* event, int32_t value) {
     if (!event || event->errors) return;
 
-    event->lastFieldPos = event->bufPos;
-    event->bufPos += put_byte(event, INT32_TYPE);
+    start_field(event, INT32_TYPE);
     event->bufPos += put_int32(event, value);
-    event->numElements++;
 }
 
 void stats_event_write_int64(struct stats_event* event, int64_t value) {
     if (!event || event->errors) return;
 
-    event->lastFieldPos = event->bufPos;
-    event->bufPos += put_byte(event, INT64_TYPE);
+    start_field(event, INT64_TYPE);
     event->bufPos += put_int64(event, value);
-    event->numElements++;
 }
 
 void stats_event_write_float(struct stats_event* event, float value) {
     if (!event || event->errors) return;
 
-    event->lastFieldPos = event->bufPos;
-    event->bufPos += put_byte(event, FLOAT_TYPE);
+    start_field(event, FLOAT_TYPE);
     event->bufPos += put_float(event, value);
-    event->numElements++;
 }
 
 void stats_event_write_bool(struct stats_event* event, bool value) {
     if (!event || event->errors) return;
 
-    event->lastFieldPos = event->bufPos;
-    event->bufPos += put_byte(event, BOOL_TYPE);
+    start_field(event, BOOL_TYPE);
     event->bufPos += put_bool(event, value);
-    event->numElements++;
 }
 
 // Buf is assumed to be encoded using UTF8
 void stats_event_write_byte_array(struct stats_event* event, uint8_t* buf, uint32_t numBytes) {
     if (!event || !buf || event->errors) return;
 
-    event->lastFieldPos = event->bufPos;
-    event->bufPos += put_byte(event, BYTE_ARRAY_TYPE);
+    start_field(event, BYTE_ARRAY_TYPE);
     event->bufPos += put_int32(event, numBytes);
     event->bufPos += put_byte_array(event, buf, numBytes);
-    event->numElements++;
 }
 
 // Buf is assumed to be encoded using UTF8
 void stats_event_write_string8(struct stats_event* event, char* buf, uint32_t numBytes) {
     if (!event || !buf || event->errors) return;
 
-    event->lastFieldPos = event->bufPos;
-    event->bufPos += put_byte(event, STRING_TYPE);
+    start_field(event, STRING_TYPE);
     event->bufPos += put_int32(event, numBytes);
     event->bufPos += put_byte_array(event, buf, numBytes);
-    event->numElements++;
-}
-
-// Side-effect: modifies event->errors if the attribution chain is too long
-static bool is_attribution_chain_too_long(struct stats_event* event, uint32_t numNodes) {
-    if (numNodes > MAX_ATTRIBUTION_NODES) {
-        event->errors |= ERROR_ATTRIBUTION_CHAIN_TOO_LONG;
-        return true;
-    }
-    return false;
 }
 
 // Tags are assumed to be encoded using UTF8
 void stats_event_write_attribution_chain(struct stats_event* event, uint32_t* uids, char** tags,
                                          uint32_t* tagLengths, uint32_t numNodes) {
     if (!event || event->errors) return;
-    if (is_attribution_chain_too_long(event, numNodes)) return;
+    if (numNodes > MAX_BYTE_VALUE) {
+        event->errors |= ERROR_ATTRIBUTION_CHAIN_TOO_LONG;
+        return;
+    }
 
-    event->lastFieldPos = event->bufPos;
-    event->bufPos += put_byte(event, ATTRIBUTION_CHAIN_TYPE);
+    start_field(event, ATTRIBUTION_CHAIN_TYPE);
     event->bufPos += put_byte(event, (byte)numNodes);
 
     for (int i = 0; i < numNodes; i++) {
@@ -239,7 +214,41 @@
         event->bufPos += put_int32(event, tagLengths[i]);
         event->bufPos += put_byte_array(event, tags[i], tagLengths[i]);
     }
-    event->numElements++;
+}
+
+void stats_event_add_key_value_pairs(struct stats_event* event, struct key_value_pair* pairs,
+                                     uint32_t numPairs) {
+    if (!event || event->errors) return;
+    if (numPairs > MAX_BYTE_VALUE) {
+        event->errors |= ERROR_TOO_MANY_KEY_VALUE_PAIRS;
+        return;
+    }
+
+    start_field(event, KEY_VALUE_PAIRS_TYPE);
+    event->bufPos += put_byte(event, (byte)numPairs);
+
+    for (int i = 0; i < numPairs; i++) {
+        event->bufPos += put_int32(event, pairs[i].key);
+        event->bufPos += put_byte(event, pairs[i].valueType);
+        switch (pairs[i].valueType) {
+            case INT32_TYPE:
+                event->bufPos += put_int32(event, pairs[i].int32Value);
+                break;
+            case INT64_TYPE:
+                event->bufPos += put_int64(event, pairs[i].int64Value);
+                break;
+            case FLOAT_TYPE:
+                event->bufPos += put_float(event, pairs[i].floatValue);
+                break;
+            case STRING_TYPE:
+                event->bufPos += put_int32(event, pairs[i].stringBytes);
+                event->bufPos += put_byte_array(event, pairs[i].stringValue, pairs[i].stringBytes);
+                break;
+            default:
+                event->errors |= ERROR_INVALID_VALUE_TYPE;
+                return;
+        }
+    }
 }
 
 // Side-effect: modifies event->errors if annotation does not follow field
@@ -253,7 +262,7 @@
 
 // Side-effect: modifies event->errors if annotation id is too large
 static bool is_valid_annotation_id(struct stats_event* event, uint32_t annotationId) {
-    if (annotationId > MAX_ANNOTATION_ID) {
+    if (annotationId > MAX_BYTE_VALUE) {
         event->errors |= ERROR_ANNOTATION_ID_TOO_LARGE;
         return false;
     }
@@ -263,15 +272,15 @@
 // Side-effect: modifies event->errors if field has too many annotations
 static void increment_annotation_count(struct stats_event* event) {
     byte fieldType = event->buf[event->lastFieldPos] & 0x0F;
-    byte oldAnnotationCount = event->buf[event->lastFieldPos] & 0xF0;
-    byte newAnnotationCount = oldAnnotationCount + 1;
+    uint32_t oldAnnotationCount = event->buf[event->lastFieldPos] & 0xF0;
+    uint32_t newAnnotationCount = oldAnnotationCount + 1;
 
     if (newAnnotationCount > MAX_ANNOTATION_COUNT) {
         event->errors |= ERROR_TOO_MANY_ANNOTATIONS;
         return;
     }
 
-    event->buf[event->lastFieldPos] = ((newAnnotationCount << 4) & 0xF0) | fieldType;
+    event->buf[event->lastFieldPos] = (((byte)newAnnotationCount << 4) & 0xF0) | fieldType;
 }
 
 void stats_event_add_bool_annotation(struct stats_event* event, uint32_t annotationId, bool value) {
@@ -305,13 +314,6 @@
     // store size before we modify bufPos
     event->size = event->bufPos;
 
-    if (event->numElements > MAX_NUM_ELEMENTS) {
-        event->errors |= ERROR_TOO_MANY_FIELDS;
-    } else {
-        event->bufPos = POS_NUM_ELEMENTS;
-        put_byte(event, (byte)event->numElements);
-    }
-
     if (event->timestampNs == 0) {
         event->errors |= ERROR_NO_TIMESTAMP;
     } else {
@@ -321,6 +323,7 @@
         event->bufPos = POS_TIMESTAMP;
         event->bufPos += put_byte(event, INT64_TYPE);
         event->bufPos += put_int64(event, event->timestampNs);
+        event->numElements++;
     }
 
     if (event->atomId == 0) {
@@ -329,6 +332,14 @@
         event->bufPos = POS_ATOM_ID;
         event->bufPos += put_byte(event, INT32_TYPE);
         event->bufPos += put_int64(event, event->atomId);
+        event->numElements++;
+    }
+
+    if (event->numElements > MAX_BYTE_VALUE) {
+        event->errors |= ERROR_TOO_MANY_FIELDS;
+    } else {
+        event->bufPos = POS_NUM_ELEMENTS;
+        put_byte(event, (byte)event->numElements);
     }
 
     // If there are errors, rewrite buffer
diff --git a/libunwindstack/tests/ArmExidxDecodeTest.cpp b/libunwindstack/tests/ArmExidxDecodeTest.cpp
index 7b1dd92..69a7816 100644
--- a/libunwindstack/tests/ArmExidxDecodeTest.cpp
+++ b/libunwindstack/tests/ArmExidxDecodeTest.cpp
@@ -1662,7 +1662,7 @@
   ASSERT_EQ(0x10U, (*exidx_->regs())[15]);
 }
 
-INSTANTIATE_TEST_SUITE_P(, ArmExidxDecodeTest,
+INSTANTIATE_TEST_SUITE_P(Unwindstack, ArmExidxDecodeTest,
                          ::testing::Values("logging", "register_logging", "no_logging"));
 
 }  // namespace unwindstack
diff --git a/libutils/include/utils/Trace.h b/libutils/include/utils/Trace.h
index fec0ffa..9986bf5 100644
--- a/libutils/include/utils/Trace.h
+++ b/libutils/include/utils/Trace.h
@@ -33,7 +33,7 @@
 // ATRACE_NAME traces from its location until the end of its enclosing scope.
 #define _PASTE(x, y) x ## y
 #define PASTE(x, y) _PASTE(x,y)
-#define ATRACE_NAME(name) android::ScopedTrace PASTE(___tracer, __LINE__) (ATRACE_TAG, name)
+#define ATRACE_NAME(name) ::android::ScopedTrace PASTE(___tracer, __LINE__)(ATRACE_TAG, name)
 
 // ATRACE_CALL is an ATRACE_NAME that uses the current function name.
 #define ATRACE_CALL() ATRACE_NAME(__FUNCTION__)
diff --git a/libziparchive/Android.bp b/libziparchive/Android.bp
index 667bddc..e3bb2ab 100644
--- a/libziparchive/Android.bp
+++ b/libziparchive/Android.bp
@@ -196,4 +196,5 @@
     srcs: ["libziparchive_fuzzer.cpp"],
     static_libs: ["libziparchive", "libbase", "libz", "liblog"],
     host_supported: true,
+    corpus: ["testdata/*"],
 }
diff --git a/libziparchive/unzip.cpp b/libziparchive/unzip.cpp
index e4839b4..81f8c0f 100644
--- a/libziparchive/unzip.cpp
+++ b/libziparchive/unzip.cpp
@@ -109,9 +109,9 @@
   return (mkdir(path.c_str(), 0777) != -1);
 }
 
-static int CompressionRatio(int64_t uncompressed, int64_t compressed) {
+static float CompressionRatio(int64_t uncompressed, int64_t compressed) {
   if (uncompressed == 0) return 0;
-  return static_cast<int>((100LL * (uncompressed - compressed)) / uncompressed);
+  return static_cast<float>(100LL * (uncompressed - compressed)) / uncompressed;
 }
 
 static void MaybeShowHeader(ZipArchiveHandle zah) {
@@ -143,7 +143,7 @@
     if (flag_v) {
       printf(
           "--------          -------  ---                            -------\n"
-          "%8" PRId64 "         %8" PRId64 " %3d%%                            %zu file%s\n",
+          "%8" PRId64 "         %8" PRId64 " %3.0f%%                            %zu file%s\n",
           total_uncompressed_length, total_compressed_length,
           CompressionRatio(total_uncompressed_length, total_compressed_length), file_count,
           (file_count == 1) ? "" : "s");
@@ -155,7 +155,7 @@
     }
   } else {
     if (!flag_1 && includes.empty() && excludes.empty()) {
-      printf("%zu files, %" PRId64 " bytes uncompressed, %" PRId64 " bytes compressed: %3d%%\n",
+      printf("%zu files, %" PRId64 " bytes uncompressed, %" PRId64 " bytes compressed:  %.1f%%\n",
              file_count, total_uncompressed_length, total_compressed_length,
              CompressionRatio(total_uncompressed_length, total_compressed_length));
     }
@@ -261,7 +261,7 @@
   snprintf(time, sizeof(time), "%04d-%02d-%02d %02d:%02d", t.tm_year + 1900, t.tm_mon + 1,
            t.tm_mday, t.tm_hour, t.tm_min);
   if (flag_v) {
-    printf("%8d  %s  %7d %3d%% %s %08x  %s\n", entry.uncompressed_length,
+    printf("%8d  %s  %7d %3.0f%% %s %08x  %s\n", entry.uncompressed_length,
            (entry.method == kCompressStored) ? "Stored" : "Defl:N", entry.compressed_length,
            CompressionRatio(entry.uncompressed_length, entry.compressed_length), time, entry.crc32,
            name.c_str());
diff --git a/lmkd/Android.bp b/lmkd/Android.bp
index e8e125b..deebb8e 100644
--- a/lmkd/Android.bp
+++ b/lmkd/Android.bp
@@ -48,6 +48,7 @@
 cc_library_static {
     name: "liblmkd_utils",
     srcs: ["liblmkd_utils.c"],
+    recovery_available: true,
     shared_libs: [
         "libcutils",
     ],
diff --git a/lmkd/include/liblmkd_utils.h b/lmkd/include/liblmkd_utils.h
index 72e3f4a..92e4d41 100644
--- a/lmkd/include/liblmkd_utils.h
+++ b/lmkd/include/liblmkd_utils.h
@@ -40,6 +40,14 @@
 int lmkd_register_proc(int sock, struct lmk_procprio *params);
 
 /*
+ * Unregisters a process previously registered with lmkd.
+ * On success returns 0.
+ * On error, -1 is returned.
+ * In the case of error errno is set appropriately.
+ */
+int lmkd_unregister_proc(int sock, struct lmk_procremove *params);
+
+/*
  * Creates memcg directory for given process.
  * On success returns 0.
  * -1 is returned if path creation failed.
diff --git a/lmkd/include/lmkd.h b/lmkd/include/lmkd.h
index 59377dd..bd9b80e 100644
--- a/lmkd/include/lmkd.h
+++ b/lmkd/include/lmkd.h
@@ -87,21 +87,33 @@
     return idx * sizeof(int);
 }
 
+/* Process types for lmk_procprio.ptype */
+enum proc_type {
+    PROC_TYPE_FIRST,
+    PROC_TYPE_APP = PROC_TYPE_FIRST,
+    PROC_TYPE_SERVICE,
+    PROC_TYPE_COUNT,
+};
+
 /* LMK_PROCPRIO packet payload */
 struct lmk_procprio {
     pid_t pid;
     uid_t uid;
     int oomadj;
+    enum proc_type ptype;
 };
 
 /*
  * For LMK_PROCPRIO packet get its payload.
  * Warning: no checks performed, caller should ensure valid parameters.
  */
-static inline void lmkd_pack_get_procprio(LMKD_CTRL_PACKET packet, struct lmk_procprio* params) {
+static inline void lmkd_pack_get_procprio(LMKD_CTRL_PACKET packet, int field_count,
+                                          struct lmk_procprio* params) {
     params->pid = (pid_t)ntohl(packet[1]);
     params->uid = (uid_t)ntohl(packet[2]);
     params->oomadj = ntohl(packet[3]);
+    /* if field is missing assume PROC_TYPE_APP for backward compatibility */
+    params->ptype = field_count > 3 ? (enum proc_type)ntohl(packet[4]) : PROC_TYPE_APP;
 }
 
 /*
@@ -113,7 +125,8 @@
     packet[1] = htonl(params->pid);
     packet[2] = htonl(params->uid);
     packet[3] = htonl(params->oomadj);
-    return 4 * sizeof(int);
+    packet[4] = htonl((int)params->ptype);
+    return 5 * sizeof(int);
 }
 
 /* LMK_PROCREMOVE packet payload */
@@ -135,7 +148,7 @@
  * Warning: no checks performed, caller should ensure valid parameters.
  */
 static inline size_t lmkd_pack_set_procremove(LMKD_CTRL_PACKET packet,
-                                              struct lmk_procprio* params) {
+                                              struct lmk_procremove* params) {
     packet[0] = htonl(LMK_PROCREMOVE);
     packet[1] = htonl(params->pid);
     return 2 * sizeof(int);
diff --git a/lmkd/liblmkd_utils.c b/lmkd/liblmkd_utils.c
index fa3b7a9..280c149 100644
--- a/lmkd/liblmkd_utils.c
+++ b/lmkd/liblmkd_utils.c
@@ -28,7 +28,7 @@
 int lmkd_connect() {
     return socket_local_client("lmkd",
                                ANDROID_SOCKET_NAMESPACE_RESERVED,
-                               SOCK_SEQPACKET);
+                               SOCK_SEQPACKET | SOCK_CLOEXEC);
 }
 
 int lmkd_register_proc(int sock, struct lmk_procprio *params) {
@@ -42,6 +42,17 @@
     return (ret < 0) ? -1 : 0;
 }
 
+int lmkd_unregister_proc(int sock, struct lmk_procremove *params) {
+    LMKD_CTRL_PACKET packet;
+    size_t size;
+    int ret;
+
+    size = lmkd_pack_set_procremove(packet, params);
+    ret = TEMP_FAILURE_RETRY(write(sock, packet, size));
+
+    return (ret < 0) ? -1 : 0;
+}
+
 int create_memcg(uid_t uid, pid_t pid) {
     char buf[256];
     int tasks_file;
diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c
index 9de7ff7..4352498 100644
--- a/lmkd/lmkd.c
+++ b/lmkd/lmkd.c
@@ -45,6 +45,7 @@
 #include <log/log.h>
 #include <log/log_event_list.h>
 #include <log/log_time.h>
+#include <private/android_filesystem_config.h>
 #include <psi/psi.h>
 #include <system/thread_defs.h>
 
@@ -240,11 +241,12 @@
 /* data required to handle socket events */
 struct sock_event_handler_info {
     int sock;
+    pid_t pid;
     struct event_handler_info handler_info;
 };
 
-/* max supported number of data connections */
-#define MAX_DATA_CONN 2
+/* max supported number of data connections (AMS, init, tests) */
+#define MAX_DATA_CONN 3
 
 /* socket event handler data */
 static struct sock_event_handler_info ctrl_sock;
@@ -254,7 +256,7 @@
 static struct event_handler_info vmpressure_hinfo[VMPRESS_LEVEL_COUNT];
 
 /*
- * 1 ctrl listen socket, 2 ctrl data socket, 3 memory pressure levels,
+ * 1 ctrl listen socket, 3 ctrl data socket, 3 memory pressure levels,
  * 1 lmk events + 1 fd to wait for process death
  */
 #define MAX_EPOLL_EVENTS (1 + MAX_DATA_CONN + VMPRESS_LEVEL_COUNT + 1 + 1)
@@ -490,6 +492,7 @@
     int pidfd;
     uid_t uid;
     int oomadj;
+    pid_t reg_pid; /* PID of the process that registered this record */
     struct proc *pidhash_next;
 };
 
@@ -845,7 +848,35 @@
     return buf;
 }
 
-static void cmd_procprio(LMKD_CTRL_PACKET packet) {
+static bool claim_record(struct proc *procp, pid_t pid) {
+    if (procp->reg_pid == pid) {
+        /* Record already belongs to the registrant */
+        return true;
+    }
+    if (procp->reg_pid == 0) {
+        /* Old registrant is gone, claim the record */
+        procp->reg_pid = pid;
+        return true;
+    }
+    /* The record is owned by another registrant */
+    return false;
+}
+
+static void remove_claims(pid_t pid) {
+    int i;
+
+    for (i = 0; i < PIDHASH_SZ; i++) {
+        struct proc *procp = pidhash[i];
+        while (procp) {
+            if (procp->reg_pid == pid) {
+                procp->reg_pid = 0;
+            }
+            procp = procp->pidhash_next;
+        }
+    }
+}
+
+static void cmd_procprio(LMKD_CTRL_PACKET packet, int field_count, struct ucred *cred) {
     struct proc *procp;
     char path[LINE_MAX];
     char val[20];
@@ -855,7 +886,7 @@
     struct passwd *pwdrec;
     int tgid;
 
-    lmkd_pack_get_procprio(packet, &params);
+    lmkd_pack_get_procprio(packet, field_count, &params);
 
     if (params.oomadj < OOM_SCORE_ADJ_MIN ||
         params.oomadj > OOM_SCORE_ADJ_MAX) {
@@ -863,6 +894,11 @@
         return;
     }
 
+    if (params.ptype < PROC_TYPE_FIRST || params.ptype >= PROC_TYPE_COUNT) {
+        ALOGE("Invalid PROCPRIO process type argument %d", params.ptype);
+        return;
+    }
+
     /* Check if registered process is a thread group leader */
     tgid = proc_get_tgid(params.pid);
     if (tgid >= 0 && tgid != params.pid) {
@@ -889,7 +925,8 @@
         return;
     }
 
-    if (per_app_memcg) {
+    /* lmkd should not change soft limits for services */
+    if (params.ptype == PROC_TYPE_APP && per_app_memcg) {
         if (params.oomadj >= 900) {
             soft_limit_mult = 0;
         } else if (params.oomadj >= 800) {
@@ -954,24 +991,47 @@
         procp->pid = params.pid;
         procp->pidfd = pidfd;
         procp->uid = params.uid;
+        procp->reg_pid = cred->pid;
         procp->oomadj = params.oomadj;
         proc_insert(procp);
     } else {
+        if (!claim_record(procp, cred->pid)) {
+            char buf[LINE_MAX];
+            /* Only registrant of the record can remove it */
+            ALOGE("%s (%d, %d) attempts to modify a process registered by another client",
+                proc_get_name(cred->pid, buf, sizeof(buf)), cred->uid, cred->pid);
+            return;
+        }
         proc_unslot(procp);
         procp->oomadj = params.oomadj;
         proc_slot(procp);
     }
 }
 
-static void cmd_procremove(LMKD_CTRL_PACKET packet) {
+static void cmd_procremove(LMKD_CTRL_PACKET packet, struct ucred *cred) {
     struct lmk_procremove params;
+    struct proc *procp;
 
     lmkd_pack_get_procremove(packet, &params);
+
     if (use_inkernel_interface) {
         stats_remove_taskname(params.pid, kpoll_info.poll_fd);
         return;
     }
 
+    procp = pid_lookup(params.pid);
+    if (!procp) {
+        return;
+    }
+
+    if (!claim_record(procp, cred->pid)) {
+        char buf[LINE_MAX];
+        /* Only registrant of the record can remove it */
+        ALOGE("%s (%d, %d) attempts to unregister a process registered by another client",
+            proc_get_name(cred->pid, buf, sizeof(buf)), cred->uid, cred->pid);
+        return;
+    }
+
     /*
      * WARNING: After pid_remove() procp is freed and can't be used!
      * Therefore placed at the end of the function.
@@ -979,7 +1039,7 @@
     pid_remove(params.pid);
 }
 
-static void cmd_procpurge() {
+static void cmd_procpurge(struct ucred *cred) {
     int i;
     struct proc *procp;
     struct proc *next;
@@ -989,20 +1049,17 @@
         return;
     }
 
-    for (i = 0; i <= ADJTOSLOT(OOM_SCORE_ADJ_MAX); i++) {
-        procadjslot_list[i].next = &procadjslot_list[i];
-        procadjslot_list[i].prev = &procadjslot_list[i];
-    }
-
     for (i = 0; i < PIDHASH_SZ; i++) {
         procp = pidhash[i];
         while (procp) {
             next = procp->pidhash_next;
-            free(procp);
+            /* Purge only records created by the requestor */
+            if (claim_record(procp, cred->pid)) {
+                pid_remove(procp->pid);
+            }
             procp = next;
         }
     }
-    memset(&pidhash[0], 0, sizeof(pidhash));
 }
 
 static void inc_killcnt(int oomadj) {
@@ -1153,19 +1210,50 @@
 
     close(data_sock[dsock_idx].sock);
     data_sock[dsock_idx].sock = -1;
+
+    /* Mark all records of the old registrant as unclaimed */
+    remove_claims(data_sock[dsock_idx].pid);
 }
 
-static int ctrl_data_read(int dsock_idx, char *buf, size_t bufsz) {
-    int ret = 0;
+static ssize_t ctrl_data_read(int dsock_idx, char *buf, size_t bufsz, struct ucred *sender_cred) {
+    struct iovec iov = { buf, bufsz };
+    char control[CMSG_SPACE(sizeof(struct ucred))];
+    struct msghdr hdr = {
+        NULL, 0, &iov, 1, control, sizeof(control), 0,
+    };
+    ssize_t ret;
 
-    ret = TEMP_FAILURE_RETRY(read(data_sock[dsock_idx].sock, buf, bufsz));
-
+    ret = TEMP_FAILURE_RETRY(recvmsg(data_sock[dsock_idx].sock, &hdr, 0));
     if (ret == -1) {
-        ALOGE("control data socket read failed; errno=%d", errno);
-    } else if (ret == 0) {
-        ALOGE("Got EOF on control data socket");
-        ret = -1;
+        ALOGE("control data socket read failed; %s", strerror(errno));
+        return -1;
     }
+    if (ret == 0) {
+        ALOGE("Got EOF on control data socket");
+        return -1;
+    }
+
+    struct ucred* cred = NULL;
+    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&hdr);
+    while (cmsg != NULL) {
+        if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDENTIALS) {
+            cred = (struct ucred*)CMSG_DATA(cmsg);
+            break;
+        }
+        cmsg = CMSG_NXTHDR(&hdr, cmsg);
+    }
+
+    if (cred == NULL) {
+        ALOGE("Failed to retrieve sender credentials");
+        /* Close the connection */
+        ctrl_data_close(dsock_idx);
+        return -1;
+    }
+
+    memcpy(sender_cred, cred, sizeof(struct ucred));
+
+    /* Store PID of the peer */
+    data_sock[dsock_idx].pid = cred->pid;
 
     return ret;
 }
@@ -1187,13 +1275,14 @@
 
 static void ctrl_command_handler(int dsock_idx) {
     LMKD_CTRL_PACKET packet;
+    struct ucred cred;
     int len;
     enum lmk_cmd cmd;
     int nargs;
     int targets;
     int kill_cnt;
 
-    len = ctrl_data_read(dsock_idx, (char *)packet, CTRL_PACKET_MAX_SIZE);
+    len = ctrl_data_read(dsock_idx, (char *)packet, CTRL_PACKET_MAX_SIZE, &cred);
     if (len <= 0)
         return;
 
@@ -1215,19 +1304,20 @@
         cmd_target(targets, packet);
         break;
     case LMK_PROCPRIO:
-        if (nargs != 3)
+        /* process type field is optional for backward compatibility */
+        if (nargs < 3 || nargs > 4)
             goto wronglen;
-        cmd_procprio(packet);
+        cmd_procprio(packet, nargs, &cred);
         break;
     case LMK_PROCREMOVE:
         if (nargs != 1)
             goto wronglen;
-        cmd_procremove(packet);
+        cmd_procremove(packet, &cred);
         break;
     case LMK_PROCPURGE:
         if (nargs != 0)
             goto wronglen;
-        cmd_procpurge();
+        cmd_procpurge(&cred);
         break;
     case LMK_GETKILLCNT:
         if (nargs != 2)
diff --git a/lmkd/lmkd.rc b/lmkd/lmkd.rc
index 76b6055..982a188 100644
--- a/lmkd/lmkd.rc
+++ b/lmkd/lmkd.rc
@@ -4,5 +4,5 @@
     group lmkd system readproc
     capabilities DAC_OVERRIDE KILL IPC_LOCK SYS_NICE SYS_RESOURCE
     critical
-    socket lmkd seqpacket 0660 system system
+    socket lmkd seqpacket+passcred 0660 system system
     writepid /dev/cpuset/system-background/tasks
diff --git a/rootdir/Android.bp b/rootdir/Android.bp
new file mode 100644
index 0000000..96b5e0d
--- /dev/null
+++ b/rootdir/Android.bp
@@ -0,0 +1,26 @@
+// Copyright 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+prebuilt_etc {
+    name: "init.rc",
+    src: "init.rc",
+    sub_dir: "init/hw",
+    required: ["fsverity_init"],
+}
+
+prebuilt_etc {
+    name: "ueventd.rc",
+    src: "ueventd.rc",
+    recovery_available: true,
+}
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index eac3f06..994d9ae 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -1,22 +1,6 @@
 LOCAL_PATH:= $(call my-dir)
 
 #######################################
-# init.rc
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := init.rc
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)
-LOCAL_REQUIRED_MODULES := fsverity_init
-
-# The init symlink must be a post install command of a file that is to TARGET_ROOT_OUT.
-# Since init.rc is required for init and satisfies that requirement, we hijack it to create the symlink.
-LOCAL_POST_INSTALL_CMD := ln -sf /system/bin/init $(TARGET_ROOT_OUT)/init
-
-include $(BUILD_PREBUILT)
-
-#######################################
 # init-debug.rc
 include $(CLEAR_VARS)
 
@@ -148,6 +132,10 @@
   LOCAL_POST_INSTALL_CMD += ; mkdir -p $(TARGET_ROOT_OUT)/postinstall
 endif
 
+# The init symlink must be a post install command of a file that is to TARGET_ROOT_OUT.
+# Since init.environ.rc is required for init and satisfies that requirement, we hijack it to create the symlink.
+LOCAL_POST_INSTALL_CMD += ; ln -sf /system/bin/init $(TARGET_ROOT_OUT)/init
+
 include $(BUILD_SYSTEM)/base_rules.mk
 
 $(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/init.environ.rc.in
@@ -294,27 +282,6 @@
 include $(BUILD_PREBUILT)
 
 #######################################
-# {llndk,vndkcore,vndksp,vndkprivate,vndkcorevariant}.libraries.txt
-vndk_libraries_files := \
-  llndk.libraries.txt:$(SOONG_LLNDK_LIBRARIES_FILE)\
-  vndkcore.libraries.txt:$(SOONG_VNDKCORE_LIBRARIES_FILE)\
-  vndksp.libraries.txt:$(SOONG_VNDKSP_LIBRARIES_FILE)\
-  vndkprivate.libraries.txt:$(SOONG_VNDKPRIVATE_LIBRARIES_FILE)\
-  vndkcorevariant.libraries.txt:$(SOONG_VNDKCOREVARIANT_LIBRARIES_FILE)
-
-$(foreach pair,$(vndk_libraries_files),\
-  $(eval _filename := $(call word-colon,1,$(pair)))\
-  $(eval _prebuilt := $(call word-colon,2,$(pair)))\
-  $(eval include $(CLEAR_VARS))\
-  $(eval LOCAL_MODULE := $(_filename))\
-  $(eval LOCAL_MODULE_CLASS := ETC)\
-  $(eval LOCAL_PREBUILT_MODULE_FILE := $(_prebuilt))\
-  $(eval LOCAL_MODULE_PATH := $(TARGET_OUT_ETC))\
-  $(eval LOCAL_MODULE_STEM := $(call append_vndk_version,$(LOCAL_MODULE)))\
-  $(eval include $(BUILD_PREBUILT)))
-vndk_libraries_files :=
-
-#######################################
 # sanitizer.libraries.txt
 include $(CLEAR_VARS)
 LOCAL_MODULE := sanitizer.libraries.txt
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 66d60fa..bc18e27 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -5,11 +5,11 @@
 #
 
 import /init.environ.rc
-import /init.usb.rc
+import /system/etc/init/hw/init.usb.rc
 import /init.${ro.hardware}.rc
 import /vendor/etc/init/hw/init.${ro.hardware}.rc
-import /init.usb.configfs.rc
-import /init.${ro.zygote}.rc
+import /system/etc/init/hw/init.usb.configfs.rc
+import /system/etc/init/hw/init.${ro.zygote}.rc
 
 # Cgroups are mounted right before early-init using list from /etc/cgroups.json
 on early-init
@@ -347,6 +347,8 @@
 
     # Start logd before any other services run to ensure we capture all of their logs.
     start logd
+    # Start lmkd before any other services run so that it can register them
+    start lmkd
 
     # Start essential services.
     start servicemanager
@@ -486,26 +488,26 @@
 
     # Start bootcharting as soon as possible after the data partition is
     # mounted to collect more data.
-    mkdir /data/bootchart 0755 shell shell
+    mkdir /data/bootchart 0755 shell shell encryption=Require
     bootchart start
 
     # Make sure that apexd is started in the default namespace
     enter_default_mount_ns
 
     # /data/apex is now available. Start apexd to scan and activate APEXes.
-    mkdir /data/apex 0750 root system
+    mkdir /data/apex 0750 root system encryption=None
     mkdir /data/apex/active 0750 root system
     mkdir /data/apex/backup 0700 root system
     mkdir /data/apex/hashtree 0700 root system
     mkdir /data/apex/sessions 0700 root system
-    mkdir /data/app-staging 0750 system system
+    mkdir /data/app-staging 0750 system system encryption=None
     start apexd
 
     # Avoid predictable entropy pool. Carry over entropy from previous boot.
     copy /data/system/entropy.dat /dev/urandom
 
     # create basic filesystem structure
-    mkdir /data/misc 01771 system misc
+    mkdir /data/misc 01771 system misc encryption=Require
     mkdir /data/misc/recovery 0770 system log
     copy /data/misc/recovery/ro.build.fingerprint /data/misc/recovery/ro.build.fingerprint.1
     chmod 0440 /data/misc/recovery/ro.build.fingerprint.1
@@ -548,7 +550,7 @@
     mkdir /data/misc/user 0771 root root
     # give system access to wpa_supplicant.conf for backup and restore
     chmod 0660 /data/misc/wifi/wpa_supplicant.conf
-    mkdir /data/local 0751 root root
+    mkdir /data/local 0751 root root encryption=Require
     mkdir /data/misc/media 0700 media media
     mkdir /data/misc/audioserver 0700 audioserver audioserver
     mkdir /data/misc/cameraserver 0700 cameraserver cameraserver
@@ -567,89 +569,91 @@
     mkdir /data/misc/gcov 0770 root root
     mkdir /data/misc/installd 0700 root root
 
-    mkdir /data/preloads 0775 system system
+    mkdir /data/preloads 0775 system system encryption=None
 
-    mkdir /data/vendor 0771 root root
-    mkdir /data/vendor_ce 0771 root root
-    mkdir /data/vendor_de 0771 root root
+    mkdir /data/vendor 0771 root root encryption=Require
+    mkdir /data/vendor_ce 0771 root root encryption=None
+    mkdir /data/vendor_de 0771 root root encryption=None
     mkdir /data/vendor/hardware 0771 root root
 
     # For security reasons, /data/local/tmp should always be empty.
     # Do not place files or directories in /data/local/tmp
     mkdir /data/local/tmp 0771 shell shell
     mkdir /data/local/traces 0777 shell shell
-    mkdir /data/data 0771 system system
-    mkdir /data/app-private 0771 system system
-    mkdir /data/app-ephemeral 0771 system system
-    mkdir /data/app-asec 0700 root root
-    mkdir /data/app-lib 0771 system system
-    mkdir /data/app 0771 system system
-    mkdir /data/property 0700 root root
-    mkdir /data/tombstones 0771 system system
+    mkdir /data/data 0771 system system encryption=None
+    mkdir /data/app-private 0771 system system encryption=Require
+    mkdir /data/app-ephemeral 0771 system system encryption=Require
+    mkdir /data/app-asec 0700 root root encryption=Require
+    mkdir /data/app-lib 0771 system system encryption=Require
+    mkdir /data/app 0771 system system encryption=Require
+    mkdir /data/property 0700 root root encryption=Require
+    mkdir /data/tombstones 0771 system system encryption=Require
     mkdir /data/vendor/tombstones 0771 root root
     mkdir /data/vendor/tombstones/wifi 0771 wifi wifi
 
     # create dalvik-cache, so as to enforce our permissions
-    mkdir /data/dalvik-cache 0771 root root
+    mkdir /data/dalvik-cache 0771 root root encryption=Require
     # create the A/B OTA directory, so as to enforce our permissions
-    mkdir /data/ota 0771 root root
+    mkdir /data/ota 0771 root root encryption=Require
 
     # create the OTA package directory. It will be accessed by GmsCore (cache
     # group), update_engine and update_verifier.
-    mkdir /data/ota_package 0770 system cache
+    mkdir /data/ota_package 0770 system cache encryption=Require
 
     # create resource-cache and double-check the perms
-    mkdir /data/resource-cache 0771 system system
+    mkdir /data/resource-cache 0771 system system encryption=Require
     chown system system /data/resource-cache
     chmod 0771 /data/resource-cache
 
     # create the lost+found directories, so as to enforce our permissions
-    mkdir /data/lost+found 0770 root root
+    mkdir /data/lost+found 0770 root root encryption=None
 
     # create directory for DRM plug-ins - give drm the read/write access to
     # the following directory.
-    mkdir /data/drm 0770 drm drm
+    mkdir /data/drm 0770 drm drm encryption=Require
 
     # create directory for MediaDrm plug-ins - give drm the read/write access to
     # the following directory.
-    mkdir /data/mediadrm 0770 mediadrm mediadrm
+    mkdir /data/mediadrm 0770 mediadrm mediadrm encryption=Require
 
-    mkdir /data/anr 0775 system system
+    mkdir /data/anr 0775 system system encryption=Require
 
     # NFC: create data/nfc for nv storage
-    mkdir /data/nfc 0770 nfc nfc
+    mkdir /data/nfc 0770 nfc nfc encryption=Require
     mkdir /data/nfc/param 0770 nfc nfc
 
     # Create all remaining /data root dirs so that they are made through init
     # and get proper encryption policy installed
-    mkdir /data/backup 0700 system system
-    mkdir /data/ss 0700 system system
+    mkdir /data/backup 0700 system system encryption=Require
+    mkdir /data/ss 0700 system system encryption=Require
 
-    mkdir /data/system 0775 system system
+    mkdir /data/system 0775 system system encryption=Require
     mkdir /data/system/dropbox 0700 system system
     mkdir /data/system/heapdump 0700 system system
     mkdir /data/system/users 0775 system system
 
-    mkdir /data/system_de 0770 system system
-    mkdir /data/system_ce 0770 system system
+    mkdir /data/system_de 0770 system system encryption=None
+    mkdir /data/system_ce 0770 system system encryption=None
 
-    mkdir /data/misc_de 01771 system misc
-    mkdir /data/misc_ce 01771 system misc
+    mkdir /data/misc_de 01771 system misc encryption=None
+    mkdir /data/misc_ce 01771 system misc encryption=None
 
-    mkdir /data/user 0711 system system
-    mkdir /data/user_de 0711 system system
+    mkdir /data/user 0711 system system encryption=None
+    mkdir /data/user_de 0711 system system encryption=None
     symlink /data/data /data/user/0
 
-    mkdir /data/media 0770 media_rw media_rw
-    mkdir /data/media/obb 0770 media_rw media_rw
+    # Special-case /data/media/obb per b/64566063
+    mkdir /data/media 0770 media_rw media_rw encryption=None
+    mkdir /data/media/obb 0770 media_rw media_rw encryption=Attempt
 
-    mkdir /data/cache 0770 system cache
+    mkdir /data/cache 0770 system cache encryption=Require
     mkdir /data/cache/recovery 0770 system cache
     mkdir /data/cache/backup_stage 0700 system system
     mkdir /data/cache/backup 0700 system system
 
-    mkdir /data/rollback 0700 system system
-    mkdir /data/rollback-observer 0700 system system
+    # Delete these if need be, per b/139193659
+    mkdir /data/rollback 0700 system system encryption=DeleteIfNecessary
+    mkdir /data/rollback-observer 0700 system system encryption=DeleteIfNecessary
 
     # Wait for apexd to finish activating APEXes before starting more processes.
     wait_for_prop apexd.status ready
@@ -867,7 +871,7 @@
     bootchart stop
     # Setup per_boot directory so other .rc could start to use it on boot_completed
     exec - system system -- /bin/rm -rf /data/per_boot
-    mkdir /data/per_boot 0700 system system
+    mkdir /data/per_boot 0700 system system encryption=Require key=per_boot_ref
 
 # system server cannot write to /proc/sys files,
 # and chown/chmod does not work for /proc/sys/ entries.
@@ -924,7 +928,7 @@
   setprop sys.init.userspace_reboot_in_progress 1
   setprop sys.boot_completed 0
   setprop sys.init.updatable_crashing 0
-  setprop apexd.status 0
+  setprop apexd.status ""
 
 on userspace-reboot-fs-remount
   # Make sure that vold is running.
diff --git a/rootdir/init.usb.rc b/rootdir/init.usb.rc
index 688d9ad..a1888fc 100644
--- a/rootdir/init.usb.rc
+++ b/rootdir/init.usb.rc
@@ -9,7 +9,7 @@
     chown system system /sys/class/android_usb/android0/f_rndis/ethaddr
     chmod 0660 /sys/class/android_usb/android0/f_rndis/ethaddr
     mkdir /data/misc/adb 02750 system shell
-    mkdir /data/adb 0700 root root
+    mkdir /data/adb 0700 root root encryption=Require
 
 # adbd is controlled via property triggers in init.<platform>.usb.rc
 service adbd /system/bin/adbd --root_seclabel=u:r:su:s0