blob: 9481b649d4c7f72f8cd59e3041cacf0b11a139e0 [file] [log] [blame] [edit]
# Copyright 2023 The Fuchsia Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/components.gni")
import("//build/toolchain/zircon/user_basic_redirect.gni")
import("//build/zircon/hermetic_code_blob.gni")
group("tests") {
testonly = true
deps = [ ":usercopy-unittests" ]
}
# TODO: Implement support for non-x86_64 arches
if (target_cpu == "x64") {
static_library("hermetic_copy_error") {
sources = [ "hermetic_copy_error.S" ]
}
} else {
group("hermetic_copy_error") {
}
}
rustc_library("usercopy") {
edition = "2021"
sources = [ "src/lib.rs" ]
deps = [
"//sdk/fidl/fuchsia.io:fuchsia.io_rust",
"//src/lib/fdio/rust:fdio",
"//src/lib/fuchsia-runtime",
"//src/lib/zircon/rust:fuchsia-zircon",
"//third_party/rust_crates:zerocopy",
]
non_rust_deps = [ ":hermetic_copy_error" ]
with_unit_tests = true
test_deps = [
"//src/lib/fuchsia",
"//third_party/rust_crates:test-case",
]
}
fuchsia_test_component("usercopy-unittests-component") {
component_name = "usercopy_test"
manifest = "meta/usercopy_test.cml"
deps = [
":hermetic_copy_bin.basic",
":usercopy_test",
]
}
fuchsia_test_package("usercopy-unittests") {
test_components = [ ":usercopy-unittests-component" ]
}
user_basic_redirect("hermetic_copy_bin.basic") {
visibility = [ ":*" ]
testonly = true
public_deps = [ ":hermetic_copy_bin" ]
}
hermetic_code_blob("hermetic_copy") {
public = [ "hermetic_copy.h" ]
sources = [ "hermetic_copy.cc" ]
public_deps = [ "//zircon/system/public" ]
# hermetic_copy_error.S assumes it can "unwind" the hermetic code blob from a
# fault just by popping the frame pointer and returning. So it needs to know
# for sure there will be a frame pointer and nothing else on the stack other
# than the return address from the original call.
#
# TODO(jamesr): This is not remotely safe to assume about compiled code. The
# only safe way to unwind is to rely on full DWARF CFI and use the full
# unwinder. However, the hermetic code blob is detached from any metadata
# such as CFI, so there is no way to make it unwindable. Without that, the
# only truly safe option is to implement the copy routine in assembly for
# each machine and have a manually-maintained contract with the error
# recovery code about how to correctly unwind it. It's easy for that
# contract to be simple since such a copy routine is usually just a leaf
# routine that doesn't spill any call-saved registers such that nothing but
# the return instruction is required. But writing it in assembly is the only
# way to ensure the code meets such a contract.
add_configs = [ ":leaf-frame-pointer" ]
# TODO(fxbug.dev/129545): LLD lets --no-pie trump the code generation
# switches, but this needs to be compiled as PIC though linked differently.
if (toolchain_variant.tags + [ "lto" ] - [ "lto" ] !=
toolchain_variant.tags) {
ldflags = [ "-Wl,-mllvm,-relocation-model=pic" ]
}
}
config("leaf-frame-pointer") {
visibility = [ ":*" ]
cflags = [ "-mno-omit-leaf-frame-pointer" ]
}
resource("hermetic_copy_bin") {
deps = [ ":hermetic_copy" ]
sources = get_target_outputs(deps[0])
outputs = [ "hermetic_copy.bin" ]
}