Add prebuilt ELF binaries checker

This commit introduces a prebuilt ELF binaries checker.  The checker
will check:

1. Whether all DT_NEEDED shared libraries are specified in
   `shared_libs` (Android.bp) or `LOCAL_SHARED_LIBRARIES` (Android.mk).

2. Whether all undefined symbols in the prebuilt binary can be resolved
   to defined symbols exported by its dependencies.

This ensures that prebuilt binaries won't silently become ABI
incompatible.

To check the prebuilt binaries, all of the dependencies must be
specified in `shared_libs` (Android.bp) or `LOCAL_SHARED_LIBRARIES`
(Android.mk).

If your prebuilt binaries cannot be checked for some reason, you may add
the following property to Android.bp:

    check_elf_files: false,

Or, add the following setting to Android.mk:

    LOCAL_CHECK_ELF_FILES := false

Bug: 119084334
Test: CHECK_ELF_FILES=true make check-elf-files
Change-Id: I523d3083f22fd4053c096d26f61f8375800281c8
This commit is contained in:
Logan Chien
2018-11-06 17:32:40 +08:00
parent 241d7cdba0
commit 0e53d887d6
11 changed files with 641 additions and 0 deletions

45
core/check_elf_file.mk Normal file
View File

@@ -0,0 +1,45 @@
# Check the correctness of the prebuilt ELF files
#
# This check ensures that DT_SONAME matches with the filename, DT_NEEDED
# matches the shared libraries specified in LOCAL_SHARED_LIBRARIES, and all
# undefined symbols in the prebuilt binary can be found in one of the shared
# libraries specified in LOCAL_SHARED_LIBRARIES.
#
# Inputs:
# - LOCAL_ALLOW_UNDEFINED_SYMBOLS
# - LOCAL_BUILT_MODULE
# - LOCAL_IS_HOST_MODULE
# - LOCAL_MODULE_CLASS
# - intermediates
# - my_installed_module_stem
# - my_prebuilt_src_file
ifndef LOCAL_IS_HOST_MODULE
ifneq ($(filter $(LOCAL_MODULE_CLASS),SHARED_LIBRARIES EXECUTABLES NATIVE_TESTS),)
check_elf_files_stamp := $(intermediates)/check_elf_files.timestamp
$(check_elf_files_stamp): PRIVATE_SONAME := $(if $(filter $(LOCAL_MODULE_CLASS),SHARED_LIBRARIES),$(my_installed_module_stem))
$(check_elf_files_stamp): PRIVATE_ALLOW_UNDEFINED_SYMBOLS := $(LOCAL_ALLOW_UNDEFINED_SYMBOLS)
$(check_elf_files_stamp): PRIVATE_SHARED_LIBRARY_FILES := # This variable will be set by `core/main.mk`
$(check_elf_files_stamp): $(my_prebuilt_src_file) $(CHECK_ELF_FILE) $(LLVM_READOBJ)
@echo Check prebuilt ELF binary: $<
$(hide) mkdir -p $(dir $@)
$(hide) rm -f $@
$(hide) $(CHECK_ELF_FILE) \
--skip-bad-elf-magic \
--skip-unknown-elf-machine \
$(if $(PRIVATE_SONAME),--soname $(PRIVATE_SONAME)) \
$(foreach l,$(PRIVATE_SHARED_LIBRARY_FILES),--shared-lib $(l)) \
$(if $(PRIVATE_ALLOW_UNDEFINED_SYMBOLS),--allow-undefined-symbols) \
--llvm-readobj=$(LLVM_READOBJ) \
$<
$(hide) touch $@
ifneq ($(PRODUCT_CHECK_ELF_FILES)$(CHECK_ELF_FILES),)
ifneq ($(LOCAL_CHECK_ELF_FILES),false)
$(LOCAL_BUILT_MODULE): $(check_elf_files_stamp)
check-elf-files: $(check_elf_files_stamp)
endif # LOCAL_CHECK_ELF_FILES
endif # PRODUCT_CHECK_ELF_FILES or CHECK_ELF_FILES
endif # SHARED_LIBRARIES, EXECUTABLES, NATIVE_TESTS
endif # !LOCAL_IS_HOST_MODULE