| package { |
| default_team: "trendy_team_native_tools_libraries", |
| default_applicable_licenses: ["bionic_linker_license"], |
| } |
| |
| license { |
| name: "bionic_linker_license", |
| visibility: [":__subpackages__"], |
| license_kinds: [ |
| "SPDX-license-identifier-BSD", |
| ], |
| license_text: [ |
| "NOTICE", |
| ], |
| } |
| |
| linker_common_flags = [ |
| "-fno-stack-protector", |
| "-Wstrict-overflow=5", |
| "-fvisibility=hidden", |
| "-Wall", |
| "-Wextra", |
| "-Wunused", |
| "-Werror", |
| ] |
| |
| // ======================================================== |
| // 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. |
| cc_object { |
| name: "linker_wrapper", |
| host_supported: true, |
| device_supported: false, |
| enabled: false, |
| target: { |
| linux_bionic: { |
| enabled: true, |
| }, |
| }, |
| |
| cflags: linker_common_flags, |
| |
| 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: linker_common_flags, |
| asflags: linker_common_flags, |
| |
| 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"], |
| |
| sanitize: { |
| // Supporting memtag_globals in the linker would be tricky, |
| // because it relocates itself very early. |
| memtag_globals: false, |
| }, |
| } |
| |
| // ======================================================== |
| // 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"], |
| apex_available: [ |
| "com.android.runtime", |
| ], |
| } |
| |
| cc_library_static { |
| name: "liblinker_malloc", |
| defaults: [ |
| "linker_defaults", |
| "linker_all_targets", |
| ], |
| srcs: ["linker_memory.cpp"], |
| apex_available: [ |
| "com.android.runtime", |
| ], |
| } |
| |
| 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_auxv.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_phdr_16kib_compat.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", |
| "arch/riscv64/tlsdesc_resolver.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", |
| "keep_symbols", |
| ], |
| |
| srcs: [":linker_sources"], |
| |
| arch: { |
| arm: { |
| srcs: [":linker_sources_arm"], |
| }, |
| arm64: { |
| srcs: [":linker_sources_arm64"], |
| }, |
| riscv64: { |
| srcs: [":linker_sources_riscv64"], |
| }, |
| x86: { |
| srcs: [":linker_sources_x86"], |
| }, |
| x86_64: { |
| srcs: [":linker_sources_x86_64"], |
| }, |
| }, |
| |
| static_executable: true, |
| |
| // -shared is used to overwrite the -Bstatic and -static flags triggered by enabling |
| // static_executable. The dynamic linker is actually a shared object linked with static |
| // libraries. |
| ldflags: [ |
| "-shared", |
| "-Wl,-Bsymbolic", |
| "-Wl,--exclude-libs,ALL", |
| "-Wl,-soname,ld-android.so", |
| // When the linker applies its own IRELATIVE relocations, it will only read DT_REL[A] and |
| // DT_JMPREL, not DT_ANDROID_REL[A], which can also theoretically contain IRELATIVE |
| // relocations. lld has been taught to not store them there as a bug workaround (see |
| // https://llvm.org/pr86751) but the workaround could be removed at some point in the |
| // future. So we explicitly prevent it from doing so by disabling DT_ANDROID_REL[A] when |
| // linking the linker (DT_RELR cannot encode IRELATIVE relocations). |
| "-Wl,--pack-dyn-relocs=relr", |
| ], |
| |
| // We link libc++_static manually because otherwise the build system will |
| // automatically add libdl to the list of static libraries. |
| stl: "none", |
| |
| // We don't want crtbegin.o (because we have our own arch/*/begin.o), |
| // so unset it just for this module. |
| nocrt: 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, |
| memtag_stack: false, |
| }, |
| |
| static_libs: [ |
| "liblinker_main", |
| "liblinker_malloc", |
| |
| // We use a version of libc++ built without exceptions, |
| // because accessing EH globals uses ELF TLS, |
| // which is not supported in the loader. |
| "libc++_static_noexcept", |
| |
| "libc_nomalloc", |
| "libc_dynamic_dispatch", |
| "libm", |
| "libunwind", |
| ], |
| |
| system_shared_libs: [], |
| |
| // Opt out of native_coverage when opting out of system_shared_libs |
| native_coverage: false, |
| } |
| |
| // ======================================================== |
| // linker[_asan][64] binary |
| // ======================================================== |
| |
| cc_defaults { |
| name: "linker_binary_defaults", |
| defaults: [ |
| "linker_bin_template", |
| "linker_version_script_overlay", |
| ], |
| |
| srcs: [ |
| "linker_translate_path.cpp", |
| ], |
| |
| symlinks: ["linker_asan"], |
| arch: { |
| arm64: { |
| symlinks: ["linker_hwasan"], |
| }, |
| }, |
| multilib: { |
| lib64: { |
| suffix: "64", |
| }, |
| }, |
| |
| compile_multilib: "both", |
| |
| apex_available: [ |
| "//apex_available:platform", |
| "com.android.runtime", |
| ], |
| |
| target: { |
| android: { |
| srcs: [ |
| "linker_debuggerd_android.cpp", |
| ], |
| static_libs: [ |
| "libc++demangle_noexcept", |
| "libdebuggerd_handler_fallback", |
| ], |
| }, |
| linux_bionic: { |
| static_libs: [ |
| "liblinker_debuggerd_stub", |
| ], |
| }, |
| }, |
| |
| afdo: true, |
| } |
| |
| cc_binary { |
| name: "linker", |
| defaults: [ |
| "linux_bionic_supported", |
| "linker_binary_defaults", |
| ], |
| |
| vendor_ramdisk_available: true, |
| } |
| |
| cc_binary { |
| name: "linker.recovery", |
| defaults: [ |
| "linker_binary_defaults", |
| ], |
| |
| recovery: true, |
| stem: "linker", |
| } |
| |
| // ======================================================== |
| // 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 { |
| 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", |
| ], |
| } |
| |
| 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", |
| "linker_crt_pad_segment_test.cpp", |
| |
| // Parts of the linker that we're testing. |
| ":elf_note_sources", |
| "linker_block_allocator.cpp", |
| "linker_config.cpp", |
| "linker_debug.cpp", |
| "linker_note_gnu_property.cpp", |
| "linker_test_globals.cpp", |
| "linker_utils.cpp", |
| "linker_phdr.cpp", |
| "linker_mapped_file_fragment.cpp", |
| "linker_sdk_versions.cpp", |
| "linker_dlwarning.cpp", |
| "linker_phdr_16kib_compat.cpp" |
| ], |
| |
| static_libs: [ |
| "libasync_safe", |
| "libbase", |
| "liblog_for_runtime_apex", |
| "libprocinfo", // For procinfo::MappedFileSize() |
| ], |
| |
| data_libs: [ |
| "crt_pad_segment_disabled", |
| "crt_pad_segment_enabled", |
| "no_crt_pad_segment", |
| ], |
| |
| 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"], |
| }, |
| }, |
| } |
| |
| cc_fuzz { |
| name: "ElfReader_fuzzer", |
| srcs: [ |
| "ElfReader_fuzzer.cpp", |
| "linker.cpp", |
| "linker_block_allocator.cpp", |
| "linker_debug.cpp", |
| "linker_dlwarning.cpp", |
| "linker_globals.cpp", |
| "linker_mapped_file_fragment.cpp", |
| "linker_phdr.cpp", |
| "linker_phdr_16kib_compat.cpp", |
| "linker_sdk_versions.cpp", |
| "linker_utils.cpp", |
| ":elf_note_sources", |
| ], |
| static_libs: [ |
| "libasync_safe", |
| "libbase", |
| "libziparchive", |
| ], |
| include_dirs: ["bionic/libc"], |
| // TODO: use all the architectures' files. |
| // We'll either need to give them unique names across architectures, |
| // or change soong to preserve subdirectories in `corpus:`, |
| // and maybe also the [deprecated] LLVM fuzzer infrastructure? |
| corpus: [":bionic_prebuilt_test_elf_files_arm64"], |
| } |