Compile update_engine_sideload as a static recovery program.

This patch converts update_engine_sideload to a statically linked
program and installs it in the recovery image. The resulting program
uses a statically linked boot_control HAL instead of relying in
libhardware to dynamically load it.

The static library or libraries needed for the boot_control HAL need to
be specified by the product with the new make variable
PRODUCT_STATIC_BOOT_CONTROL_HAL. Otherwise, a stub implementation is
included and update_engine_sideload will fail at runtime.

Bug: 27178350
TEST=`make dist` builds a recovery image with update_engine_sideload in it.

Change-Id: I1f624ecd29220ac2237e42da0a636ea0a015a78e
diff --git a/boot_control_android.cc b/boot_control_android.cc
index b3b7630..a7d7456 100644
--- a/boot_control_android.cc
+++ b/boot_control_android.cc
@@ -28,6 +28,14 @@
 
 using std::string;
 
+#ifdef _UE_SIDELOAD
+// When called from update_engine_sideload, we don't attempt to dynamically load
+// the right boot_control HAL, instead we use the only HAL statically linked in
+// via the PRODUCT_STATIC_BOOT_CONTROL_HAL make variable and access the module
+// struct directly.
+extern const hw_module_t HAL_MODULE_INFO_SYM;
+#endif  // _UE_SIDELOAD
+
 namespace chromeos_update_engine {
 
 namespace boot_control {
@@ -47,7 +55,18 @@
   const hw_module_t* hw_module;
   int ret;
 
+#ifdef _UE_SIDELOAD
+  // For update_engine_sideload, we simulate the hw_get_module() by accessing it
+  // from the current process directly.
+  hw_module = &HAL_MODULE_INFO_SYM;
+  ret = 0;
+  if (!hw_module ||
+      strcmp(BOOT_CONTROL_HARDWARE_MODULE_ID, hw_module->id) != 0) {
+    ret = -EINVAL;
+  }
+#else  // !_UE_SIDELOAD
   ret = hw_get_module(BOOT_CONTROL_HARDWARE_MODULE_ID, &hw_module);
+#endif  // _UE_SIDELOAD
   if (ret != 0) {
     LOG(ERROR) << "Error loading boot_control HAL implementation.";
     return false;