Shared libs are supported in recovery mode

adbd has been built as a static executable since the same binary was
copied to the recovery partition where shared library is not supported.
However, since we now support shared library in the recovery partition,
adbd is built as a dynamic executable.

In addition, the dependency from adbd to libdebuggerd_handler is removed
as debuggerd is handled by the dynamic linker.

A few more modules in /system/core are marked as recovery_available:
true as they are transitive dependencies of the dynamic linker.

This change also includes ld.config.recovery.txt which is the linker
config file for the recovery mode. It is installed to /etc/ld.config.txt
and contains linker namespace config for the dynamic binaries under
/sbin.

Bug: 63673171
Test: `adb reboot recovery; adb devices` shows the device ID
Test: Select 'mount /system' in the recovery mode, then `adb shell`.
$ lsof -p `pidof adbd` shows that libm.so, libc.so, etc. are loaded from
the /lib directory.

Change-Id: I363d5a787863f1677ee40afb5d5841321ddaae77
diff --git a/CleanSpec.mk b/CleanSpec.mk
index e6f8716..0e43dae 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -77,3 +77,4 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/etc/ld.config.txt)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/etc/llndk.libraries.txt)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/etc/vndksp.libraries.txt)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/recovery/root/)
diff --git a/adb/Android.bp b/adb/Android.bp
index 553473f..53bf7e3 100644
--- a/adb/Android.bp
+++ b/adb/Android.bp
@@ -302,8 +302,6 @@
     name: "adbd",
     defaults: ["adb_defaults"],
 
-    // adbd must be static, as it is copied into the recovery image.
-    static_executable: true,
     recovery_available: true,
 
     srcs: [
@@ -344,7 +342,6 @@
         "libselinux",
         "libsquashfs_utils",
         "libqemu_pipe",
-        "libdebuggerd_handler",
 
         "libbase",
         "libcutils",
@@ -371,6 +368,7 @@
         "liblog",
         "libusb",
         "libmdnssd",
+        "libselinux",
     ],
     test_suites: ["device-tests"],
 }
diff --git a/adb/daemon/main.cpp b/adb/daemon/main.cpp
index 232d9c5..c02cafa 100644
--- a/adb/daemon/main.cpp
+++ b/adb/daemon/main.cpp
@@ -38,7 +38,6 @@
 #include <scoped_minijail.h>
 
 #include <private/android_filesystem_config.h>
-#include "debuggerd/handler.h"
 #include "selinux/android.h"
 
 #include "adb.h"
@@ -274,7 +273,6 @@
 
     close_stdin();
 
-    debuggerd_init(nullptr);
     adb_trace_init(argv);
 
     D("Handling main()");
diff --git a/adb/daemon/shell_service.cpp b/adb/daemon/shell_service.cpp
index 401c99c..56d647a 100644
--- a/adb/daemon/shell_service.cpp
+++ b/adb/daemon/shell_service.cpp
@@ -98,6 +98,7 @@
 #include <android-base/properties.h>
 #include <android-base/stringprintf.h>
 #include <private/android_logger.h>
+#include <selinux/android.h>
 
 #include "adb.h"
 #include "adb_io.h"
@@ -343,6 +344,24 @@
                 adb_write(oom_score_adj_fd, oom_score_adj_value, strlen(oom_score_adj_value)));
         }
 
