platform_bionic/linker/Android.bp
Kalesh Singh 1d3ba112ab bionic: loader: Only zero the last partial page in RW segments
Only zero the partial page at the end of the segment. There may be
entire pages beyond first page boundary after the segment -- due to
segment padding (VMA extension); but these are not expected to be
touched (faulted).

Do not attempt to zero the extended region past the first partial page,
since doing so may:
  1) Result in a SIGBUS, as the region is not backed by the underlying
     file.
  2) Break the COW backing, faulting in new anon pages for a region
     that will not be used.

Bug: 327600007
Bug: 328797737
Test: Dexcom G7 app
Test: atest -c linker-unit-tests
Test: bootup/idle/system-processes-memory-direct
Change-Id: Ib76b022f94bfc4a4b7eaca2c155af81478741b91
Signed-off-by: Kalesh Singh <kaleshsingh@google.com>
2024-03-13 13:40:28 -07:00

610 lines
15 KiB
Text

// ========================================================
// 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_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",
],
}
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"],
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_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",
],
}
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",
],
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"],
},
},
}