| # 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 ] |
| } |
| } |
| } |