blob: 8300f017d0143bfe4010117d7c2c9bed8b6a369e [file] [log] [blame]
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"],
}