+#ifdef __ANDROID_RECOVERY__
+        // Special routine for recovery. Switch to shell domain when adbd is
+        // is running with dropped privileged (i.e. not running as root) and
+        // is built for the recovery mode. This is required because recovery
+        // rootfs is not labeled and everything is labeled just as rootfs.
+        char* con = nullptr;
+        if (getcon(&con) == 0) {
+            if (!strcmp(con, "u:r:adbd:s0")) {
+                if (selinux_android_setcon("u:r:shell:s0") < 0) {
+                    LOG(FATAL) << "Could not set SELinux context for subprocess";
+                }
+            }
+            freecon(con);
+        } else {
+            LOG(FATAL) << "Failed to get SELinux context";
+        }
+#endif
+
         if (command_.empty()) {
             // Spawn a login shell if we don't have a command.
             execle(_PATH_BSHELL, "-" _PATH_BSHELL, nullptr, cenv.data());
diff --git a/debuggerd/Android.bp b/debuggerd/Android.bp
index 0b13662..1b20157 100644
--- a/debuggerd/Android.bp
+++ b/debuggerd/Android.bp
@@ -47,6 +47,7 @@
 cc_library_static {
     name: "libtombstoned_client_static",
     defaults: ["debuggerd_defaults"],
+    recovery_available: true,
     srcs: [
         "tombstoned/tombstoned_client.cpp",
         "util.cpp",
@@ -90,7 +91,6 @@
 cc_library_static {
     name: "libdebuggerd_handler",
     defaults: ["debuggerd_defaults"],
-    recovery_available: true,
     srcs: ["handler/debuggerd_fallback_nop.cpp"],
 
     whole_static_libs: [
@@ -104,6 +104,7 @@
 cc_library_static {
     name: "libdebuggerd_handler_fallback",
     defaults: ["debuggerd_defaults"],
+    recovery_available: true,
     srcs: [
         "handler/debuggerd_fallback.cpp",
     ],
@@ -120,6 +121,12 @@
         "liblzma",
         "libcutils",
     ],
+    target: {
+        recovery: {
+            cflags: ["-DNO_LIBDEXFILE_SUPPORT"],
+            exclude_static_libs: ["libdexfile"],
+        },
+    },
 
     export_include_dirs: ["include"],
 }
diff --git a/libutils/Android.bp b/libutils/Android.bp
index 9395ef8..bbfa9d8 100644
--- a/libutils/Android.bp
+++ b/libutils/Android.bp
@@ -47,6 +47,7 @@
 cc_defaults {
     name: "libutils_defaults",
     vendor_available: true,
+    recovery_available: true,
     vndk: {
         enabled: true,
         support_system_process: true,
@@ -90,6 +91,10 @@
             },
         },
 
+        recovery: {
+            exclude_shared_libs: ["libvndksupport"],
+        },
+
         host: {
             cflags: ["-DLIBUTILS_NATIVE=1"],
 
diff --git a/libutils/misc.cpp b/libutils/misc.cpp
index da28dfa..f074341 100644
--- a/libutils/misc.cpp
+++ b/libutils/misc.cpp
@@ -23,7 +23,7 @@
 #include <utils/Log.h>
 #include <utils/Vector.h>
 
-#if defined(__ANDROID__)
+#if defined(__ANDROID__) && !defined(__ANDROID_RECOVERY__)
 #include <dlfcn.h>
 #include <vndksupport/linker.h>
 #endif
@@ -70,7 +70,7 @@
 void add_sysprop_change_callback(sysprop_change_callback, int) {}
 #endif
 
-#if defined(__ANDROID__)
+#if defined(__ANDROID__) && !defined(__ANDROID_RECOVERY__)
 void (*get_report_sysprop_change_func())() {
     void (*func)() = nullptr;
     void* handle = android_load_sphal_library("libutils.so", RTLD_NOW);
@@ -85,7 +85,7 @@
 void report_sysprop_change() {
     do_report_sysprop_change();
 
-#if defined(__ANDROID__)
+#if defined(__ANDROID__) && !defined(__ANDROID_RECOVERY__)
     // libutils.so is double loaded; from the default namespace and from the
     // 'sphal' namespace. Redirect the sysprop change event to the other instance
     // of libutils.so loaded in the 'sphal' namespace so that listeners attached
diff --git a/libziparchive/Android.bp b/libziparchive/Android.bp
index 6c06618..2606aa9 100644
--- a/libziparchive/Android.bp
+++ b/libziparchive/Android.bp
@@ -58,6 +58,7 @@
     name: "libziparchive",
     host_supported: true,
     vendor_available: true,
+    recovery_available: true,
     vndk: {
         enabled: true,
     },
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index 3c9e5f3..70b6a3e 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -306,6 +306,16 @@
 _enforce_vndk_lite_at_runtime :=
 
 #######################################
+# ld.config.txt for recovery
+include $(CLEAR_VARS)
+LOCAL_MODULE := ld.config.recovery.txt
+LOCAL_MODULE_CLASS := ETC
+LOCAL_SRC_FILES := etc/ld.config.recovery.txt
+LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/etc
+LOCAL_MODULE_STEM := ld.config.txt
+include $(BUILD_PREBUILT)
+
+#######################################
 # llndk.libraries.txt
 include $(CLEAR_VARS)
 LOCAL_MODULE := llndk.libraries.txt
diff --git a/rootdir/etc/ld.config.recovery.txt b/rootdir/etc/ld.config.recovery.txt
new file mode 100644
index 0000000..5d6c01a
--- /dev/null
+++ b/rootdir/etc/ld.config.recovery.txt
@@ -0,0 +1,9 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Bionic loader config file for recovery mode
+#
+
+dir.recovery = /system/bin
+
+[recovery]
+namespace.default.search.paths = /system/${LIB}
diff --git a/shell_and_utilities/Android.bp b/shell_and_utilities/Android.bp
index 2e42b70..6438e3d 100644
--- a/shell_and_utilities/Android.bp
+++ b/shell_and_utilities/Android.bp
@@ -12,10 +12,13 @@
         "mkshrc_vendor",
         "reboot",
         "sh",
+        "sh.recovery",
         "sh_vendor",
         "toolbox",
+        "toolbox.recovery",
         "toolbox_vendor",
         "toybox",
+        "toybox.recovery",
         "toybox_vendor",
     ],
 }
diff --git a/toolbox/Android.bp b/toolbox/Android.bp
index 077f542..f12c810 100644
--- a/toolbox/Android.bp
+++ b/toolbox/Android.bp
@@ -46,6 +46,7 @@
 cc_binary {
     name: "toolbox",
     defaults: ["toolbox_binary_defaults"],
+    recovery_available: true,
 }
 
 cc_binary {