1d3ba112ab
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>
610 lines
15 KiB
Text
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"],
|
|
},
|
|
},
|
|
}
|