// ======================================================== // linker_wrapper - Linux Bionic (on the host) // ======================================================== // This is used for bionic on (host) Linux to bootstrap our linker embedded into // a binary. // // Host bionic binaries do not have a PT_INTERP section, instead this gets // embedded as the entry point, and the linker is embedded as ELF sections in // each binary. There's a linker script that sets all of that up (generated by // extract_linker), and defines the extern symbols used in this file. package { default_applicable_licenses: ["bionic_linker_license"], } license { name: "bionic_linker_license", visibility: [":__subpackages__"], license_kinds: [ "SPDX-license-identifier-BSD", ], license_text: [ "NOTICE", ], } cc_object { name: "linker_wrapper", host_supported: true, device_supported: false, enabled: false, target: { linux_bionic: { enabled: true, }, }, cflags: [ "-fno-stack-protector", "-Wstrict-overflow=5", "-fvisibility=hidden", "-Wall", "-Wextra", "-Wno-unused", "-Werror", ], srcs: [ "linker_wrapper.cpp", ], arch: { arm64: { srcs: ["arch/arm64/linker_wrapper_begin.S"], }, riscv64: { srcs: ["arch/riscv64/linker_wrapper_begin.S"], }, x86_64: { srcs: ["arch/x86_64/linker_wrapper_begin.S"], }, }, header_libs: ["libc_headers"], // We need to access Bionic private headers in the linker. include_dirs: ["bionic/libc"], } // ======================================================== // linker default configuration // ======================================================== // Configuration for the linker binary and any of its static libraries. cc_defaults { name: "linker_defaults", arch: { arm: { cflags: ["-D__work_around_b_24465209__"], }, x86: { cflags: ["-D__work_around_b_24465209__"], }, }, cflags: [ "-fno-stack-protector", "-Wstrict-overflow=5", "-fvisibility=hidden", "-Wall", "-Wextra", "-Wunused", "-Werror", ], // TODO: split out the asflags. asflags: [ "-fno-stack-protector", "-Wstrict-overflow=5", "-fvisibility=hidden", "-Wall", "-Wextra", "-Wunused", "-Werror", ], product_variables: { debuggable: { cppflags: ["-DUSE_LD_CONFIG_FILE"], }, }, cppflags: ["-Wold-style-cast"], static_libs: [ "libziparchive", "libbase", "libz", "libasync_safe", "liblog_for_runtime_apex", ], // We need to access Bionic private headers in the linker. include_dirs: ["bionic/libc"], } // ======================================================== // linker components // ======================================================== // Enable a module on all targets the linker runs on (ordinary Android targets, Linux Bionic, and // native bridge implementations). cc_defaults { name: "linker_all_targets", defaults: ["linux_bionic_supported"], recovery_available: true, vendor_ramdisk_available: true, native_bridge_supported: true, } cc_library_static { name: "liblinker_main", defaults: ["linker_defaults", "linker_all_targets"], srcs: ["linker_main.cpp"], // Ensure that the compiler won't insert string function calls before ifuncs are resolved. cflags: ["-ffreestanding"], } cc_library_static { name: "liblinker_malloc", defaults: ["linker_defaults", "linker_all_targets"], srcs: ["linker_memory.cpp"], } cc_library_static { name: "liblinker_debuggerd_stub", defaults: ["linker_defaults", "linker_all_targets"], srcs: ["linker_debuggerd_stub.cpp"], } // ======================================================== // template for the linker binary // ======================================================== filegroup { name: "linker_sources", srcs: [ "dlfcn.cpp", "linker.cpp", "linker_block_allocator.cpp", "linker_dlwarning.cpp", "linker_cfi.cpp", "linker_config.cpp", "linker_debug.cpp", "linker_gdb_support.cpp", "linker_globals.cpp", "linker_libc_support.c", "linker_libcxx_support.cpp", "linker_namespaces.cpp", "linker_logger.cpp", "linker_mapped_file_fragment.cpp", "linker_note_gnu_property.cpp", "linker_phdr.cpp", "linker_relocate.cpp", "linker_sdk_versions.cpp", "linker_soinfo.cpp", "linker_transparent_hugepage_support.cpp", "linker_tls.cpp", "linker_utils.cpp", "rt.cpp", ], } filegroup { name: "linker_sources_arm", srcs: [ "arch/arm/begin.S", "arch/arm_neon/linker_gnu_hash_neon.cpp", ], } filegroup { name: "linker_sources_arm64", srcs: [ "arch/arm64/begin.S", "arch/arm64/tlsdesc_resolver.S", "arch/arm_neon/linker_gnu_hash_neon.cpp", ], } filegroup { name: "linker_sources_riscv64", srcs: [ "arch/riscv64/begin.S", ], } filegroup { name: "linker_sources_x86", srcs: [ "arch/x86/begin.S", ], } filegroup { name: "linker_sources_x86_64", srcs: [ "arch/x86_64/begin.S", ], } cc_defaults { name: "linker_version_script_overlay", arch: { arm: { version_script: "linker.arm.map" }, arm64: { version_script: "linker.generic.map" }, riscv64: { version_script: "linker.generic.map" }, x86: { version_script: "linker.generic.map" }, x86_64: { version_script: "linker.generic.map" }, }, } // A template for the linker binary. May be inherited by native bridge implementations. cc_defaults { name: "linker_bin_template", defaults: ["linker_defaults"], srcs: [":linker_sources"], arch: { arm: { srcs: [":linker_sources_arm"], // Arm 32 bit does not produce complete exidx unwind information // so keep the .debug_frame which is relatively small and does // include needed unwind information. // See b/242162222 for details. strip: { keep_symbols_and_debug_frame: true, }, }, arm64: { srcs: [":linker_sources_arm64"], // Leave the symbols in the shared library so that stack unwinders can produce // meaningful name resolution. strip: { keep_symbols: true, }, }, riscv64: { srcs: [":linker_sources_riscv64"], // Leave the symbols in the shared library so that stack unwinders can produce // meaningful name resolution. strip: { keep_symbols: true, }, }, x86: { srcs: [":linker_sources_x86"], // Leave the symbols in the shared library so that stack unwinders can produce // meaningful name resolution. strip: { keep_symbols: true, }, }, x86_64: { srcs: [":linker_sources_x86_64"], // Leave the symbols in the shared library so that stack unwinders can produce // meaningful name resolution. strip: { keep_symbols: true, }, }, }, // -shared is used to overwrite the -Bstatic and -static flags triggered by enabling // static_executable. This dynamic linker is actually a shared object linked with static // libraries. ldflags: [ "-shared", "-Wl,-Bsymbolic", "-Wl,--exclude-libs,ALL", "-Wl,-soname,ld-android.so", ], // we are going to link libc++_static manually because // when stl is not set to "none" build system adds libdl // to the list of static libraries which needs to be // avoided in the case of building loader. stl: "none", // we don't want crtbegin.o (because we have begin.o), so unset it // just for this module nocrt: true, static_executable: true, // Insert an extra objcopy step to add prefix to symbols. This is needed to prevent gdb // looking up symbols in the linker by mistake. prefix_symbols: "__dl_", sanitize: { hwaddress: false, }, static_libs: [ "liblinker_main", "liblinker_malloc", "libc++_static", "libc_nomalloc", "libc_dynamic_dispatch", "libm", "libunwind", ], // Ensure that if the linker needs __gnu_Unwind_Find_exidx, then the linker will have a // definition of the symbol. The linker links against libgcc.a, whose arm32 unwinder has a weak // reference to __gnu_Unwind_Find_exidx, which isn't sufficient to pull in the strong definition // of __gnu_Unwind_Find_exidx from libc. An unresolved weak reference would create a // non-relative dynamic relocation in the linker binary, which complicates linker startup. // // This line should be unnecessary because the linker's dependency on libunwind_llvm.a should // override libgcc.a, but this line provides a simpler guarantee. It can be removed once the // linker stops linking against libgcc.a's arm32 unwinder. whole_static_libs: ["libc_unwind_static"], system_shared_libs: [], // Opt out of native_coverage when opting out of system_shared_libs native_coverage: false, } // ======================================================== // linker[_asan][64] binary // ======================================================== cc_binary { name: "linker", defaults: [ "linker_bin_template", "linux_bionic_supported", "linker_version_script_overlay", ], srcs: [ "linker_translate_path.cpp", ], symlinks: ["linker_asan"], arch: { arm64: { symlinks: ["linker_hwasan"], }, }, multilib: { lib64: { suffix: "64", }, }, compile_multilib: "both", recovery_available: true, vendor_ramdisk_available: true, apex_available: [ "//apex_available:platform", "com.android.runtime", ], target: { android: { srcs: [ "linker_debuggerd_android.cpp", ], static_libs: [ "libc++demangle", "libdebuggerd_handler_fallback", ], }, linux_bionic: { static_libs: [ "liblinker_debuggerd_stub", ], }, }, afdo: true, } // ======================================================== // assorted modules // ======================================================== sh_binary { name: "ldd", src: "ldd.sh", } // Used to generate binaries that can be backed by transparent hugepages. cc_defaults { name: "linker_hugepage_aligned", arch: { arm64: { ldflags: ["-z max-page-size=0x200000"], }, x86_64: { ldflags: ["-z max-page-size=0x200000"], }, }, } cc_library { // NOTE: --exclude-libs=libgcc.a makes sure that any symbols ld-android.so pulls from // libgcc.a are made static to ld-android.so. This in turn ensures that libraries that // a) pull symbols from libgcc.a and b) depend on ld-android.so will not rely on ld-android.so // to provide those symbols, but will instead pull them from libgcc.a. Specifically, // we use this property to make sure libc.so has its own copy of the code from // libgcc.a it uses. // // DO NOT REMOVE --exclude-libs! ldflags: [ "-Wl,--exclude-libs=libgcc.a", "-Wl,--exclude-libs=libgcc_stripped.a", "-Wl,--exclude-libs=libclang_rt.builtins-arm-android.a", "-Wl,--exclude-libs=libclang_rt.builtins-aarch64-android.a", "-Wl,--exclude-libs=libclang_rt.builtins-riscv64-android.a", "-Wl,--exclude-libs=libclang_rt.builtins-i686-android.a", "-Wl,--exclude-libs=libclang_rt.builtins-x86_64-android.a", ], // for x86, exclude libgcc_eh.a for the same reasons as above arch: { x86: { ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"], }, x86_64: { ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"], }, }, srcs: ["ld_android.cpp"], cflags: [ "-Wall", "-Wextra", "-Wunused", "-Werror", ], stl: "none", name: "ld-android", defaults: ["linux_bionic_supported", "linker_version_script_overlay"], ramdisk_available: true, vendor_ramdisk_available: true, recovery_available: true, native_bridge_supported: true, nocrt: true, system_shared_libs: [], header_libs: ["libc_headers"], // Opt out of native_coverage when opting out of system_shared_libs native_coverage: false, sanitize: { never: true, }, apex_available: [ "//apex_available:platform", "com.android.runtime", ], lto: { never: true, }, } cc_test { name: "linker-unit-tests", test_suites: ["device-tests"], cflags: [ "-g", "-Wall", "-Wextra", "-Wunused", "-Werror", ], // We need to access Bionic private headers in the linker. include_dirs: ["bionic/libc"], srcs: [ // Tests. "linker_block_allocator_test.cpp", "linker_config_test.cpp", "linked_list_test.cpp", "linker_note_gnu_property_test.cpp", "linker_sleb128_test.cpp", "linker_utils_test.cpp", "linker_gnu_hash_test.cpp", // Parts of the linker that we're testing. "linker_block_allocator.cpp", "linker_config.cpp", "linker_debug.cpp", "linker_note_gnu_property.cpp", "linker_test_globals.cpp", "linker_utils.cpp", ], static_libs: [ "libasync_safe", "libbase", "liblog_for_runtime_apex", ], arch: { arm: { srcs: ["arch/arm_neon/linker_gnu_hash_neon.cpp"], }, arm64: { srcs: ["arch/arm_neon/linker_gnu_hash_neon.cpp"], }, }, } cc_benchmark { name: "linker-benchmarks", srcs: [ "linker_gnu_hash_benchmark.cpp", ], arch: { arm: { srcs: ["arch/arm_neon/linker_gnu_hash_neon.cpp"], }, arm64: { srcs: ["arch/arm_neon/linker_gnu_hash_neon.cpp"], }, }, }