blob: 1eee8f729f4d6a7836b7d2ed26e7c1c89a1e9954 [file] [log] [blame]
# Copyright 2019 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
if (zx == "/") {
import("$zx_build/public/gn/config/globals.gni")
import("$zx_build/public/gn/config/standard.gni")
import("$zx_build/public/gn/toolchain/environment.gni")
import("$zx_build/public/gn/toolchain/environment_redirect.gni")
} else {
import("//build/config/zircon/standard.gni")
import("//build/toolchain/zircon/zircon_toolchain_suite.gni")
import("//build/unification/global_variables.gni")
import("//build/unification/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) {
if (zx == "/") {
environment("user.vdso") {
cpu = cpu
shlib = true
strip = "--strip-sections"
configs += standard_fuchsia_configs
configs += [
# This is mostly like other user code.
"$zx_build_config:user",
# But it can't rely on full Fuchsia ABI like SafeStack/ShadowCallStack.
"$zx_build_config:no_sanitizers",
# And it can't rely on libc.
"$zx_build_config:freestanding",
"$zx_build_config:rodso",
]
# The vDSO can't use instrumentation runtimes.
exclude_variant_tags = [ "instrumented" ]
tags = [ "vdso" ]
}
} else {
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/system/ulib/zircon:user.vdso.config" ]
exclude_variant_tags = [
# The vDSO can't use instrumentation runtimes.
"instrumented",
# The vDSO cannot be built with GCC.
"gcc",
]
}
}
}
}
if (zx != "/" && toolchain.environment == "user.vdso") {
# The following are needed by the zircon_toolchain_suite() definition above.
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/zircon:no_sanitizers",
# And it can't rely on libc.
"//build/config/zircon:freestanding",
"//build/config/zircon:rodso",
]
}
group("user.vdso.config_deps") {
}
}
# True if it is possible to create redirection targets for Zircon in the current
# toolchain. The Zircon build is special because its default toolchain does not
# define the global `toolchain` scope, nor does it support environment_redirect()
# at all, hence the complicated logic below.
_can_redirect_to_zircon =
(zx != "/" || current_toolchain != default_toolchain) &&
toolchain.environment != "user.vdso"
# True iff its possible to build Zircon in the current toolchain. See comment
# above to understand the conditions below.
_can_build_zircon = (zx != "/" || current_toolchain != default_toolchain) &&
toolchain.environment == "user.vdso"
not_needed([ "_can_build_zircon" ])
if (_can_redirect_to_zircon) {
# Even non-user environments can see the headers.
if (zx == "/") {
environment_redirect("headers") {
environment_label = ":user.vdso"
# NOTE: The 'direct = true' below means that ths VDSO will never
# be built with GCC.
direct = true
shlib = true
deps = [ ":headers" ]
}
} else {
import("vdso_toolchain.gni")
group("headers") {
public_deps = [ ":headers($zircon_vdso_toolchain)" ]
}
}
if (toolchain.base_environment == "user") {
# Other userland environments redirect to pick up the real library.
if (zx == "/") {
environment_redirect("zircon") {
environment_label = ":user.vdso"
direct = true
shlib = true
deps = [ ":zircon" ]
}
} else {
group("zircon") {
public_deps = [ ":zircon($zircon_vdso_toolchain)" ]
}
}
} else {
# References from other environments only get the headers. This
# makes it easy to have "$zx/system/ulib/zircon" deps in common
# libraries that need to link against it in userland but that in
# other contexts like kernel or userboot are just using the headers.
group("zircon") {
public_deps = [ ":headers" ]
}
}
# Publish headers to the GN build so that they may be used in host binaries.
source_set("zircon-headers") {
sources = [
"include/zircon/exception.h",
"include/zircon/status.h",
]
public_configs = [ ":zircon-headers.config" ]
}
config("zircon-headers.config") {
include_dirs = [ "include" ]
}
} else if (_can_build_zircon) {
zx_library("zircon") {
shared = true
static = false
# The vDSO is never installed as a file, only baked into the kernel.
if (zx == "/") {
install_path = false
}
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_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",
"$zx/kernel/lib/syscalls:headers",
"$zx/kernel/lib/userabi:headers",
"$zx/system/ulib/affine",
]
public_deps = [ "$zx/vdso:public($default_toolchain)" ]
if (zx != "/") {
# The line above doesn't work in the Fuchsia build because its
# default toolchain does not propagate configs. Adding the config
# manually works-around the issue.
public_configs = [ "$zx/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",
]
if (zx != "/") {
# This ensures that the vDSO is never installed into Fuchsia packages
# or bootfs filesystems, since it will be hard-coded into the kernel.
metadata = {
distribution_entries_barrier = []
distribution_entries = []
}
}
}
source_set("syscall-asm") {
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 = [
":headers",
"$zx/kernel/lib/syscalls",
]
if (toolchain.base_environment == "user") {
configs -= [ "$zx_build_config:user" ]
}
}
}