blob: 8d1d1a0a9a11ceb62f46557121016a7aff3b1880 [file] [log] [blame]
# Copyright 2019 The Fuchsia Authors
#
# Use of this source code is governed by a MIT-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/MIT
import("//build/config/zircon/standard.gni")
import("//build/toolchain/zircon/zircon_toolchain_suite.gni")
import("//build/zircon/zircon_cpu.gni")
import("//build/zircon/zx_library.gni")
# The vDSO is built in its own special environment because it has special
# constraints. If all the code going into the vDSO were built entirely in
# this BUILD.gn file, then a separate environment would not be necessary.
# But the vDSO needs to be able to use some other library code defined
# elsewhere.
if (current_toolchain == default_toolchain) {
# Define the special toolchain itself only in the default toolchain.
foreach(cpu, standard_fuchsia_cpus) {
zircon_toolchain_suite("user.vdso_$cpu") {
cpu = cpu
os = current_os
strip = "--strip-sections"
environment = "user.vdso"
with_shared = false
is_pic_default = true
configs = [ "//zircon/kernel/lib/userabi/vdso:user.vdso.config" ]
exclude_variant_tags = [
# The vDSO can't use instrumentation runtimes.
"instrumented",
]
}
}
}
if (toolchain_environment == "user.vdso") {
config("user.vdso.config") {
configs = [
# This is mostly like other user code.
"//build/config/zircon:user",
# But it can't rely on full Fuchsia ABI like SafeStack/ShadowCallStack.
"//build/config/sanitizers:no_sanitizers",
# And it can't rely on libc.
"//build/config/zircon:freestanding",
"//build/config/zircon:rodso",
]
}
group("user.vdso.config_deps") {
}
shared_library("zircon") {
visibility = [ ":*" ]
sources = [
"data.S",
"syscall-wrappers.cc",
"zx_cache_flush.cc",
"zx_channel_call.cc",
"zx_clock_get_monotonic.cc",
"zx_cprng_draw.cc",
"zx_deadline_after.cc",
"zx_exception_get_string.cc",
"zx_status_get_string.cc",
"zx_system_get_dcache_line_size.cc",
"zx_system_get_features.cc",
"zx_system_get_num_cpus.cc",
"zx_system_get_page_size.cc",
"zx_system_get_physmem.cc",
"zx_system_get_version.cc",
"zx_system_get_version_string.cc",
"zx_ticks_get.cc",
"zx_ticks_per_second.cc",
]
deps = [
":syscall-asm",
"//src/zircon/lib/zircon:headers",
"//zircon/kernel/lib/syscalls:headers",
"//zircon/kernel/lib/userabi:headers",
"//zircon/system/ulib/affine",
]
configs += [ "//zircon/vdso:public.config($default_toolchain)" ]
# Instruct the linker to preserve the hidden alternate entry points.
# Note, "./" makes GN realize this is a file rather than a -l switch.
libs = [ "./alternates.ld" ]
ldflags = [
# Make sure libc++ is not linked into the vDSO. Header-only use is OK.
"-nostdlib++",
# Set e_entry so _zx_process_exit is easy to find without reading .dynsym.
"-Wl,-e,_zx_process_exit",
]
# This ensures that the vDSO is never installed into filesystem images
# since it's materialized at runtime by the kernel.
metadata = {
distribution_entries_barrier = []
distribution_entries = []
}
}
source_set("syscall-asm") {
visibility = [ ":*" ]
sources = [
"syscalls-$zircon_cpu.S",
"zx_futex_wake_handle_close_thread_exit-$zircon_cpu.S",
"zx_vmar_unmap_handle_close_thread_exit-$zircon_cpu.S",
]
deps = [
"//src/zircon/lib/zircon:headers",
"//zircon/kernel/lib/syscalls",
]
}
} else {
# The vDSO can't use any interesting variants like instrumentation.
# It uses gcc if the kernel uses gcc, otherwise the default.
if (false) { # TODO(69697): is_gcc
vdso_variant = "-gcc"
} else {
vdso_variant = ""
}
vdso_label = ":zircon(:user.vdso_${current_cpu}${vdso_variant})"
if (is_kernel) {
# Make sure the vDSO that goes into the kernel matches the ABI
# that userland links against.
abi_ifs = "//src/zircon/lib/zircon/zircon.ifs"
vdso_out_dir = get_label_info(vdso_label, "root_out_dir")
vdso_ifs_unstripped = "$vdso_out_dir/libzircon.ifs"
vdso_ifs = "$target_out_dir/libzircon_stripped.ifs"
action("strip-abi-target") {
visibility = [ ":*" ]
deps = [
"//src/zircon/lib/zircon",
vdso_label,
]
sources = [ vdso_ifs_unstripped ]
outputs = [ vdso_ifs ]
script = "$clang_tool_dir/llvm-ifs"
args = [
"--input-format=IFS",
"--strip-ifs-target",
"--write-if-changed",
"--output-ifs=" + rebase_path(vdso_ifs, root_build_dir),
rebase_path(vdso_ifs_unstripped, root_build_dir),
]
}
action("verify-abi") {
visibility = [ ":*" ]
vdso_label = ":strip-abi-target"
deps = [
"//src/zircon/lib/zircon",
vdso_label,
]
sources = [
abi_ifs,
vdso_ifs,
]
outputs = [ "$target_out_dir/$target_name.ok" ]
script = "verify-abi.sh"
# This uses absolute paths so the "cp IMPL ABI" message has easily and
# universally cut&pastable paths.
args = rebase_path(sources + outputs, root_build_dir)
metadata = {
link_output_barrier = []
}
}
# This is how the kernel depends on the built vDSO to embed the image, via
# the link_output_rspfile() metadata protocol.
group("vdso") {
visibility = [ "//zircon/kernel/lib/userabi/*" ]
public_deps = [
":verify-abi",
vdso_label,
]
}
} else {
# This is how userboot depends on the built vDSO to extract addresses,
# via the link_output_rspfile() metadata protocol.
group("vdso") {
visibility = [ "//zircon/kernel/lib/userabi/*" ]
public_deps = [ vdso_label ]
}
}
}