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.
(cherry picked from commit 44348e01c0c66e6baf1376f0b712ecae26fc5595)
Change-Id: I34fd1514eecbb2ddd89802891ea606418f28a60f
diff --git a/Android.mk b/Android.mk
index dc5fd4a..c6b0f57 100644
--- a/Android.mk
+++ b/Android.mk
@@ -62,8 +62,8 @@
external/gtest/include \
system
ue_common_shared_libraries := \
- libbrillo \
libbrillo-stream \
+ libbrillo \
libchrome
ifeq ($(local_use_dbus),1)
@@ -472,12 +472,11 @@
# from a local file directly instead of running in the background.
include $(CLEAR_VARS)
LOCAL_MODULE := update_engine_sideload
-# TODO(deymo): Make this binary a static binary and move it to recovery.
-# LOCAL_FORCE_STATIC_EXECUTABLE := true
-# LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
+LOCAL_FORCE_STATIC_EXECUTABLE := true
+LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_REQUIRED_MODULES := \
- bspatch
+ bspatch_recovery
LOCAL_CPP_EXTENSION := .cc
LOCAL_CLANG := true
LOCAL_CFLAGS := \
@@ -507,12 +506,40 @@
update_metadata-protos \
$(ue_libpayload_consumer_exported_static_libraries:-host=) \
$(ue_update_metadata_protos_exported_static_libraries)
-LOCAL_SHARED_LIBRARIES := \
+# We add the static versions of the shared libraries since we are forcing this
+# binary to be a static binary, so we also need to include all the static
+# library dependencies of these static libraries.
+LOCAL_STATIC_LIBRARIES += \
$(ue_common_shared_libraries) \
- libhardware \
libcutils \
$(ue_libpayload_consumer_exported_shared_libraries:-host=) \
- $(ue_update_metadata_protos_exported_shared_libraries)
+ $(ue_update_metadata_protos_exported_shared_libraries) \
+ libevent \
+ libmodpb64 \
+ libgtest_prod
+# libchrome requires these extra LDFLAGS which are not propagated through the
+# build system.
+LOCAL_LDFLAGS += \
+ -Wl,-wrap,calloc \
+ -Wl,-wrap,free \
+ -Wl,-wrap,malloc \
+ -Wl,-wrap,memalign \
+ -Wl,-wrap,realloc
+
+ifeq ($(strip $(PRODUCT_STATIC_BOOT_CONTROL_HAL)),)
+# No static boot_control HAL defined, so no sideload support. We use a fake
+# boot_control HAL to allow compiling update_engine_sideload for test purposes.
+ifeq ($(strip $(AB_OTA_UPDATER)),true)
+$(warning No PRODUCT_STATIC_BOOT_CONTROL_HAL configured but AB_OTA_UPDATER is \
+true, no update sideload support.)
+endif # AB_OTA_UPDATER == true
+LOCAL_SRC_FILES += \
+ boot_control_recovery_stub.cc
+else # PRODUCT_STATIC_BOOT_CONTROL_HAL != ""
+LOCAL_STATIC_LIBRARIES += \
+ $(PRODUCT_STATIC_BOOT_CONTROL_HAL)
+endif # PRODUCT_STATIC_BOOT_CONTROL_HAL != ""
+
include $(BUILD_EXECUTABLE)
# libupdate_engine_client (type: shared_library)
diff --git a/boot_control_android.cc b/boot_control_android.cc
index ba6b559..d096a1b 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;
diff --git a/boot_control_recovery_stub.cc b/boot_control_recovery_stub.cc
new file mode 100644
index 0000000..129c5d0
--- /dev/null
+++ b/boot_control_recovery_stub.cc
@@ -0,0 +1,21 @@
+//
+// Copyright (C) 2016 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 <hardware/hardware.h>
+
+hw_module_t HAL_MODULE_INFO_SYM = {
+ .id = "stub",
+};