Initial commit for Dhrystone benchmark
diff --git a/.gn b/.gn
new file mode 100644
index 0000000..2a082ff
--- /dev/null
+++ b/.gn
@@ -0,0 +1,6 @@
+# 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.
+
+# The location of the build configuration file.
+buildconfig = "//build/BUILDCONFIG.gn"
diff --git a/BUILD.gn b/BUILD.gn
new file mode 100644
index 0000000..9dd0d66
--- /dev/null
+++ b/BUILD.gn
@@ -0,0 +1,10 @@
+# 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.
+
+group("default") {
+ deps = [
+ "//third_party/dhrystone",
+ ]
+}
+
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..cf21574
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,27 @@
+// Copyright 2020 The Fuchsia Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..691d6d3
--- /dev/null
+++ b/README.md
@@ -0,0 +1,16 @@
+# Setup
+1. Install required dependencies for building: `sudo apt-get install curl unzip python python2`.
+2. Change directory to the root of the repo: `cd fuchsia-benchmarks` and run the setup script `./scripts/download-build-tools.sh`
+3. Generate ninja files: ./buildtools/linux64/gn gen out/core.astro-release --args='target_os="fuchsia" target_cpu="arm64"'
+4. Build: ./buildtools/linux64/ninja -C out/core.astro-release
+5. Start the package server: ./third_party/fuchsia-sdk/bin/fserve.sh
+
+# Dhrystone Benchmark
+See https://en.wikipedia.org/wiki/Dhrystone.
+
+## How to Run
+1. Follow previous steps from the Setup section
+2. Publish the Dhrystone component: ./third_party/fuchsia-sdk/bin/fpublish.sh out/core.astro-release/gen/third_party/dhrystone/dhrystone/dhrystone.far
+3. Run the benchmark: ./third_party/fuchsia-sdk/bin/fssh.sh run fuchsia-pkg://fuchsia.com/dhrystone#meta/dhrystone.cmx 10
+
+* This is not an officially supported Google product*
diff --git a/build/BUILD.gn b/build/BUILD.gn
new file mode 100644
index 0000000..f5eb934
--- /dev/null
+++ b/build/BUILD.gn
@@ -0,0 +1,19 @@
+# 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.
+
+config("compiler_defaults") {
+ if (current_os == "linux") {
+ cflags = [
+ "-fPIC",
+ "-pthread",
+ ]
+ }
+}
+
+config("executable_ldconfig") {
+ ldflags = [
+ "-Wl,-rpath=\$ORIGIN/",
+ "-Wl,-rpath-link=",
+ ]
+}
diff --git a/build/BUILDCONFIG.gn b/build/BUILDCONFIG.gn
new file mode 100644
index 0000000..21a1902
--- /dev/null
+++ b/build/BUILDCONFIG.gn
@@ -0,0 +1,159 @@
+# 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 (target_os == "") {
+ target_os = host_os
+}
+
+if (target_cpu == "") {
+ target_cpu = host_cpu
+}
+
+if (current_cpu == "") {
+ current_cpu = target_cpu
+}
+if (current_os == "") {
+ current_os = target_os
+}
+
+is_fuchsia = current_os == "fuchsia"
+is_linux = current_os == "linux"
+is_debug = false
+
+# Set the host_toolchain
+declare_args() {
+ host_toolchain = ""
+}
+
+# ==============================================================================
+# TOOLCHAIN SETUP
+# ==============================================================================
+#
+# Here we set the default toolchain, as well as the variable host_toolchain
+# which will identify the toolchain corresponding to the local system when
+# doing cross-compiles. When not cross-compiling, this will be the same as the
+# default toolchain.
+#
+# We do this before anything else to make sure we complain about any
+# unsupported os/cpu combinations as early as possible.
+
+if (host_toolchain == "") {
+ # This should only happen in the top-level context.
+ # In a specific toolchain context, the toolchain_args()
+ # block should have propagated a value down.
+
+ if (host_os == "linux") {
+ host_toolchain = "//build/toolchain/linux:clang_$host_cpu"
+ } else if (host_os == "mac") {
+ host_toolchain = "//build/toolchain/mac:$host_cpu"
+ } else {
+ assert(false, "Unsupported host_os: $host_os")
+ }
+}
+
+# Set toolchain based on target_os and target_cpu
+_default_toolchain = ""
+
+if (target_os == "linux") {
+ _default_toolchain = "//build/toolchain/linux:clang_$target_cpu"
+} else if (target_os == "fuchsia") {
+ _default_toolchain = "//build/toolchain/fuchsia:$target_cpu"
+} else {
+ assert(false, "Unsupported target_os: $target_os")
+}
+
+set_default_toolchain(_default_toolchain)
+
+# Set compiler defaults
+
+# Holds all configs used for running the compiler.
+default_compiler_configs = [
+ "//build:compiler_defaults",
+ "//build/config/compiler:assembler_debug_dir",
+ "//build/config/compiler:compiler",
+ "//build/config/compiler:compiler_arm_fpu",
+ "//build/config/compiler:c++",
+ "//build/config/compiler:default_include_dirs",
+ "//build/config/compiler:default_optimization",
+ "//build/config/compiler:default_symbols",
+ "//build/config/compiler:no_exceptions",
+ "//build/config/compiler:no_rtti",
+ "//build/config/compiler:runtime_library",
+ "//build/config/compiler:extra_warnings",
+ "//build/config/compiler:symbol_visibility_hidden",
+]
+
+if (is_fuchsia) {
+ default_compiler_configs += [
+ "//third_party/fuchsia-sdk/build/config:compiler",
+ "//third_party/fuchsia-sdk/build/config:runtime_library",
+ ]
+
+ # these are additional flags recommended
+ default_compiler_configs += [ "//build/config/compiler:default_stack_frames" ]
+}
+
+# Debug/release-related defines.
+if (is_debug) {
+ default_compiler_configs += [ "//build/config:debug" ]
+} else {
+ default_compiler_configs += [ "//build/config:release" ]
+}
+
+# Static libraries and source sets use only the compiler ones.
+set_defaults("static_library") {
+ configs = default_compiler_configs
+}
+set_defaults("source_set") {
+ configs = default_compiler_configs
+}
+
+# Executable defaults.
+default_executable_configs = default_compiler_configs + [
+ "//build:executable_ldconfig",
+ "//build/config:default_libs",
+ ]
+set_defaults("executable") {
+ configs = default_executable_configs
+}
+
+# Shared library and loadable module defaults (also for components in component
+# mode).
+default_shared_library_configs =
+ default_compiler_configs + [ "//build/config:default_libs" ]
+
+set_defaults("shared_library") {
+ configs = default_shared_library_configs
+}
+set_defaults("loadable_module") {
+ configs = default_shared_library_configs
+}
+
+if (is_fuchsia) {
+ # Sets default dependencies for executable and shared_library targets.
+ #
+ # Variables
+ # no_default_deps: If true, no standard dependencies will be added.
+ foreach(_target_type,
+ [
+ "executable",
+ "shared_library",
+ ]) {
+ template(_target_type) {
+ target(_target_type, target_name) {
+ forward_variables_from(invoker, "*", [ "no_default_deps" ])
+ if (!defined(deps)) {
+ deps = []
+ }
+ if (!defined(data_deps)) {
+ data_deps = []
+ }
+ if (!defined(invoker.no_default_deps) || !invoker.no_default_deps) {
+ data_deps += [ "//build/config/clang:c++-runtime-deps" ]
+ deps += [ "//third_party/fuchsia-sdk/build/config:runtime_library_group" ]
+ }
+ }
+ }
+ }
+}
diff --git a/build/config/BUILD.gn b/build/config/BUILD.gn
new file mode 100644
index 0000000..73babcb
--- /dev/null
+++ b/build/config/BUILD.gn
@@ -0,0 +1,37 @@
+# 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.
+
+# Debug/release ----------------------------------------------------------------
+
+config("debug") {
+ defines = [
+ "_DEBUG",
+ "DYNAMIC_ANNOTATIONS_ENABLED=1",
+ "WTF_USE_DYNAMIC_ANNOTATIONS=1",
+ ]
+
+ if (current_cpu == "x64") {
+ # Enable libstdc++ debugging facilities to help catch problems early.
+ defines += [ "_GLIBCXX_DEBUG=1" ]
+ }
+}
+
+config("release") {
+ defines = [ "NDEBUG" ]
+ defines += [ "NVALGRIND" ]
+ defines += [ "DYNAMIC_ANNOTATIONS_ENABLED=0" ]
+}
+
+# Default libraries ------------------------------------------------------------
+
+# This config defines the default libraries applied to all targets.
+config("default_libs") {
+ if (is_linux) {
+ libs = [
+ "dl",
+ "pthread",
+ "rt",
+ ]
+ }
+}
diff --git a/build/config/clang/BUILD.gn b/build/config/clang/BUILD.gn
new file mode 100644
index 0000000..2866aa7
--- /dev/null
+++ b/build/config/clang/BUILD.gn
@@ -0,0 +1,31 @@
+# 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.
+
+import("//build/config/clang/clang.gni")
+
+# This adds the runtime deps for C++ for usage when cross compiling.
+group("c++-runtime-deps") {
+ data_deps = [
+ ":clang-runtime-libs",
+ ]
+}
+
+copy("clang-runtime-libs") {
+ if (target_cpu == "arm64") {
+ arch = "aarch64"
+ } else if (target_cpu == "x64") {
+ arch = "x86_64"
+ }
+ vendor = "unknown"
+
+ sys = target_os
+ sources = [
+ "${clang_base_path}/lib/${arch}-${vendor}-${sys}/c++/libc++.so.2.0",
+ "${clang_base_path}/lib/${arch}-${vendor}-${sys}/c++/libc++abi.so.1.0",
+ "${clang_base_path}/lib/${arch}-${vendor}-${sys}/c++/libunwind.so.1.0",
+ ]
+ outputs = [
+ "${root_out_dir}/lib/{{source_name_part}}",
+ ]
+}
diff --git a/build/config/clang/clang.gni b/build/config/clang/clang.gni
new file mode 100644
index 0000000..0c1579b
--- /dev/null
+++ b/build/config/clang/clang.gni
@@ -0,0 +1,5 @@
+# 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.
+
+clang_base_path = "//buildtools/linux64/clang-linux-amd64"
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
new file mode 100644
index 0000000..1a1169d
--- /dev/null
+++ b/build/config/compiler/BUILD.gn
@@ -0,0 +1,235 @@
+# 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.
+
+# compiler ---------------------------------------------------------------------
+#
+# Base compiler configuration.
+#
+# See also "runtime_library" below for related stuff and a discussion about
+# where stuff should go. Put warning related stuff in the "warnings" config.
+
+import("//build/config/clang/clang.gni")
+
+config("compiler") {
+ asmflags = []
+ cflags = []
+ cflags_c = []
+ cflags_cc = []
+ cflags_objc = []
+ cflags_objcc = []
+ ldflags = []
+ defines = []
+ configs = []
+
+ # System-specific flags. If your compiler flags apply to one of the
+ # categories here, add it to the associated file to keep this shared config
+ # smaller.
+
+ cflags += [ "-fno-strict-aliasing" ] # See http://crbug.com/32204
+ cflags += [ "-fcolor-diagnostics" ]
+ cflags += [ "-fmerge-all-constants" ]
+ cflags += [ "-fcomplete-member-pointers" ]
+
+ cflags += [
+ "-Xclang",
+ "-mllvm",
+ "-Xclang",
+ "-instcombine-lower-dbg-declare=0",
+ ]
+
+ asmflags += [ "-fPIC" ]
+ cflags += [ "-fPIC" ]
+ ldflags += [ "-fPIC" ]
+
+ ldflags += [
+ "-Wl,-z,noexecstack",
+ "-Wl,-z,relro",
+ ]
+
+ ldflags += [ "-Wl,-z,now" ]
+
+ # Compiler instrumentation can introduce dependencies in DSOs to symbols in
+ # the executable they are loaded into, so they are unresolved at link-time.
+ ldflags += [
+ "-Wl,-z,defs",
+ "-Wl,--as-needed",
+ ]
+
+ if (is_debug) {
+ # Allow comparing the address of references and 'this' against 0
+ # in debug builds. Technically, these can never be null in
+ # well-defined C/C++ and Clang can optimize such checks away in
+ # release builds, but they may be used in asserts in debug builds.
+ cflags_cc += [
+ "-Wno-undefined-bool-conversion",
+ "-Wno-tautological-undefined-compare",
+ ]
+ }
+
+ cflags_c += [ "-std=c11" ]
+ cflags_cc += [ "-std=c++14" ]
+
+ # Pass the same C/C++ flags to the objective C/C++ compiler.
+ cflags_objc += cflags_c
+ cflags_objcc += cflags_cc
+}
+
+config("c++") {
+ cflags_cc = [ "-isystem" + rebase_path(clang_base_path, root_build_dir) ]
+}
+
+config("assembler_debug_dir") {
+ asmflags = [ "-Wa,-fdebug-compilation-dir,." ]
+}
+
+# This config causes functions not to be automatically exported from shared
+# libraries. By default, all symbols are exported but this means there are
+# lots of exports that slow everything down. In general we explicitly mark
+# which functions we want to export from components.
+#
+# Some third_party code assumes all functions are exported so this is separated
+# into its own config so such libraries can remove this config to make symbols
+# public again.
+#
+# See http://gcc.gnu.org/wiki/Visibility
+config("symbol_visibility_hidden") {
+ cflags = [ "-fvisibility=hidden" ]
+ cflags_cc = [ "-fvisibility-inlines-hidden" ]
+ cflags_objcc = cflags_cc
+}
+
+config("compiler_arm_fpu") {
+ if (current_cpu == "arm") {
+ cflags = [ "-mfpu=$arm_fpu" ]
+ asmflags = cflags
+ }
+}
+
+# export_dynamic ---------------------------------------------------------------
+#
+# Ensures all exported symbols are added to the dynamic symbol table. This is
+# necessary to expose Chrome's custom operator new() and operator delete() (and
+# other memory-related symbols) to libraries. Otherwise, they might
+# (de)allocate memory on a different heap, which would spell trouble if pointers
+# to heap-allocated memory are passed over shared library boundaries.
+config("export_dynamic") {
+}
+
+# default_include_dirs ---------------------------------------------------------
+#
+# This is a separate config so that third_party code (which would not use the
+# source root and might have conflicting versions of some headers) can remove
+# this and specify their own include paths.
+config("default_include_dirs") {
+ include_dirs = [
+ "//",
+ root_gen_dir,
+ ]
+}
+
+config("default_stack_frames") {
+ cflags = [ "-fomit-frame-pointer" ]
+}
+
+# The default optimization applied to all targets. This will be equivalent to
+# either "optimize" or "no_optimize", depending on the build flags.
+config("default_optimization") {
+ if (is_debug) {
+ configs = [ ":no_optimize" ]
+ } else {
+ configs = [ ":optimize" ]
+ }
+}
+
+config("optimize") {
+ cflags = [
+ "-O2",
+ "-fno-ident",
+ "-fdata-sections",
+ "-ffunction-sections",
+ ]
+ ldflags = [
+ "-Wl,-O2",
+ "-Wl,--gc-sections",
+ ]
+}
+
+# Turn off optimizations.
+config("no_optimize") {
+ cflags = [ "-O0" ]
+ ldflags = []
+}
+
+# Full symbols.
+config("symbols") {
+ cflags = []
+ if (current_cpu == "arm") {
+ cflags += [ "-gdwarf-3" ]
+ }
+ cflags += [ "-g2" ]
+
+ asmflags = cflags
+ ldflags = []
+
+ cflags += [ "-ggnu-pubnames" ]
+}
+
+# No symbols.
+config("no_symbols") {
+ cflags = [ "-g0" ]
+ asmflags = cflags
+}
+
+# Default symbols.
+config("default_symbols") {
+ if (is_debug) {
+ configs = [ ":symbols" ]
+ } else {
+ configs = [ ":no_symbols" ]
+ }
+}
+
+config("no_exceptions") {
+ cflags_cc = [ "-fno-exceptions" ]
+ cflags_objcc = cflags_cc
+}
+
+config("exceptions") {
+ cflags_cc = [ "-fexceptions" ]
+ cflags_objcc = cflags_cc
+}
+
+config("no_rtti") {
+ cflags_cc = [ "-fno-rtti" ]
+ cflags_objcc = cflags_cc
+}
+
+config("rtti") {
+ cflags_cc = [ "-frtti" ]
+ cflags_objcc = cflags_cc
+}
+
+config("runtime_library") {
+ libs = [ "pthread" ]
+}
+
+# Enables some extra Clang-specific warnings. Some third-party code won't
+# compile with these so may want to remove this config.
+config("extra_warnings") {
+ cflags = [
+ "-Wheader-hygiene",
+
+ # Warns when a const char[] is converted to bool.
+ "-Wstring-conversion",
+
+ "-Wtautological-overlap-compare",
+ ]
+}
+
+# Settings for executables.
+config("executable_config") {
+ configs = []
+ ldflags = [ "-pie" ]
+ ldflags += [ "-Wl,--disable-new-dtags" ]
+}
diff --git a/build/toolchain/clang_toolchain.gni b/build/toolchain/clang_toolchain.gni
new file mode 100644
index 0000000..d22641e
--- /dev/null
+++ b/build/toolchain/clang_toolchain.gni
@@ -0,0 +1,456 @@
+# 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.
+
+import("//build/config/clang/clang.gni")
+
+# This template defines a toolchain.
+#
+# It requires the following variables specifying the executables to run:
+# - ar
+# - cc
+# - cxx
+# - ld
+#
+# Optional parameters that control the tools:
+#
+# - extra_cflags
+# Extra flags to be appended when compiling C files (but not C++ files).
+# - extra_cppflags
+# Extra flags to be appended when compiling both C and C++ files. "CPP"
+# stands for "C PreProcessor" in this context, although it can be
+# used for non-preprocessor flags as well. Not to be confused with
+# "CXX" (which follows).
+# - extra_cxxflags
+# Extra flags to be appended when compiling C++ files (but not C files).
+# - extra_asmflags
+# Extra flags to be appended when compiling assembly.
+# - extra_ldflags
+# Extra flags to be appended when linking
+#
+# - libs_section_prefix
+# - libs_section_postfix
+# The contents of these strings, if specified, will be placed around
+# the libs section of the linker line. It allows one to inject libraries
+# at the beginning and end for all targets in a toolchain.
+# - solink_libs_section_prefix
+# - solink_libs_section_postfix
+# Same as libs_section_{pre,post}fix except used for solink instead of link.
+# - link_outputs
+# The content of this array, if specified, will be added to the list of
+# outputs from the link command. This can be useful in conjunction with
+# the post_link parameter.
+# - use_unstripped_as_runtime_outputs
+# When |strip| is set, mark unstripped executables as runtime deps rather
+# than stripped ones.
+# - post_link
+# The content of this string, if specified, will be run as a separate
+# command following the the link command.
+# - deps
+# Just forwarded to the toolchain definition.
+# - executable_extension
+# If this string is specified it will be used for the file extension
+# for an executable, rather than using no extension; targets will
+# still be able to override the extension using the output_extension
+# variable.
+# - rebuild_define
+# The contents of this string, if specified, will be passed as a #define
+# to the toolchain. It can be used to force recompiles whenever a
+# toolchain is updated.
+# - shlib_extension
+# If this string is specified it will be used for the file extension
+# for a shared library, rather than default value specified in
+# toolchain.gni
+# - strip
+# Location of the strip executable. When specified, strip will be run on
+# all shared libraries and executables as they are built. The pre-stripped
+# artifacts will be put in lib.unstripped/ and exe.unstripped/.
+template("clang_toolchain") {
+ declare_args() {
+ shlib_prefix = "lib"
+ shlib_extension = ".so"
+ }
+
+ params = {
+ if (defined(invoker.prefix)) {
+ prefix = invoker.prefix
+ } else {
+ prefix = rebase_path("$clang_base_path/bin", root_build_dir)
+ }
+ if (defined(invoker.ar)) {
+ ar = invoker.ar
+ } else {
+ ar = "${prefix}/llvm-ar"
+ }
+
+ if (defined(invoker.cc)) {
+ cc = invoker.cc
+ } else {
+ cc = "${prefix}/clang"
+ }
+
+ if (defined(invoker.cxx)) {
+ cxx = invoker.cxx
+ } else {
+ cxx = "${prefix}/clang++"
+ }
+
+ if (defined(invoker.ld)) {
+ ld = invoker.ld
+ } else {
+ ld = cxx
+ }
+ }
+
+ toolchain(target_name) {
+ assert(defined(params.ar), "clang_toolchain() must specify a \"ar\" value")
+ assert(defined(params.cc), "clang_toolchain() must specify a \"cc\" value")
+ assert(defined(params.cxx), "clang_toolchain() must specify a \"cxx\" value")
+ assert(defined(params.ld), "clang_toolchain() must specify a \"ld\" value")
+
+ # This define changes when the toolchain changes, forcing a rebuild.
+ # Nothing should ever use this define.
+ if (defined(invoker.rebuild_define)) {
+ rebuild_string = "-D" + invoker.rebuild_define + " "
+ } else {
+ rebuild_string = ""
+ }
+
+ # GN's syntax can't handle more than one scope dereference at once, like
+ # "invoker.toolchain_args.foo", so make a temporary to hold the toolchain
+ # args so we can do "invoker_toolchain_args.foo".
+ assert(defined(invoker.toolchain_args),
+ "Toolchains must specify toolchain_args")
+ invoker_toolchain_args = invoker.toolchain_args
+ assert(defined(invoker_toolchain_args.current_cpu),
+ "toolchain_args must specify a current_cpu")
+ assert(defined(invoker_toolchain_args.current_os),
+ "toolchain_args must specify a current_os")
+
+ # When invoking this toolchain not as the default one, these args will be
+ # passed to the build. They are ignored when this is the default toolchain.
+ toolchain_args = {
+ # Populate toolchain args from the invoker.
+ forward_variables_from(invoker_toolchain_args, "*")
+
+ # The host toolchain value computed by the default toolchain's setup
+ # needs to be passed through unchanged to all secondary toolchains to
+ # ensure that it's always the same, regardless of the values that may be
+ # set on those toolchains.
+ host_toolchain = host_toolchain
+ }
+
+ compiler_prefix = " "
+
+ # Create a distinct variable for "asm", since analysis runs pass # a bunch
+ # of flags to clang/clang++ that are nonsensical on assembler runs.
+ asm_prefix = compiler_prefix
+
+ cc = compiler_prefix + params.cc
+ cxx = compiler_prefix + params.cxx
+ asm = asm_prefix + params.cc
+ ar = params.ar
+ ld = params.ld
+
+ if (defined(invoker.shlib_extension)) {
+ default_shlib_extension = invoker.shlib_extension
+ } else {
+ default_shlib_extension = shlib_extension
+ }
+
+ if (defined(invoker.default_shlib_subdir)) {
+ default_shlib_subdir = invoker.default_shlib_subdir
+ } else {
+ default_shlib_subdir = ""
+ }
+
+ if (defined(invoker.executable_extension)) {
+ default_executable_extension = invoker.executable_extension
+ } else {
+ default_executable_extension = ""
+ }
+
+ # Bring these into our scope for string interpolation with default values.
+ if (defined(invoker.libs_section_prefix)) {
+ libs_section_prefix = invoker.libs_section_prefix
+ } else {
+ libs_section_prefix = ""
+ }
+
+ if (defined(invoker.libs_section_postfix)) {
+ libs_section_postfix = invoker.libs_section_postfix
+ } else {
+ libs_section_postfix = ""
+ }
+
+ if (defined(invoker.solink_libs_section_prefix)) {
+ solink_libs_section_prefix = invoker.solink_libs_section_prefix
+ } else {
+ solink_libs_section_prefix = ""
+ }
+
+ if (defined(invoker.solink_libs_section_postfix)) {
+ solink_libs_section_postfix = invoker.solink_libs_section_postfix
+ } else {
+ solink_libs_section_postfix = ""
+ }
+
+ if (defined(invoker.extra_cflags) && invoker.extra_cflags != "") {
+ extra_cflags = " " + invoker.extra_cflags
+ } else {
+ extra_cflags = ""
+ }
+
+ if (defined(invoker.extra_cppflags) && invoker.extra_cppflags != "") {
+ extra_cppflags = " " + invoker.extra_cppflags
+ } else {
+ extra_cppflags = ""
+ }
+
+ if (defined(invoker.extra_cxxflags) && invoker.extra_cxxflags != "") {
+ extra_cxxflags = " " + invoker.extra_cxxflags
+ } else {
+ extra_cxxflags = ""
+ }
+
+ if (defined(invoker.extra_asmflags) && invoker.extra_asmflags != "") {
+ extra_asmflags = " " + invoker.extra_asmflags
+ } else {
+ extra_asmflags = ""
+ }
+
+ if (defined(invoker.extra_ldflags) && invoker.extra_ldflags != "") {
+ extra_ldflags = " " + invoker.extra_ldflags
+ } else {
+ extra_ldflags = ""
+ }
+
+ # These library switches can apply to all tools below.
+ lib_switch = "-l"
+ lib_dir_switch = "-L"
+
+ # Object files go in this directory.
+ object_subdir = "{{target_out_dir}}/{{label_name}}"
+
+ tool("cc") {
+ depfile = "{{output}}.d"
+ command = "$cc -MMD -MF $depfile ${rebuild_string}{{defines}} {{include_dirs}} {{cflags}} {{cflags_c}}${extra_cppflags}${extra_cflags} -c {{source}} -o {{output}}"
+ depsformat = "gcc"
+ description = "CC {{output}}"
+ outputs = [
+ "$object_subdir/{{source_name_part}}.o",
+ ]
+ }
+
+ tool("cxx") {
+ depfile = "{{output}}.d"
+ command = "$cxx -MMD -MF $depfile ${rebuild_string}{{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}}${extra_cppflags}${extra_cxxflags} -c {{source}} -o {{output}}"
+ depsformat = "gcc"
+ description = "CXX {{output}}"
+ outputs = [
+ "$object_subdir/{{source_name_part}}.o",
+ ]
+ }
+
+ tool("asm") {
+ # For clang we can just use the C compiler to compile assembly.
+ depfile = "{{output}}.d"
+ command = "$asm -MMD -MF $depfile ${rebuild_string}{{defines}} {{include_dirs}} {{asmflags}}${extra_asmflags} -c {{source}} -o {{output}}"
+ depsformat = "gcc"
+ description = "ASM {{output}}"
+ outputs = [
+ "$object_subdir/{{source_name_part}}.o",
+ ]
+ }
+
+ tool("alink") {
+ rspfile = "{{output}}.rsp"
+ rspfile_content = "{{inputs}}"
+ command = "\"$ar\" {{arflags}} -r -c -s -D {{output}} @\"$rspfile\""
+
+ # Remove the output file first so that ar doesn't try to modify the
+ # existing file.
+ command = "rm -f {{output}} && $command"
+
+ # Almost all targets build with //build/config/compiler:thin_archive which
+ # adds -T to arflags.
+ description = "AR {{output}}"
+ outputs = [
+ "{{output_dir}}/{{target_output_name}}{{output_extension}}",
+ ]
+
+ # Shared libraries go in the target out directory by default so we can
+ # generate different targets with the same name and not have them collide.
+ default_output_dir = "{{target_out_dir}}"
+ default_output_extension = ".a"
+ output_prefix = "lib"
+ }
+
+ tool("solink") {
+ soname = "{{target_output_name}}{{output_extension}}" # e.g. "libfoo.so".
+ sofile = "{{output_dir}}/$soname" # Possibly including toolchain dir.
+ rspfile = sofile + ".rsp"
+
+ if (defined(invoker.strip)) {
+ unstripped_sofile = "{{root_out_dir}}/lib.unstripped/$soname"
+ } else {
+ unstripped_sofile = sofile
+ }
+
+ # These variables are not built into GN but are helpers that
+ # implement (1) linking to produce a .so, (2) extracting the symbols
+ # from that file (3) if the extracted list differs from the existing
+ # .TOC file, overwrite it, otherwise, don't change it.
+ tocfile = sofile + ".TOC"
+
+ link_command = "$ld -shared {{ldflags}}${extra_ldflags} -o \"$unstripped_sofile\" -Wl,-soname=\"$soname\" @\"$rspfile\""
+
+ # Generate a map file to be used for binary size analysis.
+ if (defined(invoker.strip)) {
+ strip_switch = "--strip=${invoker.strip} "
+ }
+
+ command = "$link_command"
+ rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive $solink_libs_section_prefix {{libs}} $solink_libs_section_postfix"
+ description = "SOLINK $sofile"
+
+ # Use this for {{output_extension}} expansions unless a target manually
+ # overrides it (in which case {{output_extension}} will be what the target
+ # specifies).
+ default_output_extension = default_shlib_extension
+
+ default_output_dir = "{{root_out_dir}}${default_shlib_subdir}"
+
+ output_prefix = "lib"
+
+ # Since the above commands only updates the .TOC file when it changes, ask
+ # Ninja to check if the timestamp actually changed to know if downstream
+ # dependencies should be recompiled.
+ restat = true
+
+ # Tell GN about the output files. It will link to the sofile but use the
+ # tocfile for dependency management.
+ outputs = [
+ sofile,
+ tocfile,
+ ]
+ if (sofile != unstripped_sofile) {
+ outputs += [ unstripped_sofile ]
+ if (defined(invoker.use_unstripped_as_runtime_outputs) &&
+ invoker.use_unstripped_as_runtime_outputs) {
+ runtime_outputs = [ unstripped_sofile ]
+ }
+ }
+ if (defined(map_file)) {
+ outputs += [ map_file ]
+ }
+ link_output = sofile
+ depend_output = tocfile
+ }
+
+ tool("solink_module") {
+ soname = "{{target_output_name}}{{output_extension}}" # e.g. "libfoo.so".
+ sofile = "{{output_dir}}/$soname"
+ rspfile = sofile + ".rsp"
+
+ if (defined(invoker.strip)) {
+ unstripped_sofile = "{{root_out_dir}}/lib.unstripped/$soname"
+ } else {
+ unstripped_sofile = sofile
+ }
+
+ command = "$ld -shared {{ldflags}}${extra_ldflags} -o \"$unstripped_sofile\" -Wl,-soname=\"$soname\" @\"$rspfile\""
+
+ if (defined(invoker.strip)) {
+ strip_command = "${invoker.strip} -o \"$sofile\" \"$unstripped_sofile\""
+ command += " && " + strip_command
+ }
+ rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive $solink_libs_section_prefix {{libs}} $solink_libs_section_postfix"
+
+ description = "SOLINK_MODULE $sofile"
+
+ # Use this for {{output_extension}} expansions unless a target manually
+ # overrides it (in which case {{output_extension}} will be what the target
+ # specifies).
+ if (defined(invoker.loadable_module_extension)) {
+ default_output_extension = invoker.loadable_module_extension
+ } else {
+ default_output_extension = default_shlib_extension
+ }
+
+ default_output_dir = "{{root_out_dir}}${default_shlib_subdir}"
+
+ output_prefix = "lib"
+
+ outputs = [
+ sofile,
+ ]
+ if (sofile != unstripped_sofile) {
+ outputs += [ unstripped_sofile ]
+ if (defined(invoker.use_unstripped_as_runtime_outputs) &&
+ invoker.use_unstripped_as_runtime_outputs) {
+ runtime_outputs = [ unstripped_sofile ]
+ }
+ }
+ }
+
+ tool("link") {
+ exename = "{{target_output_name}}{{output_extension}}"
+ outfile = "{{output_dir}}/$exename"
+ rspfile = "$outfile.rsp"
+ unstripped_outfile = outfile
+
+ # Use this for {{output_extension}} expansions unless a target manually
+ # overrides it (in which case {{output_extension}} will be what the target
+ # specifies).
+ default_output_extension = default_executable_extension
+
+ default_output_dir = "{{root_out_dir}}"
+
+ if (defined(invoker.strip)) {
+ unstripped_outfile = "{{root_out_dir}}/exe.unstripped/$exename"
+ }
+
+ # Generate a map file to be used for binary size analysis.
+ # Map file adds ~10% to the link time on a z620.
+ # With target_os="android", libchrome.so.map.gz is ~20MB.
+ start_group_flag = "-Wl,--start-group"
+ end_group_flag = "-Wl,--end-group "
+ link_command = "$ld {{ldflags}}${extra_ldflags} -o \"$unstripped_outfile\" $start_group_flag @\"$rspfile\" {{solibs}} $end_group_flag $libs_section_prefix {{libs}} $libs_section_postfix"
+
+ command = "$link_command"
+ description = "LINK $outfile"
+ rspfile_content = "{{inputs}}"
+ outputs = [
+ outfile,
+ ]
+ if (outfile != unstripped_outfile) {
+ outputs += [ unstripped_outfile ]
+ if (defined(invoker.use_unstripped_as_runtime_outputs) &&
+ invoker.use_unstripped_as_runtime_outputs) {
+ runtime_outputs = [ unstripped_outfile ]
+ }
+ }
+ if (defined(invoker.link_outputs)) {
+ outputs += invoker.link_outputs
+ }
+ if (defined(map_file)) {
+ outputs += [ map_file ]
+ }
+ }
+
+ # These two are really entirely generic, but have to be repeated in
+ # each toolchain because GN doesn't allow a template to be used here.
+ # See //build/toolchain/toolchain.gni for details.
+ tool("stamp") {
+ command = "touch {{output}}"
+ description = "STAMP {{output}}"
+ }
+ tool("copy") {
+ command = "ln -f {{source}} {{output}} 2>/dev/null || (rm -rf {{output}} && cp -af {{source}} {{output}})"
+ description = "COPY {{source}} {{output}}"
+ }
+
+ forward_variables_from(invoker, [ "deps" ])
+ }
+}
diff --git a/build/toolchain/fuchsia/BUILD.gn b/build/toolchain/fuchsia/BUILD.gn
new file mode 100644
index 0000000..8d2ba5c
--- /dev/null
+++ b/build/toolchain/fuchsia/BUILD.gn
@@ -0,0 +1,31 @@
+# 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.
+
+import("//build/toolchain/clang_toolchain.gni")
+
+# Fuchsia builds using the Clang toolchain, with most parameters common across
+# the different target architectures.
+template("fuchsia_toolchain") {
+ clang_toolchain(target_name) {
+ assert(host_os == "linux" || host_os == "mac")
+ assert(defined(invoker.toolchain_args),
+ "toolchain_args must be defined for fuchsia_clang_toolchain()")
+
+ default_shlib_subdir = "/lib"
+ toolchain_args = invoker.toolchain_args
+ toolchain_args.current_os = "fuchsia"
+ }
+}
+
+fuchsia_toolchain("x64") {
+ toolchain_args = {
+ current_cpu = "x64"
+ }
+}
+
+fuchsia_toolchain("arm64") {
+ toolchain_args = {
+ current_cpu = "arm64"
+ }
+}
diff --git a/build/toolchain/linux/BUILD.gn b/build/toolchain/linux/BUILD.gn
new file mode 100644
index 0000000..60e4027
--- /dev/null
+++ b/build/toolchain/linux/BUILD.gn
@@ -0,0 +1,21 @@
+# 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.
+
+import("//build/toolchain/clang_toolchain.gni")
+
+template("linux_toolchain") {
+ clang_toolchain(target_name) {
+ assert(host_os == "linux")
+ assert(defined(invoker.toolchain_args),
+ "toolchain_args must be defined for linux_toolchain()")
+
+ toolchain_args = invoker.toolchain_args
+ toolchain_args.current_os = "linux"
+ }
+}
+linux_toolchain("clang_x64") {
+ toolchain_args = {
+ current_cpu = "x64"
+ }
+}
diff --git a/out/core.astro-release/.ninja_deps b/out/core.astro-release/.ninja_deps
new file mode 100644
index 0000000..f3f0e01
--- /dev/null
+++ b/out/core.astro-release/.ninja_deps
Binary files differ
diff --git a/out/core.astro-release/.ninja_log b/out/core.astro-release/.ninja_log
new file mode 100644
index 0000000..8b33ae0
--- /dev/null
+++ b/out/core.astro-release/.ninja_log
@@ -0,0 +1,87 @@
+# ninja log v5
+1 17 315475200000000000 lib/libc++.so.2 ee46729cd52af503
+1 17 315475200000000000 lib/libc++abi.so.1 f671c24d4f61fc66
+2 18 315475200000000000 lib/libunwind.so.1 d60c36afd6aa1cd3
+3 18 1587411117000000000 lib/ld.so.1 ac3cbec5c26be1cf
+4 19 1587411114000000000 lib/libfdio.so 9a287126e71be341
+18 23 1587411706802172839 obj/build/config/clang/clang-runtime-libs.stamp aa752f47ea7054ce
+19 24 1587411706802172839 obj/third_party/fuchsia-sdk/build/config/sysroot_dist_libs.stamp 8d92d9795bd7e12b
+19 24 1587411706802172839 obj/third_party/fuchsia-sdk/pkg/fdio/fdio_dist_libs.stamp f00c166e57b559ea
+23 28 1587411706806172850 obj/build/config/clang/c++-runtime-deps.stamp 57357c7a6b6ec668
+24 31 1587411706810172860 obj/third_party/fuchsia-sdk/pkg/fdio/libfdio.a 88df563c2e735709
+31 34 1587411706814172870 obj/third_party/fuchsia-sdk/build/config/runtime_library_group.stamp b7b7a1937485a311
+3 46 1587411706822172892 obj/src/dhrystone/dhrystone_bin/dhry_2.o f1efe85914f0d6b4
+6 75 1587411706850172964 obj/third_party/fuchsia-sdk/pkg/zx/zx/eventpair.o 37b4b8c6e0db8ac4
+4 75 1587411706850172964 obj/third_party/fuchsia-sdk/pkg/zx/zx/bti.o d85b694abae78d65
+7 80 1587411706858172985 obj/third_party/fuchsia-sdk/pkg/zx/zx/fifo.o ac0ad8d41fbdaa43
+17 85 1587411706862172996 obj/third_party/fuchsia-sdk/pkg/zx/zx/vmo.o 4f60121b9dbccd0a
+16 85 1587411706862172996 obj/third_party/fuchsia-sdk/pkg/zx/zx/vmar.o f9ec532500fdb85a
+5 95 1587411706870173016 obj/third_party/fuchsia-sdk/pkg/zx/zx/debuglog.o 68964a882cc12c8c
+6 99 1587411706874173027 obj/third_party/fuchsia-sdk/pkg/zx/zx/event.o 4f185375928a1b25
+10 100 1587411706874173027 obj/third_party/fuchsia-sdk/pkg/zx/zx/port.o a3fc1fd6d856ebd6
+5 101 1587411706878173038 obj/third_party/fuchsia-sdk/pkg/zx/zx/channel.o 9d87064f18bb31a0
+13 104 1587411706882173047 obj/third_party/fuchsia-sdk/pkg/zx/zx/socket.o ef64efb780df93ce
+10 104 1587411706882173047 obj/third_party/fuchsia-sdk/pkg/zx/zx/pager.o 3263643e9cdfb24f
+7 105 1587411706882173047 obj/third_party/fuchsia-sdk/pkg/zx/zx/guest.o dee30624722a0463
+8 105 1587411706882173047 obj/third_party/fuchsia-sdk/pkg/zx/zx/interrupt.o 9f6b72acaa0a9036
+13 105 1587411706882173047 obj/third_party/fuchsia-sdk/pkg/zx/zx/stream.o 8d53c9913d66a812
+12 105 1587411706882173047 obj/third_party/fuchsia-sdk/pkg/zx/zx/resource.o 4c36db13aa9328f9
+15 108 1587411706886173058 obj/third_party/fuchsia-sdk/pkg/zx/zx/timer.o d1ed20b7fe925018
+9 108 1587411706886173058 obj/third_party/fuchsia-sdk/pkg/zx/zx/iommu.o fa3abc6d50a13908
+14 108 1587411706886173058 obj/third_party/fuchsia-sdk/pkg/zx/zx/thread.o 434f872f6fc2c2e1
+11 109 1587411706886173058 obj/third_party/fuchsia-sdk/pkg/zx/zx/profile.o ef0a38da4aa5a9b8
+9 109 1587411706886173058 obj/third_party/fuchsia-sdk/pkg/zx/zx/job.o 38df95f2c912b01f
+11 111 1587411706886173058 obj/third_party/fuchsia-sdk/pkg/zx/zx/process.o 746d6758c70fc12c
+15 111 1587411706890173068 obj/third_party/fuchsia-sdk/pkg/zx/zx/vcpu.o 3a846c44bc5d8b1f
+111 115 1587411706894173079 obj/third_party/fuchsia-sdk/pkg/zx/libzx.a 6ae6d8055a9c1190
+2 140 1587411706918173142 obj/src/dhrystone/dhrystone_bin/dhry_1.o a54bed2d8e259c4e
+140 172 1587411706946173214 dhrystone_bin cb2d05f02cd1f1ad
+172 176 1587411706954173235 obj/src/dhrystone/dhrystone_cmx.stamp 49bf52a5f622d724
+176 227 1587411707002173360 gen/src/dhrystone/dhrystone/dhrystone.archive_manifest 6939674628a2ebc7
+176 227 1587411707002173360 gen/src/dhrystone/dhrystone/ids.txt 6939674628a2ebc7
+176 227 1587411707002173360 gen/src/dhrystone/dhrystone/package 6939674628a2ebc7
+227 231 1587411707010173381 obj/src/dhrystone/dhrystone_package__archive-manifest.stamp 22a54a2ff570c77a
+231 281 1587411707054173495 gen/src/dhrystone/dhrystone/meta.far 683eaecb5f9b4482
+231 281 1587411707054173495 gen/src/dhrystone/dhrystone/package_manifest.json 683eaecb5f9b4482
+281 285 1587411707062173516 obj/src/dhrystone/dhrystone_package__archive-metadata.stamp 368104d9d2c1aa19
+285 328 1587411707102173621 gen/src/dhrystone/dhrystone/dhrystone.far f44f520c0caf6bfd
+328 332 1587411707110173641 obj/src/dhrystone/dhrystone_package.stamp 460e0a3303cdb6f0
+332 336 1587411707114173651 obj/src/dhrystone/dhrystone.stamp cd8bbdf554205453
+336 339 1587411707118173662 obj/default.stamp 779238219a0eff9c
+2 55 1587419777718045001 obj/src/dhrystone/dhrystone_bin/dhry_2.o 4eaac9e89c44ad4e
+7 73 1587419777734045039 obj/third_party/fuchsia-sdk/pkg/zx/zx/port.o 75860eb82aa56b5b
+6 74 1587419777734045039 obj/third_party/fuchsia-sdk/pkg/zx/zx/iommu.o 9bb56f97fdd7fff3
+7 74 1587419777738045048 obj/third_party/fuchsia-sdk/pkg/zx/zx/pager.o 5e1ee328cb5b56cc
+5 75 1587419777738045048 obj/third_party/fuchsia-sdk/pkg/zx/zx/guest.o 4e56d5134ce7555e
+6 80 1587419777742045057 obj/third_party/fuchsia-sdk/pkg/zx/zx/job.o 6773d780e4a17678
+8 82 1587419777746045067 obj/third_party/fuchsia-sdk/pkg/zx/zx/process.o f99b9bee1ed6f7aa
+12 86 1587419777750045076 obj/third_party/fuchsia-sdk/pkg/zx/zx/vcpu.o 79bd6b42f44d5974
+3 94 1587419777758045095 obj/third_party/fuchsia-sdk/pkg/zx/zx/debuglog.o f85d5126aa847494
+4 97 1587419777758045095 obj/third_party/fuchsia-sdk/pkg/zx/zx/event.o 33340632bbec1608
+2 101 1587419777762045105 obj/third_party/fuchsia-sdk/pkg/zx/zx/bti.o 12cd309c926c54e0
+4 103 1587419777766045113 obj/third_party/fuchsia-sdk/pkg/zx/zx/eventpair.o b8a1eea217409f24
+3 103 1587419777766045113 obj/third_party/fuchsia-sdk/pkg/zx/zx/channel.o 16eff5976b56a640
+5 103 1587419777766045113 obj/third_party/fuchsia-sdk/pkg/zx/zx/fifo.o 8f801c2e98a24aab
+10 104 1587419777766045113 obj/third_party/fuchsia-sdk/pkg/zx/zx/stream.o 5fd9122a5cfa75cf
+5 104 1587419777766045113 obj/third_party/fuchsia-sdk/pkg/zx/zx/interrupt.o ff67a9ec24b08d09
+10 104 1587419777766045113 obj/third_party/fuchsia-sdk/pkg/zx/zx/socket.o 9686dbb1ad1c045e
+13 105 1587419777766045113 obj/third_party/fuchsia-sdk/pkg/zx/zx/vmar.o 8e5f447854ca4249
+11 105 1587419777766045113 obj/third_party/fuchsia-sdk/pkg/zx/zx/timer.o 5980c56ee08eca29
+8 108 1587419777770045124 obj/third_party/fuchsia-sdk/pkg/zx/zx/profile.o 307c16e9502c469f
+11 108 1587419777770045124 obj/third_party/fuchsia-sdk/pkg/zx/zx/thread.o 7e26a4e36d377f47
+13 108 1587419777770045124 obj/third_party/fuchsia-sdk/pkg/zx/zx/vmo.o 9f65e887e0343dee
+9 112 1587419777774045132 obj/third_party/fuchsia-sdk/pkg/zx/zx/resource.o 629632a052ef021
+112 116 1587419777782045152 obj/third_party/fuchsia-sdk/pkg/zx/libzx.a 6ae6d8055a9c1190
+1 150 1587419777814045227 obj/src/dhrystone/dhrystone_bin/dhry_1.o 6526941014f399e
+150 175 1587419777834045274 dhrystone_bin d46fc42cea5891b3
+175 226 1587419777886045395 gen/src/dhrystone/dhrystone/dhrystone.archive_manifest 6939674628a2ebc7
+175 226 1587419777886045395 gen/src/dhrystone/dhrystone/ids.txt 6939674628a2ebc7
+175 226 1587419777886045395 gen/src/dhrystone/dhrystone/package 6939674628a2ebc7
+226 229 1587419777894045414 obj/src/dhrystone/dhrystone_package__archive-manifest.stamp 22a54a2ff570c77a
+230 271 1587419777930045500 gen/src/dhrystone/dhrystone/meta.far 683eaecb5f9b4482
+230 271 1587419777930045500 gen/src/dhrystone/dhrystone/package_manifest.json 683eaecb5f9b4482
+271 274 1587419777938045517 obj/src/dhrystone/dhrystone_package__archive-metadata.stamp 368104d9d2c1aa19
+274 318 1587419777978045612 gen/src/dhrystone/dhrystone/dhrystone.far f44f520c0caf6bfd
+318 321 1587419777986045631 obj/src/dhrystone/dhrystone_package.stamp 460e0a3303cdb6f0
+321 324 1587419777990045640 obj/src/dhrystone/dhrystone.stamp cd8bbdf554205453
+324 327 1587419777990045640 obj/default.stamp 779238219a0eff9c
diff --git a/out/core.astro-release/args.gn b/out/core.astro-release/args.gn
new file mode 100644
index 0000000..058cfc3
--- /dev/null
+++ b/out/core.astro-release/args.gn
@@ -0,0 +1,2 @@
+target_os = "fuchsia"
+target_cpu = "arm64"
diff --git a/out/core.astro-release/build.ninja b/out/core.astro-release/build.ninja
new file mode 100644
index 0000000..a5a6bab
--- /dev/null
+++ b/out/core.astro-release/build.ninja
@@ -0,0 +1,67 @@
+ninja_required_version = 1.7.2
+
+rule gn
+ command = ../../buildtools/downloads/gn-linux-amd64-git_revision:239533d2d91a04b3317ca9101cf7189f4e651e4d/gn --root=../.. -q gen .
+ description = Regenerating ninja files
+
+build build.ninja: gn
+ generator = 1
+ depfile = build.ninja.d
+
+subninja toolchain.ninja
+
+build default: phony obj/default.stamp
+build c++-runtime-deps: phony obj/build/config/clang/c++-runtime-deps.stamp
+build clang-runtime-libs: phony obj/build/config/clang/clang-runtime-libs.stamp
+build dhrystone: phony obj/src/dhrystone/dhrystone.stamp
+build dhrystone_cmx: phony obj/src/dhrystone/dhrystone_cmx.stamp
+build dhrystone_package: phony obj/src/dhrystone/dhrystone_package.stamp
+build dhrystone_package__archive-manifest: phony obj/src/dhrystone/dhrystone_package__archive-manifest.stamp
+build dhrystone_package__archive-metadata: phony obj/src/dhrystone/dhrystone_package__archive-metadata.stamp
+build dhrystone_packaged_components_metadata: phony obj/src/dhrystone/dhrystone_packaged_components_metadata.stamp
+build fdio: phony obj/third_party/fuchsia-sdk/pkg/fdio/libfdio.a
+build fdio_dist_libs: phony obj/third_party/fuchsia-sdk/pkg/fdio/fdio_dist_libs.stamp
+build runtime_library_group: phony obj/third_party/fuchsia-sdk/build/config/runtime_library_group.stamp
+build sysroot_dist_libs: phony obj/third_party/fuchsia-sdk/build/config/sysroot_dist_libs.stamp
+build zx: phony obj/third_party/fuchsia-sdk/pkg/zx/libzx.a
+build $:default: phony obj/default.stamp
+build build/config/clang$:c++-runtime-deps: phony obj/build/config/clang/c++-runtime-deps.stamp
+build build/config/clang$:clang-runtime-libs: phony obj/build/config/clang/clang-runtime-libs.stamp
+build src/dhrystone$:dhrystone: phony obj/src/dhrystone/dhrystone.stamp
+build src/dhrystone: phony obj/src/dhrystone/dhrystone.stamp
+build src/dhrystone$:dhrystone_bin: phony ./dhrystone_bin
+build src/dhrystone$:dhrystone_cmx: phony obj/src/dhrystone/dhrystone_cmx.stamp
+build src/dhrystone$:dhrystone_package: phony obj/src/dhrystone/dhrystone_package.stamp
+build src/dhrystone$:dhrystone_package__archive-manifest: phony obj/src/dhrystone/dhrystone_package__archive-manifest.stamp
+build src/dhrystone$:dhrystone_package__archive-metadata: phony obj/src/dhrystone/dhrystone_package__archive-metadata.stamp
+build src/dhrystone$:dhrystone_packaged_components_metadata: phony obj/src/dhrystone/dhrystone_packaged_components_metadata.stamp
+build third_party/fuchsia-sdk/build/config$:runtime_library_group: phony obj/third_party/fuchsia-sdk/build/config/runtime_library_group.stamp
+build third_party/fuchsia-sdk/build/config$:sysroot_dist_libs: phony obj/third_party/fuchsia-sdk/build/config/sysroot_dist_libs.stamp
+build third_party/fuchsia-sdk/pkg/fdio$:all: phony obj/third_party/fuchsia-sdk/pkg/fdio/all.stamp
+build third_party/fuchsia-sdk/pkg/fdio$:fdio: phony obj/third_party/fuchsia-sdk/pkg/fdio/libfdio.a
+build third_party/fuchsia-sdk/pkg/fdio: phony obj/third_party/fuchsia-sdk/pkg/fdio/libfdio.a
+build third_party/fuchsia-sdk/pkg/fdio$:fdio_dist_libs: phony obj/third_party/fuchsia-sdk/pkg/fdio/fdio_dist_libs.stamp
+build third_party/fuchsia-sdk/pkg/zx$:all: phony obj/third_party/fuchsia-sdk/pkg/zx/all.stamp
+build third_party/fuchsia-sdk/pkg/zx$:zx: phony obj/third_party/fuchsia-sdk/pkg/zx/libzx.a
+build third_party/fuchsia-sdk/pkg/zx: phony obj/third_party/fuchsia-sdk/pkg/zx/libzx.a
+
+build all: phony $
+ obj/default.stamp $
+ obj/build/config/clang/c++-runtime-deps.stamp $
+ obj/build/config/clang/clang-runtime-libs.stamp $
+ obj/src/dhrystone/dhrystone.stamp $
+ ./dhrystone_bin $
+ obj/src/dhrystone/dhrystone_cmx.stamp $
+ obj/src/dhrystone/dhrystone_package.stamp $
+ obj/src/dhrystone/dhrystone_package__archive-manifest.stamp $
+ obj/src/dhrystone/dhrystone_package__archive-metadata.stamp $
+ obj/src/dhrystone/dhrystone_packaged_components_metadata.stamp $
+ obj/third_party/fuchsia-sdk/build/config/runtime_library_group.stamp $
+ obj/third_party/fuchsia-sdk/build/config/sysroot_dist_libs.stamp $
+ obj/third_party/fuchsia-sdk/pkg/fdio/all.stamp $
+ obj/third_party/fuchsia-sdk/pkg/fdio/libfdio.a $
+ obj/third_party/fuchsia-sdk/pkg/fdio/fdio_dist_libs.stamp $
+ obj/third_party/fuchsia-sdk/pkg/zx/all.stamp $
+ obj/third_party/fuchsia-sdk/pkg/zx/libzx.a
+
+default default
diff --git a/out/core.astro-release/build.ninja.d b/out/core.astro-release/build.ninja.d
new file mode 100644
index 0000000..3633f6f
--- /dev/null
+++ b/out/core.astro-release/build.ninja.d
@@ -0,0 +1 @@
+build.ninja: ../../.gn ../../BUILD.gn ../../build/BUILD.gn ../../build/BUILDCONFIG.gn ../../build/config/BUILD.gn ../../build/config/clang/BUILD.gn ../../build/config/clang/clang.gni ../../build/config/compiler/BUILD.gn ../../build/toolchain/clang_toolchain.gni ../../build/toolchain/fuchsia/BUILD.gn ./args.gn ../../src/dhrystone/BUILD.gn ../../third_party/fuchsia-sdk/build/cmc.gni ../../third_party/fuchsia-sdk/build/component.gni ../../third_party/fuchsia-sdk/build/config/BUILD.gn ../../third_party/fuchsia-sdk/build/config/config.gni ../../third_party/fuchsia-sdk/build/fuchsia_sdk_pkg.gni ../../third_party/fuchsia-sdk/build/package.gni ../../third_party/fuchsia-sdk/build/pm_tool.gni ../../third_party/fuchsia-sdk/meta/manifest.json ../../third_party/fuchsia-sdk/pkg/fdio/BUILD.gn ../../third_party/fuchsia-sdk/pkg/zx/BUILD.gn
\ No newline at end of file
diff --git a/out/core.astro-release/dhrystone_bin b/out/core.astro-release/dhrystone_bin
new file mode 100755
index 0000000..6372bec
--- /dev/null
+++ b/out/core.astro-release/dhrystone_bin
Binary files differ
diff --git a/out/core.astro-release/gen/src/dhrystone/dhrystone/dhrystone.archive_manifest b/out/core.astro-release/gen/src/dhrystone/dhrystone/dhrystone.archive_manifest
new file mode 100644
index 0000000..9bbfc68
--- /dev/null
+++ b/out/core.astro-release/gen/src/dhrystone/dhrystone/dhrystone.archive_manifest
@@ -0,0 +1,8 @@
+meta/package=gen/src/dhrystone/dhrystone/package
+lib/libfdio.so=lib/libfdio.so
+lib/libunwind.so.1=lib/libunwind.so.1
+lib/libc++.so.2=lib/libc++.so.2
+dhrystone_bin=dhrystone_bin
+lib/ld.so.1=lib/ld.so.1
+lib/libc++abi.so.1=lib/libc++abi.so.1
+meta/dhrystone.cmx=gen/src/dhrystone/dhrystone/dhrystone.cmx
diff --git a/out/core.astro-release/gen/src/dhrystone/dhrystone/dhrystone.cmx b/out/core.astro-release/gen/src/dhrystone/dhrystone/dhrystone.cmx
new file mode 100644
index 0000000..151ce0c
--- /dev/null
+++ b/out/core.astro-release/gen/src/dhrystone/dhrystone/dhrystone.cmx
@@ -0,0 +1,6 @@
+{
+ "program": {
+ "binary" : "dhrystone_bin"
+ }
+
+}
\ No newline at end of file
diff --git a/out/core.astro-release/gen/src/dhrystone/dhrystone/dhrystone.far b/out/core.astro-release/gen/src/dhrystone/dhrystone/dhrystone.far
new file mode 100644
index 0000000..45178fc
--- /dev/null
+++ b/out/core.astro-release/gen/src/dhrystone/dhrystone/dhrystone.far
Binary files differ
diff --git a/out/core.astro-release/gen/src/dhrystone/dhrystone/dhrystone.runtime_deps b/out/core.astro-release/gen/src/dhrystone/dhrystone/dhrystone.runtime_deps
new file mode 100644
index 0000000..8832193
--- /dev/null
+++ b/out/core.astro-release/gen/src/dhrystone/dhrystone/dhrystone.runtime_deps
@@ -0,0 +1,6 @@
+./dhrystone_bin
+lib/libc++.so.2
+lib/libc++abi.so.1
+lib/libunwind.so.1
+lib/ld.so.1
+lib/libfdio.so
diff --git a/out/core.astro-release/gen/src/dhrystone/dhrystone/ids.txt b/out/core.astro-release/gen/src/dhrystone/dhrystone/ids.txt
new file mode 100644
index 0000000..8ee6311
--- /dev/null
+++ b/out/core.astro-release/gen/src/dhrystone/dhrystone/ids.txt
@@ -0,0 +1,6 @@
+ff6959a5ccf92c5b ../../../../lib/libfdio.so
+393e362e6a016296 ../../../../lib/libunwind.so.1
+ef9f9272b514463a ../../../../lib/libc++abi.so.1
+d12fb0ac271c9330 ../../../../dhrystone_bin
+fa39648a29eb2f06 ../../../../lib/ld.so.1
+a03ee9f443e83e8b ../../../../lib/libc++.so.2
diff --git a/out/core.astro-release/gen/src/dhrystone/dhrystone/meta.far b/out/core.astro-release/gen/src/dhrystone/dhrystone/meta.far
new file mode 100644
index 0000000..f0a83a0
--- /dev/null
+++ b/out/core.astro-release/gen/src/dhrystone/dhrystone/meta.far
Binary files differ
diff --git a/out/core.astro-release/gen/src/dhrystone/dhrystone/meta.far.d b/out/core.astro-release/gen/src/dhrystone/dhrystone/meta.far.d
new file mode 100644
index 0000000..c9850b1
--- /dev/null
+++ b/out/core.astro-release/gen/src/dhrystone/dhrystone/meta.far.d
@@ -0,0 +1 @@
+gen/src/dhrystone/dhrystone/meta.far: lib/libfdio.so lib/libunwind.so.1 lib/ld.so.1 lib/libc++abi.so.1 gen/src/dhrystone/dhrystone/dhrystone.cmx gen/src/dhrystone/dhrystone/package lib/libc++.so.2 dhrystone_bin gen/src/dhrystone/dhrystone/dhrystone.archive_manifest
\ No newline at end of file
diff --git a/out/core.astro-release/gen/src/dhrystone/dhrystone/meta.far.merkle b/out/core.astro-release/gen/src/dhrystone/dhrystone/meta.far.merkle
new file mode 100755
index 0000000..830cdae
--- /dev/null
+++ b/out/core.astro-release/gen/src/dhrystone/dhrystone/meta.far.merkle
@@ -0,0 +1 @@
+4d77989aa72b906a745fae10e2a82ad18f6ed88e51c78153ab8270ed9f866b2c
\ No newline at end of file
diff --git a/out/core.astro-release/gen/src/dhrystone/dhrystone/meta/contents b/out/core.astro-release/gen/src/dhrystone/dhrystone/meta/contents
new file mode 100755
index 0000000..c17f061
--- /dev/null
+++ b/out/core.astro-release/gen/src/dhrystone/dhrystone/meta/contents
@@ -0,0 +1,6 @@
+dhrystone_bin=a5ad491ae86ed86ab1fdadcc7af9ba2db0e1cb86c064ae4305c1d103312351bd
+lib/ld.so.1=452412abbe2649d773f3e62a373262cd802c4c6991e7e693f01d72d284aa84bb
+lib/libc++.so.2=2b154f638d98d9b899656da322a954c8ccbebe6c4950ac2ae8fdc853dd8a8a45
+lib/libc++abi.so.1=7cbbb4cfc47887848061dc83b250af42db252682e6d64a84ddd4974a8bc9412e
+lib/libfdio.so=e53c82434c34b3390478e8a7acebb483999046894a192fe8e72f977dc0f4eb24
+lib/libunwind.so.1=80eae8a517234fe02ff42de4d3cccfebfa234c752361caf31eacb442bb1af5c4
diff --git a/out/core.astro-release/gen/src/dhrystone/dhrystone/package b/out/core.astro-release/gen/src/dhrystone/dhrystone/package
new file mode 100644
index 0000000..a365baf
--- /dev/null
+++ b/out/core.astro-release/gen/src/dhrystone/dhrystone/package
@@ -0,0 +1 @@
+{"version": "0", "name": "dhrystone"}
\ No newline at end of file
diff --git a/out/core.astro-release/gen/src/dhrystone/dhrystone/package_manifest.json b/out/core.astro-release/gen/src/dhrystone/dhrystone/package_manifest.json
new file mode 100644
index 0000000..8083234
--- /dev/null
+++ b/out/core.astro-release/gen/src/dhrystone/dhrystone/package_manifest.json
@@ -0,0 +1,51 @@
+{
+ "version": "1",
+ "package": {
+ "name": "dhrystone",
+ "version": "0"
+ },
+ "blobs": [
+ {
+ "source_path": "gen/src/dhrystone/dhrystone/meta.far",
+ "path": "meta/",
+ "merkle": "4d77989aa72b906a745fae10e2a82ad18f6ed88e51c78153ab8270ed9f866b2c",
+ "size": 16384
+ },
+ {
+ "source_path": "dhrystone_bin",
+ "path": "dhrystone_bin",
+ "merkle": "a5ad491ae86ed86ab1fdadcc7af9ba2db0e1cb86c064ae4305c1d103312351bd",
+ "size": 201792
+ },
+ {
+ "source_path": "lib/ld.so.1",
+ "path": "lib/ld.so.1",
+ "merkle": "452412abbe2649d773f3e62a373262cd802c4c6991e7e693f01d72d284aa84bb",
+ "size": 660184
+ },
+ {
+ "source_path": "lib/libc++.so.2",
+ "path": "lib/libc++.so.2",
+ "merkle": "2b154f638d98d9b899656da322a954c8ccbebe6c4950ac2ae8fdc853dd8a8a45",
+ "size": 853560
+ },
+ {
+ "source_path": "lib/libc++abi.so.1",
+ "path": "lib/libc++abi.so.1",
+ "merkle": "7cbbb4cfc47887848061dc83b250af42db252682e6d64a84ddd4974a8bc9412e",
+ "size": 329176
+ },
+ {
+ "source_path": "lib/libfdio.so",
+ "path": "lib/libfdio.so",
+ "merkle": "e53c82434c34b3390478e8a7acebb483999046894a192fe8e72f977dc0f4eb24",
+ "size": 311984
+ },
+ {
+ "source_path": "lib/libunwind.so.1",
+ "path": "lib/libunwind.so.1",
+ "merkle": "80eae8a517234fe02ff42de4d3cccfebfa234c752361caf31eacb442bb1af5c4",
+ "size": 198024
+ }
+ ]
+}
\ No newline at end of file
diff --git a/out/core.astro-release/gen/src/dhrystone/dhrystone_package_stamp.d b/out/core.astro-release/gen/src/dhrystone/dhrystone_package_stamp.d
new file mode 100644
index 0000000..ec0b6f1
--- /dev/null
+++ b/out/core.astro-release/gen/src/dhrystone/dhrystone_package_stamp.d
@@ -0,0 +1 @@
+gen/src/dhrystone/dhrystone/dhrystone.archive_manifest: lib/libfdio.so lib/libunwind.so.1 lib/libc++.so.2 dhrystone_bin lib/ld.so.1 lib/libc++abi.so.1
\ No newline at end of file
diff --git a/out/core.astro-release/gen/src/dhrystone/dhrystone_packaged_components_metadata.json b/out/core.astro-release/gen/src/dhrystone/dhrystone_packaged_components_metadata.json
new file mode 100644
index 0000000..7aeceac
--- /dev/null
+++ b/out/core.astro-release/gen/src/dhrystone/dhrystone_packaged_components_metadata.json
@@ -0,0 +1,14 @@
+[
+ [
+ {
+ "source": "/usr/local/google/home/pshickel/src/fuchsia-benchmarks/src/dhrystone/:dhrystone_bin",
+ "type": "dep"
+ },
+ {
+ "manifest_version": "v1",
+ "output_name": "dhrystone",
+ "source": "/usr/local/google/home/pshickel/src/fuchsia-benchmarks/src/dhrystone/dhrystone.cmx",
+ "type": "manifest"
+ }
+ ]
+]
\ No newline at end of file
diff --git a/out/core.astro-release/lib/ld.so.1 b/out/core.astro-release/lib/ld.so.1
new file mode 100755
index 0000000..1d39253
--- /dev/null
+++ b/out/core.astro-release/lib/ld.so.1
Binary files differ
diff --git a/out/core.astro-release/lib/libc++.so.2 b/out/core.astro-release/lib/libc++.so.2
new file mode 100755
index 0000000..dc9d316
--- /dev/null
+++ b/out/core.astro-release/lib/libc++.so.2
Binary files differ
diff --git a/out/core.astro-release/lib/libc++abi.so.1 b/out/core.astro-release/lib/libc++abi.so.1
new file mode 100755
index 0000000..5eb0a55
--- /dev/null
+++ b/out/core.astro-release/lib/libc++abi.so.1
Binary files differ
diff --git a/out/core.astro-release/lib/libfdio.so b/out/core.astro-release/lib/libfdio.so
new file mode 100755
index 0000000..47ef705
--- /dev/null
+++ b/out/core.astro-release/lib/libfdio.so
Binary files differ
diff --git a/out/core.astro-release/lib/libunwind.so.1 b/out/core.astro-release/lib/libunwind.so.1
new file mode 100755
index 0000000..39bba3b
--- /dev/null
+++ b/out/core.astro-release/lib/libunwind.so.1
Binary files differ
diff --git a/out/core.astro-release/obj/build/config/clang/c++-runtime-deps.stamp b/out/core.astro-release/obj/build/config/clang/c++-runtime-deps.stamp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/out/core.astro-release/obj/build/config/clang/c++-runtime-deps.stamp
diff --git a/out/core.astro-release/obj/build/config/clang/clang-runtime-libs.stamp b/out/core.astro-release/obj/build/config/clang/clang-runtime-libs.stamp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/out/core.astro-release/obj/build/config/clang/clang-runtime-libs.stamp
diff --git a/out/core.astro-release/obj/default.stamp b/out/core.astro-release/obj/default.stamp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/out/core.astro-release/obj/default.stamp
diff --git a/out/core.astro-release/obj/src/dhrystone/dhrystone.stamp b/out/core.astro-release/obj/src/dhrystone/dhrystone.stamp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/out/core.astro-release/obj/src/dhrystone/dhrystone.stamp
diff --git a/out/core.astro-release/obj/src/dhrystone/dhrystone_bin.ninja b/out/core.astro-release/obj/src/dhrystone/dhrystone_bin.ninja
new file mode 100644
index 0000000..34b47d1
--- /dev/null
+++ b/out/core.astro-release/obj/src/dhrystone/dhrystone_bin.ninja
@@ -0,0 +1,17 @@
+defines = -DFUCHSIA_SDK_VERSION=0.20200420.1.1 -DNDEBUG -DNVALGRIND -DDYNAMIC_ANNOTATIONS_ENABLED=0
+include_dirs = -I../.. -Igen -I../../third_party/fuchsia-sdk/pkg/zx/include
+cflags = -Wall -pedantic -O3 -ffast-math -I src -DTIME -fno-strict-aliasing -fcolor-diagnostics -fmerge-all-constants -fcomplete-member-pointers -Xclang -mllvm -Xclang -instcombine-lower-dbg-declare=0 -fPIC -O2 -fno-ident -fdata-sections -ffunction-sections -g0 -Wheader-hygiene -Wstring-conversion -Wtautological-overlap-compare -fvisibility=hidden --target=aarch64-fuchsia --sysroot=../../third_party/fuchsia-sdk/arch/arm64/sysroot -fomit-frame-pointer
+cflags_cc = -std=c++14 -isystem../../buildtools/linux64/clang-linux-amd64 -fno-exceptions -fno-rtti -fvisibility-inlines-hidden
+label_name = dhrystone_bin
+target_out_dir = obj/src/dhrystone
+target_output_name = dhrystone_bin
+
+build obj/src/dhrystone/dhrystone_bin/dhry_1.o: cxx ../../src/dhrystone/dhry_1.cc
+build obj/src/dhrystone/dhrystone_bin/dhry_2.o: cxx ../../src/dhrystone/dhry_2.cc
+
+build ./dhrystone_bin: link obj/src/dhrystone/dhrystone_bin/dhry_1.o obj/src/dhrystone/dhrystone_bin/dhry_2.o obj/third_party/fuchsia-sdk/pkg/zx/libzx.a || obj/third_party/fuchsia-sdk/build/config/runtime_library_group.stamp obj/build/config/clang/c++-runtime-deps.stamp
+ ldflags = -fPIC -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,-z,defs -Wl,--as-needed -Wl,-O2 -Wl,--gc-sections -Wl,--no-as-needed -lfdio -Wl,--as-needed --target=aarch64-fuchsia --sysroot=../../third_party/fuchsia-sdk/arch/arm64/sysroot -Wl,-rpath=\$$ORIGIN/ -Wl,-rpath-link= -L../../third_party/fuchsia-sdk/arch/arm64/lib
+ libs = -lpthread -lzircon
+ frameworks =
+ output_extension =
+ output_dir = .
diff --git a/out/core.astro-release/obj/src/dhrystone/dhrystone_bin/dhry_1.o b/out/core.astro-release/obj/src/dhrystone/dhrystone_bin/dhry_1.o
new file mode 100644
index 0000000..b30c805
--- /dev/null
+++ b/out/core.astro-release/obj/src/dhrystone/dhrystone_bin/dhry_1.o
Binary files differ
diff --git a/out/core.astro-release/obj/src/dhrystone/dhrystone_bin/dhry_2.o b/out/core.astro-release/obj/src/dhrystone/dhrystone_bin/dhry_2.o
new file mode 100644
index 0000000..3deed83
--- /dev/null
+++ b/out/core.astro-release/obj/src/dhrystone/dhrystone_bin/dhry_2.o
Binary files differ
diff --git a/out/core.astro-release/obj/src/dhrystone/dhrystone_cmx.stamp b/out/core.astro-release/obj/src/dhrystone/dhrystone_cmx.stamp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/out/core.astro-release/obj/src/dhrystone/dhrystone_cmx.stamp
diff --git a/out/core.astro-release/obj/src/dhrystone/dhrystone_package.stamp b/out/core.astro-release/obj/src/dhrystone/dhrystone_package.stamp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/out/core.astro-release/obj/src/dhrystone/dhrystone_package.stamp
diff --git a/out/core.astro-release/obj/src/dhrystone/dhrystone_package__archive-manifest.stamp b/out/core.astro-release/obj/src/dhrystone/dhrystone_package__archive-manifest.stamp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/out/core.astro-release/obj/src/dhrystone/dhrystone_package__archive-manifest.stamp
diff --git a/out/core.astro-release/obj/src/dhrystone/dhrystone_package__archive-metadata.stamp b/out/core.astro-release/obj/src/dhrystone/dhrystone_package__archive-metadata.stamp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/out/core.astro-release/obj/src/dhrystone/dhrystone_package__archive-metadata.stamp
diff --git a/out/core.astro-release/obj/third_party/fuchsia-sdk/build/config/runtime_library_group.stamp b/out/core.astro-release/obj/third_party/fuchsia-sdk/build/config/runtime_library_group.stamp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/out/core.astro-release/obj/third_party/fuchsia-sdk/build/config/runtime_library_group.stamp
diff --git a/out/core.astro-release/obj/third_party/fuchsia-sdk/build/config/sysroot_dist_libs.stamp b/out/core.astro-release/obj/third_party/fuchsia-sdk/build/config/sysroot_dist_libs.stamp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/out/core.astro-release/obj/third_party/fuchsia-sdk/build/config/sysroot_dist_libs.stamp
diff --git a/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/fdio/fdio.ninja b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/fdio/fdio.ninja
new file mode 100644
index 0000000..c3e3100
--- /dev/null
+++ b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/fdio/fdio.ninja
@@ -0,0 +1,11 @@
+defines = -DFUCHSIA_SDK_VERSION=0.20200420.1.1 -DNDEBUG -DNVALGRIND -DDYNAMIC_ANNOTATIONS_ENABLED=0
+include_dirs = -I../.. -Igen -I../../third_party/fuchsia-sdk/pkg/fdio/include
+label_name = fdio
+target_out_dir = obj/third_party/fuchsia-sdk/pkg/fdio
+target_output_name = libfdio
+
+
+build obj/third_party/fuchsia-sdk/pkg/fdio/libfdio.a: alink || obj/third_party/fuchsia-sdk/pkg/fdio/fdio_dist_libs.stamp
+ arflags =
+ output_extension = .a
+ output_dir = obj/third_party/fuchsia-sdk/pkg/fdio
diff --git a/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/fdio/fdio_dist_libs.stamp b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/fdio/fdio_dist_libs.stamp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/fdio/fdio_dist_libs.stamp
diff --git a/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/fdio/libfdio.a b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/fdio/libfdio.a
new file mode 100644
index 0000000..8b277f0
--- /dev/null
+++ b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/fdio/libfdio.a
@@ -0,0 +1 @@
+!<arch>
diff --git a/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/libzx.a b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/libzx.a
new file mode 100644
index 0000000..5db968d
--- /dev/null
+++ b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/libzx.a
Binary files differ
diff --git a/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx.ninja b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx.ninja
new file mode 100644
index 0000000..0027893
--- /dev/null
+++ b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx.ninja
@@ -0,0 +1,35 @@
+defines = -DFUCHSIA_SDK_VERSION=0.20200420.1.1 -DNDEBUG -DNVALGRIND -DDYNAMIC_ANNOTATIONS_ENABLED=0
+include_dirs = -I../.. -Igen -I../../third_party/fuchsia-sdk/pkg/zx/include
+cflags = -fno-strict-aliasing -fcolor-diagnostics -fmerge-all-constants -fcomplete-member-pointers -Xclang -mllvm -Xclang -instcombine-lower-dbg-declare=0 -fPIC -O2 -fno-ident -fdata-sections -ffunction-sections -g0 -Wheader-hygiene -Wstring-conversion -Wtautological-overlap-compare -fvisibility=hidden --target=aarch64-fuchsia --sysroot=../../third_party/fuchsia-sdk/arch/arm64/sysroot -fomit-frame-pointer
+cflags_cc = -std=c++14 -isystem../../buildtools/linux64/clang-linux-amd64 -fno-exceptions -fno-rtti -fvisibility-inlines-hidden
+label_name = zx
+target_out_dir = obj/third_party/fuchsia-sdk/pkg/zx
+target_output_name = libzx
+
+build obj/third_party/fuchsia-sdk/pkg/zx/zx/bti.o: cxx ../../third_party/fuchsia-sdk/pkg/zx/bti.cc
+build obj/third_party/fuchsia-sdk/pkg/zx/zx/channel.o: cxx ../../third_party/fuchsia-sdk/pkg/zx/channel.cc
+build obj/third_party/fuchsia-sdk/pkg/zx/zx/debuglog.o: cxx ../../third_party/fuchsia-sdk/pkg/zx/debuglog.cc
+build obj/third_party/fuchsia-sdk/pkg/zx/zx/event.o: cxx ../../third_party/fuchsia-sdk/pkg/zx/event.cc
+build obj/third_party/fuchsia-sdk/pkg/zx/zx/eventpair.o: cxx ../../third_party/fuchsia-sdk/pkg/zx/eventpair.cc
+build obj/third_party/fuchsia-sdk/pkg/zx/zx/fifo.o: cxx ../../third_party/fuchsia-sdk/pkg/zx/fifo.cc
+build obj/third_party/fuchsia-sdk/pkg/zx/zx/guest.o: cxx ../../third_party/fuchsia-sdk/pkg/zx/guest.cc
+build obj/third_party/fuchsia-sdk/pkg/zx/zx/interrupt.o: cxx ../../third_party/fuchsia-sdk/pkg/zx/interrupt.cc
+build obj/third_party/fuchsia-sdk/pkg/zx/zx/iommu.o: cxx ../../third_party/fuchsia-sdk/pkg/zx/iommu.cc
+build obj/third_party/fuchsia-sdk/pkg/zx/zx/job.o: cxx ../../third_party/fuchsia-sdk/pkg/zx/job.cc
+build obj/third_party/fuchsia-sdk/pkg/zx/zx/pager.o: cxx ../../third_party/fuchsia-sdk/pkg/zx/pager.cc
+build obj/third_party/fuchsia-sdk/pkg/zx/zx/port.o: cxx ../../third_party/fuchsia-sdk/pkg/zx/port.cc
+build obj/third_party/fuchsia-sdk/pkg/zx/zx/process.o: cxx ../../third_party/fuchsia-sdk/pkg/zx/process.cc
+build obj/third_party/fuchsia-sdk/pkg/zx/zx/profile.o: cxx ../../third_party/fuchsia-sdk/pkg/zx/profile.cc
+build obj/third_party/fuchsia-sdk/pkg/zx/zx/resource.o: cxx ../../third_party/fuchsia-sdk/pkg/zx/resource.cc
+build obj/third_party/fuchsia-sdk/pkg/zx/zx/socket.o: cxx ../../third_party/fuchsia-sdk/pkg/zx/socket.cc
+build obj/third_party/fuchsia-sdk/pkg/zx/zx/stream.o: cxx ../../third_party/fuchsia-sdk/pkg/zx/stream.cc
+build obj/third_party/fuchsia-sdk/pkg/zx/zx/thread.o: cxx ../../third_party/fuchsia-sdk/pkg/zx/thread.cc
+build obj/third_party/fuchsia-sdk/pkg/zx/zx/timer.o: cxx ../../third_party/fuchsia-sdk/pkg/zx/timer.cc
+build obj/third_party/fuchsia-sdk/pkg/zx/zx/vcpu.o: cxx ../../third_party/fuchsia-sdk/pkg/zx/vcpu.cc
+build obj/third_party/fuchsia-sdk/pkg/zx/zx/vmar.o: cxx ../../third_party/fuchsia-sdk/pkg/zx/vmar.cc
+build obj/third_party/fuchsia-sdk/pkg/zx/zx/vmo.o: cxx ../../third_party/fuchsia-sdk/pkg/zx/vmo.cc
+
+build obj/third_party/fuchsia-sdk/pkg/zx/libzx.a: alink obj/third_party/fuchsia-sdk/pkg/zx/zx/bti.o obj/third_party/fuchsia-sdk/pkg/zx/zx/channel.o obj/third_party/fuchsia-sdk/pkg/zx/zx/debuglog.o obj/third_party/fuchsia-sdk/pkg/zx/zx/event.o obj/third_party/fuchsia-sdk/pkg/zx/zx/eventpair.o obj/third_party/fuchsia-sdk/pkg/zx/zx/fifo.o obj/third_party/fuchsia-sdk/pkg/zx/zx/guest.o obj/third_party/fuchsia-sdk/pkg/zx/zx/interrupt.o obj/third_party/fuchsia-sdk/pkg/zx/zx/iommu.o obj/third_party/fuchsia-sdk/pkg/zx/zx/job.o obj/third_party/fuchsia-sdk/pkg/zx/zx/pager.o obj/third_party/fuchsia-sdk/pkg/zx/zx/port.o obj/third_party/fuchsia-sdk/pkg/zx/zx/process.o obj/third_party/fuchsia-sdk/pkg/zx/zx/profile.o obj/third_party/fuchsia-sdk/pkg/zx/zx/resource.o obj/third_party/fuchsia-sdk/pkg/zx/zx/socket.o obj/third_party/fuchsia-sdk/pkg/zx/zx/stream.o obj/third_party/fuchsia-sdk/pkg/zx/zx/thread.o obj/third_party/fuchsia-sdk/pkg/zx/zx/timer.o obj/third_party/fuchsia-sdk/pkg/zx/zx/vcpu.o obj/third_party/fuchsia-sdk/pkg/zx/zx/vmar.o obj/third_party/fuchsia-sdk/pkg/zx/zx/vmo.o
+ arflags =
+ output_extension = .a
+ output_dir = obj/third_party/fuchsia-sdk/pkg/zx
diff --git a/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/bti.o b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/bti.o
new file mode 100644
index 0000000..f0fa4b0
--- /dev/null
+++ b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/bti.o
Binary files differ
diff --git a/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/channel.o b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/channel.o
new file mode 100644
index 0000000..a1123aa
--- /dev/null
+++ b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/channel.o
Binary files differ
diff --git a/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/debuglog.o b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/debuglog.o
new file mode 100644
index 0000000..ec743f8
--- /dev/null
+++ b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/debuglog.o
Binary files differ
diff --git a/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/event.o b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/event.o
new file mode 100644
index 0000000..787ad0f
--- /dev/null
+++ b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/event.o
Binary files differ
diff --git a/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/eventpair.o b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/eventpair.o
new file mode 100644
index 0000000..ed66dde
--- /dev/null
+++ b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/eventpair.o
Binary files differ
diff --git a/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/fifo.o b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/fifo.o
new file mode 100644
index 0000000..863ff58
--- /dev/null
+++ b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/fifo.o
Binary files differ
diff --git a/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/guest.o b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/guest.o
new file mode 100644
index 0000000..6e32f39
--- /dev/null
+++ b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/guest.o
Binary files differ
diff --git a/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/interrupt.o b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/interrupt.o
new file mode 100644
index 0000000..3d529cd
--- /dev/null
+++ b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/interrupt.o
Binary files differ
diff --git a/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/iommu.o b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/iommu.o
new file mode 100644
index 0000000..c96ec11
--- /dev/null
+++ b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/iommu.o
Binary files differ
diff --git a/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/job.o b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/job.o
new file mode 100644
index 0000000..9745437
--- /dev/null
+++ b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/job.o
Binary files differ
diff --git a/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/pager.o b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/pager.o
new file mode 100644
index 0000000..af7d0ab
--- /dev/null
+++ b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/pager.o
Binary files differ
diff --git a/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/port.o b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/port.o
new file mode 100644
index 0000000..af03506
--- /dev/null
+++ b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/port.o
Binary files differ
diff --git a/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/process.o b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/process.o
new file mode 100644
index 0000000..773741c
--- /dev/null
+++ b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/process.o
Binary files differ
diff --git a/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/profile.o b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/profile.o
new file mode 100644
index 0000000..cf22e77
--- /dev/null
+++ b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/profile.o
Binary files differ
diff --git a/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/resource.o b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/resource.o
new file mode 100644
index 0000000..353ef7a
--- /dev/null
+++ b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/resource.o
Binary files differ
diff --git a/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/socket.o b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/socket.o
new file mode 100644
index 0000000..3a87b18
--- /dev/null
+++ b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/socket.o
Binary files differ
diff --git a/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/stream.o b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/stream.o
new file mode 100644
index 0000000..b1df1c1
--- /dev/null
+++ b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/stream.o
Binary files differ
diff --git a/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/thread.o b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/thread.o
new file mode 100644
index 0000000..33db1fc
--- /dev/null
+++ b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/thread.o
Binary files differ
diff --git a/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/timer.o b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/timer.o
new file mode 100644
index 0000000..d20e937
--- /dev/null
+++ b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/timer.o
Binary files differ
diff --git a/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/vcpu.o b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/vcpu.o
new file mode 100644
index 0000000..d96ce6c
--- /dev/null
+++ b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/vcpu.o
Binary files differ
diff --git a/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/vmar.o b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/vmar.o
new file mode 100644
index 0000000..c1e70c8
--- /dev/null
+++ b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/vmar.o
Binary files differ
diff --git a/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/vmo.o b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/vmo.o
new file mode 100644
index 0000000..ec486f4
--- /dev/null
+++ b/out/core.astro-release/obj/third_party/fuchsia-sdk/pkg/zx/zx/vmo.o
Binary files differ
diff --git a/out/core.astro-release/toolchain.ninja b/out/core.astro-release/toolchain.ninja
new file mode 100644
index 0000000..c507c7d
--- /dev/null
+++ b/out/core.astro-release/toolchain.ninja
@@ -0,0 +1,91 @@
+rule solink
+ command = ../../buildtools/linux64/clang-linux-amd64/bin/clang++ -shared ${ldflags} -o "${output_dir}/${target_output_name}${output_extension}" -Wl,-soname="${target_output_name}${output_extension}" @"${output_dir}/${target_output_name}${output_extension}.rsp"
+ description = SOLINK ${output_dir}/${target_output_name}${output_extension}
+ rspfile = ${output_dir}/${target_output_name}${output_extension}.rsp
+ rspfile_content = -Wl,--whole-archive ${in} ${solibs} -Wl,--no-whole-archive ${libs}
+ restat = 1
+rule alink
+ command = rm -f ${out} && "../../buildtools/linux64/clang-linux-amd64/bin/llvm-ar" ${arflags} -r -c -s -D ${out} @"${out}.rsp"
+ description = AR ${out}
+ rspfile = ${out}.rsp
+ rspfile_content = ${in}
+rule stamp
+ command = touch ${out}
+ description = STAMP ${out}
+rule link
+ command = ../../buildtools/linux64/clang-linux-amd64/bin/clang++ ${ldflags} -o "${output_dir}/${target_output_name}${output_extension}" -Wl,--start-group @"${output_dir}/${target_output_name}${output_extension}.rsp" ${solibs} -Wl,--end-group ${libs}
+ description = LINK ${output_dir}/${target_output_name}${output_extension}
+ rspfile = ${output_dir}/${target_output_name}${output_extension}.rsp
+ rspfile_content = ${in}
+rule cxx
+ command = ../../buildtools/linux64/clang-linux-amd64/bin/clang++ -MMD -MF ${out}.d ${defines} ${include_dirs} ${cflags} ${cflags_cc} -c ${in} -o ${out}
+ description = CXX ${out}
+ depfile = ${out}.d
+ deps = gcc
+rule solink_module
+ command = ../../buildtools/linux64/clang-linux-amd64/bin/clang++ -shared ${ldflags} -o "${output_dir}/${target_output_name}${output_extension}" -Wl,-soname="${target_output_name}${output_extension}" @"${output_dir}/${target_output_name}${output_extension}.rsp"
+ description = SOLINK_MODULE ${output_dir}/${target_output_name}${output_extension}
+ rspfile = ${output_dir}/${target_output_name}${output_extension}.rsp
+ rspfile_content = -Wl,--whole-archive ${in} ${solibs} -Wl,--no-whole-archive ${libs}
+rule cc
+ command = ../../buildtools/linux64/clang-linux-amd64/bin/clang -MMD -MF ${out}.d ${defines} ${include_dirs} ${cflags} ${cflags_c} -c ${in} -o ${out}
+ description = CC ${out}
+ depfile = ${out}.d
+ deps = gcc
+rule asm
+ command = ../../buildtools/linux64/clang-linux-amd64/bin/clang -MMD -MF ${out}.d ${defines} ${include_dirs} ${asmflags} -c ${in} -o ${out}
+ description = ASM ${out}
+ depfile = ${out}.d
+ deps = gcc
+rule copy
+ command = ln -f ${in} ${out} 2>/dev/null || (rm -rf ${out} && cp -af ${in} ${out})
+ description = COPY ${in} ${out}
+
+build obj/default.stamp: stamp obj/src/dhrystone/dhrystone.stamp
+build obj/build/config/clang/c++-runtime-deps.stamp: stamp || obj/build/config/clang/clang-runtime-libs.stamp
+build lib/libc++.so.2: copy ../../buildtools/linux64/clang-linux-amd64/lib/aarch64-unknown-fuchsia/c++/libc++.so.2.0
+build lib/libc++abi.so.1: copy ../../buildtools/linux64/clang-linux-amd64/lib/aarch64-unknown-fuchsia/c++/libc++abi.so.1.0
+build lib/libunwind.so.1: copy ../../buildtools/linux64/clang-linux-amd64/lib/aarch64-unknown-fuchsia/c++/libunwind.so.1.0
+
+build obj/build/config/clang/clang-runtime-libs.stamp: stamp lib/libc++.so.2 lib/libc++abi.so.1 lib/libunwind.so.1
+build obj/src/dhrystone/dhrystone.stamp: stamp ./dhrystone_bin obj/src/dhrystone/dhrystone_package.stamp
+subninja obj/src/dhrystone/dhrystone_bin.ninja
+build obj/src/dhrystone/dhrystone_cmx.stamp: stamp || ./dhrystone_bin
+rule __src_dhrystone_dhrystone_package___build_toolchain_fuchsia_arm64__rule
+ command = python ../../third_party/fuchsia-sdk/build/gn_run_binary.py ../../third_party/fuchsia-sdk/tools/pm -o gen/src/dhrystone/dhrystone -m gen/src/dhrystone/dhrystone/dhrystone.archive_manifest archive --output /usr/local/google/home/pshickel/src/fuchsia-benchmarks/out/core.astro-release/gen/src/dhrystone/dhrystone/dhrystone
+ description = ACTION //src/dhrystone:dhrystone_package(//build/toolchain/fuchsia:arm64)
+ restat = 1
+
+build gen/src/dhrystone/dhrystone/dhrystone.far: __src_dhrystone_dhrystone_package___build_toolchain_fuchsia_arm64__rule | ../../third_party/fuchsia-sdk/build/gn_run_binary.py ../../third_party/fuchsia-sdk/meta/manifest.json ../../third_party/fuchsia-sdk/tools/pm gen/src/dhrystone/dhrystone/dhrystone.archive_manifest gen/src/dhrystone/dhrystone/meta.far obj/src/dhrystone/dhrystone_package__archive-metadata.stamp
+
+build obj/src/dhrystone/dhrystone_package.stamp: stamp gen/src/dhrystone/dhrystone/dhrystone.far
+rule __src_dhrystone_dhrystone_package__archive-manifest___build_toolchain_fuchsia_arm64__rule
+ command = python ../../third_party/fuchsia-sdk/build/prepare_package_inputs.py --root-dir ../../ --out-dir . --app-name dhrystone --runtime-deps-file gen/src/dhrystone/dhrystone/dhrystone.runtime_deps --depfile-path gen/src/dhrystone/dhrystone_package_stamp.d --manifest-path gen/src/dhrystone/dhrystone/dhrystone.archive_manifest --build-ids-file gen/src/dhrystone/dhrystone/ids.txt --json-file /usr/local/google/home/pshickel/src/fuchsia-benchmarks/out/core.astro-release/gen/src/dhrystone/dhrystone_packaged_components_metadata.json
+ description = ACTION //src/dhrystone:dhrystone_package__archive-manifest(//build/toolchain/fuchsia:arm64)
+ restat = 1
+
+build gen/src/dhrystone/dhrystone/dhrystone.archive_manifest gen/src/dhrystone/dhrystone/ids.txt gen/src/dhrystone/dhrystone/package: __src_dhrystone_dhrystone_package__archive-manifest___build_toolchain_fuchsia_arm64__rule | ../../third_party/fuchsia-sdk/build/prepare_package_inputs.py gen/src/dhrystone/dhrystone/dhrystone.runtime_deps obj/src/dhrystone/dhrystone_cmx.stamp
+ depfile = gen/src/dhrystone/dhrystone_package_stamp.d
+
+build obj/src/dhrystone/dhrystone_package__archive-manifest.stamp: stamp gen/src/dhrystone/dhrystone/dhrystone.archive_manifest gen/src/dhrystone/dhrystone/ids.txt gen/src/dhrystone/dhrystone/package || obj/src/dhrystone/dhrystone_cmx.stamp
+rule __src_dhrystone_dhrystone_package__archive-metadata___build_toolchain_fuchsia_arm64__rule
+ command = python ../../third_party/fuchsia-sdk/build/gn_run_binary.py ../../third_party/fuchsia-sdk/tools/pm -o gen/src/dhrystone/dhrystone -m gen/src/dhrystone/dhrystone/dhrystone.archive_manifest build -depfile -output-package-manifest gen/src/dhrystone/dhrystone/package_manifest.json
+ description = ACTION //src/dhrystone:dhrystone_package__archive-metadata(//build/toolchain/fuchsia:arm64)
+ restat = 1
+
+build gen/src/dhrystone/dhrystone/meta.far gen/src/dhrystone/dhrystone/package_manifest.json: __src_dhrystone_dhrystone_package__archive-metadata___build_toolchain_fuchsia_arm64__rule | ../../third_party/fuchsia-sdk/build/gn_run_binary.py ../../third_party/fuchsia-sdk/meta/manifest.json ../../third_party/fuchsia-sdk/tools/pm gen/src/dhrystone/dhrystone/dhrystone.archive_manifest obj/src/dhrystone/dhrystone_package__archive-manifest.stamp
+ depfile = gen/src/dhrystone/dhrystone/meta.far.d
+
+build obj/src/dhrystone/dhrystone_package__archive-metadata.stamp: stamp gen/src/dhrystone/dhrystone/meta.far gen/src/dhrystone/dhrystone/package_manifest.json
+build obj/src/dhrystone/dhrystone_packaged_components_metadata.stamp: stamp obj/src/dhrystone/dhrystone_cmx.stamp
+build obj/third_party/fuchsia-sdk/build/config/runtime_library_group.stamp: stamp || obj/third_party/fuchsia-sdk/build/config/sysroot_dist_libs.stamp obj/third_party/fuchsia-sdk/pkg/fdio/libfdio.a
+build lib/ld.so.1: copy ../../third_party/fuchsia-sdk/arch/arm64/sysroot/dist/lib/ld.so.1
+
+build obj/third_party/fuchsia-sdk/build/config/sysroot_dist_libs.stamp: stamp lib/ld.so.1
+build obj/third_party/fuchsia-sdk/pkg/fdio/all.stamp: stamp obj/third_party/fuchsia-sdk/pkg/fdio/libfdio.a
+subninja obj/third_party/fuchsia-sdk/pkg/fdio/fdio.ninja
+build lib/libfdio.so: copy ../../third_party/fuchsia-sdk/arch/arm64/dist/libfdio.so
+
+build obj/third_party/fuchsia-sdk/pkg/fdio/fdio_dist_libs.stamp: stamp lib/libfdio.so
+build obj/third_party/fuchsia-sdk/pkg/zx/all.stamp: stamp obj/third_party/fuchsia-sdk/pkg/zx/libzx.a
+subninja obj/third_party/fuchsia-sdk/pkg/zx/zx.ninja
diff --git a/scripts/common.sh b/scripts/common.sh
new file mode 100755
index 0000000..c8f5654
--- /dev/null
+++ b/scripts/common.sh
@@ -0,0 +1,54 @@
+#!/bin/bash
+# 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.
+
+set -eu # Error checking
+err_print() {
+ echo "Error on line $1"
+}
+trap 'err_print $LINENO' ERR
+DEBUG_LINE() {
+ "$@"
+}
+
+function get_gn_root() {
+ ROOT_DIR="$(pwd)"
+ while [[ "${ROOT_DIR}" != "/" ]]; do
+ if [[ -f "${ROOT_DIR}/.gn" ]]; then
+ break
+ fi
+ ROOT_DIR="$(dirname "${ROOT_DIR}")"
+ done
+ if [[ "${ROOT_DIR}" == "/" ]]; then
+ echo "Error! could not find the root of the project. The current working directory needs to be under the root of the project"
+ exit 2
+ fi
+ echo "${ROOT_DIR}"
+}
+
+function get_buildtools_dir() {
+ echo "$(get_gn_root)/buildtools"
+}
+
+function get_third_party_dir() {
+ echo "$(get_gn_root)/third_party"
+}
+
+function get_depot_tools_dir() {
+ # Make the host os specific subdir
+ # The directory structure is designed to be compatibile with
+ # Chromium Depot tools
+ # see https://chromium.googlesource.com/chromium/src/+/master/docs/linux_build_instructions.md#install
+ case "$(uname -s)" in
+ Linux*) HOST_DIR="linux64";;
+ Darwin*) HOST_DIR="mac64";;
+ *) echo "Unsupported host os: $(uname -s)" && exit 1
+ esac
+ echo "$(get_buildtools_dir)/${HOST_DIR}"
+}
+
+function is-mac {
+ [[ "$(uname -s)" == "Darwin" ]] && return 0
+ return 1
+}
diff --git a/scripts/download-build-tools.sh b/scripts/download-build-tools.sh
new file mode 100755
index 0000000..9235225
--- /dev/null
+++ b/scripts/download-build-tools.sh
@@ -0,0 +1,142 @@
+#!/bin/bash
+# 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.
+
+set -eu # Error checking
+err_print() {
+ cleanup
+ echo "Error on line $1"
+}
+trap 'err_print $LINENO' ERR
+DEBUG_LINE() {
+ "$@"
+}
+
+SCRIPT_SRC_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
+FORCE=0
+
+# shellcheck disable=SC1090
+source "${SCRIPT_SRC_DIR}/common.sh" || exit $?
+REPO_ROOT="$(get_gn_root)" # finds path to REPO_ROOT
+BUILD_TOOLS_DIR="$(get_buildtools_dir)" # finds path to BUILD_TOOLS_DIR
+DEPOT_TOOLS_DIR="$(get_depot_tools_dir)" # finds path to DEPOT_TOOLS_DIR
+DOWNLOADS_DIR="${BUILD_TOOLS_DIR}/downloads"
+
+cleanup() {
+ echo "Cleaning up downloaded build tools..."
+ # Remove the download directories
+ rm -rf "${BUILD_TOOLS_DIR}" "${DEPOT_TOOLS_DIR}"
+}
+
+function usage {
+ echo "Usage: $0"
+ echo " [--force]"
+ echo " Delete build tools directory before downloading"
+}
+
+# Parse command line
+for i in "$@"
+do
+case "${i}" in
+ -f|--force)
+ FORCE=1
+ ;;
+ *)
+ # unknown option
+ usage
+ exit 1
+ ;;
+esac
+done
+
+# If force option is set, cleanup all downloaded tools
+if (( FORCE )); then
+ cleanup
+fi
+
+# Create build tools directory if it doesn't exist
+if [ ! -d "${BUILD_TOOLS_DIR}" ]; then
+ mkdir "${BUILD_TOOLS_DIR}"
+fi
+
+# Create depot tools directory if it doesn't exist
+if [[ ! -d "${DEPOT_TOOLS_DIR}" ]]; then
+ mkdir "${DEPOT_TOOLS_DIR}"
+fi
+
+# Create build tools download directory if it doesn't exist
+if [ ! -d "${DOWNLOADS_DIR}" ]; then
+ mkdir "${DOWNLOADS_DIR}"
+fi
+
+if is-mac; then
+ ARCH=mac-amd64
+else
+ ARCH=linux-amd64
+fi
+
+# Download a CIPD archive and extract it to a directory based on the name and ${ARCH}
+# download_cipd [name] [cipd-ref] [cipd-version] [cipd-architecture]
+function download_cipd {
+ CIPD_NAME="$1"
+ # Valid cipd references can be found with the command-line tool: cipd ls -r | grep $search
+ CIPD_REF="$2"
+ # Valid cipd versions can be of many types, such as "latest", a git_revision, or a version string
+ CIPD_VERSION="$3"
+ # Download for a specific architecture, if empty string then download a generic version
+ # For CIPD urls, replace /dl/ with /p/ if you want to inspect the directory in a web browser
+ if [[ "$4" == "" ]]; then
+ CIPD_URL="https://chrome-infra-packages.appspot.com/dl/${CIPD_REF}/+/${CIPD_VERSION}"
+ else
+ CIPD_URL="https://chrome-infra-packages.appspot.com/dl/${CIPD_REF}/${4}/+/${CIPD_VERSION}"
+ fi
+ CIPD_FILE="${DOWNLOADS_DIR}/${CIPD_NAME}-${ARCH}-${CIPD_VERSION}.zip"
+ CIPD_TMP="${DOWNLOADS_DIR}/tmp-${CIPD_NAME}-${ARCH}-${CIPD_VERSION}"
+ CIPD_DIR="${DOWNLOADS_DIR}/${CIPD_NAME}-${ARCH}-${CIPD_VERSION}"
+ if [ ! -f "${CIPD_FILE}" ]; then
+ mkdir -p "${DOWNLOADS_DIR}"
+ echo "Downloading ${CIPD_NAME} archive ${CIPD_URL} ..."
+ curl -L "${CIPD_URL}" -o "${CIPD_FILE}" -#
+ echo -e "Verifying ${CIPD_NAME} download ${CIPD_FILE} ...\c"
+ # CIPD will return a file containing "no such ref" if the URL is invalid, so need to verify the ZIP file
+ if ! unzip -qq -t "${CIPD_FILE}" &> /dev/null; then
+ rm -f "${CIPD_FILE}"
+ echo "Error: Downloaded archive from ${CIPD_URL} failed with invalid data"
+ exit 1
+ fi
+ rm -rf "${CIPD_TMP}" "${CIPD_DIR}"
+ echo "complete."
+ fi
+ if [ ! -d "${CIPD_DIR}" ]; then
+ echo -e "Extracting ${CIPD_NAME} archive to ${CIPD_DIR} ...\c"
+ rm -rf "${CIPD_TMP}"
+ unzip -q "${CIPD_FILE}" -d "${CIPD_TMP}"
+ ln -sf "${CIPD_NAME}-${ARCH}-${CIPD_VERSION}" "${DOWNLOADS_DIR}/${CIPD_NAME}-${ARCH}"
+ mv "${CIPD_TMP}" "${CIPD_DIR}"
+ echo "complete."
+ fi
+}
+
+# Download prebuilt binaries with specific versions known to work with the SDK.
+# These values can be found in $FUCHSIA_ROOT/integration/prebuilts but should
+# not need to be updated regularly since these tools do not change very often.
+download_cipd "clang" "fuchsia/third_party/clang" "git_revision:b25fc4123c77097c05ea221e023fa5c6a16e0f41" "${ARCH}"
+download_cipd "gn" "gn/gn" "git_revision:239533d2d91a04b3317ca9101cf7189f4e651e4d" "${ARCH}"
+download_cipd "ninja" "infra/ninja" "version:1.9.0" "${ARCH}"
+# Download python version of gsutil, not referenced by $FUCHSIA_ROOT/integration/prebuilts, with generic architecture
+download_cipd "gsutil" "infra/gsutil" "version:4.46" ""
+
+# Always refresh the symlinks because this script may have been updated
+echo -e "Rebuilding symlinks in ${DEPOT_TOOLS_DIR} ...\c"
+ln -sf "../downloads/clang-${ARCH}" "${DEPOT_TOOLS_DIR}/clang-${ARCH}"
+ln -sf "../downloads/clang-${ARCH}/bin/clang-format" "${DEPOT_TOOLS_DIR}/clang-format"
+ln -sf "../downloads/gn-${ARCH}/gn" "${DEPOT_TOOLS_DIR}/gn"
+ln -sf "../downloads/ninja-${ARCH}/ninja" "${DEPOT_TOOLS_DIR}/ninja"
+ln -sf "../downloads/gsutil-${ARCH}/gsutil" "${DEPOT_TOOLS_DIR}/gsutil"
+if [ ! -x "$(command -v gsutil)" ]; then
+ ln -sf "../../../buildtools/downloads/gsutil-${ARCH}/gsutil" "${REPO_ROOT}/third_party/fuchsia-sdk/bin/gsutil"
+fi
+echo "complete."
+
+echo "All build tools downloaded and extracted successfully to ${BUILD_TOOLS_DIR}"
diff --git a/scripts/update-fuchsia-sdk.sh b/scripts/update-fuchsia-sdk.sh
new file mode 100755
index 0000000..d485e68
--- /dev/null
+++ b/scripts/update-fuchsia-sdk.sh
@@ -0,0 +1,99 @@
+#!/bin/bash
+# Copyright 2020 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.
+
+# Specify the version of the tools to download
+if [[ "$1" == "" ]]; then
+ VER_FUCHSIA_SDK="latest"
+else
+ VER_FUCHSIA_SDK="$1"
+fi
+
+set -eu # Error checking
+err_print() {
+ cleanup
+ echo "Error on line $1"
+}
+trap 'err_print $LINENO' ERR
+DEBUG_LINE() {
+ "$@"
+}
+
+SCRIPT_SRC_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
+
+# Common functions.
+# shellcheck disable=SC1090
+source "${SCRIPT_SRC_DIR}/common.sh" || exit $?
+THIRD_PARTY_DIR="$(get_third_party_dir)" # finds path to //third_party
+FUCHSIA_SDK_DIR="${THIRD_PARTY_DIR}/fuchsia-sdk" # finds path to //third_party/fuchsia-sdk
+TMP_SDK_DOWNLOAD_DIR=$(mktemp -d)
+DOWNLOADED_SDK_PATH="${TMP_SDK_DOWNLOAD_DIR}/gn-sdk.tar.gz"
+TMP_SDK_DIR=$(mktemp -d)
+
+cleanup() {
+ # Remove the SDK downloads directory
+ if [ -f "${TMP_SDK_DOWNLOAD_DIR}" ]; then
+ rm -rf "${TMP_SDK_DOWNLOAD_DIR}"
+ fi
+ if [ -d "${TMP_SDK_DIR}" ]; then
+ rm -rf "${TMP_SDK_DIR}"
+ fi
+}
+
+if is-mac; then
+ PLATFORM="mac"
+else
+ PLATFORM="linux"
+fi
+ARCH="${PLATFORM}-amd64"
+
+# You can browse the GCS bucket from here to look for builds https://console.cloud.google.com/storage/browser/fuchsia/development
+# You can get the instance ID with the following curl commands:
+# Linux: `curl -sL "https://storage.googleapis.com/fuchsia/development/LATEST_LINUX`
+# Mac: `curl -sL "https://storage.googleapis.com/fuchsia/development/LATEST_MAC`
+# You can use the gsutil command-line tool to browse and search as well:
+# Get the instance ID:
+# Linux: `gsutil cat gs://fuchsia/development/LATEST_LINUX`
+# Mac: `gsutil cat gs://fuchsia/development/LATEST_MAC`
+# List the SDKs available for the instance ID
+# `gsutil ls -r gs://fuchsia/development/$INSTANCE_ID/sdk`
+# Download a SDK from GCS to your current directory:
+# Linux: `gsutil cp gs://fuchsia/development/$INSTANCE_ID/sdk/linux-amd64/gn.tar.gz .`
+# Mac: `gsutil cp gs://fuchsia/development/$INSTANCE_ID/sdk/mac-amd64/gn.tar.gz .`
+
+# If specified version is "latest" get the latest version number
+if [ "${VER_FUCHSIA_SDK}" == "latest" ]; then
+ PLATFORM_UPPER="$(echo "${PLATFORM}" | tr '[:lower:]' '[:upper:]')"
+ VER_FUCHSIA_SDK="$(curl -sL "https://storage.googleapis.com/fuchsia/development/LATEST_${PLATFORM_UPPER}")"
+fi
+
+echo "Downloading Fuchsia SDK ${VER_FUCHSIA_SDK} ..."
+# Example URL: https://storage.googleapis.com/fuchsia/development/8888449404525421136/sdk/linux-amd64/gn.tar.gz
+curl -sL "https://storage.googleapis.com/fuchsia/development/${VER_FUCHSIA_SDK}/sdk/${ARCH}/gn.tar.gz" -o "${DOWNLOADED_SDK_PATH}"
+echo "complete."
+echo
+
+echo "Extracting Fuchsia SDK..."
+tar -xf "${DOWNLOADED_SDK_PATH}" -C "${TMP_SDK_DIR}"
+echo "complete."
+echo
+
+
+# Delete existing SDK
+if [ -d "${FUCHSIA_SDK_DIR}" ]; then
+ echo "Removing existing SDK..."
+ # Remove entire folder and remake folder of the same name to remove hidden files
+ # e.g. third_party/fuchsia-sdk/.build-id/
+ rm -rf "${FUCHSIA_SDK_DIR}"
+ mkdir "${FUCHSIA_SDK_DIR}"
+ echo "complete."
+ echo
+fi
+
+# Copy new SDK to SDK dir
+cp -r "${TMP_SDK_DIR}/." "${FUCHSIA_SDK_DIR}"
+
+cleanup
+
+echo "New SDK downloaded and extracted successfully to ${FUCHSIA_SDK_DIR}."
diff --git a/third_party/dhrystone/BUILD.gn b/third_party/dhrystone/BUILD.gn
new file mode 100644
index 0000000..e228911
--- /dev/null
+++ b/third_party/dhrystone/BUILD.gn
@@ -0,0 +1,45 @@
+# 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.
+
+# default group
+group("dhrystone") {
+ deps = [
+ ":dhrystone_bin",
+ ]
+ if (is_fuchsia) {
+ deps += [ ":dhrystone_package" ]
+ }
+}
+
+executable("dhrystone_bin") {
+ sources = [
+ "dhry_1.cc",
+ "dhry_2.cc"
+ ]
+
+ deps = [
+ "//third_party/fuchsia-sdk/pkg/zx"
+ ]
+
+ cflags = ["-Wall", "-pedantic", "-O3", "-ffast-math", "-I", "src", "-DTIME"]
+}
+
+if (is_fuchsia) {
+ import("//third_party/fuchsia-sdk/build/component.gni")
+ import("//third_party/fuchsia-sdk/build/package.gni")
+
+ fuchsia_component("dhrystone_cmx") {
+ manifest = "dhrystone.cmx"
+ data_deps = [
+ ":dhrystone_bin",
+ ]
+ }
+
+ fuchsia_package("dhrystone_package") {
+ package_name = "dhrystone"
+ deps = [
+ ":dhrystone_cmx",
+ ]
+ }
+}
diff --git a/third_party/dhrystone/LICENSE.txt b/third_party/dhrystone/LICENSE.txt
new file mode 100644
index 0000000..d159169
--- /dev/null
+++ b/third_party/dhrystone/LICENSE.txt
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/third_party/dhrystone/dhry.h b/third_party/dhrystone/dhry.h
new file mode 100644
index 0000000..34a4ada
--- /dev/null
+++ b/third_party/dhrystone/dhry.h
@@ -0,0 +1,435 @@
+/*****************************************************************************
+ * The BYTE UNIX Benchmarks - Release 3
+ * Module: dhry.h SID: 3.4 5/15/91 19:30:21
+ *
+ *****************************************************************************
+ * Bug reports, patches, comments, suggestions should be sent to:
+ *
+ * Ben Smith, Rick Grehan or Tom Yager
+ * ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
+ *
+ *****************************************************************************
+ * Modification Log:
+ * addapted from:
+ *
+ *
+ * "DHRYSTONE" Benchmark Program
+ * -----------------------------
+ *
+ * Version: C, Version 2.1
+ *
+ * File: dhry.h (part 1 of 3)
+ *
+ * Date: May 25, 1988
+ *
+ * Author: Reinhold P. Weicker
+ * Siemens AG, AUT E 51
+ * Postfach 3220
+ * 8520 Erlangen
+ * Germany (West)
+ * Phone: [+49]-9131-7-20330
+ * (8-17 Central European Time)
+ * Usenet: ..!mcvax!unido!estevax!weicker
+ *
+ * Original Version (in Ada) published in
+ * "Communications of the ACM" vol. 27., no. 10 (Oct. 1984),
+ * pp. 1013 - 1030, together with the statistics
+ * on which the distribution of statements etc. is based.
+ *
+ * In this C version, the following C library functions are used:
+ * - strcpy, strcmp (inside the measurement loop)
+ * - printf, scanf (outside the measurement loop)
+ * In addition, Berkeley UNIX system calls "times ()" or "time ()"
+ * are used for execution time measurement. For measurements
+ * on other systems, these calls have to be changed.
+ *
+ * Collection of Results:
+ * Reinhold Weicker (address see above) and
+ *
+ * Rick Richardson
+ * PC Research. Inc.
+ * 94 Apple Orchard Drive
+ * Tinton Falls, NJ 07724
+ * Phone: (201) 834-1378 (9-17 EST)
+ * Usenet: ...!seismo!uunet!pcrat!rick
+ *
+ * Please send results to Rick Richardson and/or Reinhold Weicker.
+ * Complete information should be given on hardware and software used.
+ * Hardware information includes: Machine type, CPU, type and size
+ * of caches; for microprocessors: clock frequency, memory speed
+ * (number of wait states).
+ * Software information includes: Compiler (and runtime library)
+ * manufacturer and version, compilation switches, OS version.
+ * The Operating System version may give an indication about the
+ * compiler; Dhrystone itself performs no OS calls in the measurement loop.
+ *
+ * The complete output generated by the program should be mailed
+ * such that at least some checks for correctness can be made.
+ *
+ ***************************************************************************
+ *
+ * History: This version C/2.1 has been made for two reasons:
+ *
+ * 1) There is an obvious need for a common C version of
+ * Dhrystone, since C is at present the most popular system
+ * programming language for the class of processors
+ * (microcomputers, minicomputers) where Dhrystone is used most.
+ * There should be, as far as possible, only one C version of
+ * Dhrystone such that results can be compared without
+ * restrictions. In the past, the C versions distributed
+ * by Rick Richardson (Version 1.1) and by Reinhold Weicker
+ * had small (though not significant) differences.
+ *
+ * 2) As far as it is possible without changes to the Dhrystone
+ * statistics, optimizing compilers should be prevented from
+ * removing significant statements.
+ *
+ * This C version has been developed in cooperation with
+ * Rick Richardson (Tinton Falls, NJ), it incorporates many
+ * ideas from the "Version 1.1" distributed previously by
+ * him over the UNIX network Usenet.
+ * I also thank Chaim Benedelac (National Semiconductor),
+ * David Ditzel (SUN), Earl Killian and John Mashey (MIPS),
+ * Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley)
+ * for their help with comments on earlier versions of the
+ * benchmark.
+ *
+ * Changes: In the initialization part, this version follows mostly
+ * Rick Richardson's version distributed via Usenet, not the
+ * version distributed earlier via floppy disk by Reinhold Weicker.
+ * As a concession to older compilers, names have been made
+ * unique within the first 8 characters.
+ * Inside the measurement loop, this version follows the
+ * version previously distributed by Reinhold Weicker.
+ *
+ * At several places in the benchmark, code has been added,
+ * but within the measurement loop only in branches that
+ * are not executed. The intention is that optimizing compilers
+ * should be prevented from moving code out of the measurement
+ * loop, or from removing code altogether. Since the statements
+ * that are executed within the measurement loop have NOT been
+ * changed, the numbers defining the "Dhrystone distribution"
+ * (distribution of statements, operand types and locality)
+ * still hold. Except for sophisticated optimizing compilers,
+ * execution times for this version should be the same as
+ * for previous versions.
+ *
+ * Since it has proven difficult to subtract the time for the
+ * measurement loop overhead in a correct way, the loop check
+ * has been made a part of the benchmark. This does have
+ * an impact - though a very minor one - on the distribution
+ * statistics which have been updated for this version.
+ *
+ * All changes within the measurement loop are described
+ * and discussed in the companion paper "Rationale for
+ * Dhrystone version 2".
+ *
+ * Because of the self-imposed limitation that the order and
+ * distribution of the executed statements should not be
+ * changed, there are still cases where optimizing compilers
+ * may not generate code for some statements. To a certain
+ * degree, this is unavoidable for small synthetic benchmarks.
+ * Users of the benchmark are advised to check code listings
+ * whether code is generated for all statements of Dhrystone.
+ *
+ * Version 2.1 is identical to version 2.0 distributed via
+ * the UNIX network Usenet in March 1988 except that it corrects
+ * some minor deficiencies that were found by users of version 2.0.
+ * The only change within the measurement loop is that a
+ * non-executed "else" part was added to the "if" statement in
+ * Func_3, and a non-executed "else" part removed from Proc_3.
+ *
+ ***************************************************************************
+ *
+ * Defines: The following "Defines" are possible:
+ * -DREG=register (default: Not defined)
+ * As an approximation to what an average C programmer
+ * might do, the "register" storage class is applied
+ * (if enabled by -DREG=register)
+ * - for local variables, if they are used (dynamically)
+ * five or more times
+ * - for parameters if they are used (dynamically)
+ * six or more times
+ * Note that an optimal "register" strategy is
+ * compiler-dependent, and that "register" declarations
+ * do not necessarily lead to faster execution.
+ * -DNOSTRUCTASSIGN (default: Not defined)
+ * Define if the C compiler does not support
+ * assignment of structures.
+ * -DNOENUMS (default: Not defined)
+ * Define if the C compiler does not support
+ * enumeration types.
+ * -DTIMES (default)
+ * -DTIME
+ * The "times" function of UNIX (returning process times)
+ * or the "time" function (returning wallclock time)
+ * is used for measurement.
+ * For single user machines, "time ()" is adequate. For
+ * multi-user machines where you cannot get single-user
+ * access, use the "times ()" function. If you have
+ * neither, use a stopwatch in the dead of night.
+ * "printf"s are provided marking the points "Start Timer"
+ * and "Stop Timer". DO NOT use the UNIX "time(1)"
+ * command, as this will measure the total time to
+ * run this program, which will (erroneously) include
+ * the time to allocate storage (malloc) and to perform
+ * the initialization.
+ * -DHZ=nnn
+ * In Berkeley UNIX, the function "times" returns process
+ * time in 1/HZ seconds, with HZ = 60 for most systems.
+ * CHECK YOUR SYSTEM DESCRIPTION BEFORE YOU JUST APPLY
+ * A VALUE.
+ *
+ ***************************************************************************
+ *
+ * Compilation model and measurement (IMPORTANT):
+ *
+ * This C version of Dhrystone consists of three files:
+ * - dhry.h (this file, containing global definitions and comments)
+ * - dhry_1.c (containing the code corresponding to Ada package Pack_1)
+ * - dhry_2.c (containing the code corresponding to Ada package Pack_2)
+ *
+ * The following "ground rules" apply for measurements:
+ * - Separate compilation
+ * - No procedure merging
+ * - Otherwise, compiler optimizations are allowed but should be indicated
+ * - Default results are those without register declarations
+ * See the companion paper "Rationale for Dhrystone Version 2" for a more
+ * detailed discussion of these ground rules.
+ *
+ * For 16-Bit processors (e.g. 80186, 80286), times for all compilation
+ * models ("small", "medium", "large" etc.) should be given if possible,
+ * together with a definition of these models for the compiler system used.
+ *
+ **************************************************************************
+ *
+ * Dhrystone (C version) statistics:
+ *
+ * [Comment from the first distribution, updated for version 2.
+ * Note that because of language differences, the numbers are slightly
+ * different from the Ada version.]
+ *
+ * The following program contains statements of a high level programming
+ * language (here: C) in a distribution considered representative:
+ *
+ * assignments 52 (51.0 %)
+ * control statements 33 (32.4 %)
+ * procedure, function calls 17 (16.7 %)
+ *
+ * 103 statements are dynamically executed. The program is balanced with
+ * respect to the three aspects:
+ *
+ * - statement type
+ * - operand type
+ * - operand locality
+ * operand global, local, parameter, or constant.
+ *
+ * The combination of these three aspects is balanced only approximately.
+ *
+ * 1. Statement Type:
+ * ----------------- number
+ *
+ * V1 = V2 9
+ * (incl. V1 = F(..)
+ * V = Constant 12
+ * Assignment, 7
+ * with array element
+ * Assignment, 6
+ * with record component
+ * --
+ * 34 34
+ *
+ * X = Y +|-|"&&"|"|" Z 5
+ * X = Y +|-|"==" Constant 6
+ * X = X +|- 1 3
+ * X = Y *|/ Z 2
+ * X = Expression, 1
+ * two operators
+ * X = Expression, 1
+ * three operators
+ * --
+ * 18 18
+ *
+ * if .... 14
+ * with "else" 7
+ * without "else" 7
+ * executed 3
+ * not executed 4
+ * for ... 7 | counted every time
+ * while ... 4 | the loop condition
+ * do ... while 1 | is evaluated
+ * switch ... 1
+ * break 1
+ * declaration with 1
+ * initialization
+ * --
+ * 34 34
+ *
+ * P (...) procedure call 11
+ * user procedure 10
+ * library procedure 1
+ * X = F (...)
+ * function call 6
+ * user function 5
+ * library function 1
+ * --
+ * 17 17
+ * ---
+ * 103
+ *
+ * The average number of parameters in procedure or function calls
+ * is 1.82 (not counting the function values as implicit parameters).
+ *
+ *
+ * 2. Operators
+ * ------------
+ * number approximate
+ * percentage
+ *
+ * Arithmetic 32 50.8
+ *
+ * + 21 33.3
+ * - 7 11.1
+ * * 3 4.8
+ * / (int div) 1 1.6
+ *
+ * Comparison 27 42.8
+ *
+ * == 9 14.3
+ * /= 4 6.3
+ * > 1 1.6
+ * < 3 4.8
+ * >= 1 1.6
+ * <= 9 14.3
+ *
+ * Logic 4 6.3
+ *
+ * && (AND-THEN) 1 1.6
+ * | (OR) 1 1.6
+ * ! (NOT) 2 3.2
+ *
+ * -- -----
+ * 63 100.1
+ *
+ *
+ * 3. Operand Type (counted once per operand reference):
+ * ---------------
+ * number approximate
+ * percentage
+ *
+ * Integer 175 72.3 %
+ * Character 45 18.6 %
+ * Pointer 12 5.0 %
+ * String30 6 2.5 %
+ * Array 2 0.8 %
+ * Record 2 0.8 %
+ * --- -------
+ * 242 100.0 %
+ *
+ * When there is an access path leading to the final operand (e.g. a record
+ * component), only the final data type on the access path is counted.
+ *
+ *
+ * 4. Operand Locality:
+ * -------------------
+ * number approximate
+ * percentage
+ *
+ * local variable 114 47.1 %
+ * global variable 22 9.1 %
+ * parameter 45 18.6 %
+ * value 23 9.5 %
+ * reference 22 9.1 %
+ * function result 6 2.5 %
+ * constant 55 22.7 %
+ * --- -------
+ * 242 100.0 %
+ *
+ *
+ * The program does not compute anything meaningful, but it is syntactically
+ * and semantically correct. All variables have a value assigned to them
+ * before they are used as a source operand.
+ *
+ * There has been no explicit effort to account for the effects of a
+ * cache, or to balance the use of long or short displacements for code or
+ * data.
+ *
+ ***************************************************************************
+ */
+
+
+/* Compiler and system dependent definitions: */
+
+#ifndef TIME
+#define TIMES
+#endif
+ /* Use times(2) time function unless */
+ /* explicitly defined otherwise */
+
+#ifdef TIMES
+#include <sys/types.h>
+#include <sys/times.h>
+ /* for "times" */
+#endif
+
+#define Mic_secs_Per_Second 1000000.0
+ /* Berkeley UNIX C returns process times in seconds/HZ */
+
+#ifdef NOSTRUCTASSIGN
+#define structassign(d, s) memcpy(&(d), &(s), sizeof(d))
+#else
+#define structassign(d, s) d = s
+#endif
+
+#ifdef NOENUM
+#define Ident_1 0
+#define Ident_2 1
+#define Ident_3 2
+#define Ident_4 3
+#define Ident_5 4
+ typedef int Enumeration;
+#else
+ typedef enum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5}
+ Enumeration;
+#endif
+ /* for boolean and enumeration types in Ada, Pascal */
+
+/* General definitions: */
+
+#include <stdio.h>
+ /* for strcpy, strcmp */
+
+#define Null 0
+ /* Value of a Null pointer */
+#define true 1
+#define false 0
+
+typedef int One_Thirty;
+typedef int One_Fifty;
+typedef char Capital_Letter;
+typedef int Boolean;
+typedef char Str_30 [31];
+typedef int Arr_1_Dim [50];
+typedef int Arr_2_Dim [50] [50];
+
+typedef struct record
+ {
+ struct record *Ptr_Comp;
+ Enumeration Discr;
+ union {
+ struct {
+ Enumeration Enum_Comp;
+ int Int_Comp;
+ char Str_Comp [31];
+ } var_1;
+ struct {
+ Enumeration E_Comp_2;
+ char Str_2_Comp [31];
+ } var_2;
+ struct {
+ char Ch_1_Comp;
+ char Ch_2_Comp;
+ } var_3;
+ } variant;
+ } Rec_Type, *Rec_Pointer;
+
diff --git a/third_party/dhrystone/dhry_1.cc b/third_party/dhrystone/dhry_1.cc
new file mode 100644
index 0000000..cbfc476
--- /dev/null
+++ b/third_party/dhrystone/dhry_1.cc
@@ -0,0 +1,430 @@
+/*****************************************************************************
+ * The BYTE UNIX Benchmarks - Release 3
+ * Module: dhry_1.c SID: 3.4 5/15/91 19:30:21
+ *
+ *****************************************************************************
+ * Bug reports, patches, comments, suggestions should be sent to:
+ *
+ * Ben Smith, Rick Grehan or Tom Yager
+ * ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
+ *
+ *****************************************************************************
+ *
+ * *** WARNING **** With BYTE's modifications applied, results obtained with
+ * ******* this version of the Dhrystone program may not be applicable
+ * to other versions.
+ *
+ * Modification Log:
+ * 10/22/97 - code cleanup to remove ANSI C compiler warnings
+ * Andy Kahn <kahn@zk3.dec.com>
+ *
+ * Adapted from:
+ *
+ * "DHRYSTONE" Benchmark Program
+ * -----------------------------
+ *
+ * Version: C, Version 2.1
+ *
+ * File: dhry_1.c (part 2 of 3)
+ *
+ * Date: May 25, 1988
+ *
+ * Author: Reinhold P. Weicker
+ *
+ ***************************************************************************/
+char SCCSid[] = "@(#) @(#)dhry_1.c:3.4 -- 5/15/91 19:30:21";
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "dhry.h"
+#include "timeit.c"
+#include <atomic>
+
+// unsigned long Run_Index;
+std::atomic<unsigned long> Run_Index;
+
+void report()
+{
+ fprintf(stderr,"COUNT|%ld|1|lps\n", Run_Index.load());
+ exit(0);
+}
+
+/* Global Variables: */
+
+Rec_Pointer Ptr_Glob,
+ Next_Ptr_Glob;
+int Int_Glob;
+Boolean Bool_Glob;
+char Ch_1_Glob,
+ Ch_2_Glob;
+int Arr_1_Glob [50];
+int Arr_2_Glob [50] [50];
+
+// Enumeration Func_1 ();
+Enumeration Func_1 (Capital_Letter, Capital_Letter);
+ /* forward declaration necessary since Enumeration may not simply be int */
+
+#ifndef REG
+ Boolean Reg = false;
+#define REG
+ /* REG becomes defined as empty */
+ /* i.e. no register variables */
+#else
+ Boolean Reg = true;
+#endif
+
+/* variables for time measurement: */
+
+#ifdef TIMES
+#include <time.h>
+#include <sys/times.h>
+#define Too_Small_Time 120
+ /* Measurements should last at least about 2 seconds */
+#endif
+#ifdef TIME
+#include <time.h>
+#define Too_Small_Time 2
+ /* Measurements should last at least 2 seconds */
+#endif
+
+long Begin_Time,
+ End_Time,
+ User_Time;
+float Microseconds,
+ Dhrystones_Per_Second;
+
+/* end of variables for time measurement */
+
+void Proc_1 (REG Rec_Pointer Ptr_Val_Par);
+void Proc_2 (One_Fifty *Int_Par_Ref);
+void Proc_3 (Rec_Pointer *Ptr_Ref_Par);
+void Proc_4 (void);
+void Proc_5 (void);
+
+
+extern Boolean Func_2(Str_30, Str_30);
+extern void Proc_6(Enumeration, Enumeration *);
+extern void Proc_7(One_Fifty, One_Fifty, One_Fifty *);
+extern void Proc_8(Arr_1_Dim, Arr_2_Dim, int, int);
+
+int main (int argc, char *argv[])
+ /* main program, corresponds to procedures */
+ /* Main and Proc_0 in the Ada version */
+{
+ int duration;
+ One_Fifty Int_1_Loc;
+ REG One_Fifty Int_2_Loc;
+ One_Fifty Int_3_Loc;
+ REG char Ch_Index;
+ Enumeration Enum_Loc;
+ Str_30 Str_1_Loc;
+ Str_30 Str_2_Loc;
+
+ /* Initializations */
+
+ Next_Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
+ Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
+
+ Ptr_Glob->Ptr_Comp = Next_Ptr_Glob;
+ Ptr_Glob->Discr = Ident_1;
+ Ptr_Glob->variant.var_1.Enum_Comp = Ident_3;
+ Ptr_Glob->variant.var_1.Int_Comp = 40;
+ strcpy (Ptr_Glob->variant.var_1.Str_Comp,
+ "DHRYSTONE PROGRAM, SOME STRING");
+ strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING");
+
+ Arr_2_Glob [8][7] = 10;
+ /* Was missing in published program. Without this statement, */
+ /* Arr_2_Glob [8][7] would have an undefined value. */
+ /* Warning: With 16-Bit processors and Number_Of_Runs > 32000, */
+ /* overflow may occur for this array element. */
+
+#ifdef PRATTLE
+ printf ("\n");
+ printf ("Dhrystone Benchmark, Version 2.1 (Language: C)\n");
+ printf ("\n");
+ if (Reg)
+ {
+ printf ("Program compiled with 'register' attribute\n");
+ printf ("\n");
+ }
+ else
+ {
+ printf ("Program compiled without 'register' attribute\n");
+ printf ("\n");
+ }
+ printf ("Please give the number of runs through the benchmark: ");
+ {
+ int n;
+ scanf ("%d", &n);
+ Number_Of_Runs = n;
+ }
+ printf ("\n");
+
+ printf ("Execution starts, %d runs through Dhrystone\n", Number_Of_Runs);
+#endif /* PRATTLE */
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s duration\n", argv[0]);
+ exit(1);
+ }
+
+ duration = atoi(argv[1]);
+ Run_Index = 0;
+ wake_me(duration, report);
+
+ /***************/
+ /* Start timer */
+ /***************/
+
+#ifdef SELF_TIMED
+#ifdef TIMES
+ times (&time_info);
+ Begin_Time = (long) time_info.tms_utime;
+#endif
+#ifdef TIME
+ Begin_Time = time ( (long *) 0);
+#endif
+#endif /* SELF_TIMED */
+
+ for (Run_Index = 1; ; Run_Index.fetch_add(1, std::memory_order_relaxed))
+ {
+
+ Proc_5();
+ Proc_4();
+ /* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */
+ Int_1_Loc = 2;
+ Int_2_Loc = 3;
+ strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
+ Enum_Loc = Ident_2;
+ Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc);
+ /* Bool_Glob == 1 */
+ while (Int_1_Loc < Int_2_Loc) /* loop body executed once */
+ {
+ Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
+ /* Int_3_Loc == 7 */
+ Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc);
+ /* Int_3_Loc == 7 */
+ Int_1_Loc += 1;
+ } /* while */
+ /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
+ Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);
+ /* Int_Glob == 5 */
+ Proc_1 (Ptr_Glob);
+ for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index)
+ /* loop body executed twice */
+ {
+ if (Enum_Loc == Func_1 (Ch_Index, 'C'))
+ /* then, not executed */
+ {
+ Proc_6 (Ident_1, &Enum_Loc);
+ strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING");
+ Int_2_Loc = Run_Index;
+ Int_Glob = Run_Index;
+ }
+ }
+ /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
+ Int_2_Loc = Int_2_Loc * Int_1_Loc;
+ Int_1_Loc = Int_2_Loc / Int_3_Loc;
+ Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;
+ /* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */
+ Proc_2 (&Int_1_Loc);
+ /* Int_1_Loc == 5 */
+
+ } /* loop "for Run_Index" */
+
+ /**************/
+ /* Stop timer */
+ /**************/
+#ifdef SELF_TIMED
+#ifdef TIMES
+ times (&time_info);
+ End_Time = (long) time_info.tms_utime;
+#endif
+#ifdef TIME
+ End_Time = time ( (long *) 0);
+#endif
+#endif /* SELF_TIMED */
+
+ /* BYTE version never executes this stuff */
+#ifdef SELF_TIMED
+ printf ("Execution ends\n");
+ printf ("\n");
+ printf ("Final values of the variables used in the benchmark:\n");
+ printf ("\n");
+ printf ("Int_Glob: %d\n", Int_Glob);
+ printf (" should be: %d\n", 5);
+ printf ("Bool_Glob: %d\n", Bool_Glob);
+ printf (" should be: %d\n", 1);
+ printf ("Ch_1_Glob: %c\n", Ch_1_Glob);
+ printf (" should be: %c\n", 'A');
+ printf ("Ch_2_Glob: %c\n", Ch_2_Glob);
+ printf (" should be: %c\n", 'B');
+ printf ("Arr_1_Glob[8]: %d\n", Arr_1_Glob[8]);
+ printf (" should be: %d\n", 7);
+ printf ("Arr_2_Glob[8][7]: %d\n", Arr_2_Glob[8][7]);
+ printf (" should be: Number_Of_Runs + 10\n");
+ printf ("Ptr_Glob->\n");
+ printf (" Ptr_Comp: %d\n", (int) Ptr_Glob->Ptr_Comp);
+ printf (" should be: (implementation-dependent)\n");
+ printf (" Discr: %d\n", Ptr_Glob->Discr);
+ printf (" should be: %d\n", 0);
+ printf (" Enum_Comp: %d\n", Ptr_Glob->variant.var_1.Enum_Comp);
+ printf (" should be: %d\n", 2);
+ printf (" Int_Comp: %d\n", Ptr_Glob->variant.var_1.Int_Comp);
+ printf (" should be: %d\n", 17);
+ printf (" Str_Comp: %s\n", Ptr_Glob->variant.var_1.Str_Comp);
+ printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n");
+ printf ("Next_Ptr_Glob->\n");
+ printf (" Ptr_Comp: %d\n", (int) Next_Ptr_Glob->Ptr_Comp);
+ printf (" should be: (implementation-dependent), same as above\n");
+ printf (" Discr: %d\n", Next_Ptr_Glob->Discr);
+ printf (" should be: %d\n", 0);
+ printf (" Enum_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp);
+ printf (" should be: %d\n", 1);
+ printf (" Int_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Int_Comp);
+ printf (" should be: %d\n", 18);
+ printf (" Str_Comp: %s\n",
+ Next_Ptr_Glob->variant.var_1.Str_Comp);
+ printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n");
+ printf ("Int_1_Loc: %d\n", Int_1_Loc);
+ printf (" should be: %d\n", 5);
+ printf ("Int_2_Loc: %d\n", Int_2_Loc);
+ printf (" should be: %d\n", 13);
+ printf ("Int_3_Loc: %d\n", Int_3_Loc);
+ printf (" should be: %d\n", 7);
+ printf ("Enum_Loc: %d\n", Enum_Loc);
+ printf (" should be: %d\n", 1);
+ printf ("Str_1_Loc: %s\n", Str_1_Loc);
+ printf (" should be: DHRYSTONE PROGRAM, 1'ST STRING\n");
+ printf ("Str_2_Loc: %s\n", Str_2_Loc);
+ printf (" should be: DHRYSTONE PROGRAM, 2'ND STRING\n");
+ printf ("\n");
+
+ User_Time = End_Time - Begin_Time;
+
+ if (User_Time < Too_Small_Time)
+ {
+ printf ("Measured time too small to obtain meaningful results\n");
+ printf ("Please increase number of runs\n");
+ printf ("\n");
+ }
+ else
+ {
+#ifdef TIME
+ Microseconds = (float) User_Time * Mic_secs_Per_Second
+ / (float) Number_Of_Runs;
+ Dhrystones_Per_Second = (float) Number_Of_Runs / (float) User_Time;
+#else
+ Microseconds = (float) User_Time * Mic_secs_Per_Second
+ / ((float) HZ * ((float) Number_Of_Runs));
+ Dhrystones_Per_Second = ((float) HZ * (float) Number_Of_Runs)
+ / (float) User_Time;
+#endif
+ printf ("Microseconds for one run through Dhrystone: ");
+ printf ("%6.1f \n", Microseconds);
+ printf ("Dhrystones per Second: ");
+ printf ("%6.1f \n", Dhrystones_Per_Second);
+ printf ("\n");
+ }
+#endif /* SELF_TIMED */
+}
+
+
+void Proc_1 (REG Rec_Pointer Ptr_Val_Par)
+ /* executed once */
+{
+ REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp;
+ /* == Ptr_Glob_Next */
+ /* Local variable, initialized with Ptr_Val_Par->Ptr_Comp, */
+ /* corresponds to "rename" in Ada, "with" in Pascal */
+
+ structassign (*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob);
+ Ptr_Val_Par->variant.var_1.Int_Comp = 5;
+ Next_Record->variant.var_1.Int_Comp
+ = Ptr_Val_Par->variant.var_1.Int_Comp;
+ Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp;
+ Proc_3 (&Next_Record->Ptr_Comp);
+ /* Ptr_Val_Par->Ptr_Comp->Ptr_Comp
+ == Ptr_Glob->Ptr_Comp */
+ if (Next_Record->Discr == Ident_1)
+ /* then, executed */
+ {
+ Next_Record->variant.var_1.Int_Comp = 6;
+ Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp,
+ &Next_Record->variant.var_1.Enum_Comp);
+ Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp;
+ Proc_7 (Next_Record->variant.var_1.Int_Comp, 10,
+ &Next_Record->variant.var_1.Int_Comp);
+ }
+ else /* not executed */
+ structassign (*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp);
+} /* Proc_1 */
+
+
+void Proc_2 (One_Fifty *Int_Par_Ref)
+ /* executed once */
+ /* *Int_Par_Ref == 1, becomes 4 */
+{
+ One_Fifty Int_Loc;
+ Enumeration Enum_Loc;
+
+ Enum_Loc = Ident_1;
+
+ Int_Loc = *Int_Par_Ref + 10;
+ do /* executed once */
+ if (Ch_1_Glob == 'A')
+ /* then, executed */
+ {
+ Int_Loc -= 1;
+ *Int_Par_Ref = Int_Loc - Int_Glob;
+ Enum_Loc = Ident_1;
+ } /* if */
+ while (Enum_Loc != Ident_1); /* true */
+} /* Proc_2 */
+
+
+void Proc_3 (Rec_Pointer *Ptr_Ref_Par)
+ /* executed once */
+ /* Ptr_Ref_Par becomes Ptr_Glob */
+{
+ if (Ptr_Glob != Null)
+ /* then, executed */
+ *Ptr_Ref_Par = Ptr_Glob->Ptr_Comp;
+ Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp);
+} /* Proc_3 */
+
+
+void Proc_4 (void) /* without parameters */
+ /* executed once */
+{
+ Boolean Bool_Loc;
+
+ Bool_Loc = Ch_1_Glob == 'A';
+ Bool_Glob = Bool_Loc | Bool_Glob;
+ Ch_2_Glob = 'B';
+} /* Proc_4 */
+
+void Proc_5 (void) /* without parameters */
+/*******/
+ /* executed once */
+{
+ Ch_1_Glob = 'A';
+ Bool_Glob = false;
+} /* Proc_5 */
+
+
+ /* Procedure for the assignment of structures, */
+ /* if the C compiler doesn't support this feature */
+#ifdef NOSTRUCTASSIGN
+memcpy (d, s, l)
+register char *d;
+register char *s;
+register int l;
+{
+ while (l--) *d++ = *s++;
+}
+#endif
+
+
diff --git a/third_party/dhrystone/dhry_2.cc b/third_party/dhrystone/dhry_2.cc
new file mode 100644
index 0000000..daac987
--- /dev/null
+++ b/third_party/dhrystone/dhry_2.cc
@@ -0,0 +1,198 @@
+/*****************************************************************************
+ * The BYTE UNIX Benchmarks - Release 3
+ * Module: dhry_2.c SID: 3.4 5/15/91 19:30:22
+ *
+ *****************************************************************************
+ * Bug reports, patches, comments, suggestions should be sent to:
+ *
+ * Ben Smith, Rick Grehan or Tom Yager
+ * ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
+ *
+ *****************************************************************************
+ * Modification Log:
+ * 10/22/97 - code cleanup to remove ANSI C compiler warnings
+ * Andy Kahn <kahn@zk3.dec.com>
+ *
+ * Adapted from:
+ *
+ * "DHRYSTONE" Benchmark Program
+ * -----------------------------
+ *
+ * **** WARNING **** See warning in n.dhry_1.c
+ *
+ * Version: C, Version 2.1
+ *
+ * File: dhry_2.c (part 3 of 3)
+ *
+ * Date: May 25, 1988
+ *
+ * Author: Reinhold P. Weicker
+ *
+ ****************************************************************************/
+/* SCCSid is defined in dhry_1.c */
+
+#include <string.h>
+#include "dhry.h"
+
+#ifndef REG
+#define REG
+ /* REG becomes defined as empty */
+ /* i.e. no register variables */
+#endif
+
+extern int Int_Glob;
+extern char Ch_1_Glob;
+
+void Proc_6(Enumeration, Enumeration *);
+void Proc_7(One_Fifty, One_Fifty, One_Fifty *);
+void Proc_8(Arr_1_Dim, Arr_2_Dim, int, int);
+Enumeration Func_1(Capital_Letter, Capital_Letter);
+Boolean Func_2(Str_30, Str_30);
+Boolean Func_3(Enumeration);
+
+void Proc_6 (Enumeration Enum_Val_Par, Enumeration *Enum_Ref_Par)
+ /* executed once */
+ /* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */
+{
+ *Enum_Ref_Par = Enum_Val_Par;
+ if (! Func_3 (Enum_Val_Par))
+ /* then, not executed */
+ *Enum_Ref_Par = Ident_4;
+ switch (Enum_Val_Par)
+ {
+ case Ident_1:
+ *Enum_Ref_Par = Ident_1;
+ break;
+ case Ident_2:
+ if (Int_Glob > 100)
+ /* then */
+ *Enum_Ref_Par = Ident_1;
+ else *Enum_Ref_Par = Ident_4;
+ break;
+ case Ident_3: /* executed */
+ *Enum_Ref_Par = Ident_2;
+ break;
+ case Ident_4: break;
+ case Ident_5:
+ *Enum_Ref_Par = Ident_3;
+ break;
+ } /* switch */
+} /* Proc_6 */
+
+void Proc_7 (One_Fifty Int_1_Par_Val, One_Fifty Int_2_Par_Val, One_Fifty *Int_Par_Ref)
+/**********************************************/
+ /* executed three times */
+ /* first call: Int_1_Par_Val == 2, Int_2_Par_Val == 3, */
+ /* Int_Par_Ref becomes 7 */
+ /* second call: Int_1_Par_Val == 10, Int_2_Par_Val == 5, */
+ /* Int_Par_Ref becomes 17 */
+ /* third call: Int_1_Par_Val == 6, Int_2_Par_Val == 10, */
+ /* Int_Par_Ref becomes 18 */
+{
+ One_Fifty Int_Loc;
+
+ Int_Loc = Int_1_Par_Val + 2;
+ *Int_Par_Ref = Int_2_Par_Val + Int_Loc;
+} /* Proc_7 */
+
+
+void Proc_8 (Arr_1_Dim Arr_1_Par_Ref, Arr_2_Dim Arr_2_Par_Ref, int Int_1_Par_Val, int Int_2_Par_Val)
+/*********************************************************************/
+ /* executed once */
+ /* Int_Par_Val_1 == 3 */
+ /* Int_Par_Val_2 == 7 */
+{
+ REG One_Fifty Int_Index;
+ REG One_Fifty Int_Loc;
+
+ Int_Loc = Int_1_Par_Val + 5;
+ Arr_1_Par_Ref [Int_Loc] = Int_2_Par_Val;
+ Arr_1_Par_Ref [Int_Loc+1] = Arr_1_Par_Ref [Int_Loc];
+ Arr_1_Par_Ref [Int_Loc+30] = Int_Loc;
+ for (Int_Index = Int_Loc; Int_Index <= Int_Loc+1; ++Int_Index)
+ Arr_2_Par_Ref [Int_Loc] [Int_Index] = Int_Loc;
+ Arr_2_Par_Ref [Int_Loc] [Int_Loc-1] += 1;
+ Arr_2_Par_Ref [Int_Loc+20] [Int_Loc] = Arr_1_Par_Ref [Int_Loc];
+ Int_Glob = 5;
+} /* Proc_8 */
+
+
+Enumeration Func_1 (Capital_Letter Ch_1_Par_Val, Capital_Letter Ch_2_Par_Val)
+/*************************************************/
+ /* executed three times */
+ /* first call: Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R' */
+ /* second call: Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C' */
+ /* third call: Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C' */
+{
+ Capital_Letter Ch_1_Loc;
+ Capital_Letter Ch_2_Loc;
+
+ Ch_1_Loc = Ch_1_Par_Val;
+ Ch_2_Loc = Ch_1_Loc;
+ if (Ch_2_Loc != Ch_2_Par_Val)
+ /* then, executed */
+ return (Ident_1);
+ else /* not executed */
+ {
+ Ch_1_Glob = Ch_1_Loc;
+ return (Ident_2);
+ }
+} /* Func_1 */
+
+
+
+Boolean Func_2 (Str_30 Str_1_Par_Ref, Str_30 Str_2_Par_Ref)
+/*************************************************/
+ /* executed once */
+ /* Str_1_Par_Ref == "DHRYSTONE PROGRAM, 1'ST STRING" */
+ /* Str_2_Par_Ref == "DHRYSTONE PROGRAM, 2'ND STRING" */
+{
+ REG One_Thirty Int_Loc;
+ Capital_Letter Ch_Loc;
+
+ Ch_Loc = 'A';
+ Int_Loc = 2;
+ while (Int_Loc <= 2) /* loop body executed once */
+ if (Func_1 (Str_1_Par_Ref[Int_Loc],
+ Str_2_Par_Ref[Int_Loc+1]) == Ident_1)
+ /* then, executed */
+ {
+ Ch_Loc = 'A';
+ Int_Loc += 1;
+ } /* if, while */
+ if (Ch_Loc >= 'W' && Ch_Loc < 'Z')
+ /* then, not executed */
+ Int_Loc = 7;
+ if (Ch_Loc == 'R')
+ /* then, not executed */
+ return (true);
+ else /* executed */
+ {
+ if (strcmp (Str_1_Par_Ref, Str_2_Par_Ref) > 0)
+ /* then, not executed */
+ {
+ Int_Loc += 7;
+ Int_Glob = Int_Loc;
+ return (true);
+ }
+ else /* executed */
+ return (false);
+ } /* if Ch_Loc */
+} /* Func_2 */
+
+
+Boolean Func_3 (Enumeration Enum_Par_Val)
+/***************************/
+ /* executed once */
+ /* Enum_Par_Val == Ident_3 */
+{
+ Enumeration Enum_Loc;
+
+ Enum_Loc = Enum_Par_Val;
+ if (Enum_Loc == Ident_3)
+ /* then, executed */
+ return (true);
+ else /* not executed */
+ return (false);
+} /* Func_3 */
+
diff --git a/third_party/dhrystone/dhrystone.cmx b/third_party/dhrystone/dhrystone.cmx
new file mode 100644
index 0000000..151ce0c
--- /dev/null
+++ b/third_party/dhrystone/dhrystone.cmx
@@ -0,0 +1,6 @@
+{
+ "program": {
+ "binary" : "dhrystone_bin"
+ }
+
+}
\ No newline at end of file
diff --git a/third_party/dhrystone/timeit.c b/third_party/dhrystone/timeit.c
new file mode 100644
index 0000000..9d7dd7a
--- /dev/null
+++ b/third_party/dhrystone/timeit.c
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ *
+ * The BYTE UNIX Benchmarks - Release 3
+ * Module: timeit.c SID: 3.3 5/15/91 19:30:21
+ *******************************************************************************
+ * Bug reports, patches, comments, suggestions should be sent to:
+ *
+ * Ben Smith, Rick Grehan or Tom Yager
+ * ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
+ *
+ *******************************************************************************
+ * Modification Log:
+ * May 12, 1989 - modified empty loops to avoid nullifying by optimizing
+ * compilers
+ * August 28, 1990 - changed timing relationship--now returns total number
+ * of iterations (ty)
+ * October 22, 1997 - code cleanup to remove ANSI C compiler warnings
+ * Andy Kahn <kahn@zk3.dec.com>
+ *
+ ******************************************************************************/
+
+/* this module is #included in other modules--no separate SCCS ID */
+
+/*
+ * Timing routine
+ *
+ */
+
+#include <signal.h>
+#include <unistd.h>
+
+#include <pthread.h>
+#include <lib/zx/time.h>
+
+struct TimerArgs {
+ int seconds;
+ void (*func)();
+};
+
+pthread_t gTimerThread;
+TimerArgs gTimerArgs;
+
+void * timerFunc(void *arg) {
+ zx::nanosleep(zx::deadline_after(zx::sec(gTimerArgs.seconds)));
+ gTimerArgs.func();
+ return NULL;
+}
+
+void wake_me(int seconds, void (*func)())
+{
+ gTimerArgs.seconds = seconds;
+ gTimerArgs.func = func;
+
+ pthread_create(&gTimerThread, NULL, &timerFunc, NULL);
+}
+
diff --git a/third_party/fuchsia-sdk/.build-id/07/b0d3ac8f42e1e7.debug b/third_party/fuchsia-sdk/.build-id/07/b0d3ac8f42e1e7.debug
new file mode 100755
index 0000000..8695283
--- /dev/null
+++ b/third_party/fuchsia-sdk/.build-id/07/b0d3ac8f42e1e7.debug
Binary files differ
diff --git a/third_party/fuchsia-sdk/.build-id/0e/754a242d3990b5.debug b/third_party/fuchsia-sdk/.build-id/0e/754a242d3990b5.debug
new file mode 100755
index 0000000..ccb6eeb
--- /dev/null
+++ b/third_party/fuchsia-sdk/.build-id/0e/754a242d3990b5.debug
Binary files differ
diff --git a/third_party/fuchsia-sdk/.build-id/19/dfb7dfc513c781.debug b/third_party/fuchsia-sdk/.build-id/19/dfb7dfc513c781.debug
new file mode 100755
index 0000000..43f3215
--- /dev/null
+++ b/third_party/fuchsia-sdk/.build-id/19/dfb7dfc513c781.debug
Binary files differ
diff --git a/third_party/fuchsia-sdk/.build-id/2f/61d6b2df790300.debug b/third_party/fuchsia-sdk/.build-id/2f/61d6b2df790300.debug
new file mode 100755
index 0000000..fc8f68a
--- /dev/null
+++ b/third_party/fuchsia-sdk/.build-id/2f/61d6b2df790300.debug
Binary files differ
diff --git a/third_party/fuchsia-sdk/.build-id/47/c225b4c387e374.debug b/third_party/fuchsia-sdk/.build-id/47/c225b4c387e374.debug
new file mode 100755
index 0000000..ffadfd1
--- /dev/null
+++ b/third_party/fuchsia-sdk/.build-id/47/c225b4c387e374.debug
Binary files differ
diff --git a/third_party/fuchsia-sdk/.build-id/4c/570772eef1424d.debug b/third_party/fuchsia-sdk/.build-id/4c/570772eef1424d.debug
new file mode 100755
index 0000000..30ef708
--- /dev/null
+++ b/third_party/fuchsia-sdk/.build-id/4c/570772eef1424d.debug
Binary files differ
diff --git a/third_party/fuchsia-sdk/.build-id/55/2eec3497a99775.debug b/third_party/fuchsia-sdk/.build-id/55/2eec3497a99775.debug
new file mode 100755
index 0000000..f82f809
--- /dev/null
+++ b/third_party/fuchsia-sdk/.build-id/55/2eec3497a99775.debug
Binary files differ
diff --git a/third_party/fuchsia-sdk/.build-id/7b/adfd381297bf6f.debug b/third_party/fuchsia-sdk/.build-id/7b/adfd381297bf6f.debug
new file mode 100755
index 0000000..e0fab91
--- /dev/null
+++ b/third_party/fuchsia-sdk/.build-id/7b/adfd381297bf6f.debug
Binary files differ
diff --git a/third_party/fuchsia-sdk/.build-id/85/7fd35c7c483025.debug b/third_party/fuchsia-sdk/.build-id/85/7fd35c7c483025.debug
new file mode 100755
index 0000000..0a5d20f
--- /dev/null
+++ b/third_party/fuchsia-sdk/.build-id/85/7fd35c7c483025.debug
Binary files differ
diff --git a/third_party/fuchsia-sdk/.build-id/88/90c23f2347327f.debug b/third_party/fuchsia-sdk/.build-id/88/90c23f2347327f.debug
new file mode 100755
index 0000000..4892d09
--- /dev/null
+++ b/third_party/fuchsia-sdk/.build-id/88/90c23f2347327f.debug
Binary files differ
diff --git a/third_party/fuchsia-sdk/.build-id/91/d1859cac2f8ed7.debug b/third_party/fuchsia-sdk/.build-id/91/d1859cac2f8ed7.debug
new file mode 100755
index 0000000..06422b1
--- /dev/null
+++ b/third_party/fuchsia-sdk/.build-id/91/d1859cac2f8ed7.debug
Binary files differ
diff --git a/third_party/fuchsia-sdk/.build-id/94/49060f220c6b71.debug b/third_party/fuchsia-sdk/.build-id/94/49060f220c6b71.debug
new file mode 100755
index 0000000..59c2ff6
--- /dev/null
+++ b/third_party/fuchsia-sdk/.build-id/94/49060f220c6b71.debug
Binary files differ
diff --git a/third_party/fuchsia-sdk/.build-id/99/7608d3dc8531e7.debug b/third_party/fuchsia-sdk/.build-id/99/7608d3dc8531e7.debug
new file mode 100755
index 0000000..19cfb6b
--- /dev/null
+++ b/third_party/fuchsia-sdk/.build-id/99/7608d3dc8531e7.debug
Binary files differ
diff --git a/third_party/fuchsia-sdk/.build-id/ab/9f1945a249d81a.debug b/third_party/fuchsia-sdk/.build-id/ab/9f1945a249d81a.debug
new file mode 100755
index 0000000..a40723d
--- /dev/null
+++ b/third_party/fuchsia-sdk/.build-id/ab/9f1945a249d81a.debug
Binary files differ
diff --git a/third_party/fuchsia-sdk/.build-id/b9/5927328f66db02.debug b/third_party/fuchsia-sdk/.build-id/b9/5927328f66db02.debug
new file mode 100755
index 0000000..394ba86
--- /dev/null
+++ b/third_party/fuchsia-sdk/.build-id/b9/5927328f66db02.debug
Binary files differ
diff --git a/third_party/fuchsia-sdk/.build-id/e5/b5b39218398272.debug b/third_party/fuchsia-sdk/.build-id/e5/b5b39218398272.debug
new file mode 100755
index 0000000..614a041
--- /dev/null
+++ b/third_party/fuchsia-sdk/.build-id/e5/b5b39218398272.debug
Binary files differ
diff --git a/third_party/fuchsia-sdk/.build-id/ea/46fea0942ef671.debug b/third_party/fuchsia-sdk/.build-id/ea/46fea0942ef671.debug
new file mode 100755
index 0000000..68b82a4
--- /dev/null
+++ b/third_party/fuchsia-sdk/.build-id/ea/46fea0942ef671.debug
Binary files differ
diff --git a/third_party/fuchsia-sdk/.build-id/fa/39648a29eb2f06.debug b/third_party/fuchsia-sdk/.build-id/fa/39648a29eb2f06.debug
new file mode 100755
index 0000000..fedc0d4
--- /dev/null
+++ b/third_party/fuchsia-sdk/.build-id/fa/39648a29eb2f06.debug
Binary files differ
diff --git a/third_party/fuchsia-sdk/.build-id/fd/0aaad880fd8e81.debug b/third_party/fuchsia-sdk/.build-id/fd/0aaad880fd8e81.debug
new file mode 100755
index 0000000..71d9539
--- /dev/null
+++ b/third_party/fuchsia-sdk/.build-id/fd/0aaad880fd8e81.debug
Binary files differ
diff --git a/third_party/fuchsia-sdk/.build-id/ff/6959a5ccf92c5b.debug b/third_party/fuchsia-sdk/.build-id/ff/6959a5ccf92c5b.debug
new file mode 100755
index 0000000..6941c04
--- /dev/null
+++ b/third_party/fuchsia-sdk/.build-id/ff/6959a5ccf92c5b.debug
Binary files differ
diff --git a/third_party/fuchsia-sdk/.gitignore b/third_party/fuchsia-sdk/.gitignore
new file mode 100644
index 0000000..20de49f
--- /dev/null
+++ b/third_party/fuchsia-sdk/.gitignore
@@ -0,0 +1,4 @@
+# gitignore for GN SDK
+/images/
+/bin/gsutil
+/authkeys.txt
diff --git a/third_party/fuchsia-sdk/AUTHORS b/third_party/fuchsia-sdk/AUTHORS
new file mode 100644
index 0000000..61ae302
--- /dev/null
+++ b/third_party/fuchsia-sdk/AUTHORS
@@ -0,0 +1,10 @@
+# This is the list of Fuchsia Authors.
+
+# Names should be added to this file as one of
+# Organization's name
+# Individual's name <submission email address>
+# Individual's name <submission email address> <email2> <emailN>
+
+Google Inc.
+The Chromium Authors
+The Go Authors
diff --git a/third_party/fuchsia-sdk/COPYRIGHT.musl b/third_party/fuchsia-sdk/COPYRIGHT.musl
new file mode 100644
index 0000000..faebed7
--- /dev/null
+++ b/third_party/fuchsia-sdk/COPYRIGHT.musl
@@ -0,0 +1,129 @@
+musl as a whole is licensed under the following standard MIT license:
+
+----------------------------------------------------------------------
+Copyright © 2005-2014 Rich Felker, et al.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+----------------------------------------------------------------------
+
+Authors/contributors include:
+
+Alex Dowad
+Alexander Monakov
+Anthony G. Basile
+Arvid Picciani
+Bobby Bingham
+Boris Brezillon
+Brent Cook
+Chris Spiegel
+Clément Vasseur
+Daniel Micay
+Denys Vlasenko
+Emil Renner Berthing
+Felix Fietkau
+Felix Janda
+Gianluca Anzolin
+Hauke Mehrtens
+Hiltjo Posthuma
+Isaac Dunham
+Jaydeep Patil
+Jens Gustedt
+Jeremy Huntwork
+Jo-Philipp Wich
+Joakim Sindholt
+John Spencer
+Josiah Worcester
+Justin Cormack
+Khem Raj
+Kylie McClain
+Luca Barbato
+Luka Perkov
+M Farkas-Dyck (Strake)
+Mahesh Bodapati
+Michael Forney
+Natanael Copa
+Nicholas J. Kain
+orc
+Pascal Cuoq
+Petr Hosek
+Pierre Carrier
+Rich Felker
+Richard Pennington
+Shiz
+sin
+Solar Designer
+Stefan Kristiansson
+Szabolcs Nagy
+Timo Teräs
+Trutz Behn
+Valentin Ochs
+William Haddon
+
+Portions of this software are derived from third-party works licensed
+under terms compatible with the above MIT license:
+
+Much of the math library code (third_party/math/* and
+third_party/complex/*, and third_party/include/libm.h) is
+Copyright © 1993,2004 Sun Microsystems or
+Copyright © 2003-2011 David Schultz or
+Copyright © 2003-2009 Steven G. Kargl or
+Copyright © 2003-2009 Bruce D. Evans or
+Copyright © 2008 Stephen L. Moshier
+and labelled as such in comments in the individual source files. All
+have been licensed under extremely permissive terms.
+
+The smoothsort implementation (third_party/smoothsort/qsort.c) is
+Copyright © 2011 Valentin Ochs and is licensed under an MIT-style
+license.
+
+The x86_64 files in third_party/arch were written by Nicholas J. Kain
+and is licensed under the standard MIT terms.
+
+All other files which have no copyright comments are original works
+produced specifically for use as part of this library, written either
+by Rich Felker, the main author of the library, or by one or more
+contibutors listed above. Details on authorship of individual files
+can be found in the git version control history of the project. The
+omission of copyright and license comments in each file is in the
+interest of source tree size.
+
+In addition, permission is hereby granted for all public header files
+(include/* and arch/*/bits/*) and crt files intended to be linked into
+applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit
+the copyright notice and permission notice otherwise required by the
+license, and to use these files without any requirement of
+attribution. These files include substantial contributions from:
+
+Bobby Bingham
+John Spencer
+Nicholas J. Kain
+Rich Felker
+Richard Pennington
+Stefan Kristiansson
+Szabolcs Nagy
+
+all of whom have explicitly granted such permission.
+
+This file previously contained text expressing a belief that most of
+the files covered by the above exception were sufficiently trivial not
+to be subject to copyright, resulting in confusion over whether it
+negated the permissions granted in the license. In the spirit of
+permissive licensing, and of not having licensing issues being an
+obstacle to adoption, that text has been removed.
diff --git a/third_party/fuchsia-sdk/LICENSE b/third_party/fuchsia-sdk/LICENSE
new file mode 100644
index 0000000..87f152c
--- /dev/null
+++ b/third_party/fuchsia-sdk/LICENSE
@@ -0,0 +1,27 @@
+Copyright 2019 The Fuchsia Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/third_party/fuchsia-sdk/LICENSE.vulkan b/third_party/fuchsia-sdk/LICENSE.vulkan
new file mode 100644
index 0000000..6599e31
--- /dev/null
+++ b/third_party/fuchsia-sdk/LICENSE.vulkan
@@ -0,0 +1,207 @@
+The majority of files in this project use the Apache 2.0 License.
+There are a few exceptions and their license can be found in the source.
+Any license deviations from Apache 2.0 are "more permissive" licenses.
+
+===========================================================================================
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/third_party/fuchsia-sdk/PATENTS b/third_party/fuchsia-sdk/PATENTS
new file mode 100644
index 0000000..2746e78
--- /dev/null
+++ b/third_party/fuchsia-sdk/PATENTS
@@ -0,0 +1,22 @@
+Additional IP Rights Grant (Patents)
+
+"This implementation" means the copyrightable works distributed by
+Google as part of the Fuchsia project.
+
+Google hereby grants to you a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable (except as stated in this
+section) patent license to make, have made, use, offer to sell, sell,
+import, transfer, and otherwise run, modify and propagate the contents
+of this implementation of Fuchsia, where such license applies only to
+those patent claims, both currently owned by Google and acquired in
+the future, licensable by Google that are necessarily infringed by
+this implementation. This grant does not include claims that would be
+infringed only as a consequence of further modification of this
+implementation. If you or your agent or exclusive licensee institute
+or order or agree to the institution of patent litigation or any other
+patent enforcement activity against any entity (including a
+cross-claim or counterclaim in a lawsuit) alleging that this
+implementation of Fuchsia constitutes direct or contributory patent
+infringement, or inducement of patent infringement, then any patent
+rights granted to you under this License for this implementation of
+Fuchsia shall terminate as of the date such litigation is filed.
diff --git a/third_party/fuchsia-sdk/README.GN.md b/third_party/fuchsia-sdk/README.GN.md
new file mode 100644
index 0000000..34fd511
--- /dev/null
+++ b/third_party/fuchsia-sdk/README.GN.md
@@ -0,0 +1,5 @@
+# GN SDK for Fuchsia
+
+See https://fuchsia.dev/fuchsia-src/development/sdk/gn for information on using
+this SDK.
+
diff --git a/third_party/fuchsia-sdk/README.md b/third_party/fuchsia-sdk/README.md
new file mode 100644
index 0000000..b50c6b0
--- /dev/null
+++ b/third_party/fuchsia-sdk/README.md
@@ -0,0 +1,113 @@
+# Fuchsia Core SDK
+
+This archive contains the Fuchsia Core SDK, which is a small set of
+Fuchsia-specific libraries and tools required to start building and running
+programs for Fuchsia.
+
+This SDK differs from traditional SDKs in that it is not readily usable out of
+the box.
+For example, it does not contain any build system, favor any
+toolchain, or provide standard non-Fuchsia libraries (e.g. for crypto or
+graphics).
+Instead, it provides metadata accurately describing its various
+parts, so that this SDK can be post-processed and augmented with all the pieces
+necessary for a satisfactory end-to-end development experience.
+
+Most developers who wish to build something for Fuchsia should not need to
+deal directly with this particular SDK.
+They will instead consume a transformed version of it, for instance within the
+development environment and ecosystem supporting a given language runtime.
+Maintainers of development environments who wish to add support for Fuchsia are
+the main audience for this SDK.
+See [the section below](#ingestion) for a description of how to process this
+SDK.
+
+As such, the Core SDK is the representation of the Fuchsia platform developers'
+contract with other developers who work with Fuchsia.
+While that contract is absolutely necessary, as this SDK contains the very bits
+that are unique to Fuchsia, it is not sufficient and will be complemented by
+other "contracts".
+The Fuchsia Core SDK is mirroring the Fuchsia platform in that respect: highly
+composable and extensible, with a clear separation of concerns.
+
+
+## Structure
+
+From this point on, the root of the SDK archive will be referred to as `//`.
+
+### Metadata
+
+Metadata is present throughout this SDK in the form of JSON files.
+Every element in this SDK has its own metadata file: for example, a FIDL library
+`//fidl/fuchsia.foobar` has its metadata encoded in
+`//fidl/fuchsia.foobar/meta.json`.
+
+Every metadata file follows a JSON schema available under `//meta/schemas`: for
+example, a FIDL library's metadata file conforms to
+`//meta/schemas/fidl_library.json`.
+Schemas act as the documentation for the metadata and may be used to facilitate
+the SDK ingestion process.
+
+### Documentation
+
+General documentation is available under [`//docs`](docs/README.md).
+Some individual SDK elements will also provide documentation directly under the
+path where they are hosted in the SDK.
+
+### Target prebuilts
+
+Target prebuilts are hosted under `//arch/<architecture>`.
+This includes a full-fledged sysroot for each available architecture.
+
+### Source libraries
+
+The SDK contains sources for a large number of FIDL libraries (under
+`//fidl`) as well as a few C/C++ libraries (under `//pkg`).
+
+### Host tools
+
+Multiple host-side tools can be found under `//tools`.
+This includes tools for building programs, deploying to a device, debugging,
+etc...
+Some information about how to use these tools can be found under `//docs`.
+
+### Images
+
+`//device` contains metadata describing device configurations matching a given
+version of the SDK.
+This metadata contains pointers to images that can be flashed onto said devices.
+
+
+## Ingestion
+
+This section describes the basic process of consuming the Core SDK and turning
+it into something usable.
+
+The main entry point for the ingestion process is a file at
+`//meta/manifest.json`.
+As with every metadata file in the SDK, the manifest follows a JSON schema which
+is included under `//meta/schemas/manifest.json`.
+
+This file contains a list of all the elements included in this SDK, represented
+by the path to their respective metadata file.
+Each element file is guaranteed to contain a top-level `type` attribute, which
+may be used to apply different treatments to different element types, e.g.
+generating a build file for a FIDL library vs. just moving a host tool to a
+convenient location in the final development environment.
+
+The existence of the various metadata files as well as the exhaustiveness of
+their contents should make it so that the ingestion process may be fully
+automated.
+JSON schemas may even be used to generate code representing the metadata
+containers and let the ingestion program handle idiomatic data structures
+instead of raw JSON representations.
+
+The metadata schemas will evolve over time.
+In order to allow consumers of that metadata to adjust to schema changes, the
+main metadata file contains a property named `schema_version` which is an opaque
+version identifier for these schemas.
+This version identifier will be modified every time the metadata schemas evolve
+in a way that requires the attention of a developer.
+SDK consumers may record the version identifier of the metadata they used to last
+ingest an SDK and compare that version identifier to next SDK's version
+identifier in order to detect when developer action may be required.
diff --git a/third_party/fuchsia-sdk/arch/arm64/dist/VkLayer_core_validation.so b/third_party/fuchsia-sdk/arch/arm64/dist/VkLayer_core_validation.so
new file mode 100755
index 0000000..708f073
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/dist/VkLayer_core_validation.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/arm64/dist/VkLayer_image_pipe_swapchain.so b/third_party/fuchsia-sdk/arch/arm64/dist/VkLayer_image_pipe_swapchain.so
new file mode 100755
index 0000000..b7e433a
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/dist/VkLayer_image_pipe_swapchain.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/arm64/dist/VkLayer_khronos_validation.so b/third_party/fuchsia-sdk/arch/arm64/dist/VkLayer_khronos_validation.so
new file mode 100755
index 0000000..77d483f
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/dist/VkLayer_khronos_validation.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/arm64/dist/VkLayer_object_lifetimes.so b/third_party/fuchsia-sdk/arch/arm64/dist/VkLayer_object_lifetimes.so
new file mode 100755
index 0000000..51f9096
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/dist/VkLayer_object_lifetimes.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/arm64/dist/VkLayer_stateless_validation.so b/third_party/fuchsia-sdk/arch/arm64/dist/VkLayer_stateless_validation.so
new file mode 100755
index 0000000..0226451
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/dist/VkLayer_stateless_validation.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/arm64/dist/VkLayer_thread_safety.so b/third_party/fuchsia-sdk/arch/arm64/dist/VkLayer_thread_safety.so
new file mode 100755
index 0000000..24d750d
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/dist/VkLayer_thread_safety.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/arm64/dist/VkLayer_unique_objects.so b/third_party/fuchsia-sdk/arch/arm64/dist/VkLayer_unique_objects.so
new file mode 100755
index 0000000..5177ddd
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/dist/VkLayer_unique_objects.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/arm64/dist/libasync-default.so b/third_party/fuchsia-sdk/arch/arm64/dist/libasync-default.so
new file mode 100755
index 0000000..c25a530
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/dist/libasync-default.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/arm64/dist/libfdio.so b/third_party/fuchsia-sdk/arch/arm64/dist/libfdio.so
new file mode 100755
index 0000000..47ef705
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/dist/libfdio.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/arm64/dist/libmemfs.so b/third_party/fuchsia-sdk/arch/arm64/dist/libmemfs.so
new file mode 100755
index 0000000..e5c9981
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/dist/libmemfs.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/arm64/dist/libsvc.so b/third_party/fuchsia-sdk/arch/arm64/dist/libsvc.so
new file mode 100755
index 0000000..09a6407
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/dist/libsvc.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/arm64/dist/libsyslog.so b/third_party/fuchsia-sdk/arch/arm64/dist/libsyslog.so
new file mode 100755
index 0000000..2f936fb
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/dist/libsyslog.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/arm64/dist/libtrace-engine.so b/third_party/fuchsia-sdk/arch/arm64/dist/libtrace-engine.so
new file mode 100755
index 0000000..e5149b4
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/dist/libtrace-engine.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/arm64/dist/libtrace-provider-so.so b/third_party/fuchsia-sdk/arch/arm64/dist/libtrace-provider-so.so
new file mode 100755
index 0000000..435d074
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/dist/libtrace-provider-so.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/arm64/dist/libvulkan.so b/third_party/fuchsia-sdk/arch/arm64/dist/libvulkan.so
new file mode 100755
index 0000000..df72921
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/dist/libvulkan.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/arm64/lib/libasync-default.so b/third_party/fuchsia-sdk/arch/arm64/lib/libasync-default.so
new file mode 100755
index 0000000..8695283
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/lib/libasync-default.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/arm64/lib/libasync-loop-default.a b/third_party/fuchsia-sdk/arch/arm64/lib/libasync-loop-default.a
new file mode 100644
index 0000000..5a3001f
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/lib/libasync-loop-default.a
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/arm64/lib/libfdio.so b/third_party/fuchsia-sdk/arch/arm64/lib/libfdio.so
new file mode 100755
index 0000000..6941c04
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/lib/libfdio.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/arm64/lib/libmemfs.so b/third_party/fuchsia-sdk/arch/arm64/lib/libmemfs.so
new file mode 100755
index 0000000..30ef708
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/lib/libmemfs.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/arm64/lib/libsvc.so b/third_party/fuchsia-sdk/arch/arm64/lib/libsvc.so
new file mode 100755
index 0000000..09a6407
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/lib/libsvc.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/arm64/lib/libsync.a b/third_party/fuchsia-sdk/arch/arm64/lib/libsync.a
new file mode 100644
index 0000000..f5f8e08
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/lib/libsync.a
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/arm64/lib/libsyslog.so b/third_party/fuchsia-sdk/arch/arm64/lib/libsyslog.so
new file mode 100755
index 0000000..68b82a4
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/lib/libsyslog.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/arm64/lib/libtrace-engine.so b/third_party/fuchsia-sdk/arch/arm64/lib/libtrace-engine.so
new file mode 100755
index 0000000..ffadfd1
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/lib/libtrace-engine.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/arm64/lib/libtrace-provider-so.so b/third_party/fuchsia-sdk/arch/arm64/lib/libtrace-provider-so.so
new file mode 100755
index 0000000..43f3215
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/lib/libtrace-provider-so.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/arm64/lib/libvulkan.so b/third_party/fuchsia-sdk/arch/arm64/lib/libvulkan.so
new file mode 100755
index 0000000..df72921
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/lib/libvulkan.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/dist/lib/ld.so.1 b/third_party/fuchsia-sdk/arch/arm64/sysroot/dist/lib/ld.so.1
new file mode 100755
index 0000000..1d39253
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/dist/lib/ld.so.1
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/alloca.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/alloca.h
new file mode 100644
index 0000000..7deb5b9
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/alloca.h
@@ -0,0 +1,21 @@
+#ifndef SYSROOT_ALLOCA_H_
+#define SYSROOT_ALLOCA_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_size_t
+#include <bits/alltypes.h>
+
+void* alloca(size_t);
+
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_ALLOCA_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/ar.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/ar.h
new file mode 100644
index 0000000..d0d4176
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/ar.h
@@ -0,0 +1,25 @@
+#ifndef SYSROOT_AR_H_
+#define SYSROOT_AR_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ARMAG "!<arch>\n"
+#define SARMAG 8
+#define ARFMAG "`\n"
+
+struct ar_hdr {
+ char ar_name[16];
+ char ar_date[12];
+ char ar_uid[6], ar_gid[6];
+ char ar_mode[8];
+ char ar_size[10];
+ char ar_fmag[2];
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_AR_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/arpa/ftp.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/arpa/ftp.h
new file mode 100644
index 0000000..7d86bec
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/arpa/ftp.h
@@ -0,0 +1,37 @@
+#ifndef SYSROOT_ARPA_FTP_H_
+#define SYSROOT_ARPA_FTP_H_
+
+#define PRELIM 1
+#define COMPLETE 2
+#define CONTINUE 3
+#define TRANSIENT 4
+#define ERROR 5
+#define TYPE_A 1
+#define TYPE_E 2
+#define TYPE_I 3
+#define TYPE_L 4
+#define FORM_N 1
+#define FORM_T 2
+#define FORM_C 3
+#define STRU_F 1
+#define STRU_R 2
+#define STRU_P 3
+#define MODE_S 1
+#define MODE_B 2
+#define MODE_C 3
+#define REC_ESC '\377'
+#define REC_EOR '\001'
+#define REC_EOF '\002'
+#define BLK_EOR 0x80
+#define BLK_EOF 0x40
+#define BLK_ERRORS 0x20
+#define BLK_RESTART 0x10
+#define BLK_BYTECOUNT 2
+#ifdef FTP_NAMES
+char* modenames[] = {"0", "Stream", "Block", "Compressed"};
+char* strunames[] = {"0", "File", "Record", "Page"};
+char* typenames[] = {"0", "ASCII", "EBCDIC", "Image", "Local"};
+char* formnames[] = {"0", "Nonprint", "Telnet", "Carriage-control"};
+#endif
+
+#endif // SYSROOT_ARPA_FTP_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/arpa/inet.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/arpa/inet.h
new file mode 100644
index 0000000..4fa0af5
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/arpa/inet.h
@@ -0,0 +1,36 @@
+#ifndef SYSROOT_ARPA_INET_H_
+#define SYSROOT_ARPA_INET_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <netinet/in.h>
+
+uint32_t htonl(uint32_t);
+uint16_t htons(uint16_t);
+uint32_t ntohl(uint32_t);
+uint16_t ntohs(uint16_t);
+
+in_addr_t inet_addr(const char*);
+in_addr_t inet_network(const char*);
+char* inet_ntoa(struct in_addr);
+int inet_pton(int, const char* __restrict, void* __restrict);
+const char* inet_ntop(int, const void* __restrict, char* __restrict, socklen_t);
+
+int inet_aton(const char*, struct in_addr*);
+struct in_addr inet_makeaddr(in_addr_t, in_addr_t);
+in_addr_t inet_lnaof(struct in_addr);
+in_addr_t inet_netof(struct in_addr);
+
+#undef INET_ADDRSTRLEN
+#undef INET6_ADDRSTRLEN
+#define INET_ADDRSTRLEN 16
+#define INET6_ADDRSTRLEN 46
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_ARPA_INET_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/arpa/nameser.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/arpa/nameser.h
new file mode 100644
index 0000000..734d205
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/arpa/nameser.h
@@ -0,0 +1,451 @@
+#ifndef SYSROOT_ARPA_NAMESER_H_
+#define SYSROOT_ARPA_NAMESER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define __NAMESER 19991006
+#define NS_PACKETSZ 512
+#define NS_MAXDNAME 1025
+#define NS_MAXMSG 65535
+#define NS_MAXCDNAME 255
+#define NS_MAXLABEL 63
+#define NS_HFIXEDSZ 12
+#define NS_QFIXEDSZ 4
+#define NS_RRFIXEDSZ 10
+#define NS_INT32SZ 4
+#define NS_INT16SZ 2
+#define NS_INT8SZ 1
+#define NS_INADDRSZ 4
+#define NS_IN6ADDRSZ 16
+#define NS_CMPRSFLGS 0xc0
+#define NS_DEFAULTPORT 53
+
+typedef enum __ns_sect {
+ ns_s_qd = 0,
+ ns_s_zn = 0,
+ ns_s_an = 1,
+ ns_s_pr = 1,
+ ns_s_ns = 2,
+ ns_s_ud = 2,
+ ns_s_ar = 3,
+ ns_s_max = 4
+} ns_sect;
+
+typedef struct __ns_msg {
+ const unsigned char *_msg, *_eom;
+ uint16_t _id, _flags, _counts[ns_s_max];
+ const unsigned char* _sections[ns_s_max];
+ ns_sect _sect;
+ int _rrnum;
+ const unsigned char* _msg_ptr;
+} ns_msg;
+
+struct _ns_flagdata {
+ int mask, shift;
+};
+extern const struct _ns_flagdata _ns_flagdata[];
+
+#define ns_msg_id(handle) ((handle)._id + 0)
+#define ns_msg_base(handle) ((handle)._msg + 0)
+#define ns_msg_end(handle) ((handle)._eom + 0)
+#define ns_msg_size(handle) ((handle)._eom - (handle)._msg)
+#define ns_msg_count(handle, section) ((handle)._counts[section] + 0)
+#define ns_msg_getflag(handle, flag) \
+ (((handle)._flags & _ns_flagdata[flag].mask) >> _ns_flagdata[flag].shift)
+
+typedef struct __ns_rr {
+ char name[NS_MAXDNAME];
+ uint16_t type;
+ uint16_t rr_class;
+ uint32_t ttl;
+ uint16_t rdlength;
+ const unsigned char* rdata;
+} ns_rr;
+
+#define ns_rr_name(rr) (((rr).name[0] != '\0') ? (rr).name : ".")
+#define ns_rr_type(rr) ((ns_type)((rr).type + 0))
+#define ns_rr_class(rr) ((ns_class)((rr).rr_class + 0))
+#define ns_rr_ttl(rr) ((rr).ttl + 0)
+#define ns_rr_rdlen(rr) ((rr).rdlength + 0)
+#define ns_rr_rdata(rr) ((rr).rdata + 0)
+
+typedef enum __ns_flag {
+ ns_f_qr,
+ ns_f_opcode,
+ ns_f_aa,
+ ns_f_tc,
+ ns_f_rd,
+ ns_f_ra,
+ ns_f_z,
+ ns_f_ad,
+ ns_f_cd,
+ ns_f_rcode,
+ ns_f_max
+} ns_flag;
+
+typedef enum __ns_opcode {
+ ns_o_query = 0,
+ ns_o_iquery = 1,
+ ns_o_status = 2,
+ ns_o_notify = 4,
+ ns_o_update = 5,
+ ns_o_max = 6
+} ns_opcode;
+
+typedef enum __ns_rcode {
+ ns_r_noerror = 0,
+ ns_r_formerr = 1,
+ ns_r_servfail = 2,
+ ns_r_nxdomain = 3,
+ ns_r_notimpl = 4,
+ ns_r_refused = 5,
+ ns_r_yxdomain = 6,
+ ns_r_yxrrset = 7,
+ ns_r_nxrrset = 8,
+ ns_r_notauth = 9,
+ ns_r_notzone = 10,
+ ns_r_max = 11,
+ ns_r_badvers = 16,
+ ns_r_badsig = 16,
+ ns_r_badkey = 17,
+ ns_r_badtime = 18
+} ns_rcode;
+
+typedef enum __ns_update_operation {
+ ns_uop_delete = 0,
+ ns_uop_add = 1,
+ ns_uop_max = 2
+} ns_update_operation;
+
+struct ns_tsig_key {
+ char name[NS_MAXDNAME], alg[NS_MAXDNAME];
+ unsigned char* data;
+ int len;
+};
+typedef struct ns_tsig_key ns_tsig_key;
+
+struct ns_tcp_tsig_state {
+ int counter;
+ struct dst_key* key;
+ void* ctx;
+ unsigned char sig[NS_PACKETSZ];
+ int siglen;
+};
+typedef struct ns_tcp_tsig_state ns_tcp_tsig_state;
+
+#define NS_TSIG_FUDGE 300
+#define NS_TSIG_TCP_COUNT 100
+#define NS_TSIG_ALG_HMAC_MD5 "HMAC-MD5.SIG-ALG.REG.INT"
+
+#define NS_TSIG_ERROR_NO_TSIG -10
+#define NS_TSIG_ERROR_NO_SPACE -11
+#define NS_TSIG_ERROR_FORMERR -12
+
+typedef enum __ns_type {
+ ns_t_invalid = 0,
+ ns_t_a = 1,
+ ns_t_ns = 2,
+ ns_t_md = 3,
+ ns_t_mf = 4,
+ ns_t_cname = 5,
+ ns_t_soa = 6,
+ ns_t_mb = 7,
+ ns_t_mg = 8,
+ ns_t_mr = 9,
+ ns_t_null = 10,
+ ns_t_wks = 11,
+ ns_t_ptr = 12,
+ ns_t_hinfo = 13,
+ ns_t_minfo = 14,
+ ns_t_mx = 15,
+ ns_t_txt = 16,
+ ns_t_rp = 17,
+ ns_t_afsdb = 18,
+ ns_t_x25 = 19,
+ ns_t_isdn = 20,
+ ns_t_rt = 21,
+ ns_t_nsap = 22,
+ ns_t_nsap_ptr = 23,
+ ns_t_sig = 24,
+ ns_t_key = 25,
+ ns_t_px = 26,
+ ns_t_gpos = 27,
+ ns_t_aaaa = 28,
+ ns_t_loc = 29,
+ ns_t_nxt = 30,
+ ns_t_eid = 31,
+ ns_t_nimloc = 32,
+ ns_t_srv = 33,
+ ns_t_atma = 34,
+ ns_t_naptr = 35,
+ ns_t_kx = 36,
+ ns_t_cert = 37,
+ ns_t_a6 = 38,
+ ns_t_dname = 39,
+ ns_t_sink = 40,
+ ns_t_opt = 41,
+ ns_t_apl = 42,
+ ns_t_tkey = 249,
+ ns_t_tsig = 250,
+ ns_t_ixfr = 251,
+ ns_t_axfr = 252,
+ ns_t_mailb = 253,
+ ns_t_maila = 254,
+ ns_t_any = 255,
+ ns_t_zxfr = 256,
+ ns_t_max = 65536
+} ns_type;
+
+#define ns_t_qt_p(t) (ns_t_xfr_p(t) || (t) == ns_t_any || (t) == ns_t_mailb || (t) == ns_t_maila)
+#define ns_t_mrr_p(t) ((t) == ns_t_tsig || (t) == ns_t_opt)
+#define ns_t_rr_p(t) (!ns_t_qt_p(t) && !ns_t_mrr_p(t))
+#define ns_t_udp_p(t) ((t) != ns_t_axfr && (t) != ns_t_zxfr)
+#define ns_t_xfr_p(t) ((t) == ns_t_axfr || (t) == ns_t_ixfr || (t) == ns_t_zxfr)
+
+typedef enum __ns_class {
+ ns_c_invalid = 0,
+ ns_c_in = 1,
+ ns_c_2 = 2,
+ ns_c_chaos = 3,
+ ns_c_hs = 4,
+ ns_c_none = 254,
+ ns_c_any = 255,
+ ns_c_max = 65536
+} ns_class;
+
+typedef enum __ns_key_types {
+ ns_kt_rsa = 1,
+ ns_kt_dh = 2,
+ ns_kt_dsa = 3,
+ ns_kt_private = 254
+} ns_key_types;
+
+typedef enum __ns_cert_types {
+ cert_t_pkix = 1,
+ cert_t_spki = 2,
+ cert_t_pgp = 3,
+ cert_t_url = 253,
+ cert_t_oid = 254
+} ns_cert_types;
+
+#define NS_KEY_TYPEMASK 0xC000
+#define NS_KEY_TYPE_AUTH_CONF 0x0000
+#define NS_KEY_TYPE_CONF_ONLY 0x8000
+#define NS_KEY_TYPE_AUTH_ONLY 0x4000
+#define NS_KEY_TYPE_NO_KEY 0xC000
+#define NS_KEY_NO_AUTH 0x8000
+#define NS_KEY_NO_CONF 0x4000
+#define NS_KEY_RESERVED2 0x2000
+#define NS_KEY_EXTENDED_FLAGS 0x1000
+#define NS_KEY_RESERVED4 0x0800
+#define NS_KEY_RESERVED5 0x0400
+#define NS_KEY_NAME_TYPE 0x0300
+#define NS_KEY_NAME_USER 0x0000
+#define NS_KEY_NAME_ENTITY 0x0200
+#define NS_KEY_NAME_ZONE 0x0100
+#define NS_KEY_NAME_RESERVED 0x0300
+#define NS_KEY_RESERVED8 0x0080
+#define NS_KEY_RESERVED9 0x0040
+#define NS_KEY_RESERVED10 0x0020
+#define NS_KEY_RESERVED11 0x0010
+#define NS_KEY_SIGNATORYMASK 0x000F
+#define NS_KEY_RESERVED_BITMASK \
+ (NS_KEY_RESERVED2 | NS_KEY_RESERVED4 | NS_KEY_RESERVED5 | NS_KEY_RESERVED8 | NS_KEY_RESERVED9 | \
+ NS_KEY_RESERVED10 | NS_KEY_RESERVED11)
+#define NS_KEY_RESERVED_BITMASK2 0xFFFF
+#define NS_ALG_MD5RSA 1
+#define NS_ALG_DH 2
+#define NS_ALG_DSA 3
+#define NS_ALG_DSS NS_ALG_DSA
+#define NS_ALG_EXPIRE_ONLY 253
+#define NS_ALG_PRIVATE_OID 254
+
+#define NS_KEY_PROT_TLS 1
+#define NS_KEY_PROT_EMAIL 2
+#define NS_KEY_PROT_DNSSEC 3
+#define NS_KEY_PROT_IPSEC 4
+#define NS_KEY_PROT_ANY 255
+
+#define NS_MD5RSA_MIN_BITS 512
+#define NS_MD5RSA_MAX_BITS 4096
+#define NS_MD5RSA_MAX_BYTES ((NS_MD5RSA_MAX_BITS + 7 / 8) * 2 + 3)
+#define NS_MD5RSA_MAX_BASE64 (((NS_MD5RSA_MAX_BYTES + 2) / 3) * 4)
+#define NS_MD5RSA_MIN_SIZE ((NS_MD5RSA_MIN_BITS + 7) / 8)
+#define NS_MD5RSA_MAX_SIZE ((NS_MD5RSA_MAX_BITS + 7) / 8)
+
+#define NS_DSA_SIG_SIZE 41
+#define NS_DSA_MIN_SIZE 213
+#define NS_DSA_MAX_BYTES 405
+
+#define NS_SIG_TYPE 0
+#define NS_SIG_ALG 2
+#define NS_SIG_LABELS 3
+#define NS_SIG_OTTL 4
+#define NS_SIG_EXPIR 8
+#define NS_SIG_SIGNED 12
+#define NS_SIG_FOOT 16
+#define NS_SIG_SIGNER 18
+#define NS_NXT_BITS 8
+#define NS_NXT_BIT_SET(n, p) (p[(n) / NS_NXT_BITS] |= (0x80 >> ((n) % NS_NXT_BITS)))
+#define NS_NXT_BIT_CLEAR(n, p) (p[(n) / NS_NXT_BITS] &= ~(0x80 >> ((n) % NS_NXT_BITS)))
+#define NS_NXT_BIT_ISSET(n, p) (p[(n) / NS_NXT_BITS] & (0x80 >> ((n) % NS_NXT_BITS)))
+#define NS_NXT_MAX 127
+
+#define NS_OPT_DNSSEC_OK 0x8000U
+#define NS_OPT_NSID 3
+
+#define NS_GET16(s, cp) (void)((s) = ns_get16(((cp) += 2) - 2))
+#define NS_GET32(l, cp) (void)((l) = ns_get32(((cp) += 4) - 4))
+#define NS_PUT16(s, cp) ns_put16((s), ((cp) += 2) - 2)
+#define NS_PUT32(l, cp) ns_put32((l), ((cp) += 4) - 4)
+
+unsigned ns_get16(const unsigned char*);
+unsigned long ns_get32(const unsigned char*);
+void ns_put16(unsigned, unsigned char*);
+void ns_put32(unsigned long, unsigned char*);
+
+int ns_initparse(const unsigned char*, int, ns_msg*);
+int ns_parserr(ns_msg*, ns_sect, int, ns_rr*);
+int ns_skiprr(const unsigned char*, const unsigned char*, ns_sect, int);
+int ns_name_uncompress(const unsigned char*, const unsigned char*, const unsigned char*, char*,
+ size_t);
+
+#define __BIND 19950621
+
+typedef struct {
+ unsigned id : 16;
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned qr : 1;
+ unsigned opcode : 4;
+ unsigned aa : 1;
+ unsigned tc : 1;
+ unsigned rd : 1;
+ unsigned ra : 1;
+ unsigned unused : 1;
+ unsigned ad : 1;
+ unsigned cd : 1;
+ unsigned rcode : 4;
+#else
+ unsigned rd : 1;
+ unsigned tc : 1;
+ unsigned aa : 1;
+ unsigned opcode : 4;
+ unsigned qr : 1;
+ unsigned rcode : 4;
+ unsigned cd : 1;
+ unsigned ad : 1;
+ unsigned unused : 1;
+ unsigned ra : 1;
+#endif
+ unsigned qdcount : 16;
+ unsigned ancount : 16;
+ unsigned nscount : 16;
+ unsigned arcount : 16;
+} HEADER;
+
+#define PACKETSZ NS_PACKETSZ
+#define MAXDNAME NS_MAXDNAME
+#define MAXCDNAME NS_MAXCDNAME
+#define MAXLABEL NS_MAXLABEL
+#define HFIXEDSZ NS_HFIXEDSZ
+#define QFIXEDSZ NS_QFIXEDSZ
+#define RRFIXEDSZ NS_RRFIXEDSZ
+#define INT32SZ NS_INT32SZ
+#define INT16SZ NS_INT16SZ
+#define INT8SZ NS_INT8SZ
+#define INADDRSZ NS_INADDRSZ
+#define IN6ADDRSZ NS_IN6ADDRSZ
+#define INDIR_MASK NS_CMPRSFLGS
+#define NAMESERVER_PORT NS_DEFAULTPORT
+
+#define S_ZONE ns_s_zn
+#define S_PREREQ ns_s_pr
+#define S_UPDATE ns_s_ud
+#define S_ADDT ns_s_ar
+
+#define QUERY ns_o_query
+#define IQUERY ns_o_iquery
+#define STATUS ns_o_status
+#define NS_NOTIFY_OP ns_o_notify
+#define NS_UPDATE_OP ns_o_update
+
+#define NOERROR ns_r_noerror
+#define FORMERR ns_r_formerr
+#define SERVFAIL ns_r_servfail
+#define NXDOMAIN ns_r_nxdomain
+#define NOTIMP ns_r_notimpl
+#define REFUSED ns_r_refused
+#define YXDOMAIN ns_r_yxdomain
+#define YXRRSET ns_r_yxrrset
+#define NXRRSET ns_r_nxrrset
+#define NOTAUTH ns_r_notauth
+#define NOTZONE ns_r_notzone
+
+#define DELETE ns_uop_delete
+#define ADD ns_uop_add
+
+#define T_A ns_t_a
+#define T_NS ns_t_ns
+#define T_MD ns_t_md
+#define T_MF ns_t_mf
+#define T_CNAME ns_t_cname
+#define T_SOA ns_t_soa
+#define T_MB ns_t_mb
+#define T_MG ns_t_mg
+#define T_MR ns_t_mr
+#define T_NULL ns_t_null
+#define T_WKS ns_t_wks
+#define T_PTR ns_t_ptr
+#define T_HINFO ns_t_hinfo
+#define T_MINFO ns_t_minfo
+#define T_MX ns_t_mx
+#define T_TXT ns_t_txt
+#define T_RP ns_t_rp
+#define T_AFSDB ns_t_afsdb
+#define T_X25 ns_t_x25
+#define T_ISDN ns_t_isdn
+#define T_RT ns_t_rt
+#define T_NSAP ns_t_nsap
+#define T_NSAP_PTR ns_t_nsap_ptr
+#define T_SIG ns_t_sig
+#define T_KEY ns_t_key
+#define T_PX ns_t_px
+#define T_GPOS ns_t_gpos
+#define T_AAAA ns_t_aaaa
+#define T_LOC ns_t_loc
+#define T_NXT ns_t_nxt
+#define T_EID ns_t_eid
+#define T_NIMLOC ns_t_nimloc
+#define T_SRV ns_t_srv
+#define T_ATMA ns_t_atma
+#define T_NAPTR ns_t_naptr
+#define T_A6 ns_t_a6
+#define T_DNAME ns_t_dname
+#define T_TSIG ns_t_tsig
+#define T_IXFR ns_t_ixfr
+#define T_AXFR ns_t_axfr
+#define T_MAILB ns_t_mailb
+#define T_MAILA ns_t_maila
+#define T_ANY ns_t_any
+
+#define C_IN ns_c_in
+#define C_CHAOS ns_c_chaos
+#define C_HS ns_c_hs
+#define C_NONE ns_c_none
+#define C_ANY ns_c_any
+
+#define GETSHORT NS_GET16
+#define GETLONG NS_GET32
+#define PUTSHORT NS_PUT16
+#define PUTLONG NS_PUT32
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_ARPA_NAMESER_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/arpa/nameser_compat.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/arpa/nameser_compat.h
new file mode 100644
index 0000000..ee3b1a9
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/arpa/nameser_compat.h
@@ -0,0 +1 @@
+#include <arpa/nameser.h>
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/arpa/telnet.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/arpa/telnet.h
new file mode 100644
index 0000000..2da3eda
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/arpa/telnet.h
@@ -0,0 +1,279 @@
+#ifndef SYSROOT_ARPA_TELNET_H_
+#define SYSROOT_ARPA_TELNET_H_
+
+#define IAC 255
+#define DONT 254
+#define DO 253
+#define WONT 252
+#define WILL 251
+#define SB 250
+#define GA 249
+#define EL 248
+#define EC 247
+#define AYT 246
+#define AO 245
+#define IP 244
+#define BREAK 243
+#define DM 242
+#define NOP 241
+#define SE 240
+#define EOR 239
+#define ABORT 238
+#define SUSP 237
+#define xEOF 236
+
+#define SYNCH 242
+
+#define telcmds \
+ ((char[][6]){"EOF", "SUSP", "ABORT", "EOR", "SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", \
+ "EC", "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC", 0})
+
+#define TELCMD_FIRST xEOF
+#define TELCMD_LAST IAC
+#define TELCMD_OK(x) ((unsigned int)(x) <= TELCMD_LAST && (unsigned int)(x) >= TELCMD_FIRST)
+#define TELCMD(x) telcmds[(x)-TELCMD_FIRST]
+
+#define TELOPT_BINARY 0
+#define TELOPT_ECHO 1
+#define TELOPT_RCP 2
+#define TELOPT_SGA 3
+#define TELOPT_NAMS 4
+#define TELOPT_STATUS 5
+#define TELOPT_TM 6
+#define TELOPT_RCTE 7
+#define TELOPT_NAOL 8
+#define TELOPT_NAOP 9
+#define TELOPT_NAOCRD 10
+#define TELOPT_NAOHTS 11
+#define TELOPT_NAOHTD 12
+#define TELOPT_NAOFFD 13
+#define TELOPT_NAOVTS 14
+#define TELOPT_NAOVTD 15
+#define TELOPT_NAOLFD 16
+#define TELOPT_XASCII 17
+#define TELOPT_LOGOUT 18
+#define TELOPT_BM 19
+#define TELOPT_DET 20
+#define TELOPT_SUPDUP 21
+#define TELOPT_SUPDUPOUTPUT 22
+#define TELOPT_SNDLOC 23
+#define TELOPT_TTYPE 24
+#define TELOPT_EOR 25
+#define TELOPT_TUID 26
+#define TELOPT_OUTMRK 27
+#define TELOPT_TTYLOC 28
+#define TELOPT_3270REGIME 29
+#define TELOPT_X3PAD 30
+#define TELOPT_NAWS 31
+#define TELOPT_TSPEED 32
+#define TELOPT_LFLOW 33
+#define TELOPT_LINEMODE 34
+#define TELOPT_XDISPLOC 35
+#define TELOPT_OLD_ENVIRON 36
+#define TELOPT_AUTHENTICATION 37 /* Authenticate */
+#define TELOPT_ENCRYPT 38
+#define TELOPT_NEW_ENVIRON 39
+#define TELOPT_EXOPL 255
+
+#define NTELOPTS (1 + TELOPT_NEW_ENVIRON)
+#ifdef TELOPTS
+char* telopts[NTELOPTS + 1] = {
+ "BINARY",
+ "ECHO",
+ "RCP",
+ "SUPPRESS GO AHEAD",
+ "NAME",
+ "STATUS",
+ "TIMING MARK",
+ "RCTE",
+ "NAOL",
+ "NAOP",
+ "NAOCRD",
+ "NAOHTS",
+ "NAOHTD",
+ "NAOFFD",
+ "NAOVTS",
+ "NAOVTD",
+ "NAOLFD",
+ "EXTEND ASCII",
+ "LOGOUT",
+ "BYTE MACRO",
+ "DATA ENTRY TERMINAL",
+ "SUPDUP",
+ "SUPDUP OUTPUT",
+ "SEND LOCATION",
+ "TERMINAL TYPE",
+ "END OF RECORD",
+ "TACACS UID",
+ "OUTPUT MARKING",
+ "TTYLOC",
+ "3270 REGIME",
+ "X.3 PAD",
+ "NAWS",
+ "TSPEED",
+ "LFLOW",
+ "LINEMODE",
+ "XDISPLOC",
+ "OLD-ENVIRON",
+ "AUTHENTICATION",
+ "ENCRYPT",
+ "NEW-ENVIRON",
+ 0,
+};
+#define TELOPT_FIRST TELOPT_BINARY
+#define TELOPT_LAST TELOPT_NEW_ENVIRON
+#define TELOPT_OK(x) ((unsigned int)(x) <= TELOPT_LAST)
+#define TELOPT(x) telopts[(x)-TELOPT_FIRST]
+#endif
+
+#define TELQUAL_IS 0
+#define TELQUAL_SEND 1
+#define TELQUAL_INFO 2
+#define TELQUAL_REPLY 2
+#define TELQUAL_NAME 3
+
+#define LFLOW_OFF 0
+#define LFLOW_ON 1
+#define LFLOW_RESTART_ANY 2
+#define LFLOW_RESTART_XON 3
+
+#define LM_MODE 1
+#define LM_FORWARDMASK 2
+#define LM_SLC 3
+
+#define MODE_EDIT 0x01
+#define MODE_TRAPSIG 0x02
+#define MODE_ACK 0x04
+#define MODE_SOFT_TAB 0x08
+#define MODE_LIT_ECHO 0x10
+
+#define MODE_MASK 0x1f
+
+#define MODE_FLOW 0x0100
+#define MODE_ECHO 0x0200
+#define MODE_INBIN 0x0400
+#define MODE_OUTBIN 0x0800
+#define MODE_FORCE 0x1000
+
+#define SLC_SYNCH 1
+#define SLC_BRK 2
+#define SLC_IP 3
+#define SLC_AO 4
+#define SLC_AYT 5
+#define SLC_EOR 6
+#define SLC_ABORT 7
+#define SLC_EOF 8
+#define SLC_SUSP 9
+#define SLC_EC 10
+#define SLC_EL 11
+#define SLC_EW 12
+#define SLC_RP 13
+#define SLC_LNEXT 14
+#define SLC_XON 15
+#define SLC_XOFF 16
+#define SLC_FORW1 17
+#define SLC_FORW2 18
+
+#define NSLC 18
+
+#define SLC_NAMELIST \
+ "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", "ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \
+ "LNEXT", "XON", "XOFF", "FORW1", "FORW2", 0,
+#ifdef SLC_NAMES
+char* slc_names[] = {SLC_NAMELIST};
+#else
+extern char* slc_names[];
+#define SLC_NAMES SLC_NAMELIST
+#endif
+
+#define SLC_NAME_OK(x) ((unsigned int)(x) <= NSLC)
+#define SLC_NAME(x) slc_names[x]
+
+#define SLC_NOSUPPORT 0
+#define SLC_CANTCHANGE 1
+#define SLC_VARIABLE 2
+#define SLC_DEFAULT 3
+#define SLC_LEVELBITS 0x03
+
+#define SLC_FUNC 0
+#define SLC_FLAGS 1
+#define SLC_VALUE 2
+
+#define SLC_ACK 0x80
+#define SLC_FLUSHIN 0x40
+#define SLC_FLUSHOUT 0x20
+
+#define OLD_ENV_VAR 1
+#define OLD_ENV_VALUE 0
+#define NEW_ENV_VAR 0
+#define NEW_ENV_VALUE 1
+#define ENV_ESC 2
+#define ENV_USERVAR 3
+
+#define AUTH_WHO_CLIENT 0
+#define AUTH_WHO_SERVER 1
+#define AUTH_WHO_MASK 1
+
+#define AUTH_HOW_ONE_WAY 0
+#define AUTH_HOW_MUTUAL 2
+#define AUTH_HOW_MASK 2
+
+#define AUTHTYPE_NULL 0
+#define AUTHTYPE_KERBEROS_V4 1
+#define AUTHTYPE_KERBEROS_V5 2
+#define AUTHTYPE_SPX 3
+#define AUTHTYPE_MINK 4
+#define AUTHTYPE_CNT 5
+
+#define AUTHTYPE_TEST 99
+
+#ifdef AUTH_NAMES
+char* authtype_names[] = {
+ "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", 0,
+};
+#else
+extern char* authtype_names[];
+#endif
+
+#define AUTHTYPE_NAME_OK(x) ((unsigned int)(x) < AUTHTYPE_CNT)
+#define AUTHTYPE_NAME(x) authtype_names[x]
+
+#define ENCRYPT_IS 0
+#define ENCRYPT_SUPPORT 1
+#define ENCRYPT_REPLY 2
+#define ENCRYPT_START 3
+#define ENCRYPT_END 4
+#define ENCRYPT_REQSTART 5
+#define ENCRYPT_REQEND 6
+#define ENCRYPT_ENC_KEYID 7
+#define ENCRYPT_DEC_KEYID 8
+#define ENCRYPT_CNT 9
+
+#define ENCTYPE_ANY 0
+#define ENCTYPE_DES_CFB64 1
+#define ENCTYPE_DES_OFB64 2
+#define ENCTYPE_CNT 3
+
+#ifdef ENCRYPT_NAMES
+char* encrypt_names[] = {
+ "IS", "SUPPORT", "REPLY", "START", "END", "REQUEST-START",
+ "REQUEST-END", "ENC-KEYID", "DEC-KEYID", 0,
+};
+char* enctype_names[] = {
+ "ANY",
+ "DES_CFB64",
+ "DES_OFB64",
+ 0,
+};
+#else
+extern char* encrypt_names[];
+extern char* enctype_names[];
+#endif
+
+#define ENCRYPT_NAME_OK(x) ((unsigned int)(x) < ENCRYPT_CNT)
+#define ENCRYPT_NAME(x) encrypt_names[x]
+
+#define ENCTYPE_NAME_OK(x) ((unsigned int)(x) < ENCTYPE_CNT)
+#define ENCTYPE_NAME(x) enctype_names[x]
+
+#endif // SYSROOT_ARPA_TELNET_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/arpa/tftp.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/arpa/tftp.h
new file mode 100644
index 0000000..e091368
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/arpa/tftp.h
@@ -0,0 +1,32 @@
+#ifndef SYSROOT_ARPA_TFTP_H_
+#define SYSROOT_ARPA_TFTP_H_
+
+#define SEGSIZE 512
+#define RRQ 01
+#define WRQ 02
+#define DATA 03
+#define ACK 04
+#define ERROR 05
+struct tftphdr {
+ short th_opcode;
+ union {
+ unsigned short tu_block;
+ short tu_code;
+ char tu_stuff[1];
+ } th_u;
+ char th_data[1];
+};
+#define th_block th_u.tu_block
+#define th_code th_u.tu_code
+#define th_stuff th_u.tu_stuff
+#define th_msg th_data
+#define EUNDEF 0
+#define ENOTFOUND 1
+#define EACCESS 2
+#define ENOSPACE 3
+#define EBADOP 4
+#define EBADID 5
+#define EEXISTS 6
+#define ENOUSER 7
+
+#endif // SYSROOT_ARPA_TFTP_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/assert.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/assert.h
new file mode 100644
index 0000000..02e96dc
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/assert.h
@@ -0,0 +1,23 @@
+#include <features.h>
+
+#undef assert
+
+#ifdef NDEBUG
+#define assert(x) (void)0
+#else
+#define assert(x) ((void)((x) || (__assert_fail(#x, __FILE__, __LINE__, __func__), 0)))
+#endif
+
+#if __STDC_VERSION__ >= 201112L && !defined(__cplusplus) && !defined(static_assert)
+#define static_assert _Static_assert
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void __assert_fail(const char*, const char*, int, const char*);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/aarch64/endian.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/aarch64/endian.h
new file mode 100644
index 0000000..7a74d2f
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/aarch64/endian.h
@@ -0,0 +1,5 @@
+#if __AARCH64EB__
+#define __BYTE_ORDER __BIG_ENDIAN
+#else
+#define __BYTE_ORDER __LITTLE_ENDIAN
+#endif
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/aarch64/fenv.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/aarch64/fenv.h
new file mode 100644
index 0000000..a370540
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/aarch64/fenv.h
@@ -0,0 +1,19 @@
+#define FE_INVALID 1
+#define FE_DIVBYZERO 2
+#define FE_OVERFLOW 4
+#define FE_UNDERFLOW 8
+#define FE_INEXACT 16
+#define FE_ALL_EXCEPT 31
+#define FE_TONEAREST 0
+#define FE_DOWNWARD 0x800000
+#define FE_UPWARD 0x400000
+#define FE_TOWARDZERO 0xc00000
+
+typedef unsigned int fexcept_t;
+
+typedef struct {
+ unsigned int __fpcr;
+ unsigned int __fpsr;
+} fenv_t;
+
+#define FE_DFL_ENV ((const fenv_t*)-1)
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/aarch64/io.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/aarch64/io.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/aarch64/io.h
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/aarch64/ioctl.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/aarch64/ioctl.h
new file mode 100644
index 0000000..40835ba
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/aarch64/ioctl.h
@@ -0,0 +1,213 @@
+#define _IOC(a, b, c, d) (((a) << 30) | ((b) << 8) | (c) | ((d) << 16))
+#define _IOC_NONE 0U
+#define _IOC_WRITE 1U
+#define _IOC_READ 2U
+
+#define _IO(a, b) _IOC(_IOC_NONE, (a), (b), 0)
+#define _IOW(a, b, c) _IOC(_IOC_WRITE, (a), (b), sizeof(c))
+#define _IOR(a, b, c) _IOC(_IOC_READ, (a), (b), sizeof(c))
+#define _IOWR(a, b, c) _IOC(_IOC_READ | _IOC_WRITE, (a), (b), sizeof(c))
+
+#define TCGETS 0x5401
+#define TCSETS 0x5402
+#define TCSETSW 0x5403
+#define TCSETSF 0x5404
+#define TCGETA 0x5405
+#define TCSETA 0x5406
+#define TCSETAW 0x5407
+#define TCSETAF 0x5408
+#define TCSBRK 0x5409
+#define TCXONC 0x540A
+#define TCFLSH 0x540B
+#define TIOCEXCL 0x540C
+#define TIOCNXCL 0x540D
+#define TIOCSCTTY 0x540E
+#define TIOCGPGRP 0x540F
+#define TIOCSPGRP 0x5410
+#define TIOCOUTQ 0x5411
+#define TIOCSTI 0x5412
+#define TIOCGWINSZ 0x5413
+#define TIOCSWINSZ 0x5414
+#define TIOCMGET 0x5415
+#define TIOCMBIS 0x5416
+#define TIOCMBIC 0x5417
+#define TIOCMSET 0x5418
+#define TIOCGSOFTCAR 0x5419
+#define TIOCSSOFTCAR 0x541A
+#define FIONREAD 0x541B
+#define TIOCINQ FIONREAD
+#define TIOCLINUX 0x541C
+#define TIOCCONS 0x541D
+#define TIOCGSERIAL 0x541E
+#define TIOCSSERIAL 0x541F
+#define TIOCPKT 0x5420
+#define FIONBIO 0x5421
+#define TIOCNOTTY 0x5422
+#define TIOCSETD 0x5423
+#define TIOCGETD 0x5424
+#define TCSBRKP 0x5425
+#define TIOCTTYGSTRUCT 0x5426
+#define TIOCSBRK 0x5427
+#define TIOCCBRK 0x5428
+#define TIOCGSID 0x5429
+#define TIOCGRS485 0x542E
+#define TIOCSRS485 0x542F
+#define TIOCGPTN _IOR('T', 0x30, unsigned int)
+#define TIOCSPTLCK _IOW('T', 0x31, int)
+#define TIOCGDEV _IOR('T', 0x32, unsigned int)
+#define TCGETX 0x5432
+#define TCSETX 0x5433
+#define TCSETXF 0x5434
+#define TCSETXW 0x5435
+#define TIOCSIG 0x40045436
+#define TIOCVHANGUP 0x5437
+#define TIOCGPKT 0x80045438
+#define TIOCGPTLCK 0x80045439
+#define TIOCGEXCL 0x80045440
+
+#define FIONCLEX 0x5450
+#define FIOCLEX 0x5451
+#define FIOASYNC 0x5452
+#define TIOCSERCONFIG 0x5453
+#define TIOCSERGWILD 0x5454
+#define TIOCSERSWILD 0x5455
+#define TIOCGLCKTRMIOS 0x5456
+#define TIOCSLCKTRMIOS 0x5457
+#define TIOCSERGSTRUCT 0x5458
+#define TIOCSERGETLSR 0x5459
+#define TIOCSERGETMULTI 0x545A
+#define TIOCSERSETMULTI 0x545B
+
+#define TIOCMIWAIT 0x545C
+#define TIOCGICOUNT 0x545D
+#define FIOQSIZE 0x5460
+
+#define TIOCPKT_DATA 0
+#define TIOCPKT_FLUSHREAD 1
+#define TIOCPKT_FLUSHWRITE 2
+#define TIOCPKT_STOP 4
+#define TIOCPKT_START 8
+#define TIOCPKT_NOSTOP 16
+#define TIOCPKT_DOSTOP 32
+#define TIOCPKT_IOCTL 64
+
+#define TIOCSER_TEMT 0x01
+
+struct winsize {
+ unsigned short ws_row;
+ unsigned short ws_col;
+ unsigned short ws_xpixel;
+ unsigned short ws_ypixel;
+};
+
+#define TIOCM_LE 0x001
+#define TIOCM_DTR 0x002
+#define TIOCM_RTS 0x004
+#define TIOCM_ST 0x008
+#define TIOCM_SR 0x010
+#define TIOCM_CTS 0x020
+#define TIOCM_CAR 0x040
+#define TIOCM_RNG 0x080
+#define TIOCM_DSR 0x100
+#define TIOCM_CD TIOCM_CAR
+#define TIOCM_RI TIOCM_RNG
+#define TIOCM_OUT1 0x2000
+#define TIOCM_OUT2 0x4000
+#define TIOCM_LOOP 0x8000
+#define TIOCM_MODEM_BITS TIOCM_OUT2
+
+#define N_TTY 0
+#define N_SLIP 1
+#define N_MOUSE 2
+#define N_PPP 3
+#define N_STRIP 4
+#define N_AX25 5
+#define N_X25 6
+#define N_6PACK 7
+#define N_MASC 8
+#define N_R3964 9
+#define N_PROFIBUS_FDL 10
+#define N_IRDA 11
+#define N_SMSBLOCK 12
+#define N_HDLC 13
+#define N_SYNC_PPP 14
+#define N_HCI 15
+#define N_GIGASET_M101 16
+#define N_SLCAN 17
+#define N_PPS 18
+#define N_V253 19
+#define N_CAIF 20
+#define N_GSM0710 21
+#define N_TI_WL 22
+#define N_TRACESINK 23
+#define N_TRACEROUTER 24
+
+#define FIOSETOWN 0x8901
+#define SIOCSPGRP 0x8902
+#define FIOGETOWN 0x8903
+#define SIOCGPGRP 0x8904
+#define SIOCATMARK 0x8905
+#define SIOCGSTAMP 0x8906
+#define SIOCGSTAMPNS 0x8907
+
+#define SIOCADDRT 0x890B
+#define SIOCDELRT 0x890C
+#define SIOCRTMSG 0x890D
+
+#define SIOCGIFNAME 0x8910
+#define SIOCSIFLINK 0x8911
+#define SIOCGIFCONF 0x8912
+#define SIOCGIFFLAGS 0x8913
+#define SIOCSIFFLAGS 0x8914
+#define SIOCGIFADDR 0x8915
+#define SIOCSIFADDR 0x8916
+#define SIOCGIFDSTADDR 0x8917
+#define SIOCSIFDSTADDR 0x8918
+#define SIOCGIFBRDADDR 0x8919
+#define SIOCSIFBRDADDR 0x891a
+#define SIOCGIFNETMASK 0x891b
+#define SIOCSIFNETMASK 0x891c
+#define SIOCGIFMETRIC 0x891d
+#define SIOCSIFMETRIC 0x891e
+#define SIOCGIFMEM 0x891f
+#define SIOCSIFMEM 0x8920
+#define SIOCGIFMTU 0x8921
+#define SIOCSIFMTU 0x8922
+#define SIOCSIFHWADDR 0x8924
+#define SIOCGIFENCAP 0x8925
+#define SIOCSIFENCAP 0x8926
+#define SIOCGIFHWADDR 0x8927
+#define SIOCGIFSLAVE 0x8929
+#define SIOCSIFSLAVE 0x8930
+#define SIOCADDMULTI 0x8931
+#define SIOCDELMULTI 0x8932
+#define SIOCGIFINDEX 0x8933
+#define SIOGIFINDEX SIOCGIFINDEX
+#define SIOCSIFPFLAGS 0x8934
+#define SIOCGIFPFLAGS 0x8935
+#define SIOCDIFADDR 0x8936
+#define SIOCSIFHWBROADCAST 0x8937
+#define SIOCGIFCOUNT 0x8938
+
+#define SIOCGIFBR 0x8940
+#define SIOCSIFBR 0x8941
+
+#define SIOCGIFTXQLEN 0x8942
+#define SIOCSIFTXQLEN 0x8943
+
+#define SIOCDARP 0x8953
+#define SIOCGARP 0x8954
+#define SIOCSARP 0x8955
+
+#define SIOCDRARP 0x8960
+#define SIOCGRARP 0x8961
+#define SIOCSRARP 0x8962
+
+#define SIOCGIFMAP 0x8970
+#define SIOCSIFMAP 0x8971
+
+#define SIOCADDDLCI 0x8980
+#define SIOCDELDLCI 0x8981
+
+#define SIOCDEVPRIVATE 0x89F0
+#define SIOCPROTOPRIVATE 0x89E0
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/aarch64/ipc.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/aarch64/ipc.h
new file mode 100644
index 0000000..26161a2
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/aarch64/ipc.h
@@ -0,0 +1,14 @@
+struct ipc_perm {
+ key_t __ipc_perm_key;
+ uid_t uid;
+ gid_t gid;
+ uid_t cuid;
+ gid_t cgid;
+ mode_t mode;
+ unsigned short __ipc_perm_seq;
+
+ unsigned long __pad1;
+ unsigned long __pad2;
+};
+
+#define IPC_64 0
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/aarch64/reg.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/aarch64/reg.h
new file mode 100644
index 0000000..2633f39
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/aarch64/reg.h
@@ -0,0 +1,2 @@
+#undef __WORDSIZE
+#define __WORDSIZE 64
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/aarch64/setjmp.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/aarch64/setjmp.h
new file mode 100644
index 0000000..c37aeb8
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/aarch64/setjmp.h
@@ -0,0 +1 @@
+typedef unsigned long long int __jmp_buf[23];
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/aarch64/signal.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/aarch64/signal.h
new file mode 100644
index 0000000..64e57f3
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/aarch64/signal.h
@@ -0,0 +1,107 @@
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define MINSIGSTKSZ 6144
+#define SIGSTKSZ 12288
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+typedef unsigned long greg_t;
+typedef unsigned long gregset_t[34];
+
+typedef struct {
+ long double vregs[32];
+ unsigned int fpsr;
+ unsigned int fpcr;
+} fpregset_t;
+typedef struct sigcontext {
+ unsigned long fault_address;
+ unsigned long regs[31];
+ unsigned long sp, pc, pstate;
+ long double __reserved[256];
+} mcontext_t;
+
+#define FPSIMD_MAGIC 0x46508001
+#define ESR_MAGIC 0x45535201
+struct _aarch64_ctx {
+ unsigned int magic;
+ unsigned int size;
+};
+struct fpsimd_context {
+ struct _aarch64_ctx head;
+ unsigned int fpsr;
+ unsigned int fpcr;
+ long double vregs[32];
+};
+struct esr_context {
+ struct _aarch64_ctx head;
+ unsigned long esr;
+};
+#else
+typedef struct {
+ long double __regs[18 + 256];
+} mcontext_t;
+#endif
+
+struct sigaltstack {
+ void* ss_sp;
+ int ss_flags;
+ size_t ss_size;
+};
+
+typedef struct __ucontext {
+ unsigned long uc_flags;
+ struct ucontext* uc_link;
+ stack_t uc_stack;
+ sigset_t uc_sigmask;
+ mcontext_t uc_mcontext;
+} ucontext_t;
+
+#define SA_NOCLDSTOP 1
+#define SA_NOCLDWAIT 2
+#define SA_SIGINFO 4
+#define SA_ONSTACK 0x08000000
+#define SA_RESTART 0x10000000
+#define SA_NODEFER 0x40000000
+#define SA_RESETHAND 0x80000000
+#define SA_RESTORER 0x04000000
+
+#endif
+
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGIOT SIGABRT
+#define SIGBUS 7
+#define SIGFPE 8
+#define SIGKILL 9
+#define SIGUSR1 10
+#define SIGSEGV 11
+#define SIGUSR2 12
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGSTKFLT 16
+#define SIGCHLD 17
+#define SIGCONT 18
+#define SIGSTOP 19
+#define SIGTSTP 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGURG 23
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGIO 29
+#define SIGPOLL 29
+#define SIGPWR 30
+#define SIGSYS 31
+#define SIGUNUSED SIGSYS
+
+#define _NSIG 65
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/aarch64/stat.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/aarch64/stat.h
new file mode 100644
index 0000000..02102fa
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/aarch64/stat.h
@@ -0,0 +1,18 @@
+struct stat {
+ dev_t st_dev;
+ ino_t st_ino;
+ mode_t st_mode;
+ nlink_t st_nlink;
+ uid_t st_uid;
+ gid_t st_gid;
+ dev_t st_rdev;
+ unsigned long __pad;
+ off_t st_size;
+ blksize_t st_blksize;
+ int __pad2;
+ blkcnt_t st_blocks;
+ struct timespec st_atim;
+ struct timespec st_mtim;
+ struct timespec st_ctim;
+ unsigned __unused1[2];
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/alltypes.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/alltypes.h
new file mode 100644
index 0000000..95da44c
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/alltypes.h
@@ -0,0 +1,544 @@
+#if defined(__cplusplus) && !defined(__clang__)
+#define __C11_ATOMIC(t) t
+#else
+#define __C11_ATOMIC(t) _Atomic(t)
+#endif
+
+#if defined(__NEED_uint8_t) && !defined(__DEFINED_uint8_t)
+typedef __UINT8_TYPE__ uint8_t;
+#define __DEFINED_uint8_t
+#endif
+
+#if defined(__NEED_uint16_t) && !defined(__DEFINED_uint16_t)
+typedef __UINT16_TYPE__ uint16_t;
+#define __DEFINED_uint16_t
+#endif
+
+#if defined(__NEED_uint32_t) && !defined(__DEFINED_uint32_t)
+typedef __UINT32_TYPE__ uint32_t;
+#define __DEFINED_uint32_t
+#endif
+
+#if defined(__NEED_uint64_t) && !defined(__DEFINED_uint64_t)
+typedef __UINT64_TYPE__ uint64_t;
+#define __DEFINED_uint64_t
+#endif
+
+#if defined(__NEED_int8_t) && !defined(__DEFINED_int8_t)
+typedef __INT8_TYPE__ int8_t;
+#define __DEFINED_int8_t
+#endif
+
+#if defined(__NEED_int16_t) && !defined(__DEFINED_int16_t)
+typedef __INT16_TYPE__ int16_t;
+#define __DEFINED_int16_t
+#endif
+
+#if defined(__NEED_int32_t) && !defined(__DEFINED_int32_t)
+typedef __INT32_TYPE__ int32_t;
+#define __DEFINED_int32_t
+#endif
+
+#if defined(__NEED_int64_t) && !defined(__DEFINED_int64_t)
+typedef __INT64_TYPE__ int64_t;
+#define __DEFINED_int64_t
+#endif
+
+#if defined(__NEED_uint_least8_t) && !defined(__DEFINED_uint_least8_t)
+typedef __UINT_LEAST8_TYPE__ uint_least8_t;
+#define __DEFINED_uint_least8_t
+#endif
+
+#if defined(__NEED_uint_least16_t) && !defined(__DEFINED_uint_least16_t)
+typedef __UINT_LEAST16_TYPE__ uint_least16_t;
+#define __DEFINED_uint_least16_t
+#endif
+
+#if defined(__NEED_uint_least32_t) && !defined(__DEFINED_uint_least32_t)
+typedef __UINT_LEAST32_TYPE__ uint_least32_t;
+#define __DEFINED_uint_least32_t
+#endif
+
+#if defined(__NEED_uint_least64_t) && !defined(__DEFINED_uint_least64_t)
+typedef __UINT_LEAST64_TYPE__ uint_least64_t;
+#define __DEFINED_uint_least64_t
+#endif
+
+#if defined(__NEED_int_least8_t) && !defined(__DEFINED_int_least8_t)
+typedef __INT_LEAST8_TYPE__ int_least8_t;
+#define __DEFINED_int_least8_t
+#endif
+
+#if defined(__NEED_int_least16_t) && !defined(__DEFINED_int_least16_t)
+typedef __INT_LEAST16_TYPE__ int_least16_t;
+#define __DEFINED_int_least16_t
+#endif
+
+#if defined(__NEED_int_least32_t) && !defined(__DEFINED_int_least32_t)
+typedef __INT_LEAST32_TYPE__ int_least32_t;
+#define __DEFINED_int_least32_t
+#endif
+
+#if defined(__NEED_int_least64_t) && !defined(__DEFINED_int_least64_t)
+typedef __INT_LEAST64_TYPE__ int_least64_t;
+#define __DEFINED_int_least64_t
+#endif
+
+#if defined(__NEED_uint_fast8_t) && !defined(__DEFINED_uint_fast8_t)
+typedef __UINT_FAST8_TYPE__ uint_fast8_t;
+#define __DEFINED_uint_fast8_t
+#endif
+
+#if defined(__NEED_uint_fast16_t) && !defined(__DEFINED_uint_fast16_t)
+typedef __UINT_FAST16_TYPE__ uint_fast16_t;
+#define __DEFINED_uint_fast16_t
+#endif
+
+#if defined(__NEED_uint_fast32_t) && !defined(__DEFINED_uint_fast32_t)
+typedef __UINT_FAST32_TYPE__ uint_fast32_t;
+#define __DEFINED_uint_fast32_t
+#endif
+
+#if defined(__NEED_uint_fast64_t) && !defined(__DEFINED_uint_fast64_t)
+typedef __UINT_FAST64_TYPE__ uint_fast64_t;
+#define __DEFINED_uint_fast64_t
+#endif
+
+#if defined(__NEED_int_fast8_t) && !defined(__DEFINED_int_fast8_t)
+typedef __INT_FAST8_TYPE__ int_fast8_t;
+#define __DEFINED_int_fast8_t
+#endif
+
+#if defined(__NEED_int_fast16_t) && !defined(__DEFINED_int_fast16_t)
+typedef __INT_FAST16_TYPE__ int_fast16_t;
+#define __DEFINED_int_fast16_t
+#endif
+
+#if defined(__NEED_int_fast32_t) && !defined(__DEFINED_int_fast32_t)
+typedef __INT_FAST32_TYPE__ int_fast32_t;
+#define __DEFINED_int_fast32_t
+#endif
+
+#if defined(__NEED_int_fast64_t) && !defined(__DEFINED_int_fast64_t)
+typedef __INT_FAST64_TYPE__ int_fast64_t;
+#define __DEFINED_int_fast64_t
+#endif
+
+#if defined(__NEED_intptr_t) && !defined(__DEFINED_intptr_t)
+typedef __INTPTR_TYPE__ intptr_t;
+#define __DEFINED_intptr_t
+#endif
+
+#if defined(__NEED_uintptr_t) && !defined(__DEFINED_uintptr_t)
+typedef __UINTPTR_TYPE__ uintptr_t;
+#define __DEFINED_uintptr_t
+#endif
+
+#if defined(__NEED_intmax_t) && !defined(__DEFINED_intmax_t)
+typedef __INTMAX_TYPE__ intmax_t;
+#define __DEFINED_intmax_t
+#endif
+
+#if defined(__NEED_uintmax_t) && !defined(__DEFINED_uintmax_t)
+typedef __UINTMAX_TYPE__ uintmax_t;
+#define __DEFINED_uintmax_t
+#endif
+
+#ifndef __cplusplus
+#if defined(__NEED_wchar_t) && !defined(__DEFINED_wchar_t)
+typedef __WCHAR_TYPE__ wchar_t;
+#define __DEFINED_wchar_t
+#endif
+#endif
+
+#if defined(__NEED_wint_t) && !defined(__DEFINED_wint_t)
+typedef unsigned wint_t;
+#define __DEFINED_wint_t
+#endif
+
+#if defined(__NEED_wctype_t) && !defined(__DEFINED_wctype_t)
+typedef unsigned long wctype_t;
+#define __DEFINED_wctype_t
+#endif
+
+#if defined(__NEED_size_t) && !defined(__DEFINED_size_t)
+typedef __SIZE_TYPE__ size_t;
+#define __DEFINED_size_t
+#endif
+
+#if defined(__NEED_ptrdiff_t) && !defined(__DEFINED_ptrdiff_t)
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+#define __DEFINED_ptrdiff_t
+#endif
+
+#if defined(__NEED_va_list) && !defined(__DEFINED_va_list)
+typedef __builtin_va_list va_list;
+#define __DEFINED_va_list
+#endif
+
+#if defined(__NEED___isoc_va_list) && !defined(__DEFINED___isoc_va_list)
+typedef __builtin_va_list __isoc_va_list;
+#define __DEFINED___isoc_va_list
+#endif
+
+#if defined(__NEED_ssize_t) && !defined(__DEFINED_ssize_t)
+typedef long ssize_t;
+#define __DEFINED_ssize_t
+#endif
+
+#if defined(__NEED_time_t) && !defined(__DEFINED_time_t)
+typedef long time_t;
+#define __DEFINED_time_t
+#endif
+
+#if defined(__NEED_max_align_t) && !defined(__DEFINED_max_align_t)
+typedef struct {
+ long long __ll;
+ long double __ld;
+} max_align_t;
+#define __DEFINED_max_align_t
+#endif
+
+#if defined(__x86_64__) && defined(__FLT_EVAL_METHOD__) && __FLT_EVAL_METHOD__ == 2
+#if defined(__NEED_float_t) && !defined(__DEFINED_float_t)
+typedef long double float_t;
+#define __DEFINED_float_t
+#endif
+
+#if defined(__NEED_double_t) && !defined(__DEFINED_double_t)
+typedef long double double_t;
+#define __DEFINED_double_t
+#endif
+
+#else
+#if defined(__NEED_float_t) && !defined(__DEFINED_float_t)
+typedef float float_t;
+#define __DEFINED_float_t
+#endif
+
+#if defined(__NEED_double_t) && !defined(__DEFINED_double_t)
+typedef double double_t;
+#define __DEFINED_double_t
+#endif
+
+#endif
+
+#if defined(__NEED_suseconds_t) && !defined(__DEFINED_suseconds_t)
+typedef long suseconds_t;
+#define __DEFINED_suseconds_t
+#endif
+
+#if defined(__NEED_useconds_t) && !defined(__DEFINED_useconds_t)
+typedef unsigned useconds_t;
+#define __DEFINED_useconds_t
+#endif
+
+#if defined(__NEED_clockid_t) && !defined(__DEFINED_clockid_t)
+typedef int clockid_t;
+#define __DEFINED_clockid_t
+#endif
+
+#if defined(__NEED_clock_t) && !defined(__DEFINED_clock_t)
+typedef long clock_t;
+#define __DEFINED_clock_t
+#endif
+
+#if defined(__NEED_pid_t) && !defined(__DEFINED_pid_t)
+typedef int pid_t;
+#define __DEFINED_pid_t
+#endif
+
+#if defined(__NEED_id_t) && !defined(__DEFINED_id_t)
+typedef unsigned id_t;
+#define __DEFINED_id_t
+#endif
+
+#if defined(__NEED_uid_t) && !defined(__DEFINED_uid_t)
+typedef unsigned uid_t;
+#define __DEFINED_uid_t
+#endif
+
+#if defined(__NEED_gid_t) && !defined(__DEFINED_gid_t)
+typedef unsigned gid_t;
+#define __DEFINED_gid_t
+#endif
+
+#if defined(__NEED_register_t) && !defined(__DEFINED_register_t)
+typedef long register_t;
+#define __DEFINED_register_t
+#endif
+
+#if defined(__NEED_nlink_t) && !defined(__DEFINED_nlink_t)
+typedef unsigned long nlink_t;
+#define __DEFINED_nlink_t
+#endif
+
+#if defined(__NEED_off_t) && !defined(__DEFINED_off_t)
+typedef long long off_t;
+#define __DEFINED_off_t
+#endif
+
+#if defined(__NEED_ino_t) && !defined(__DEFINED_ino_t)
+typedef unsigned long long ino_t;
+#define __DEFINED_ino_t
+#endif
+
+#if defined(__NEED_dev_t) && !defined(__DEFINED_dev_t)
+typedef unsigned long long dev_t;
+#define __DEFINED_dev_t
+#endif
+
+#if defined(__NEED_blksize_t) && !defined(__DEFINED_blksize_t)
+typedef long blksize_t;
+#define __DEFINED_blksize_t
+#endif
+
+#if defined(__NEED_blkcnt_t) && !defined(__DEFINED_blkcnt_t)
+typedef long long blkcnt_t;
+#define __DEFINED_blkcnt_t
+#endif
+
+#if defined(__NEED_fsblkcnt_t) && !defined(__DEFINED_fsblkcnt_t)
+typedef unsigned long long fsblkcnt_t;
+#define __DEFINED_fsblkcnt_t
+#endif
+
+#if defined(__NEED_fsfilcnt_t) && !defined(__DEFINED_fsfilcnt_t)
+typedef unsigned long long fsfilcnt_t;
+#define __DEFINED_fsfilcnt_t
+#endif
+
+#if defined(__NEED_struct_iovec) && !defined(__DEFINED_struct_iovec)
+struct iovec {
+ void* iov_base;
+ size_t iov_len;
+};
+#define __DEFINED_struct_iovec
+#endif
+
+#if defined(__NEED_struct_timeval) && !defined(__DEFINED_struct_timeval)
+struct timeval {
+ time_t tv_sec;
+ suseconds_t tv_usec;
+};
+#define __DEFINED_struct_timeval
+#endif
+
+#if defined(__NEED_struct_timespec) && !defined(__DEFINED_struct_timespec)
+struct timespec {
+ time_t tv_sec;
+ long tv_nsec;
+};
+#define __DEFINED_struct_timespec
+#endif
+
+#if defined(__NEED_key_t) && !defined(__DEFINED_key_t)
+typedef int key_t;
+#define __DEFINED_key_t
+#endif
+
+#if defined(__NEED_timer_t) && !defined(__DEFINED_timer_t)
+typedef void* timer_t;
+#define __DEFINED_timer_t
+#endif
+
+#if defined(__NEED_regoff_t) && !defined(__DEFINED_regoff_t)
+typedef long regoff_t;
+#define __DEFINED_regoff_t
+#endif
+
+#if defined(__NEED_socklen_t) && !defined(__DEFINED_socklen_t)
+typedef unsigned socklen_t;
+#define __DEFINED_socklen_t
+#endif
+
+#if defined(__NEED_sa_family_t) && !defined(__DEFINED_sa_family_t)
+typedef unsigned short sa_family_t;
+#define __DEFINED_sa_family_t
+#endif
+
+#if defined(__NEED_FILE) && !defined(__DEFINED_FILE)
+typedef struct _IO_FILE FILE;
+#define __DEFINED_FILE
+#endif
+
+#if defined(__NEED_locale_t) && !defined(__DEFINED_locale_t)
+typedef struct __locale_struct* locale_t;
+#define __DEFINED_locale_t
+#endif
+
+#if defined(__NEED_mode_t) && !defined(__DEFINED_mode_t)
+typedef unsigned mode_t;
+#define __DEFINED_mode_t
+#endif
+
+#if defined(__NEED_sigset_t) && !defined(__DEFINED_sigset_t)
+typedef struct __sigset_t {
+ unsigned long __bits[128 / sizeof(long)];
+} sigset_t;
+#define __DEFINED_sigset_t
+#endif
+
+#if defined(__NEED_pthread_once_t) && !defined(__DEFINED_pthread_once_t)
+typedef __C11_ATOMIC(int) pthread_once_t;
+#define __DEFINED_pthread_once_t
+#endif
+
+#if defined(__NEED_once_flag) && !defined(__DEFINED_once_flag)
+typedef __C11_ATOMIC(int) once_flag;
+#define __DEFINED_once_flag
+#endif
+
+#if defined(__NEED_pthread_key_t) && !defined(__DEFINED_pthread_key_t)
+typedef unsigned pthread_key_t;
+#define __DEFINED_pthread_key_t
+#endif
+
+#if defined(__NEED_pthread_spinlock_t) && !defined(__DEFINED_pthread_spinlock_t)
+typedef __C11_ATOMIC(int) pthread_spinlock_t;
+#define __DEFINED_pthread_spinlock_t
+#endif
+
+#if defined(__NEED_pthread_mutexattr_t) && !defined(__DEFINED_pthread_mutexattr_t)
+typedef struct {
+ unsigned __attr;
+} pthread_mutexattr_t;
+#define __DEFINED_pthread_mutexattr_t
+#endif
+
+#if defined(__NEED_pthread_condattr_t) && !defined(__DEFINED_pthread_condattr_t)
+typedef struct {
+ unsigned __attr;
+} pthread_condattr_t;
+#define __DEFINED_pthread_condattr_t
+#endif
+
+#if defined(__NEED_pthread_barrierattr_t) && !defined(__DEFINED_pthread_barrierattr_t)
+typedef struct {
+ unsigned __attr;
+} pthread_barrierattr_t;
+#define __DEFINED_pthread_barrierattr_t
+#endif
+
+#if defined(__NEED_pthread_rwlockattr_t) && !defined(__DEFINED_pthread_rwlockattr_t)
+typedef struct {
+ unsigned __attr[2];
+} pthread_rwlockattr_t;
+#define __DEFINED_pthread_rwlockattr_t
+#endif
+
+#ifdef __cplusplus
+#if defined(__NEED_pthread_t) && !defined(__DEFINED_pthread_t)
+typedef unsigned long pthread_t;
+#define __DEFINED_pthread_t
+#endif
+
+#else
+#if defined(__NEED_pthread_t) && !defined(__DEFINED_pthread_t)
+typedef struct __pthread* pthread_t;
+#define __DEFINED_pthread_t
+#endif
+
+#endif
+
+#if defined(__NEED_mbstate_t) && !defined(__DEFINED_mbstate_t)
+typedef struct __mbstate_t {
+ unsigned __opaque1, __opaque2;
+} mbstate_t;
+#define __DEFINED_mbstate_t
+#endif
+
+#if defined(__NEED_pthread_attr_t) && !defined(__DEFINED_pthread_attr_t)
+typedef struct {
+ const char* __name;
+ int __c11;
+ size_t _a_stacksize;
+ size_t _a_guardsize;
+ void* _a_stackaddr;
+ int _a_detach;
+ int _a_sched;
+ int _a_policy;
+ int _a_prio;
+} pthread_attr_t;
+#define __DEFINED_pthread_attr_t
+#endif
+
+#if defined(__NEED_pthread_mutex_t) && !defined(__DEFINED_pthread_mutex_t)
+typedef struct {
+ unsigned _m_attr;
+ __C11_ATOMIC(int)
+ _m_lock;
+ __C11_ATOMIC(int)
+ _m_waiters;
+ int _m_count;
+} pthread_mutex_t;
+#define __DEFINED_pthread_mutex_t
+#endif
+
+#if defined(__NEED_mtx_t) && !defined(__DEFINED_mtx_t)
+typedef struct
+#if defined(__clang__)
+ __attribute__((__capability__("mutex")))
+#endif
+{
+ int __i[1];
+} mtx_t;
+#define __DEFINED_mtx_t
+#endif
+
+#if defined(__NEED_pthread_cond_t) && !defined(__DEFINED_pthread_cond_t)
+typedef struct {
+ void* _c_head;
+ int _c_clock;
+ void* _c_tail;
+ __C11_ATOMIC(int)
+ _c_lock;
+} pthread_cond_t;
+#define __DEFINED_pthread_cond_t
+#endif
+
+#if defined(__NEED_cnd_t) && !defined(__DEFINED_cnd_t)
+typedef struct {
+ void* _c_head;
+ int _c_clock;
+ void* _c_tail;
+ __C11_ATOMIC(int) _c_lock;
+} cnd_t;
+#define __DEFINED_cnd_t
+#endif
+
+#if defined(__NEED_pthread_rwlock_t) && !defined(__DEFINED_pthread_rwlock_t)
+typedef struct {
+ __C11_ATOMIC(int)
+ _rw_lock;
+ __C11_ATOMIC(int)
+ _rw_waiters;
+} pthread_rwlock_t;
+#define __DEFINED_pthread_rwlock_t
+#endif
+
+#if defined(__NEED_pthread_barrier_t) && !defined(__DEFINED_pthread_barrier_t)
+typedef struct {
+ __C11_ATOMIC(int)
+ _b_lock;
+ __C11_ATOMIC(int)
+ _b_waiters;
+ unsigned int _b_limit;
+ __C11_ATOMIC(int)
+ _b_count;
+ __C11_ATOMIC(int)
+ _b_waiters2;
+ void* _b_inst;
+} pthread_barrier_t;
+#define __DEFINED_pthread_barrier_t
+#endif
+
+#if defined(__NEED_sem_t) && !defined(__DEFINED_sem_t)
+typedef struct {
+ __C11_ATOMIC(int)
+ _s_value;
+ __C11_ATOMIC(int)
+ _s_waiters;
+} sem_t;
+#define __DEFINED_sem_t
+#endif
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/endian.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/endian.h
new file mode 100644
index 0000000..ed44e80
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/endian.h
@@ -0,0 +1,7 @@
+#if defined(__x86_64__)
+#include "x86_64/endian.h"
+#elif defined(__aarch64__)
+#include "aarch64/endian.h"
+#else
+#error Unsupported architecture!
+#endif
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/errno.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/errno.h
new file mode 100644
index 0000000..b9ebc31
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/errno.h
@@ -0,0 +1,134 @@
+#define EPERM 1
+#define ENOENT 2
+#define ESRCH 3
+#define EINTR 4
+#define EIO 5
+#define ENXIO 6
+#define E2BIG 7
+#define ENOEXEC 8
+#define EBADF 9
+#define ECHILD 10
+#define EAGAIN 11
+#define ENOMEM 12
+#define EACCES 13
+#define EFAULT 14
+#define ENOTBLK 15
+#define EBUSY 16
+#define EEXIST 17
+#define EXDEV 18
+#define ENODEV 19
+#define ENOTDIR 20
+#define EISDIR 21
+#define EINVAL 22
+#define ENFILE 23
+#define EMFILE 24
+#define ENOTTY 25
+#define ETXTBSY 26
+#define EFBIG 27
+#define ENOSPC 28
+#define ESPIPE 29
+#define EROFS 30
+#define EMLINK 31
+#define EPIPE 32
+#define EDOM 33
+#define ERANGE 34
+#define EDEADLK 35
+#define ENAMETOOLONG 36
+#define ENOLCK 37
+#define ENOSYS 38
+#define ENOTEMPTY 39
+#define ELOOP 40
+#define EWOULDBLOCK EAGAIN
+#define ENOMSG 42
+#define EIDRM 43
+#define ECHRNG 44
+#define EL2NSYNC 45
+#define EL3HLT 46
+#define EL3RST 47
+#define ELNRNG 48
+#define EUNATCH 49
+#define ENOCSI 50
+#define EL2HLT 51
+#define EBADE 52
+#define EBADR 53
+#define EXFULL 54
+#define ENOANO 55
+#define EBADRQC 56
+#define EBADSLT 57
+#define EDEADLOCK EDEADLK
+#define EBFONT 59
+#define ENOSTR 60
+#define ENODATA 61
+#define ETIME 62
+#define ENOSR 63
+#define ENONET 64
+#define ENOPKG 65
+#define EREMOTE 66
+#define ENOLINK 67
+#define EADV 68
+#define ESRMNT 69
+#define ECOMM 70
+#define EPROTO 71
+#define EMULTIHOP 72
+#define EDOTDOT 73
+#define EBADMSG 74
+#define EOVERFLOW 75
+#define ENOTUNIQ 76
+#define EBADFD 77
+#define EREMCHG 78
+#define ELIBACC 79
+#define ELIBBAD 80
+#define ELIBSCN 81
+#define ELIBMAX 82
+#define ELIBEXEC 83
+#define EILSEQ 84
+#define ERESTART 85
+#define ESTRPIPE 86
+#define EUSERS 87
+#define ENOTSOCK 88
+#define EDESTADDRREQ 89
+#define EMSGSIZE 90
+#define EPROTOTYPE 91
+#define ENOPROTOOPT 92
+#define EPROTONOSUPPORT 93
+#define ESOCKTNOSUPPORT 94
+#define EOPNOTSUPP 95
+#define ENOTSUP EOPNOTSUPP
+#define EPFNOSUPPORT 96
+#define EAFNOSUPPORT 97
+#define EADDRINUSE 98
+#define EADDRNOTAVAIL 99
+#define ENETDOWN 100
+#define ENETUNREACH 101
+#define ENETRESET 102
+#define ECONNABORTED 103
+#define ECONNRESET 104
+#define ENOBUFS 105
+#define EISCONN 106
+#define ENOTCONN 107
+#define ESHUTDOWN 108
+#define ETOOMANYREFS 109
+#define ETIMEDOUT 110
+#define ECONNREFUSED 111
+#define EHOSTDOWN 112
+#define EHOSTUNREACH 113
+#define EALREADY 114
+#define EINPROGRESS 115
+#define ESTALE 116
+#define EUCLEAN 117
+#define ENOTNAM 118
+#define ENAVAIL 119
+#define EISNAM 120
+#define EREMOTEIO 121
+#define EDQUOT 122
+#define ENOMEDIUM 123
+#define EMEDIUMTYPE 124
+#define ECANCELED 125
+#define ENOKEY 126
+#define EKEYEXPIRED 127
+#define EKEYREVOKED 128
+#define EKEYREJECTED 129
+#define EOWNERDEAD 130
+#define ENOTRECOVERABLE 131
+#define ERFKILL 132
+#define EHWPOISON 133
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/fcntl.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/fcntl.h
new file mode 100644
index 0000000..c96e45f
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/fcntl.h
@@ -0,0 +1,7 @@
+#if defined(__x86_64__)
+#include "x86_64/fcntl.h"
+#elif defined(__aarch64__)
+#include "aarch64/fcntl.h"
+#else
+#error Unsupported architecture!
+#endif
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/fenv.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/fenv.h
new file mode 100644
index 0000000..99ca0ba
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/fenv.h
@@ -0,0 +1,7 @@
+#if defined(__x86_64__)
+#include "x86_64/fenv.h"
+#elif defined(__aarch64__)
+#include "aarch64/fenv.h"
+#else
+#error Unsupported architecture!
+#endif
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/io.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/io.h
new file mode 100644
index 0000000..480bbaf
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/io.h
@@ -0,0 +1,7 @@
+#if defined(__x86_64__)
+#include "x86_64/io.h"
+#elif defined(__aarch64__)
+#include "aarch64/io.h"
+#else
+#error Unsupported architecture!
+#endif
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/ioctl.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/ioctl.h
new file mode 100644
index 0000000..d8bcfa3
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/ioctl.h
@@ -0,0 +1,7 @@
+#if defined(__x86_64__)
+#include "x86_64/ioctl.h"
+#elif defined(__aarch64__)
+#include "aarch64/ioctl.h"
+#else
+#error Unsupported architecture!
+#endif
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/ipc.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/ipc.h
new file mode 100644
index 0000000..a81d510
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/ipc.h
@@ -0,0 +1,7 @@
+#if defined(__x86_64__)
+#include "x86_64/ipc.h"
+#elif defined(__aarch64__)
+#include "aarch64/ipc.h"
+#else
+#error Unsupported architecture!
+#endif
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/limits.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/limits.h
new file mode 100644
index 0000000..8d1910b
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/limits.h
@@ -0,0 +1,8 @@
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define PAGE_SIZE 4096
+#define LONG_BIT 64
+#endif
+
+#define LONG_MAX 0x7fffffffffffffffL
+#define LLONG_MAX 0x7fffffffffffffffLL
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/msg.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/msg.h
new file mode 100644
index 0000000..1c8034b
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/msg.h
@@ -0,0 +1,12 @@
+struct msqid_ds {
+ struct ipc_perm msg_perm;
+ time_t msg_stime;
+ time_t msg_rtime;
+ time_t msg_ctime;
+ unsigned long msg_cbytes;
+ msgqnum_t msg_qnum;
+ msglen_t msg_qbytes;
+ pid_t msg_lspid;
+ pid_t msg_lrpid;
+ unsigned long __unused[2];
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/null.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/null.h
new file mode 100644
index 0000000..76e7b77
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/null.h
@@ -0,0 +1,15 @@
+// Copyright 2017 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
+
+#ifndef SYSROOT_BITS_NULL_H_
+#define SYSROOT_BITS_NULL_H_
+
+// The compiler's <stddef.h> defines NULL without defining anything
+// else if __need_NULL is defined first.
+#define __need_NULL
+#include <stddef.h>
+
+#endif // SYSROOT_BITS_NULL_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/poll.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/poll.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/poll.h
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/posix.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/posix.h
new file mode 100644
index 0000000..8068ce9
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/posix.h
@@ -0,0 +1,2 @@
+#define _POSIX_V6_LP64_OFF64 1
+#define _POSIX_V7_LP64_OFF64 1
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/reg.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/reg.h
new file mode 100644
index 0000000..ad220cc
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/reg.h
@@ -0,0 +1,7 @@
+#if defined(__x86_64__)
+#include "x86_64/reg.h"
+#elif defined(__aarch64__)
+#include "aarch64/reg.h"
+#else
+#error Unsupported architecture!
+#endif
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/resource.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/resource.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/resource.h
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/sem.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/sem.h
new file mode 100644
index 0000000..db4102f
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/sem.h
@@ -0,0 +1,14 @@
+struct semid_ds {
+ struct ipc_perm sem_perm;
+ time_t sem_otime;
+ time_t sem_ctime;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned short sem_nsems;
+ char __sem_nsems_pad[sizeof(time_t) - sizeof(short)];
+#else
+ char __sem_nsems_pad[sizeof(time_t) - sizeof(short)];
+ unsigned short sem_nsems;
+#endif
+ time_t __unused3;
+ time_t __unused4;
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/setjmp.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/setjmp.h
new file mode 100644
index 0000000..d42af58
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/setjmp.h
@@ -0,0 +1,7 @@
+#if defined(__x86_64__)
+#include "x86_64/setjmp.h"
+#elif defined(__aarch64__)
+#include "aarch64/setjmp.h"
+#else
+#error Unsupported architecture!
+#endif
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/shm.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/shm.h
new file mode 100644
index 0000000..a3b9dcc
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/shm.h
@@ -0,0 +1,24 @@
+#define SHMLBA 4096
+
+struct shmid_ds {
+ struct ipc_perm shm_perm;
+ size_t shm_segsz;
+ time_t shm_atime;
+ time_t shm_dtime;
+ time_t shm_ctime;
+ pid_t shm_cpid;
+ pid_t shm_lpid;
+ unsigned long shm_nattch;
+ unsigned long __pad1;
+ unsigned long __pad2;
+};
+
+struct shminfo {
+ unsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];
+};
+
+struct shm_info {
+ int __used_ids;
+ unsigned long shm_tot, shm_rss, shm_swp;
+ unsigned long __swap_attempts, __swap_successes;
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/signal.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/signal.h
new file mode 100644
index 0000000..021a17f
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/signal.h
@@ -0,0 +1,7 @@
+#if defined(__x86_64__)
+#include "x86_64/signal.h"
+#elif defined(__aarch64__)
+#include "aarch64/signal.h"
+#else
+#error Unsupported architecture!
+#endif
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/socket.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/socket.h
new file mode 100644
index 0000000..1127d5b
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/socket.h
@@ -0,0 +1,33 @@
+#include <endian.h>
+
+struct msghdr {
+ void* msg_name;
+ socklen_t msg_namelen;
+ struct iovec* msg_iov;
+#if __BYTE_ORDER == __BIG_ENDIAN
+ int __pad1, msg_iovlen;
+#else
+ int msg_iovlen, __pad1;
+#endif
+ void* msg_control;
+#if __BYTE_ORDER == __BIG_ENDIAN
+ int __pad2;
+ socklen_t msg_controllen;
+#else
+ socklen_t msg_controllen;
+ int __pad2;
+#endif
+ int msg_flags;
+};
+
+struct cmsghdr {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ int __pad1;
+ socklen_t cmsg_len;
+#else
+ socklen_t cmsg_len;
+ int __pad1;
+#endif
+ int cmsg_level;
+ int cmsg_type;
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/stat.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/stat.h
new file mode 100644
index 0000000..308b256
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/stat.h
@@ -0,0 +1,7 @@
+#if defined(__x86_64__)
+#include "x86_64/stat.h"
+#elif defined(__aarch64__)
+#include "aarch64/stat.h"
+#else
+#error Unsupported architecture!
+#endif
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/statfs.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/statfs.h
new file mode 100644
index 0000000..ef2bbe3
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/statfs.h
@@ -0,0 +1,7 @@
+struct statfs {
+ unsigned long f_type, f_bsize;
+ fsblkcnt_t f_blocks, f_bfree, f_bavail;
+ fsfilcnt_t f_files, f_ffree;
+ fsid_t f_fsid;
+ unsigned long f_namelen, f_frsize, f_flags, f_spare[4];
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/termios.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/termios.h
new file mode 100644
index 0000000..d9a7359
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/termios.h
@@ -0,0 +1,159 @@
+struct termios {
+ tcflag_t c_iflag;
+ tcflag_t c_oflag;
+ tcflag_t c_cflag;
+ tcflag_t c_lflag;
+ cc_t c_line;
+ cc_t c_cc[NCCS];
+ speed_t __c_ispeed;
+ speed_t __c_ospeed;
+};
+
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+#define IGNBRK 0000001
+#define BRKINT 0000002
+#define IGNPAR 0000004
+#define PARMRK 0000010
+#define INPCK 0000020
+#define ISTRIP 0000040
+#define INLCR 0000100
+#define IGNCR 0000200
+#define ICRNL 0000400
+#define IUCLC 0001000
+#define IXON 0002000
+#define IXANY 0004000
+#define IXOFF 0010000
+#define IMAXBEL 0020000
+#define IUTF8 0040000
+
+#define OPOST 0000001
+#define OLCUC 0000002
+#define ONLCR 0000004
+#define OCRNL 0000010
+#define ONOCR 0000020
+#define ONLRET 0000040
+#define OFILL 0000100
+#define OFDEL 0000200
+#define NLDLY 0000400
+#define NL0 0000000
+#define NL1 0000400
+#define CRDLY 0003000
+#define CR0 0000000
+#define CR1 0001000
+#define CR2 0002000
+#define CR3 0003000
+#define TABDLY 0014000
+#define TAB0 0000000
+#define TAB1 0004000
+#define TAB2 0010000
+#define TAB3 0014000
+#define BSDLY 0020000
+#define BS0 0000000
+#define BS1 0020000
+#define FFDLY 0100000
+#define FF0 0000000
+#define FF1 0100000
+
+#define VTDLY 0040000
+#define VT0 0000000
+#define VT1 0040000
+
+#define B0 0000000
+#define B50 0000001
+#define B75 0000002
+#define B110 0000003
+#define B134 0000004
+#define B150 0000005
+#define B200 0000006
+#define B300 0000007
+#define B600 0000010
+#define B1200 0000011
+#define B1800 0000012
+#define B2400 0000013
+#define B4800 0000014
+#define B9600 0000015
+#define B19200 0000016
+#define B38400 0000017
+
+#define B57600 0010001
+#define B115200 0010002
+#define B230400 0010003
+#define B460800 0010004
+#define B500000 0010005
+#define B576000 0010006
+#define B921600 0010007
+#define B1000000 0010010
+#define B1152000 0010011
+#define B1500000 0010012
+#define B2000000 0010013
+#define B2500000 0010014
+#define B3000000 0010015
+#define B3500000 0010016
+#define B4000000 0010017
+
+#define CBAUD 0010017
+
+#define CSIZE 0000060
+#define CS5 0000000
+#define CS6 0000020
+#define CS7 0000040
+#define CS8 0000060
+#define CSTOPB 0000100
+#define CREAD 0000200
+#define PARENB 0000400
+#define PARODD 0001000
+#define HUPCL 0002000
+#define CLOCAL 0004000
+
+#define ISIG 0000001
+#define ICANON 0000002
+#define ECHO 0000010
+#define ECHOE 0000020
+#define ECHOK 0000040
+#define ECHONL 0000100
+#define NOFLSH 0000200
+#define TOSTOP 0000400
+#define IEXTEN 0100000
+
+#define ECHOCTL 0001000
+#define ECHOPRT 0002000
+#define ECHOKE 0004000
+#define FLUSHO 0010000
+#define PENDIN 0040000
+
+#define TCOOFF 0
+#define TCOON 1
+#define TCIOFF 2
+#define TCION 3
+
+#define TCIFLUSH 0
+#define TCOFLUSH 1
+#define TCIOFLUSH 2
+
+#define TCSANOW 0
+#define TCSADRAIN 1
+#define TCSAFLUSH 2
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define CBAUDEX 0010000
+#define CRTSCTS 020000000000
+#define EXTPROC 0200000
+#define XTABS 0014000
+#endif
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/x86_64/endian.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/x86_64/endian.h
new file mode 100644
index 0000000..172c338
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/x86_64/endian.h
@@ -0,0 +1 @@
+#define __BYTE_ORDER __LITTLE_ENDIAN
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/x86_64/fenv.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/x86_64/fenv.h
new file mode 100644
index 0000000..32e7dbf
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/x86_64/fenv.h
@@ -0,0 +1,34 @@
+#define FE_INVALID 1
+#define __FE_DENORM 2
+#define FE_DIVBYZERO 4
+#define FE_OVERFLOW 8
+#define FE_UNDERFLOW 16
+#define FE_INEXACT 32
+
+#define FE_ALL_EXCEPT 63
+
+#define FE_TONEAREST 0
+#define FE_DOWNWARD 0x400
+#define FE_UPWARD 0x800
+#define FE_TOWARDZERO 0xc00
+
+typedef unsigned short fexcept_t;
+
+typedef struct {
+ unsigned short __control_word;
+ unsigned short __unused1;
+ unsigned short __status_word;
+ unsigned short __unused2;
+ unsigned short __tags;
+ unsigned short __unused3;
+ unsigned int __eip;
+ unsigned short __cs_selector;
+ unsigned int __opcode : 11;
+ unsigned int __unused4 : 5;
+ unsigned int __data_offset;
+ unsigned short __data_selector;
+ unsigned short __unused5;
+ unsigned int __mxcsr;
+} fenv_t;
+
+#define FE_DFL_ENV ((const fenv_t*)-1)
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/x86_64/io.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/x86_64/io.h
new file mode 100644
index 0000000..7234422
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/x86_64/io.h
@@ -0,0 +1,53 @@
+static __inline void outb(unsigned char __val, unsigned short __port) {
+ __asm__ volatile("outb %0,%1" : : "a"(__val), "dN"(__port));
+}
+
+static __inline void outw(unsigned short __val, unsigned short __port) {
+ __asm__ volatile("outw %0,%1" : : "a"(__val), "dN"(__port));
+}
+
+static __inline void outl(unsigned int __val, unsigned short __port) {
+ __asm__ volatile("outl %0,%1" : : "a"(__val), "dN"(__port));
+}
+
+static __inline unsigned char inb(unsigned short __port) {
+ unsigned char __val;
+ __asm__ volatile("inb %1,%0" : "=a"(__val) : "dN"(__port));
+ return __val;
+}
+
+static __inline unsigned short inw(unsigned short __port) {
+ unsigned short __val;
+ __asm__ volatile("inw %1,%0" : "=a"(__val) : "dN"(__port));
+ return __val;
+}
+
+static __inline unsigned int inl(unsigned short __port) {
+ unsigned int __val;
+ __asm__ volatile("inl %1,%0" : "=a"(__val) : "dN"(__port));
+ return __val;
+}
+
+static __inline void outsb(unsigned short __port, const void* __buf, unsigned long __n) {
+ __asm__ volatile("cld; rep; outsb" : "+S"(__buf), "+c"(__n) : "d"(__port));
+}
+
+static __inline void outsw(unsigned short __port, const void* __buf, unsigned long __n) {
+ __asm__ volatile("cld; rep; outsw" : "+S"(__buf), "+c"(__n) : "d"(__port));
+}
+
+static __inline void outsl(unsigned short __port, const void* __buf, unsigned long __n) {
+ __asm__ volatile("cld; rep; outsl" : "+S"(__buf), "+c"(__n) : "d"(__port));
+}
+
+static __inline void insb(unsigned short __port, void* __buf, unsigned long __n) {
+ __asm__ volatile("cld; rep; insb" : "+D"(__buf), "+c"(__n) : "d"(__port));
+}
+
+static __inline void insw(unsigned short __port, void* __buf, unsigned long __n) {
+ __asm__ volatile("cld; rep; insw" : "+D"(__buf), "+c"(__n) : "d"(__port));
+}
+
+static __inline void insl(unsigned short __port, void* __buf, unsigned long __n) {
+ __asm__ volatile("cld; rep; insl" : "+D"(__buf), "+c"(__n) : "d"(__port));
+}
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/x86_64/ioctl.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/x86_64/ioctl.h
new file mode 100644
index 0000000..bc8d16a
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/x86_64/ioctl.h
@@ -0,0 +1,197 @@
+#define _IOC(a, b, c, d) (((a) << 30) | ((b) << 8) | (c) | ((d) << 16))
+#define _IOC_NONE 0U
+#define _IOC_WRITE 1U
+#define _IOC_READ 2U
+
+#define _IO(a, b) _IOC(_IOC_NONE, (a), (b), 0)
+#define _IOW(a, b, c) _IOC(_IOC_WRITE, (a), (b), sizeof(c))
+#define _IOR(a, b, c) _IOC(_IOC_READ, (a), (b), sizeof(c))
+#define _IOWR(a, b, c) _IOC(_IOC_READ | _IOC_WRITE, (a), (b), sizeof(c))
+
+#define TCGETS 0x5401
+#define TCSETS 0x5402
+#define TCSETSW 0x5403
+#define TCSETSF 0x5404
+#define TCGETA 0x5405
+#define TCSETA 0x5406
+#define TCSETAW 0x5407
+#define TCSETAF 0x5408
+#define TCSBRK 0x5409
+#define TCXONC 0x540A
+#define TCFLSH 0x540B
+#define TIOCEXCL 0x540C
+#define TIOCNXCL 0x540D
+#define TIOCSCTTY 0x540E
+#define TIOCGPGRP 0x540F
+#define TIOCSPGRP 0x5410
+#define TIOCOUTQ 0x5411
+#define TIOCSTI 0x5412
+#define TIOCGWINSZ 0x5413
+#define TIOCSWINSZ 0x5414
+#define TIOCMGET 0x5415
+#define TIOCMBIS 0x5416
+#define TIOCMBIC 0x5417
+#define TIOCMSET 0x5418
+#define TIOCGSOFTCAR 0x5419
+#define TIOCSSOFTCAR 0x541A
+#define FIONREAD 0x541B
+#define TIOCINQ FIONREAD
+#define TIOCLINUX 0x541C
+#define TIOCCONS 0x541D
+#define TIOCGSERIAL 0x541E
+#define TIOCSSERIAL 0x541F
+#define TIOCPKT 0x5420
+#define FIONBIO 0x5421
+#define TIOCNOTTY 0x5422
+#define TIOCSETD 0x5423
+#define TIOCGETD 0x5424
+#define TCSBRKP 0x5425
+#define TIOCTTYGSTRUCT 0x5426
+#define TIOCSBRK 0x5427
+#define TIOCCBRK 0x5428
+#define TIOCGSID 0x5429
+#define TIOCGPTN 0x80045430
+#define TIOCSPTLCK 0x40045431
+#define TCGETX 0x5432
+#define TCSETX 0x5433
+#define TCSETXF 0x5434
+#define TCSETXW 0x5435
+
+#define FIONCLEX 0x5450
+#define FIOCLEX 0x5451
+#define FIOASYNC 0x5452
+#define TIOCSERCONFIG 0x5453
+#define TIOCSERGWILD 0x5454
+#define TIOCSERSWILD 0x5455
+#define TIOCGLCKTRMIOS 0x5456
+#define TIOCSLCKTRMIOS 0x5457
+#define TIOCSERGSTRUCT 0x5458
+#define TIOCSERGETLSR 0x5459
+#define TIOCSERGETMULTI 0x545A
+#define TIOCSERSETMULTI 0x545B
+
+#define TIOCMIWAIT 0x545C
+#define TIOCGICOUNT 0x545D
+#define TIOCGHAYESESP 0x545E
+#define TIOCSHAYESESP 0x545F
+#define FIOQSIZE 0x5460
+
+#define TIOCPKT_DATA 0
+#define TIOCPKT_FLUSHREAD 1
+#define TIOCPKT_FLUSHWRITE 2
+#define TIOCPKT_STOP 4
+#define TIOCPKT_START 8
+#define TIOCPKT_NOSTOP 16
+#define TIOCPKT_DOSTOP 32
+#define TIOCPKT_IOCTL 64
+
+#define TIOCSER_TEMT 0x01
+
+struct winsize {
+ unsigned short ws_row;
+ unsigned short ws_col;
+ unsigned short ws_xpixel;
+ unsigned short ws_ypixel;
+};
+
+#define TIOCM_LE 0x001
+#define TIOCM_DTR 0x002
+#define TIOCM_RTS 0x004
+#define TIOCM_ST 0x008
+#define TIOCM_SR 0x010
+#define TIOCM_CTS 0x020
+#define TIOCM_CAR 0x040
+#define TIOCM_RNG 0x080
+#define TIOCM_DSR 0x100
+#define TIOCM_CD TIOCM_CAR
+#define TIOCM_RI TIOCM_RNG
+#define TIOCM_OUT1 0x2000
+#define TIOCM_OUT2 0x4000
+#define TIOCM_LOOP 0x8000
+#define TIOCM_MODEM_BITS TIOCM_OUT2
+
+#define N_TTY 0
+#define N_SLIP 1
+#define N_MOUSE 2
+#define N_PPP 3
+#define N_STRIP 4
+#define N_AX25 5
+#define N_X25 6
+#define N_6PACK 7
+#define N_MASC 8
+#define N_R3964 9
+#define N_PROFIBUS_FDL 10
+#define N_IRDA 11
+#define N_SMSBLOCK 12
+#define N_HDLC 13
+#define N_SYNC_PPP 14
+#define N_HCI 15
+
+#define FIOSETOWN 0x8901
+#define SIOCSPGRP 0x8902
+#define FIOGETOWN 0x8903
+#define SIOCGPGRP 0x8904
+#define SIOCATMARK 0x8905
+#define SIOCGSTAMP 0x8906
+
+#define SIOCADDRT 0x890B
+#define SIOCDELRT 0x890C
+#define SIOCRTMSG 0x890D
+
+#define SIOCGIFNAME 0x8910
+#define SIOCSIFLINK 0x8911
+#define SIOCGIFCONF 0x8912
+#define SIOCGIFFLAGS 0x8913
+#define SIOCSIFFLAGS 0x8914
+#define SIOCGIFADDR 0x8915
+#define SIOCSIFADDR 0x8916
+#define SIOCGIFDSTADDR 0x8917
+#define SIOCSIFDSTADDR 0x8918
+#define SIOCGIFBRDADDR 0x8919
+#define SIOCSIFBRDADDR 0x891a
+#define SIOCGIFNETMASK 0x891b
+#define SIOCSIFNETMASK 0x891c
+#define SIOCGIFMETRIC 0x891d
+#define SIOCSIFMETRIC 0x891e
+#define SIOCGIFMEM 0x891f
+#define SIOCSIFMEM 0x8920
+#define SIOCGIFMTU 0x8921
+#define SIOCSIFMTU 0x8922
+#define SIOCSIFHWADDR 0x8924
+#define SIOCGIFENCAP 0x8925
+#define SIOCSIFENCAP 0x8926
+#define SIOCGIFHWADDR 0x8927
+#define SIOCGIFSLAVE 0x8929
+#define SIOCSIFSLAVE 0x8930
+#define SIOCADDMULTI 0x8931
+#define SIOCDELMULTI 0x8932
+#define SIOCGIFINDEX 0x8933
+#define SIOGIFINDEX SIOCGIFINDEX
+#define SIOCSIFPFLAGS 0x8934
+#define SIOCGIFPFLAGS 0x8935
+#define SIOCDIFADDR 0x8936
+#define SIOCSIFHWBROADCAST 0x8937
+#define SIOCGIFCOUNT 0x8938
+
+#define SIOCGIFBR 0x8940
+#define SIOCSIFBR 0x8941
+
+#define SIOCGIFTXQLEN 0x8942
+#define SIOCSIFTXQLEN 0x8943
+
+#define SIOCDARP 0x8953
+#define SIOCGARP 0x8954
+#define SIOCSARP 0x8955
+
+#define SIOCDRARP 0x8960
+#define SIOCGRARP 0x8961
+#define SIOCSRARP 0x8962
+
+#define SIOCGIFMAP 0x8970
+#define SIOCSIFMAP 0x8971
+
+#define SIOCADDDLCI 0x8980
+#define SIOCDELDLCI 0x8981
+
+#define SIOCDEVPRIVATE 0x89F0
+#define SIOCPROTOPRIVATE 0x89E0
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/x86_64/ipc.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/x86_64/ipc.h
new file mode 100644
index 0000000..c66f9ed
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/x86_64/ipc.h
@@ -0,0 +1,13 @@
+struct ipc_perm {
+ key_t __ipc_perm_key;
+ uid_t uid;
+ gid_t gid;
+ uid_t cuid;
+ gid_t cgid;
+ mode_t mode;
+ int __ipc_perm_seq;
+ long __pad1;
+ long __pad2;
+};
+
+#define IPC_64 0
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/x86_64/reg.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/x86_64/reg.h
new file mode 100644
index 0000000..12d43c5
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/x86_64/reg.h
@@ -0,0 +1,29 @@
+#undef __WORDSIZE
+#define __WORDSIZE 64
+#define R15 0
+#define R14 1
+#define R13 2
+#define R12 3
+#define RBP 4
+#define RBX 5
+#define R11 6
+#define R10 7
+#define R9 8
+#define R8 9
+#define RAX 10
+#define RCX 11
+#define RDX 12
+#define RSI 13
+#define RDI 14
+#define ORIG_RAX 15
+#define RIP 16
+#define CS 17
+#define EFLAGS 18
+#define RSP 19
+#define SS 20
+#define FS_BASE 21
+#define GS_BASE 22
+#define DS 23
+#define ES 24
+#define FS 25
+#define GS 26
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/x86_64/setjmp.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/x86_64/setjmp.h
new file mode 100644
index 0000000..29336e4
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/x86_64/setjmp.h
@@ -0,0 +1 @@
+typedef unsigned long long int __jmp_buf[9];
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/x86_64/signal.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/x86_64/signal.h
new file mode 100644
index 0000000..26095e9
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/x86_64/signal.h
@@ -0,0 +1,129 @@
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define MINSIGSTKSZ 2048
+#define SIGSTKSZ 8192
+#endif
+
+#ifdef _GNU_SOURCE
+#define REG_R8 0
+#define REG_R9 1
+#define REG_R10 2
+#define REG_R11 3
+#define REG_R12 4
+#define REG_R13 5
+#define REG_R14 6
+#define REG_R15 7
+#define REG_RDI 8
+#define REG_RSI 9
+#define REG_RBP 10
+#define REG_RBX 11
+#define REG_RDX 12
+#define REG_RAX 13
+#define REG_RCX 14
+#define REG_RSP 15
+#define REG_RIP 16
+#define REG_EFL 17
+#define REG_CSGSFS 18
+#define REG_ERR 19
+#define REG_TRAPNO 20
+#define REG_OLDMASK 21
+#define REG_CR2 22
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+typedef long long greg_t, gregset_t[23];
+typedef struct _fpstate {
+ unsigned short cwd, swd, ftw, fop;
+ unsigned long long rip, rdp;
+ unsigned mxcsr, mxcr_mask;
+ struct {
+ unsigned short significand[4], exponent, padding[3];
+ } _st[8];
+ struct {
+ unsigned element[4];
+ } _xmm[16];
+ unsigned padding[24];
+} * fpregset_t;
+struct sigcontext {
+ unsigned long r8, r9, r10, r11, r12, r13, r14, r15;
+ unsigned long rdi, rsi, rbp, rbx, rdx, rax, rcx, rsp, rip, eflags;
+ unsigned short cs, gs, fs, __pad0;
+ unsigned long err, trapno, oldmask, cr2;
+ struct _fpstate* fpstate;
+ unsigned long __reserved1[8];
+};
+typedef struct {
+ gregset_t gregs;
+ fpregset_t fpregs;
+ unsigned long long __reserved1[8];
+} mcontext_t;
+#else
+typedef struct {
+ unsigned long __space[32];
+} mcontext_t;
+#endif
+
+struct sigaltstack {
+ void* ss_sp;
+ int ss_flags;
+ size_t ss_size;
+};
+
+typedef struct __ucontext {
+ unsigned long uc_flags;
+ struct __ucontext* uc_link;
+ stack_t uc_stack;
+ mcontext_t uc_mcontext;
+ sigset_t uc_sigmask;
+ unsigned long __fpregs_mem[64];
+} ucontext_t;
+
+#define SA_NOCLDSTOP 1
+#define SA_NOCLDWAIT 2
+#define SA_SIGINFO 4
+#define SA_ONSTACK 0x08000000
+#define SA_RESTART 0x10000000
+#define SA_NODEFER 0x40000000
+#define SA_RESETHAND 0x80000000
+#define SA_RESTORER 0x04000000
+
+#endif
+
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGIOT SIGABRT
+#define SIGBUS 7
+#define SIGFPE 8
+#define SIGKILL 9
+#define SIGUSR1 10
+#define SIGSEGV 11
+#define SIGUSR2 12
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGSTKFLT 16
+#define SIGCHLD 17
+#define SIGCONT 18
+#define SIGSTOP 19
+#define SIGTSTP 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGURG 23
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGIO 29
+#define SIGPOLL 29
+#define SIGPWR 30
+#define SIGSYS 31
+#define SIGUNUSED SIGSYS
+
+#define _NSIG 65
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/x86_64/stat.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/x86_64/stat.h
new file mode 100644
index 0000000..9533ce5
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/bits/x86_64/stat.h
@@ -0,0 +1,22 @@
+/* copied from kernel definition, but with padding replaced
+ * by the corresponding correctly-sized userspace types. */
+
+struct stat {
+ dev_t st_dev;
+ ino_t st_ino;
+ nlink_t st_nlink;
+
+ mode_t st_mode;
+ uid_t st_uid;
+ gid_t st_gid;
+ unsigned int __pad0;
+ dev_t st_rdev;
+ off_t st_size;
+ blksize_t st_blksize;
+ blkcnt_t st_blocks;
+
+ struct timespec st_atim;
+ struct timespec st_mtim;
+ struct timespec st_ctim;
+ long __unused1[3];
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/byteswap.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/byteswap.h
new file mode 100644
index 0000000..54d1c36
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/byteswap.h
@@ -0,0 +1,21 @@
+#ifndef SYSROOT_BYTESWAP_H_
+#define SYSROOT_BYTESWAP_H_
+
+#include <features.h>
+#include <stdint.h>
+
+static __inline uint16_t __bswap_16(uint16_t __x) { return (uint16_t)(__x << 8 | __x >> 8); }
+
+static __inline uint32_t __bswap_32(uint32_t __x) {
+ return __x >> 24 | ((__x >> 8) & 0xff00) | ((__x << 8) & 0xff0000) | __x << 24;
+}
+
+static __inline uint64_t __bswap_64(uint64_t __x) {
+ return ((uint64_t)__bswap_32((uint32_t)__x)) << 32 | __bswap_32((uint32_t)(__x >> 32));
+}
+
+#define bswap_16(x) __bswap_16(x)
+#define bswap_32(x) __bswap_32(x)
+#define bswap_64(x) __bswap_64(x)
+
+#endif // SYSROOT_BYTESWAP_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/complex.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/complex.h
new file mode 100644
index 0000000..c4bb294
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/complex.h
@@ -0,0 +1,138 @@
+#ifndef SYSROOT_COMPLEX_H_
+#define SYSROOT_COMPLEX_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define complex _Complex
+#ifdef __GNUC__
+#define _Complex_I (__extension__(0.0f + 1.0fj))
+#else
+#define _Complex_I (0.0f + 1.0fj)
+#endif
+#define I _Complex_I
+
+double complex cacos(double complex);
+float complex cacosf(float complex);
+long double complex cacosl(long double complex);
+
+double complex casin(double complex);
+float complex casinf(float complex);
+long double complex casinl(long double complex);
+
+double complex catan(double complex);
+float complex catanf(float complex);
+long double complex catanl(long double complex);
+
+double complex ccos(double complex);
+float complex ccosf(float complex);
+long double complex ccosl(long double complex);
+
+double complex csin(double complex);
+float complex csinf(float complex);
+long double complex csinl(long double complex);
+
+double complex ctan(double complex);
+float complex ctanf(float complex);
+long double complex ctanl(long double complex);
+
+double complex cacosh(double complex);
+float complex cacoshf(float complex);
+long double complex cacoshl(long double complex);
+
+double complex casinh(double complex);
+float complex casinhf(float complex);
+long double complex casinhl(long double complex);
+
+double complex catanh(double complex);
+float complex catanhf(float complex);
+long double complex catanhl(long double complex);
+
+double complex ccosh(double complex);
+float complex ccoshf(float complex);
+long double complex ccoshl(long double complex);
+
+double complex csinh(double complex);
+float complex csinhf(float complex);
+long double complex csinhl(long double complex);
+
+double complex ctanh(double complex);
+float complex ctanhf(float complex);
+long double complex ctanhl(long double complex);
+
+double complex cexp(double complex);
+float complex cexpf(float complex);
+long double complex cexpl(long double complex);
+
+double complex clog(double complex);
+float complex clogf(float complex);
+long double complex clogl(long double complex);
+
+double cabs(double complex);
+float cabsf(float complex);
+long double cabsl(long double complex);
+
+double complex cpow(double complex, double complex);
+float complex cpowf(float complex, float complex);
+long double complex cpowl(long double complex, long double complex);
+
+double complex csqrt(double complex);
+float complex csqrtf(float complex);
+long double complex csqrtl(long double complex);
+
+double carg(double complex);
+float cargf(float complex);
+long double cargl(long double complex);
+
+double cimag(double complex);
+float cimagf(float complex);
+long double cimagl(long double complex);
+
+double complex conj(double complex);
+float complex conjf(float complex);
+long double complex conjl(long double complex);
+
+double complex cproj(double complex);
+float complex cprojf(float complex);
+long double complex cprojl(long double complex);
+
+double creal(double complex);
+float crealf(float complex);
+long double creall(long double complex);
+
+#ifndef __cplusplus
+#define __CIMAG(x, t) \
+ (+(union { \
+ _Complex t __z; \
+ t __xy[2]; \
+ }){(_Complex t)(x)} \
+ .__xy[1])
+
+#define creal(x) ((double)(x))
+#define crealf(x) ((float)(x))
+#define creall(x) ((long double)(x))
+
+#define cimag(x) __CIMAG(x, double)
+#define cimagf(x) __CIMAG(x, float)
+#define cimagl(x) __CIMAG(x, long double)
+#endif
+
+#if __STDC_VERSION__ >= 201112L
+#if defined(_Imaginary_I)
+#define __CMPLX(x, y, t) ((t)(x) + _Imaginary_I * (t)(y))
+#elif defined(__clang__)
+#define __CMPLX(x, y, t) (+(_Complex t){(t)(x), (t)(y)})
+#else
+#define __CMPLX(x, y, t) (__builtin_complex((t)(x), (t)(y)))
+#endif
+#define CMPLX(x, y) __CMPLX(x, y, double)
+#define CMPLXF(x, y) __CMPLX(x, y, float)
+#define CMPLXL(x, y) __CMPLX(x, y, long double)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_COMPLEX_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/cpio.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/cpio.h
new file mode 100644
index 0000000..21d069e
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/cpio.h
@@ -0,0 +1,29 @@
+#ifndef SYSROOT_CPIO_H_
+#define SYSROOT_CPIO_H_
+
+#define MAGIC "070707"
+
+#define C_IRUSR 000400
+#define C_IWUSR 000200
+#define C_IXUSR 000100
+#define C_IRGRP 000040
+#define C_IWGRP 000020
+#define C_IXGRP 000010
+#define C_IROTH 000004
+#define C_IWOTH 000002
+#define C_IXOTH 000001
+
+#define C_ISUID 004000
+#define C_ISGID 002000
+#define C_ISVTX 001000
+
+#define C_ISBLK 060000
+#define C_ISCHR 020000
+#define C_ISDIR 040000
+#define C_ISFIFO 010000
+#define C_ISSOCK 0140000
+#define C_ISLNK 0120000
+#define C_ISCTG 0110000
+#define C_ISREG 0100000
+
+#endif // SYSROOT_CPIO_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/ctype.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/ctype.h
new file mode 100644
index 0000000..12be80d
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/ctype.h
@@ -0,0 +1,52 @@
+#ifndef SYSROOT_CTYPE_H_
+#define SYSROOT_CTYPE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+int isalnum(int);
+int isalpha(int);
+int isblank(int);
+int iscntrl(int);
+int isdigit(int);
+int isgraph(int);
+int islower(int);
+int isprint(int);
+int ispunct(int);
+int isspace(int);
+int isupper(int);
+int isxdigit(int);
+int tolower(int);
+int toupper(int);
+
+#ifndef __cplusplus
+static __inline int __isspace(int _c) { return _c == ' ' || (unsigned)_c - '\t' < 5; }
+
+#define isalpha(a) (0 ? isalpha(a) : (((unsigned)(a) | 32) - 'a') < 26)
+#define isdigit(a) (0 ? isdigit(a) : ((unsigned)(a) - '0') < 10)
+#define islower(a) (0 ? islower(a) : ((unsigned)(a) - 'a') < 26)
+#define isupper(a) (0 ? isupper(a) : ((unsigned)(a) - 'A') < 26)
+#define isprint(a) (0 ? isprint(a) : ((unsigned)(a)-0x20) < 0x5f)
+#define isgraph(a) (0 ? isgraph(a) : ((unsigned)(a)-0x21) < 0x5e)
+#define isspace(a) __isspace(a)
+#endif
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+int isascii(int);
+int toascii(int);
+#define _tolower(a) ((a) | 0x20)
+#define _toupper(a) ((a)&0x5f)
+#define isascii(a) (0 ? isascii(a) : (unsigned)(a) < 128)
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_CTYPE_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/dirent.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/dirent.h
new file mode 100644
index 0000000..4542825
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/dirent.h
@@ -0,0 +1,67 @@
+#ifndef SYSROOT_DIRENT_H_
+#define SYSROOT_DIRENT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_ino_t
+#define __NEED_off_t
+#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+#define __NEED_size_t
+#endif
+
+#include <bits/alltypes.h>
+
+typedef struct __dirstream DIR;
+
+struct dirent {
+ ino_t d_ino;
+ off_t d_off;
+ unsigned short d_reclen;
+ unsigned char d_type;
+ char d_name[256];
+};
+
+#define d_fileno d_ino
+
+int closedir(DIR*);
+DIR* fdopendir(int);
+DIR* opendir(const char*);
+struct dirent* readdir(DIR*);
+int readdir_r(DIR* __restrict, struct dirent* __restrict, struct dirent** __restrict);
+void rewinddir(DIR*);
+void seekdir(DIR*, long);
+long telldir(DIR*);
+int dirfd(DIR*);
+
+int alphasort(const struct dirent**, const struct dirent**);
+int scandir(const char*, struct dirent***, int (*)(const struct dirent*),
+ int (*)(const struct dirent**, const struct dirent**));
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define DT_UNKNOWN 0
+#define DT_FIFO 1
+#define DT_CHR 2
+#define DT_DIR 4
+#define DT_BLK 6
+#define DT_REG 8
+#define DT_LNK 10
+#define DT_SOCK 12
+#define DT_WHT 14
+#define IFTODT(x) ((x) >> 12 & 017)
+#define DTTOIF(x) ((x) << 12)
+int getdents(int, struct dirent*, size_t);
+#endif
+
+#ifdef _GNU_SOURCE
+int versionsort(const struct dirent**, const struct dirent**);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_DIRENT_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/dlfcn.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/dlfcn.h
new file mode 100644
index 0000000..ff069c9
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/dlfcn.h
@@ -0,0 +1,42 @@
+#ifndef SYSROOT_DLFCN_H_
+#define SYSROOT_DLFCN_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define RTLD_LAZY 1
+#define RTLD_NOW 2
+#define RTLD_NOLOAD 4
+#define RTLD_NODELETE 4096
+#define RTLD_GLOBAL 256
+#define RTLD_LOCAL 0
+
+#define RTLD_NEXT ((void*)-1)
+#define RTLD_DEFAULT ((void*)0)
+
+#define RTLD_DI_LINKMAP 2
+
+int dlclose(void*);
+char* dlerror(void);
+void* dlopen(const char*, int);
+void* dlsym(void* __restrict, const char* __restrict);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+typedef struct {
+ const char* dli_fname;
+ void* dli_fbase;
+ const char* dli_sname;
+ void* dli_saddr;
+} Dl_info;
+int dladdr(const void*, Dl_info*);
+int dlinfo(void*, int, void*);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_DLFCN_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/elf.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/elf.h
new file mode 100644
index 0000000..88a35f0
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/elf.h
@@ -0,0 +1,2585 @@
+#ifndef SYSROOT_ELF_H_
+#define SYSROOT_ELF_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+typedef uint16_t Elf32_Half;
+typedef uint16_t Elf64_Half;
+
+typedef uint32_t Elf32_Word;
+typedef int32_t Elf32_Sword;
+typedef uint32_t Elf64_Word;
+typedef int32_t Elf64_Sword;
+
+typedef uint64_t Elf32_Xword;
+typedef int64_t Elf32_Sxword;
+typedef uint64_t Elf64_Xword;
+typedef int64_t Elf64_Sxword;
+
+typedef uint32_t Elf32_Addr;
+typedef uint64_t Elf64_Addr;
+
+typedef uint32_t Elf32_Off;
+typedef uint64_t Elf64_Off;
+
+typedef uint16_t Elf32_Section;
+typedef uint16_t Elf64_Section;
+
+typedef Elf32_Half Elf32_Versym;
+typedef Elf64_Half Elf64_Versym;
+
+#define EI_NIDENT (16)
+
+typedef struct {
+ unsigned char e_ident[EI_NIDENT];
+ Elf32_Half e_type;
+ Elf32_Half e_machine;
+ Elf32_Word e_version;
+ Elf32_Addr e_entry;
+ Elf32_Off e_phoff;
+ Elf32_Off e_shoff;
+ Elf32_Word e_flags;
+ Elf32_Half e_ehsize;
+ Elf32_Half e_phentsize;
+ Elf32_Half e_phnum;
+ Elf32_Half e_shentsize;
+ Elf32_Half e_shnum;
+ Elf32_Half e_shstrndx;
+} Elf32_Ehdr;
+
+typedef struct {
+ unsigned char e_ident[EI_NIDENT];
+ Elf64_Half e_type;
+ Elf64_Half e_machine;
+ Elf64_Word e_version;
+ Elf64_Addr e_entry;
+ Elf64_Off e_phoff;
+ Elf64_Off e_shoff;
+ Elf64_Word e_flags;
+ Elf64_Half e_ehsize;
+ Elf64_Half e_phentsize;
+ Elf64_Half e_phnum;
+ Elf64_Half e_shentsize;
+ Elf64_Half e_shnum;
+ Elf64_Half e_shstrndx;
+} Elf64_Ehdr;
+
+#define EI_MAG0 0
+#define ELFMAG0 0x7f
+
+#define EI_MAG1 1
+#define ELFMAG1 'E'
+
+#define EI_MAG2 2
+#define ELFMAG2 'L'
+
+#define EI_MAG3 3
+#define ELFMAG3 'F'
+
+#define ELFMAG "\177ELF"
+#define SELFMAG 4
+
+#define EI_CLASS 4
+#define ELFCLASSNONE 0
+#define ELFCLASS32 1
+#define ELFCLASS64 2
+#define ELFCLASSNUM 3
+
+#define EI_DATA 5
+#define ELFDATANONE 0
+#define ELFDATA2LSB 1
+#define ELFDATA2MSB 2
+#define ELFDATANUM 3
+
+#define EI_VERSION 6
+
+#define EI_OSABI 7
+#define ELFOSABI_NONE 0
+#define ELFOSABI_SYSV 0
+#define ELFOSABI_HPUX 1
+#define ELFOSABI_NETBSD 2
+#define ELFOSABI_LINUX 3
+#define ELFOSABI_GNU 3
+#define ELFOSABI_SOLARIS 6
+#define ELFOSABI_AIX 7
+#define ELFOSABI_IRIX 8
+#define ELFOSABI_FREEBSD 9
+#define ELFOSABI_TRU64 10
+#define ELFOSABI_MODESTO 11
+#define ELFOSABI_OPENBSD 12
+#define ELFOSABI_ARM 97
+#define ELFOSABI_STANDALONE 255
+
+#define EI_ABIVERSION 8
+
+#define EI_PAD 9
+
+#define ET_NONE 0
+#define ET_REL 1
+#define ET_EXEC 2
+#define ET_DYN 3
+#define ET_CORE 4
+#define ET_NUM 5
+#define ET_LOOS 0xfe00
+#define ET_HIOS 0xfeff
+#define ET_LOPROC 0xff00
+#define ET_HIPROC 0xffff
+
+#define EM_NONE 0
+#define EM_M32 1
+#define EM_SPARC 2
+#define EM_386 3
+#define EM_68K 4
+#define EM_88K 5
+#define EM_860 7
+#define EM_MIPS 8
+#define EM_S370 9
+#define EM_MIPS_RS3_LE 10
+
+#define EM_PARISC 15
+#define EM_VPP500 17
+#define EM_SPARC32PLUS 18
+#define EM_960 19
+#define EM_PPC 20
+#define EM_PPC64 21
+#define EM_S390 22
+
+#define EM_V800 36
+#define EM_FR20 37
+#define EM_RH32 38
+#define EM_RCE 39
+#define EM_ARM 40
+#define EM_FAKE_ALPHA 41
+#define EM_SH 42
+#define EM_SPARCV9 43
+#define EM_TRICORE 44
+#define EM_ARC 45
+#define EM_H8_300 46
+#define EM_H8_300H 47
+#define EM_H8S 48
+#define EM_H8_500 49
+#define EM_IA_64 50
+#define EM_MIPS_X 51
+#define EM_COLDFIRE 52
+#define EM_68HC12 53
+#define EM_MMA 54
+#define EM_PCP 55
+#define EM_NCPU 56
+#define EM_NDR1 57
+#define EM_STARCORE 58
+#define EM_ME16 59
+#define EM_ST100 60
+#define EM_TINYJ 61
+#define EM_X86_64 62
+#define EM_PDSP 63
+
+#define EM_FX66 66
+#define EM_ST9PLUS 67
+#define EM_ST7 68
+#define EM_68HC16 69
+#define EM_68HC11 70
+#define EM_68HC08 71
+#define EM_68HC05 72
+#define EM_SVX 73
+#define EM_ST19 74
+#define EM_VAX 75
+#define EM_CRIS 76
+#define EM_JAVELIN 77
+#define EM_FIREPATH 78
+#define EM_ZSP 79
+#define EM_MMIX 80
+#define EM_HUANY 81
+#define EM_PRISM 82
+#define EM_AVR 83
+#define EM_FR30 84
+#define EM_D10V 85
+#define EM_D30V 86
+#define EM_V850 87
+#define EM_M32R 88
+#define EM_MN10300 89
+#define EM_MN10200 90
+#define EM_PJ 91
+#define EM_OR1K 92
+#define EM_ARC_A5 93
+#define EM_XTENSA 94
+#define EM_AARCH64 183
+#define EM_TILEPRO 188
+#define EM_MICROBLAZE 189
+#define EM_TILEGX 191
+#define EM_NUM 192
+#define EM_ALPHA 0x9026
+
+#define EV_NONE 0
+#define EV_CURRENT 1
+#define EV_NUM 2
+
+typedef struct {
+ Elf32_Word sh_name;
+ Elf32_Word sh_type;
+ Elf32_Word sh_flags;
+ Elf32_Addr sh_addr;
+ Elf32_Off sh_offset;
+ Elf32_Word sh_size;
+ Elf32_Word sh_link;
+ Elf32_Word sh_info;
+ Elf32_Word sh_addralign;
+ Elf32_Word sh_entsize;
+} Elf32_Shdr;
+
+typedef struct {
+ Elf64_Word sh_name;
+ Elf64_Word sh_type;
+ Elf64_Xword sh_flags;
+ Elf64_Addr sh_addr;
+ Elf64_Off sh_offset;
+ Elf64_Xword sh_size;
+ Elf64_Word sh_link;
+ Elf64_Word sh_info;
+ Elf64_Xword sh_addralign;
+ Elf64_Xword sh_entsize;
+} Elf64_Shdr;
+
+#define SHN_UNDEF 0
+#define SHN_LORESERVE 0xff00
+#define SHN_LOPROC 0xff00
+#define SHN_BEFORE 0xff00
+
+#define SHN_AFTER 0xff01
+
+#define SHN_HIPROC 0xff1f
+#define SHN_LOOS 0xff20
+#define SHN_HIOS 0xff3f
+#define SHN_ABS 0xfff1
+#define SHN_COMMON 0xfff2
+#define SHN_XINDEX 0xffff
+#define SHN_HIRESERVE 0xffff
+
+#define SHT_NULL 0
+#define SHT_PROGBITS 1
+#define SHT_SYMTAB 2
+#define SHT_STRTAB 3
+#define SHT_RELA 4
+#define SHT_HASH 5
+#define SHT_DYNAMIC 6
+#define SHT_NOTE 7
+#define SHT_NOBITS 8
+#define SHT_REL 9
+#define SHT_SHLIB 10
+#define SHT_DYNSYM 11
+#define SHT_INIT_ARRAY 14
+#define SHT_FINI_ARRAY 15
+#define SHT_PREINIT_ARRAY 16
+#define SHT_GROUP 17
+#define SHT_SYMTAB_SHNDX 18
+#define SHT_NUM 19
+#define SHT_LOOS 0x60000000
+#define SHT_GNU_ATTRIBUTES 0x6ffffff5
+#define SHT_GNU_HASH 0x6ffffff6
+#define SHT_GNU_LIBLIST 0x6ffffff7
+#define SHT_CHECKSUM 0x6ffffff8
+#define SHT_LOSUNW 0x6ffffffa
+#define SHT_SUNW_move 0x6ffffffa
+#define SHT_SUNW_COMDAT 0x6ffffffb
+#define SHT_SUNW_syminfo 0x6ffffffc
+#define SHT_GNU_verdef 0x6ffffffd
+#define SHT_GNU_verneed 0x6ffffffe
+#define SHT_GNU_versym 0x6fffffff
+#define SHT_HISUNW 0x6fffffff
+#define SHT_HIOS 0x6fffffff
+#define SHT_LOPROC 0x70000000
+#define SHT_HIPROC 0x7fffffff
+#define SHT_LOUSER 0x80000000
+#define SHT_HIUSER 0x8fffffff
+
+#define SHF_WRITE (1 << 0)
+#define SHF_ALLOC (1 << 1)
+#define SHF_EXECINSTR (1 << 2)
+#define SHF_MERGE (1 << 4)
+#define SHF_STRINGS (1 << 5)
+#define SHF_INFO_LINK (1 << 6)
+#define SHF_LINK_ORDER (1 << 7)
+#define SHF_OS_NONCONFORMING (1 << 8)
+
+#define SHF_GROUP (1 << 9)
+#define SHF_TLS (1 << 10)
+#define SHF_MASKOS 0x0ff00000
+#define SHF_MASKPROC 0xf0000000
+#define SHF_ORDERED (1 << 30)
+#define SHF_EXCLUDE (1U << 31)
+
+#define GRP_COMDAT 0x1
+
+typedef struct {
+ Elf32_Word st_name;
+ Elf32_Addr st_value;
+ Elf32_Word st_size;
+ unsigned char st_info;
+ unsigned char st_other;
+ Elf32_Section st_shndx;
+} Elf32_Sym;
+
+typedef struct {
+ Elf64_Word st_name;
+ unsigned char st_info;
+ unsigned char st_other;
+ Elf64_Section st_shndx;
+ Elf64_Addr st_value;
+ Elf64_Xword st_size;
+} Elf64_Sym;
+
+typedef struct {
+ Elf32_Half si_boundto;
+ Elf32_Half si_flags;
+} Elf32_Syminfo;
+
+typedef struct {
+ Elf64_Half si_boundto;
+ Elf64_Half si_flags;
+} Elf64_Syminfo;
+
+#define SYMINFO_BT_SELF 0xffff
+#define SYMINFO_BT_PARENT 0xfffe
+#define SYMINFO_BT_LOWRESERVE 0xff00
+
+#define SYMINFO_FLG_DIRECT 0x0001
+#define SYMINFO_FLG_PASSTHRU 0x0002
+#define SYMINFO_FLG_COPY 0x0004
+#define SYMINFO_FLG_LAZYLOAD 0x0008
+
+#define SYMINFO_NONE 0
+#define SYMINFO_CURRENT 1
+#define SYMINFO_NUM 2
+
+#define ELF32_ST_BIND(val) (((unsigned char)(val)) >> 4)
+#define ELF32_ST_TYPE(val) ((val)&0xf)
+#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type)&0xf))
+
+#define ELF64_ST_BIND(val) ELF32_ST_BIND(val)
+#define ELF64_ST_TYPE(val) ELF32_ST_TYPE(val)
+#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO((bind), (type))
+
+#define STB_LOCAL 0
+#define STB_GLOBAL 1
+#define STB_WEAK 2
+#define STB_NUM 3
+#define STB_LOOS 10
+#define STB_GNU_UNIQUE 10
+#define STB_HIOS 12
+#define STB_LOPROC 13
+#define STB_HIPROC 15
+
+#define STT_NOTYPE 0
+#define STT_OBJECT 1
+#define STT_FUNC 2
+#define STT_SECTION 3
+#define STT_FILE 4
+#define STT_COMMON 5
+#define STT_TLS 6
+#define STT_NUM 7
+#define STT_LOOS 10
+#define STT_GNU_IFUNC 10
+#define STT_HIOS 12
+#define STT_LOPROC 13
+#define STT_HIPROC 15
+
+#define STN_UNDEF 0
+
+#define ELF32_ST_VISIBILITY(o) ((o)&0x03)
+#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY(o)
+
+#define STV_DEFAULT 0
+#define STV_INTERNAL 1
+#define STV_HIDDEN 2
+#define STV_PROTECTED 3
+
+typedef struct {
+ Elf32_Addr r_offset;
+ Elf32_Word r_info;
+} Elf32_Rel;
+
+typedef struct {
+ Elf64_Addr r_offset;
+ Elf64_Xword r_info;
+} Elf64_Rel;
+
+typedef struct {
+ Elf32_Addr r_offset;
+ Elf32_Word r_info;
+ Elf32_Sword r_addend;
+} Elf32_Rela;
+
+typedef struct {
+ Elf64_Addr r_offset;
+ Elf64_Xword r_info;
+ Elf64_Sxword r_addend;
+} Elf64_Rela;
+
+#define ELF32_R_SYM(val) ((val) >> 8)
+#define ELF32_R_TYPE(val) ((val)&0xff)
+#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type)&0xff))
+
+#define ELF64_R_SYM(i) ((i) >> 32)
+#define ELF64_R_TYPE(i) ((i)&0xffffffff)
+#define ELF64_R_INFO(sym, type) ((((Elf64_Xword)(sym)) << 32) + (type))
+
+typedef struct {
+ Elf32_Word p_type;
+ Elf32_Off p_offset;
+ Elf32_Addr p_vaddr;
+ Elf32_Addr p_paddr;
+ Elf32_Word p_filesz;
+ Elf32_Word p_memsz;
+ Elf32_Word p_flags;
+ Elf32_Word p_align;
+} Elf32_Phdr;
+
+typedef struct {
+ Elf64_Word p_type;
+ Elf64_Word p_flags;
+ Elf64_Off p_offset;
+ Elf64_Addr p_vaddr;
+ Elf64_Addr p_paddr;
+ Elf64_Xword p_filesz;
+ Elf64_Xword p_memsz;
+ Elf64_Xword p_align;
+} Elf64_Phdr;
+
+#define PT_NULL 0
+#define PT_LOAD 1
+#define PT_DYNAMIC 2
+#define PT_INTERP 3
+#define PT_NOTE 4
+#define PT_SHLIB 5
+#define PT_PHDR 6
+#define PT_TLS 7
+#define PT_NUM 8
+#define PT_LOOS 0x60000000
+#define PT_GNU_EH_FRAME 0x6474e550
+#define PT_GNU_STACK 0x6474e551
+#define PT_GNU_RELRO 0x6474e552
+#define PT_LOSUNW 0x6ffffffa
+#define PT_SUNWBSS 0x6ffffffa
+#define PT_SUNWSTACK 0x6ffffffb
+#define PT_HISUNW 0x6fffffff
+#define PT_HIOS 0x6fffffff
+#define PT_LOPROC 0x70000000
+#define PT_HIPROC 0x7fffffff
+
+#define PN_XNUM 0xffff
+
+#define PF_X (1 << 0)
+#define PF_W (1 << 1)
+#define PF_R (1 << 2)
+#define PF_MASKOS 0x0ff00000
+#define PF_MASKPROC 0xf0000000
+
+#define NT_PRSTATUS 1
+#define NT_FPREGSET 2
+#define NT_PRPSINFO 3
+#define NT_PRXREG 4
+#define NT_TASKSTRUCT 4
+#define NT_PLATFORM 5
+#define NT_AUXV 6
+#define NT_GWINDOWS 7
+#define NT_ASRS 8
+#define NT_PSTATUS 10
+#define NT_PSINFO 13
+#define NT_PRCRED 14
+#define NT_UTSNAME 15
+#define NT_LWPSTATUS 16
+#define NT_LWPSINFO 17
+#define NT_PRFPXREG 20
+#define NT_SIGINFO 0x53494749
+#define NT_FILE 0x46494c45
+#define NT_PRXFPREG 0x46e62b7f
+#define NT_PPC_VMX 0x100
+#define NT_PPC_SPE 0x101
+#define NT_PPC_VSX 0x102
+#define NT_386_TLS 0x200
+#define NT_386_IOPERM 0x201
+#define NT_X86_XSTATE 0x202
+#define NT_S390_HIGH_GPRS 0x300
+#define NT_S390_TIMER 0x301
+#define NT_S390_TODCMP 0x302
+#define NT_S390_TODPREG 0x303
+#define NT_S390_CTRS 0x304
+#define NT_S390_PREFIX 0x305
+#define NT_S390_LAST_BREAK 0x306
+#define NT_S390_SYSTEM_CALL 0x307
+#define NT_S390_TDB 0x308
+#define NT_ARM_VFP 0x400
+#define NT_ARM_TLS 0x401
+#define NT_ARM_HW_BREAK 0x402
+#define NT_ARM_HW_WATCH 0x403
+#define NT_METAG_CBUF 0x500
+#define NT_METAG_RPIPE 0x501
+#define NT_METAG_TLS 0x502
+#define NT_VERSION 1
+
+typedef struct {
+ Elf32_Sword d_tag;
+ union {
+ Elf32_Word d_val;
+ Elf32_Addr d_ptr;
+ } d_un;
+} Elf32_Dyn;
+
+typedef struct {
+ Elf64_Sxword d_tag;
+ union {
+ Elf64_Xword d_val;
+ Elf64_Addr d_ptr;
+ } d_un;
+} Elf64_Dyn;
+
+#define DT_NULL 0
+#define DT_NEEDED 1
+#define DT_PLTRELSZ 2
+#define DT_PLTGOT 3
+#define DT_HASH 4
+#define DT_STRTAB 5
+#define DT_SYMTAB 6
+#define DT_RELA 7
+#define DT_RELASZ 8
+#define DT_RELAENT 9
+#define DT_STRSZ 10
+#define DT_SYMENT 11
+#define DT_INIT 12
+#define DT_FINI 13
+#define DT_SONAME 14
+#define DT_RPATH 15
+#define DT_SYMBOLIC 16
+#define DT_REL 17
+#define DT_RELSZ 18
+#define DT_RELENT 19
+#define DT_PLTREL 20
+#define DT_DEBUG 21
+#define DT_TEXTREL 22
+#define DT_JMPREL 23
+#define DT_BIND_NOW 24
+#define DT_INIT_ARRAY 25
+#define DT_FINI_ARRAY 26
+#define DT_INIT_ARRAYSZ 27
+#define DT_FINI_ARRAYSZ 28
+#define DT_RUNPATH 29
+#define DT_FLAGS 30
+#define DT_ENCODING 32
+#define DT_PREINIT_ARRAY 32
+#define DT_PREINIT_ARRAYSZ 33
+#define DT_RELRSZ 35
+#define DT_RELR 36
+#define DT_RELRENT 37
+#define DT_NUM 38
+#define DT_LOOS 0x6000000d
+#define DT_HIOS 0x6ffff000
+#define DT_LOPROC 0x70000000
+#define DT_HIPROC 0x7fffffff
+#define DT_PROCNUM DT_MIPS_NUM
+
+#define DT_VALRNGLO 0x6ffffd00
+#define DT_GNU_PRELINKED 0x6ffffdf5
+#define DT_GNU_CONFLICTSZ 0x6ffffdf6
+#define DT_GNU_LIBLISTSZ 0x6ffffdf7
+#define DT_CHECKSUM 0x6ffffdf8
+#define DT_PLTPADSZ 0x6ffffdf9
+#define DT_MOVEENT 0x6ffffdfa
+#define DT_MOVESZ 0x6ffffdfb
+#define DT_FEATURE_1 0x6ffffdfc
+#define DT_POSFLAG_1 0x6ffffdfd
+
+#define DT_SYMINSZ 0x6ffffdfe
+#define DT_SYMINENT 0x6ffffdff
+#define DT_VALRNGHI 0x6ffffdff
+#define DT_VALTAGIDX(tag) (DT_VALRNGHI - (tag))
+#define DT_VALNUM 12
+
+#define DT_ADDRRNGLO 0x6ffffe00
+#define DT_GNU_HASH 0x6ffffef5
+#define DT_TLSDESC_PLT 0x6ffffef6
+#define DT_TLSDESC_GOT 0x6ffffef7
+#define DT_GNU_CONFLICT 0x6ffffef8
+#define DT_GNU_LIBLIST 0x6ffffef9
+#define DT_CONFIG 0x6ffffefa
+#define DT_DEPAUDIT 0x6ffffefb
+#define DT_AUDIT 0x6ffffefc
+#define DT_PLTPAD 0x6ffffefd
+#define DT_MOVETAB 0x6ffffefe
+#define DT_SYMINFO 0x6ffffeff
+#define DT_ADDRRNGHI 0x6ffffeff
+#define DT_ADDRTAGIDX(tag) (DT_ADDRRNGHI - (tag))
+#define DT_ADDRNUM 11
+
+#define DT_VERSYM 0x6ffffff0
+
+#define DT_RELACOUNT 0x6ffffff9
+#define DT_RELCOUNT 0x6ffffffa
+
+#define DT_FLAGS_1 0x6ffffffb
+#define DT_VERDEF 0x6ffffffc
+
+#define DT_VERDEFNUM 0x6ffffffd
+#define DT_VERNEED 0x6ffffffe
+
+#define DT_VERNEEDNUM 0x6fffffff
+#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag))
+#define DT_VERSIONTAGNUM 16
+
+#define DT_AUXILIARY 0x7ffffffd
+#define DT_FILTER 0x7fffffff
+#define DT_EXTRATAGIDX(tag) ((Elf32_Word) - ((Elf32_Sword)(tag) << 1 >> 1) - 1)
+#define DT_EXTRANUM 3
+
+#define DF_ORIGIN 0x00000001
+#define DF_SYMBOLIC 0x00000002
+#define DF_TEXTREL 0x00000004
+#define DF_BIND_NOW 0x00000008
+#define DF_STATIC_TLS 0x00000010
+
+#define DF_1_NOW 0x00000001
+#define DF_1_GLOBAL 0x00000002
+#define DF_1_GROUP 0x00000004
+#define DF_1_NODELETE 0x00000008
+#define DF_1_LOADFLTR 0x00000010
+#define DF_1_INITFIRST 0x00000020
+#define DF_1_NOOPEN 0x00000040
+#define DF_1_ORIGIN 0x00000080
+#define DF_1_DIRECT 0x00000100
+#define DF_1_TRANS 0x00000200
+#define DF_1_INTERPOSE 0x00000400
+#define DF_1_NODEFLIB 0x00000800
+#define DF_1_NODUMP 0x00001000
+#define DF_1_CONFALT 0x00002000
+#define DF_1_ENDFILTEE 0x00004000
+#define DF_1_DISPRELDNE 0x00008000
+#define DF_1_DISPRELPND 0x00010000
+#define DF_1_NODIRECT 0x00020000
+#define DF_1_IGNMULDEF 0x00040000
+#define DF_1_NOKSYMS 0x00080000
+#define DF_1_NOHDR 0x00100000
+#define DF_1_EDITED 0x00200000
+#define DF_1_NORELOC 0x00400000
+#define DF_1_SYMINTPOSE 0x00800000
+#define DF_1_GLOBAUDIT 0x01000000
+#define DF_1_SINGLETON 0x02000000
+
+#define DTF_1_PARINIT 0x00000001
+#define DTF_1_CONFEXP 0x00000002
+
+#define DF_P1_LAZYLOAD 0x00000001
+#define DF_P1_GROUPPERM 0x00000002
+
+typedef struct {
+ Elf32_Half vd_version;
+ Elf32_Half vd_flags;
+ Elf32_Half vd_ndx;
+ Elf32_Half vd_cnt;
+ Elf32_Word vd_hash;
+ Elf32_Word vd_aux;
+ Elf32_Word vd_next;
+} Elf32_Verdef;
+
+typedef struct {
+ Elf64_Half vd_version;
+ Elf64_Half vd_flags;
+ Elf64_Half vd_ndx;
+ Elf64_Half vd_cnt;
+ Elf64_Word vd_hash;
+ Elf64_Word vd_aux;
+ Elf64_Word vd_next;
+} Elf64_Verdef;
+
+#define VER_DEF_NONE 0
+#define VER_DEF_CURRENT 1
+#define VER_DEF_NUM 2
+
+#define VER_FLG_BASE 0x1
+#define VER_FLG_WEAK 0x2
+
+#define VER_NDX_LOCAL 0
+#define VER_NDX_GLOBAL 1
+#define VER_NDX_LORESERVE 0xff00
+#define VER_NDX_ELIMINATE 0xff01
+
+typedef struct {
+ Elf32_Word vda_name;
+ Elf32_Word vda_next;
+} Elf32_Verdaux;
+
+typedef struct {
+ Elf64_Word vda_name;
+ Elf64_Word vda_next;
+} Elf64_Verdaux;
+
+typedef struct {
+ Elf32_Half vn_version;
+ Elf32_Half vn_cnt;
+ Elf32_Word vn_file;
+ Elf32_Word vn_aux;
+ Elf32_Word vn_next;
+} Elf32_Verneed;
+
+typedef struct {
+ Elf64_Half vn_version;
+ Elf64_Half vn_cnt;
+ Elf64_Word vn_file;
+ Elf64_Word vn_aux;
+ Elf64_Word vn_next;
+} Elf64_Verneed;
+
+#define VER_NEED_NONE 0
+#define VER_NEED_CURRENT 1
+#define VER_NEED_NUM 2
+
+typedef struct {
+ Elf32_Word vna_hash;
+ Elf32_Half vna_flags;
+ Elf32_Half vna_other;
+ Elf32_Word vna_name;
+ Elf32_Word vna_next;
+} Elf32_Vernaux;
+
+typedef struct {
+ Elf64_Word vna_hash;
+ Elf64_Half vna_flags;
+ Elf64_Half vna_other;
+ Elf64_Word vna_name;
+ Elf64_Word vna_next;
+} Elf64_Vernaux;
+
+#define VER_FLG_WEAK 0x2
+
+typedef struct {
+ uint32_t a_type;
+ union {
+ uint32_t a_val;
+ } a_un;
+} Elf32_auxv_t;
+
+typedef struct {
+ uint64_t a_type;
+ union {
+ uint64_t a_val;
+ } a_un;
+} Elf64_auxv_t;
+
+#define AT_NULL 0
+#define AT_IGNORE 1
+#define AT_EXECFD 2
+#define AT_PHDR 3
+#define AT_PHENT 4
+#define AT_PHNUM 5
+#define AT_PAGESZ 6
+#define AT_BASE 7
+#define AT_FLAGS 8
+#define AT_ENTRY 9
+#define AT_NOTELF 10
+#define AT_UID 11
+#define AT_EUID 12
+#define AT_GID 13
+#define AT_EGID 14
+#define AT_CLKTCK 17
+
+#define AT_PLATFORM 15
+#define AT_HWCAP 16
+
+#define AT_FPUCW 18
+
+#define AT_DCACHEBSIZE 19
+#define AT_ICACHEBSIZE 20
+#define AT_UCACHEBSIZE 21
+
+#define AT_IGNOREPPC 22
+
+#define AT_SECURE 23
+
+#define AT_BASE_PLATFORM 24
+
+#define AT_RANDOM 25
+
+#define AT_HWCAP2 26
+
+#define AT_EXECFN 31
+
+#define AT_SYSINFO 32
+#define AT_SYSINFO_EHDR 33
+
+#define AT_L1I_CACHESHAPE 34
+#define AT_L1D_CACHESHAPE 35
+#define AT_L2_CACHESHAPE 36
+#define AT_L3_CACHESHAPE 37
+
+typedef struct {
+ Elf32_Word n_namesz;
+ Elf32_Word n_descsz;
+ Elf32_Word n_type;
+} Elf32_Nhdr;
+
+typedef struct {
+ Elf64_Word n_namesz;
+ Elf64_Word n_descsz;
+ Elf64_Word n_type;
+} Elf64_Nhdr;
+
+#define ELF_NOTE_SOLARIS "SUNW Solaris"
+
+#define ELF_NOTE_GNU "GNU"
+
+#define ELF_NOTE_PAGESIZE_HINT 1
+
+#define NT_GNU_ABI_TAG 1
+#define ELF_NOTE_ABI NT_GNU_ABI_TAG
+
+#define ELF_NOTE_OS_LINUX 0
+#define ELF_NOTE_OS_GNU 1
+#define ELF_NOTE_OS_SOLARIS2 2
+#define ELF_NOTE_OS_FREEBSD 3
+
+#define NT_GNU_BUILD_ID 3
+#define NT_GNU_GOLD_VERSION 4
+
+typedef struct {
+ Elf32_Xword m_value;
+ Elf32_Word m_info;
+ Elf32_Word m_poffset;
+ Elf32_Half m_repeat;
+ Elf32_Half m_stride;
+} Elf32_Move;
+
+typedef struct {
+ Elf64_Xword m_value;
+ Elf64_Xword m_info;
+ Elf64_Xword m_poffset;
+ Elf64_Half m_repeat;
+ Elf64_Half m_stride;
+} Elf64_Move;
+
+#define ELF32_M_SYM(info) ((info) >> 8)
+#define ELF32_M_SIZE(info) ((unsigned char)(info))
+#define ELF32_M_INFO(sym, size) (((sym) << 8) + (unsigned char)(size))
+
+#define ELF64_M_SYM(info) ELF32_M_SYM(info)
+#define ELF64_M_SIZE(info) ELF32_M_SIZE(info)
+#define ELF64_M_INFO(sym, size) ELF32_M_INFO(sym, size)
+
+#define EF_CPU32 0x00810000
+
+#define R_68K_NONE 0
+#define R_68K_32 1
+#define R_68K_16 2
+#define R_68K_8 3
+#define R_68K_PC32 4
+#define R_68K_PC16 5
+#define R_68K_PC8 6
+#define R_68K_GOT32 7
+#define R_68K_GOT16 8
+#define R_68K_GOT8 9
+#define R_68K_GOT32O 10
+#define R_68K_GOT16O 11
+#define R_68K_GOT8O 12
+#define R_68K_PLT32 13
+#define R_68K_PLT16 14
+#define R_68K_PLT8 15
+#define R_68K_PLT32O 16
+#define R_68K_PLT16O 17
+#define R_68K_PLT8O 18
+#define R_68K_COPY 19
+#define R_68K_GLOB_DAT 20
+#define R_68K_JMP_SLOT 21
+#define R_68K_RELATIVE 22
+#define R_68K_NUM 23
+
+#define R_386_NONE 0
+#define R_386_32 1
+#define R_386_PC32 2
+#define R_386_GOT32 3
+#define R_386_PLT32 4
+#define R_386_COPY 5
+#define R_386_GLOB_DAT 6
+#define R_386_JMP_SLOT 7
+#define R_386_RELATIVE 8
+#define R_386_GOTOFF 9
+#define R_386_GOTPC 10
+#define R_386_32PLT 11
+#define R_386_TLS_TPOFF 14
+#define R_386_TLS_IE 15
+#define R_386_TLS_GOTIE 16
+#define R_386_TLS_LE 17
+#define R_386_TLS_GD 18
+#define R_386_TLS_LDM 19
+#define R_386_16 20
+#define R_386_PC16 21
+#define R_386_8 22
+#define R_386_PC8 23
+#define R_386_TLS_GD_32 24
+#define R_386_TLS_GD_PUSH 25
+#define R_386_TLS_GD_CALL 26
+#define R_386_TLS_GD_POP 27
+#define R_386_TLS_LDM_32 28
+#define R_386_TLS_LDM_PUSH 29
+#define R_386_TLS_LDM_CALL 30
+#define R_386_TLS_LDM_POP 31
+#define R_386_TLS_LDO_32 32
+#define R_386_TLS_IE_32 33
+#define R_386_TLS_LE_32 34
+#define R_386_TLS_DTPMOD32 35
+#define R_386_TLS_DTPOFF32 36
+#define R_386_TLS_TPOFF32 37
+#define R_386_SIZE32 38
+#define R_386_TLS_GOTDESC 39
+#define R_386_TLS_DESC_CALL 40
+#define R_386_TLS_DESC 41
+#define R_386_IRELATIVE 42
+#define R_386_NUM 43
+
+#define STT_SPARC_REGISTER 13
+
+#define EF_SPARCV9_MM 3
+#define EF_SPARCV9_TSO 0
+#define EF_SPARCV9_PSO 1
+#define EF_SPARCV9_RMO 2
+#define EF_SPARC_LEDATA 0x800000
+#define EF_SPARC_EXT_MASK 0xFFFF00
+#define EF_SPARC_32PLUS 0x000100
+#define EF_SPARC_SUN_US1 0x000200
+#define EF_SPARC_HAL_R1 0x000400
+#define EF_SPARC_SUN_US3 0x000800
+
+#define R_SPARC_NONE 0
+#define R_SPARC_8 1
+#define R_SPARC_16 2
+#define R_SPARC_32 3
+#define R_SPARC_DISP8 4
+#define R_SPARC_DISP16 5
+#define R_SPARC_DISP32 6
+#define R_SPARC_WDISP30 7
+#define R_SPARC_WDISP22 8
+#define R_SPARC_HI22 9
+#define R_SPARC_22 10
+#define R_SPARC_13 11
+#define R_SPARC_LO10 12
+#define R_SPARC_GOT10 13
+#define R_SPARC_GOT13 14
+#define R_SPARC_GOT22 15
+#define R_SPARC_PC10 16
+#define R_SPARC_PC22 17
+#define R_SPARC_WPLT30 18
+#define R_SPARC_COPY 19
+#define R_SPARC_GLOB_DAT 20
+#define R_SPARC_JMP_SLOT 21
+#define R_SPARC_RELATIVE 22
+#define R_SPARC_UA32 23
+
+#define R_SPARC_PLT32 24
+#define R_SPARC_HIPLT22 25
+#define R_SPARC_LOPLT10 26
+#define R_SPARC_PCPLT32 27
+#define R_SPARC_PCPLT22 28
+#define R_SPARC_PCPLT10 29
+#define R_SPARC_10 30
+#define R_SPARC_11 31
+#define R_SPARC_64 32
+#define R_SPARC_OLO10 33
+#define R_SPARC_HH22 34
+#define R_SPARC_HM10 35
+#define R_SPARC_LM22 36
+#define R_SPARC_PC_HH22 37
+#define R_SPARC_PC_HM10 38
+#define R_SPARC_PC_LM22 39
+#define R_SPARC_WDISP16 40
+#define R_SPARC_WDISP19 41
+#define R_SPARC_GLOB_JMP 42
+#define R_SPARC_7 43
+#define R_SPARC_5 44
+#define R_SPARC_6 45
+#define R_SPARC_DISP64 46
+#define R_SPARC_PLT64 47
+#define R_SPARC_HIX22 48
+#define R_SPARC_LOX10 49
+#define R_SPARC_H44 50
+#define R_SPARC_M44 51
+#define R_SPARC_L44 52
+#define R_SPARC_REGISTER 53
+#define R_SPARC_UA64 54
+#define R_SPARC_UA16 55
+#define R_SPARC_TLS_GD_HI22 56
+#define R_SPARC_TLS_GD_LO10 57
+#define R_SPARC_TLS_GD_ADD 58
+#define R_SPARC_TLS_GD_CALL 59
+#define R_SPARC_TLS_LDM_HI22 60
+#define R_SPARC_TLS_LDM_LO10 61
+#define R_SPARC_TLS_LDM_ADD 62
+#define R_SPARC_TLS_LDM_CALL 63
+#define R_SPARC_TLS_LDO_HIX22 64
+#define R_SPARC_TLS_LDO_LOX10 65
+#define R_SPARC_TLS_LDO_ADD 66
+#define R_SPARC_TLS_IE_HI22 67
+#define R_SPARC_TLS_IE_LO10 68
+#define R_SPARC_TLS_IE_LD 69
+#define R_SPARC_TLS_IE_LDX 70
+#define R_SPARC_TLS_IE_ADD 71
+#define R_SPARC_TLS_LE_HIX22 72
+#define R_SPARC_TLS_LE_LOX10 73
+#define R_SPARC_TLS_DTPMOD32 74
+#define R_SPARC_TLS_DTPMOD64 75
+#define R_SPARC_TLS_DTPOFF32 76
+#define R_SPARC_TLS_DTPOFF64 77
+#define R_SPARC_TLS_TPOFF32 78
+#define R_SPARC_TLS_TPOFF64 79
+#define R_SPARC_GOTDATA_HIX22 80
+#define R_SPARC_GOTDATA_LOX10 81
+#define R_SPARC_GOTDATA_OP_HIX22 82
+#define R_SPARC_GOTDATA_OP_LOX10 83
+#define R_SPARC_GOTDATA_OP 84
+#define R_SPARC_H34 85
+#define R_SPARC_SIZE32 86
+#define R_SPARC_SIZE64 87
+#define R_SPARC_GNU_VTINHERIT 250
+#define R_SPARC_GNU_VTENTRY 251
+#define R_SPARC_REV32 252
+
+#define R_SPARC_NUM 253
+
+#define DT_SPARC_REGISTER 0x70000001
+#define DT_SPARC_NUM 2
+
+#define EF_MIPS_NOREORDER 1
+#define EF_MIPS_PIC 2
+#define EF_MIPS_CPIC 4
+#define EF_MIPS_XGOT 8
+#define EF_MIPS_64BIT_WHIRL 16
+#define EF_MIPS_ABI2 32
+#define EF_MIPS_ABI_ON32 64
+#define EF_MIPS_NAN2008 1024
+#define EF_MIPS_ARCH 0xf0000000
+
+#define EF_MIPS_ARCH_1 0x00000000
+#define EF_MIPS_ARCH_2 0x10000000
+#define EF_MIPS_ARCH_3 0x20000000
+#define EF_MIPS_ARCH_4 0x30000000
+#define EF_MIPS_ARCH_5 0x40000000
+#define EF_MIPS_ARCH_32 0x50000000
+#define EF_MIPS_ARCH_64 0x60000000
+#define EF_MIPS_ARCH_32R2 0x70000000
+#define EF_MIPS_ARCH_64R2 0x80000000
+
+#define E_MIPS_ARCH_1 0x00000000
+#define E_MIPS_ARCH_2 0x10000000
+#define E_MIPS_ARCH_3 0x20000000
+#define E_MIPS_ARCH_4 0x30000000
+#define E_MIPS_ARCH_5 0x40000000
+#define E_MIPS_ARCH_32 0x50000000
+#define E_MIPS_ARCH_64 0x60000000
+
+#define SHN_MIPS_ACOMMON 0xff00
+#define SHN_MIPS_TEXT 0xff01
+#define SHN_MIPS_DATA 0xff02
+#define SHN_MIPS_SCOMMON 0xff03
+#define SHN_MIPS_SUNDEFINED 0xff04
+
+#define SHT_MIPS_LIBLIST 0x70000000
+#define SHT_MIPS_MSYM 0x70000001
+#define SHT_MIPS_CONFLICT 0x70000002
+#define SHT_MIPS_GPTAB 0x70000003
+#define SHT_MIPS_UCODE 0x70000004
+#define SHT_MIPS_DEBUG 0x70000005
+#define SHT_MIPS_REGINFO 0x70000006
+#define SHT_MIPS_PACKAGE 0x70000007
+#define SHT_MIPS_PACKSYM 0x70000008
+#define SHT_MIPS_RELD 0x70000009
+#define SHT_MIPS_IFACE 0x7000000b
+#define SHT_MIPS_CONTENT 0x7000000c
+#define SHT_MIPS_OPTIONS 0x7000000d
+#define SHT_MIPS_SHDR 0x70000010
+#define SHT_MIPS_FDESC 0x70000011
+#define SHT_MIPS_EXTSYM 0x70000012
+#define SHT_MIPS_DENSE 0x70000013
+#define SHT_MIPS_PDESC 0x70000014
+#define SHT_MIPS_LOCSYM 0x70000015
+#define SHT_MIPS_AUXSYM 0x70000016
+#define SHT_MIPS_OPTSYM 0x70000017
+#define SHT_MIPS_LOCSTR 0x70000018
+#define SHT_MIPS_LINE 0x70000019
+#define SHT_MIPS_RFDESC 0x7000001a
+#define SHT_MIPS_DELTASYM 0x7000001b
+#define SHT_MIPS_DELTAINST 0x7000001c
+#define SHT_MIPS_DELTACLASS 0x7000001d
+#define SHT_MIPS_DWARF 0x7000001e
+#define SHT_MIPS_DELTADECL 0x7000001f
+#define SHT_MIPS_SYMBOL_LIB 0x70000020
+#define SHT_MIPS_EVENTS 0x70000021
+#define SHT_MIPS_TRANSLATE 0x70000022
+#define SHT_MIPS_PIXIE 0x70000023
+#define SHT_MIPS_XLATE 0x70000024
+#define SHT_MIPS_XLATE_DEBUG 0x70000025
+#define SHT_MIPS_WHIRL 0x70000026
+#define SHT_MIPS_EH_REGION 0x70000027
+#define SHT_MIPS_XLATE_OLD 0x70000028
+#define SHT_MIPS_PDR_EXCEPTION 0x70000029
+
+#define SHF_MIPS_GPREL 0x10000000
+#define SHF_MIPS_MERGE 0x20000000
+#define SHF_MIPS_ADDR 0x40000000
+#define SHF_MIPS_STRINGS 0x80000000
+#define SHF_MIPS_NOSTRIP 0x08000000
+#define SHF_MIPS_LOCAL 0x04000000
+#define SHF_MIPS_NAMES 0x02000000
+#define SHF_MIPS_NODUPE 0x01000000
+
+#define STO_MIPS_DEFAULT 0x0
+#define STO_MIPS_INTERNAL 0x1
+#define STO_MIPS_HIDDEN 0x2
+#define STO_MIPS_PROTECTED 0x3
+#define STO_MIPS_PLT 0x8
+#define STO_MIPS_SC_ALIGN_UNUSED 0xff
+
+#define STB_MIPS_SPLIT_COMMON 13
+
+typedef union {
+ struct {
+ Elf32_Word gt_current_g_value;
+ Elf32_Word gt_unused;
+ } gt_header;
+ struct {
+ Elf32_Word gt_g_value;
+ Elf32_Word gt_bytes;
+ } gt_entry;
+} Elf32_gptab;
+
+typedef struct {
+ Elf32_Word ri_gprmask;
+ Elf32_Word ri_cprmask[4];
+ Elf32_Sword ri_gp_value;
+} Elf32_RegInfo;
+
+typedef struct {
+ unsigned char kind;
+
+ unsigned char size;
+ Elf32_Section section;
+
+ Elf32_Word info;
+} Elf_Options;
+
+#define ODK_NULL 0
+#define ODK_REGINFO 1
+#define ODK_EXCEPTIONS 2
+#define ODK_PAD 3
+#define ODK_HWPATCH 4
+#define ODK_FILL 5
+#define ODK_TAGS 6
+#define ODK_HWAND 7
+#define ODK_HWOR 8
+
+#define OEX_FPU_MIN 0x1f
+#define OEX_FPU_MAX 0x1f00
+#define OEX_PAGE0 0x10000
+#define OEX_SMM 0x20000
+#define OEX_FPDBUG 0x40000
+#define OEX_PRECISEFP OEX_FPDBUG
+#define OEX_DISMISS 0x80000
+
+#define OEX_FPU_INVAL 0x10
+#define OEX_FPU_DIV0 0x08
+#define OEX_FPU_OFLO 0x04
+#define OEX_FPU_UFLO 0x02
+#define OEX_FPU_INEX 0x01
+
+#define OHW_R4KEOP 0x1
+#define OHW_R8KPFETCH 0x2
+#define OHW_R5KEOP 0x4
+#define OHW_R5KCVTL 0x8
+
+#define OPAD_PREFIX 0x1
+#define OPAD_POSTFIX 0x2
+#define OPAD_SYMBOL 0x4
+
+typedef struct {
+ Elf32_Word hwp_flags1;
+ Elf32_Word hwp_flags2;
+} Elf_Options_Hw;
+
+#define OHWA0_R4KEOP_CHECKED 0x00000001
+#define OHWA1_R4KEOP_CLEAN 0x00000002
+
+#define R_MIPS_NONE 0
+#define R_MIPS_16 1
+#define R_MIPS_32 2
+#define R_MIPS_REL32 3
+#define R_MIPS_26 4
+#define R_MIPS_HI16 5
+#define R_MIPS_LO16 6
+#define R_MIPS_GPREL16 7
+#define R_MIPS_LITERAL 8
+#define R_MIPS_GOT16 9
+#define R_MIPS_PC16 10
+#define R_MIPS_CALL16 11
+#define R_MIPS_GPREL32 12
+
+#define R_MIPS_SHIFT5 16
+#define R_MIPS_SHIFT6 17
+#define R_MIPS_64 18
+#define R_MIPS_GOT_DISP 19
+#define R_MIPS_GOT_PAGE 20
+#define R_MIPS_GOT_OFST 21
+#define R_MIPS_GOT_HI16 22
+#define R_MIPS_GOT_LO16 23
+#define R_MIPS_SUB 24
+#define R_MIPS_INSERT_A 25
+#define R_MIPS_INSERT_B 26
+#define R_MIPS_DELETE 27
+#define R_MIPS_HIGHER 28
+#define R_MIPS_HIGHEST 29
+#define R_MIPS_CALL_HI16 30
+#define R_MIPS_CALL_LO16 31
+#define R_MIPS_SCN_DISP 32
+#define R_MIPS_REL16 33
+#define R_MIPS_ADD_IMMEDIATE 34
+#define R_MIPS_PJUMP 35
+#define R_MIPS_RELGOT 36
+#define R_MIPS_JALR 37
+#define R_MIPS_TLS_DTPMOD32 38
+#define R_MIPS_TLS_DTPREL32 39
+#define R_MIPS_TLS_DTPMOD64 40
+#define R_MIPS_TLS_DTPREL64 41
+#define R_MIPS_TLS_GD 42
+#define R_MIPS_TLS_LDM 43
+#define R_MIPS_TLS_DTPREL_HI16 44
+#define R_MIPS_TLS_DTPREL_LO16 45
+#define R_MIPS_TLS_GOTTPREL 46
+#define R_MIPS_TLS_TPREL32 47
+#define R_MIPS_TLS_TPREL64 48
+#define R_MIPS_TLS_TPREL_HI16 49
+#define R_MIPS_TLS_TPREL_LO16 50
+#define R_MIPS_GLOB_DAT 51
+#define R_MIPS_COPY 126
+#define R_MIPS_JUMP_SLOT 127
+
+#define R_MIPS_NUM 128
+
+#define PT_MIPS_REGINFO 0x70000000
+#define PT_MIPS_RTPROC 0x70000001
+#define PT_MIPS_OPTIONS 0x70000002
+
+#define PF_MIPS_LOCAL 0x10000000
+
+#define DT_MIPS_RLD_VERSION 0x70000001
+#define DT_MIPS_TIME_STAMP 0x70000002
+#define DT_MIPS_ICHECKSUM 0x70000003
+#define DT_MIPS_IVERSION 0x70000004
+#define DT_MIPS_FLAGS 0x70000005
+#define DT_MIPS_BASE_ADDRESS 0x70000006
+#define DT_MIPS_MSYM 0x70000007
+#define DT_MIPS_CONFLICT 0x70000008
+#define DT_MIPS_LIBLIST 0x70000009
+#define DT_MIPS_LOCAL_GOTNO 0x7000000a
+#define DT_MIPS_CONFLICTNO 0x7000000b
+#define DT_MIPS_LIBLISTNO 0x70000010
+#define DT_MIPS_SYMTABNO 0x70000011
+#define DT_MIPS_UNREFEXTNO 0x70000012
+#define DT_MIPS_GOTSYM 0x70000013
+#define DT_MIPS_HIPAGENO 0x70000014
+#define DT_MIPS_RLD_MAP 0x70000016
+#define DT_MIPS_DELTA_CLASS 0x70000017
+#define DT_MIPS_DELTA_CLASS_NO 0x70000018
+
+#define DT_MIPS_DELTA_INSTANCE 0x70000019
+#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a
+
+#define DT_MIPS_DELTA_RELOC 0x7000001b
+#define DT_MIPS_DELTA_RELOC_NO 0x7000001c
+
+#define DT_MIPS_DELTA_SYM 0x7000001d
+
+#define DT_MIPS_DELTA_SYM_NO 0x7000001e
+
+#define DT_MIPS_DELTA_CLASSSYM 0x70000020
+
+#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021
+
+#define DT_MIPS_CXX_FLAGS 0x70000022
+#define DT_MIPS_PIXIE_INIT 0x70000023
+#define DT_MIPS_SYMBOL_LIB 0x70000024
+#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
+#define DT_MIPS_LOCAL_GOTIDX 0x70000026
+#define DT_MIPS_HIDDEN_GOTIDX 0x70000027
+#define DT_MIPS_PROTECTED_GOTIDX 0x70000028
+#define DT_MIPS_OPTIONS 0x70000029
+#define DT_MIPS_INTERFACE 0x7000002a
+#define DT_MIPS_DYNSTR_ALIGN 0x7000002b
+#define DT_MIPS_INTERFACE_SIZE 0x7000002c
+#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d
+
+#define DT_MIPS_PERF_SUFFIX 0x7000002e
+
+#define DT_MIPS_COMPACT_SIZE 0x7000002f
+#define DT_MIPS_GP_VALUE 0x70000030
+#define DT_MIPS_AUX_DYNAMIC 0x70000031
+
+#define DT_MIPS_PLTGOT 0x70000032
+
+#define DT_MIPS_RWPLT 0x70000034
+#define DT_MIPS_NUM 0x35
+
+#define RHF_NONE 0
+#define RHF_QUICKSTART (1 << 0)
+#define RHF_NOTPOT (1 << 1)
+#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2)
+#define RHF_NO_MOVE (1 << 3)
+#define RHF_SGI_ONLY (1 << 4)
+#define RHF_GUARANTEE_INIT (1 << 5)
+#define RHF_DELTA_C_PLUS_PLUS (1 << 6)
+#define RHF_GUARANTEE_START_INIT (1 << 7)
+#define RHF_PIXIE (1 << 8)
+#define RHF_DEFAULT_DELAY_LOAD (1 << 9)
+#define RHF_REQUICKSTART (1 << 10)
+#define RHF_REQUICKSTARTED (1 << 11)
+#define RHF_CORD (1 << 12)
+#define RHF_NO_UNRES_UNDEF (1 << 13)
+#define RHF_RLD_ORDER_SAFE (1 << 14)
+
+typedef struct {
+ Elf32_Word l_name;
+ Elf32_Word l_time_stamp;
+ Elf32_Word l_checksum;
+ Elf32_Word l_version;
+ Elf32_Word l_flags;
+} Elf32_Lib;
+
+typedef struct {
+ Elf64_Word l_name;
+ Elf64_Word l_time_stamp;
+ Elf64_Word l_checksum;
+ Elf64_Word l_version;
+ Elf64_Word l_flags;
+} Elf64_Lib;
+
+#define LL_NONE 0
+#define LL_EXACT_MATCH (1 << 0)
+#define LL_IGNORE_INT_VER (1 << 1)
+#define LL_REQUIRE_MINOR (1 << 2)
+#define LL_EXPORTS (1 << 3)
+#define LL_DELAY_LOAD (1 << 4)
+#define LL_DELTA (1 << 5)
+
+typedef Elf32_Addr Elf32_Conflict;
+
+#define EF_PARISC_TRAPNIL 0x00010000
+#define EF_PARISC_EXT 0x00020000
+#define EF_PARISC_LSB 0x00040000
+#define EF_PARISC_WIDE 0x00080000
+#define EF_PARISC_NO_KABP 0x00100000
+
+#define EF_PARISC_LAZYSWAP 0x00400000
+#define EF_PARISC_ARCH 0x0000ffff
+
+#define EFA_PARISC_1_0 0x020b
+#define EFA_PARISC_1_1 0x0210
+#define EFA_PARISC_2_0 0x0214
+
+#define SHN_PARISC_ANSI_COMMON 0xff00
+
+#define SHN_PARISC_HUGE_COMMON 0xff01
+
+#define SHT_PARISC_EXT 0x70000000
+#define SHT_PARISC_UNWIND 0x70000001
+#define SHT_PARISC_DOC 0x70000002
+
+#define SHF_PARISC_SHORT 0x20000000
+#define SHF_PARISC_HUGE 0x40000000
+#define SHF_PARISC_SBP 0x80000000
+
+#define STT_PARISC_MILLICODE 13
+
+#define STT_HP_OPAQUE (STT_LOOS + 0x1)
+#define STT_HP_STUB (STT_LOOS + 0x2)
+
+#define R_PARISC_NONE 0
+#define R_PARISC_DIR32 1
+#define R_PARISC_DIR21L 2
+#define R_PARISC_DIR17R 3
+#define R_PARISC_DIR17F 4
+#define R_PARISC_DIR14R 6
+#define R_PARISC_PCREL32 9
+#define R_PARISC_PCREL21L 10
+#define R_PARISC_PCREL17R 11
+#define R_PARISC_PCREL17F 12
+#define R_PARISC_PCREL14R 14
+#define R_PARISC_DPREL21L 18
+#define R_PARISC_DPREL14R 22
+#define R_PARISC_GPREL21L 26
+#define R_PARISC_GPREL14R 30
+#define R_PARISC_LTOFF21L 34
+#define R_PARISC_LTOFF14R 38
+#define R_PARISC_SECREL32 41
+#define R_PARISC_SEGBASE 48
+#define R_PARISC_SEGREL32 49
+#define R_PARISC_PLTOFF21L 50
+#define R_PARISC_PLTOFF14R 54
+#define R_PARISC_LTOFF_FPTR32 57
+#define R_PARISC_LTOFF_FPTR21L 58
+#define R_PARISC_LTOFF_FPTR14R 62
+#define R_PARISC_FPTR64 64
+#define R_PARISC_PLABEL32 65
+#define R_PARISC_PLABEL21L 66
+#define R_PARISC_PLABEL14R 70
+#define R_PARISC_PCREL64 72
+#define R_PARISC_PCREL22F 74
+#define R_PARISC_PCREL14WR 75
+#define R_PARISC_PCREL14DR 76
+#define R_PARISC_PCREL16F 77
+#define R_PARISC_PCREL16WF 78
+#define R_PARISC_PCREL16DF 79
+#define R_PARISC_DIR64 80
+#define R_PARISC_DIR14WR 83
+#define R_PARISC_DIR14DR 84
+#define R_PARISC_DIR16F 85
+#define R_PARISC_DIR16WF 86
+#define R_PARISC_DIR16DF 87
+#define R_PARISC_GPREL64 88
+#define R_PARISC_GPREL14WR 91
+#define R_PARISC_GPREL14DR 92
+#define R_PARISC_GPREL16F 93
+#define R_PARISC_GPREL16WF 94
+#define R_PARISC_GPREL16DF 95
+#define R_PARISC_LTOFF64 96
+#define R_PARISC_LTOFF14WR 99
+#define R_PARISC_LTOFF14DR 100
+#define R_PARISC_LTOFF16F 101
+#define R_PARISC_LTOFF16WF 102
+#define R_PARISC_LTOFF16DF 103
+#define R_PARISC_SECREL64 104
+#define R_PARISC_SEGREL64 112
+#define R_PARISC_PLTOFF14WR 115
+#define R_PARISC_PLTOFF14DR 116
+#define R_PARISC_PLTOFF16F 117
+#define R_PARISC_PLTOFF16WF 118
+#define R_PARISC_PLTOFF16DF 119
+#define R_PARISC_LTOFF_FPTR64 120
+#define R_PARISC_LTOFF_FPTR14WR 123
+#define R_PARISC_LTOFF_FPTR14DR 124
+#define R_PARISC_LTOFF_FPTR16F 125
+#define R_PARISC_LTOFF_FPTR16WF 126
+#define R_PARISC_LTOFF_FPTR16DF 127
+#define R_PARISC_LORESERVE 128
+#define R_PARISC_COPY 128
+#define R_PARISC_IPLT 129
+#define R_PARISC_EPLT 130
+#define R_PARISC_TPREL32 153
+#define R_PARISC_TPREL21L 154
+#define R_PARISC_TPREL14R 158
+#define R_PARISC_LTOFF_TP21L 162
+#define R_PARISC_LTOFF_TP14R 166
+#define R_PARISC_LTOFF_TP14F 167
+#define R_PARISC_TPREL64 216
+#define R_PARISC_TPREL14WR 219
+#define R_PARISC_TPREL14DR 220
+#define R_PARISC_TPREL16F 221
+#define R_PARISC_TPREL16WF 222
+#define R_PARISC_TPREL16DF 223
+#define R_PARISC_LTOFF_TP64 224
+#define R_PARISC_LTOFF_TP14WR 227
+#define R_PARISC_LTOFF_TP14DR 228
+#define R_PARISC_LTOFF_TP16F 229
+#define R_PARISC_LTOFF_TP16WF 230
+#define R_PARISC_LTOFF_TP16DF 231
+#define R_PARISC_GNU_VTENTRY 232
+#define R_PARISC_GNU_VTINHERIT 233
+#define R_PARISC_TLS_GD21L 234
+#define R_PARISC_TLS_GD14R 235
+#define R_PARISC_TLS_GDCALL 236
+#define R_PARISC_TLS_LDM21L 237
+#define R_PARISC_TLS_LDM14R 238
+#define R_PARISC_TLS_LDMCALL 239
+#define R_PARISC_TLS_LDO21L 240
+#define R_PARISC_TLS_LDO14R 241
+#define R_PARISC_TLS_DTPMOD32 242
+#define R_PARISC_TLS_DTPMOD64 243
+#define R_PARISC_TLS_DTPOFF32 244
+#define R_PARISC_TLS_DTPOFF64 245
+#define R_PARISC_TLS_LE21L R_PARISC_TPREL21L
+#define R_PARISC_TLS_LE14R R_PARISC_TPREL14R
+#define R_PARISC_TLS_IE21L R_PARISC_LTOFF_TP21L
+#define R_PARISC_TLS_IE14R R_PARISC_LTOFF_TP14R
+#define R_PARISC_TLS_TPREL32 R_PARISC_TPREL32
+#define R_PARISC_TLS_TPREL64 R_PARISC_TPREL64
+#define R_PARISC_HIRESERVE 255
+
+#define PT_HP_TLS (PT_LOOS + 0x0)
+#define PT_HP_CORE_NONE (PT_LOOS + 0x1)
+#define PT_HP_CORE_VERSION (PT_LOOS + 0x2)
+#define PT_HP_CORE_KERNEL (PT_LOOS + 0x3)
+#define PT_HP_CORE_COMM (PT_LOOS + 0x4)
+#define PT_HP_CORE_PROC (PT_LOOS + 0x5)
+#define PT_HP_CORE_LOADABLE (PT_LOOS + 0x6)
+#define PT_HP_CORE_STACK (PT_LOOS + 0x7)
+#define PT_HP_CORE_SHM (PT_LOOS + 0x8)
+#define PT_HP_CORE_MMF (PT_LOOS + 0x9)
+#define PT_HP_PARALLEL (PT_LOOS + 0x10)
+#define PT_HP_FASTBIND (PT_LOOS + 0x11)
+#define PT_HP_OPT_ANNOT (PT_LOOS + 0x12)
+#define PT_HP_HSL_ANNOT (PT_LOOS + 0x13)
+#define PT_HP_STACK (PT_LOOS + 0x14)
+
+#define PT_PARISC_ARCHEXT 0x70000000
+#define PT_PARISC_UNWIND 0x70000001
+
+#define PF_PARISC_SBP 0x08000000
+
+#define PF_HP_PAGE_SIZE 0x00100000
+#define PF_HP_FAR_SHARED 0x00200000
+#define PF_HP_NEAR_SHARED 0x00400000
+#define PF_HP_CODE 0x01000000
+#define PF_HP_MODIFY 0x02000000
+#define PF_HP_LAZYSWAP 0x04000000
+#define PF_HP_SBP 0x08000000
+
+#define EF_ALPHA_32BIT 1
+#define EF_ALPHA_CANRELAX 2
+
+#define SHT_ALPHA_DEBUG 0x70000001
+#define SHT_ALPHA_REGINFO 0x70000002
+
+#define SHF_ALPHA_GPREL 0x10000000
+
+#define STO_ALPHA_NOPV 0x80
+#define STO_ALPHA_STD_GPLOAD 0x88
+
+#define R_ALPHA_NONE 0
+#define R_ALPHA_REFLONG 1
+#define R_ALPHA_REFQUAD 2
+#define R_ALPHA_GPREL32 3
+#define R_ALPHA_LITERAL 4
+#define R_ALPHA_LITUSE 5
+#define R_ALPHA_GPDISP 6
+#define R_ALPHA_BRADDR 7
+#define R_ALPHA_HINT 8
+#define R_ALPHA_SREL16 9
+#define R_ALPHA_SREL32 10
+#define R_ALPHA_SREL64 11
+#define R_ALPHA_GPRELHIGH 17
+#define R_ALPHA_GPRELLOW 18
+#define R_ALPHA_GPREL16 19
+#define R_ALPHA_COPY 24
+#define R_ALPHA_GLOB_DAT 25
+#define R_ALPHA_JMP_SLOT 26
+#define R_ALPHA_RELATIVE 27
+#define R_ALPHA_TLS_GD_HI 28
+#define R_ALPHA_TLSGD 29
+#define R_ALPHA_TLS_LDM 30
+#define R_ALPHA_DTPMOD64 31
+#define R_ALPHA_GOTDTPREL 32
+#define R_ALPHA_DTPREL64 33
+#define R_ALPHA_DTPRELHI 34
+#define R_ALPHA_DTPRELLO 35
+#define R_ALPHA_DTPREL16 36
+#define R_ALPHA_GOTTPREL 37
+#define R_ALPHA_TPREL64 38
+#define R_ALPHA_TPRELHI 39
+#define R_ALPHA_TPRELLO 40
+#define R_ALPHA_TPREL16 41
+
+#define R_ALPHA_NUM 46
+
+#define LITUSE_ALPHA_ADDR 0
+#define LITUSE_ALPHA_BASE 1
+#define LITUSE_ALPHA_BYTOFF 2
+#define LITUSE_ALPHA_JSR 3
+#define LITUSE_ALPHA_TLS_GD 4
+#define LITUSE_ALPHA_TLS_LDM 5
+
+#define DT_ALPHA_PLTRO (DT_LOPROC + 0)
+#define DT_ALPHA_NUM 1
+
+#define EF_PPC_EMB 0x80000000
+
+#define EF_PPC_RELOCATABLE 0x00010000
+#define EF_PPC_RELOCATABLE_LIB 0x00008000
+
+#define R_PPC_NONE 0
+#define R_PPC_ADDR32 1
+#define R_PPC_ADDR24 2
+#define R_PPC_ADDR16 3
+#define R_PPC_ADDR16_LO 4
+#define R_PPC_ADDR16_HI 5
+#define R_PPC_ADDR16_HA 6
+#define R_PPC_ADDR14 7
+#define R_PPC_ADDR14_BRTAKEN 8
+#define R_PPC_ADDR14_BRNTAKEN 9
+#define R_PPC_REL24 10
+#define R_PPC_REL14 11
+#define R_PPC_REL14_BRTAKEN 12
+#define R_PPC_REL14_BRNTAKEN 13
+#define R_PPC_GOT16 14
+#define R_PPC_GOT16_LO 15
+#define R_PPC_GOT16_HI 16
+#define R_PPC_GOT16_HA 17
+#define R_PPC_PLTREL24 18
+#define R_PPC_COPY 19
+#define R_PPC_GLOB_DAT 20
+#define R_PPC_JMP_SLOT 21
+#define R_PPC_RELATIVE 22
+#define R_PPC_LOCAL24PC 23
+#define R_PPC_UADDR32 24
+#define R_PPC_UADDR16 25
+#define R_PPC_REL32 26
+#define R_PPC_PLT32 27
+#define R_PPC_PLTREL32 28
+#define R_PPC_PLT16_LO 29
+#define R_PPC_PLT16_HI 30
+#define R_PPC_PLT16_HA 31
+#define R_PPC_SDAREL16 32
+#define R_PPC_SECTOFF 33
+#define R_PPC_SECTOFF_LO 34
+#define R_PPC_SECTOFF_HI 35
+#define R_PPC_SECTOFF_HA 36
+
+#define R_PPC_TLS 67
+#define R_PPC_DTPMOD32 68
+#define R_PPC_TPREL16 69
+#define R_PPC_TPREL16_LO 70
+#define R_PPC_TPREL16_HI 71
+#define R_PPC_TPREL16_HA 72
+#define R_PPC_TPREL32 73
+#define R_PPC_DTPREL16 74
+#define R_PPC_DTPREL16_LO 75
+#define R_PPC_DTPREL16_HI 76
+#define R_PPC_DTPREL16_HA 77
+#define R_PPC_DTPREL32 78
+#define R_PPC_GOT_TLSGD16 79
+#define R_PPC_GOT_TLSGD16_LO 80
+#define R_PPC_GOT_TLSGD16_HI 81
+#define R_PPC_GOT_TLSGD16_HA 82
+#define R_PPC_GOT_TLSLD16 83
+#define R_PPC_GOT_TLSLD16_LO 84
+#define R_PPC_GOT_TLSLD16_HI 85
+#define R_PPC_GOT_TLSLD16_HA 86
+#define R_PPC_GOT_TPREL16 87
+#define R_PPC_GOT_TPREL16_LO 88
+#define R_PPC_GOT_TPREL16_HI 89
+#define R_PPC_GOT_TPREL16_HA 90
+#define R_PPC_GOT_DTPREL16 91
+#define R_PPC_GOT_DTPREL16_LO 92
+#define R_PPC_GOT_DTPREL16_HI 93
+#define R_PPC_GOT_DTPREL16_HA 94
+
+#define R_PPC_EMB_NADDR32 101
+#define R_PPC_EMB_NADDR16 102
+#define R_PPC_EMB_NADDR16_LO 103
+#define R_PPC_EMB_NADDR16_HI 104
+#define R_PPC_EMB_NADDR16_HA 105
+#define R_PPC_EMB_SDAI16 106
+#define R_PPC_EMB_SDA2I16 107
+#define R_PPC_EMB_SDA2REL 108
+#define R_PPC_EMB_SDA21 109
+#define R_PPC_EMB_MRKREF 110
+#define R_PPC_EMB_RELSEC16 111
+#define R_PPC_EMB_RELST_LO 112
+#define R_PPC_EMB_RELST_HI 113
+#define R_PPC_EMB_RELST_HA 114
+#define R_PPC_EMB_BIT_FLD 115
+#define R_PPC_EMB_RELSDA 116
+
+#define R_PPC_DIAB_SDA21_LO 180
+#define R_PPC_DIAB_SDA21_HI 181
+#define R_PPC_DIAB_SDA21_HA 182
+#define R_PPC_DIAB_RELSDA_LO 183
+#define R_PPC_DIAB_RELSDA_HI 184
+#define R_PPC_DIAB_RELSDA_HA 185
+
+#define R_PPC_IRELATIVE 248
+
+#define R_PPC_REL16 249
+#define R_PPC_REL16_LO 250
+#define R_PPC_REL16_HI 251
+#define R_PPC_REL16_HA 252
+
+#define R_PPC_TOC16 255
+
+#define DT_PPC_GOT (DT_LOPROC + 0)
+#define DT_PPC_NUM 1
+
+#define R_PPC64_NONE R_PPC_NONE
+#define R_PPC64_ADDR32 R_PPC_ADDR32
+#define R_PPC64_ADDR24 R_PPC_ADDR24
+#define R_PPC64_ADDR16 R_PPC_ADDR16
+#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO
+#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI
+#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA
+#define R_PPC64_ADDR14 R_PPC_ADDR14
+#define R_PPC64_ADDR14_BRTAKEN R_PPC_ADDR14_BRTAKEN
+#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN
+#define R_PPC64_REL24 R_PPC_REL24
+#define R_PPC64_REL14 R_PPC_REL14
+#define R_PPC64_REL14_BRTAKEN R_PPC_REL14_BRTAKEN
+#define R_PPC64_REL14_BRNTAKEN R_PPC_REL14_BRNTAKEN
+#define R_PPC64_GOT16 R_PPC_GOT16
+#define R_PPC64_GOT16_LO R_PPC_GOT16_LO
+#define R_PPC64_GOT16_HI R_PPC_GOT16_HI
+#define R_PPC64_GOT16_HA R_PPC_GOT16_HA
+
+#define R_PPC64_COPY R_PPC_COPY
+#define R_PPC64_GLOB_DAT R_PPC_GLOB_DAT
+#define R_PPC64_JMP_SLOT R_PPC_JMP_SLOT
+#define R_PPC64_RELATIVE R_PPC_RELATIVE
+
+#define R_PPC64_UADDR32 R_PPC_UADDR32
+#define R_PPC64_UADDR16 R_PPC_UADDR16
+#define R_PPC64_REL32 R_PPC_REL32
+#define R_PPC64_PLT32 R_PPC_PLT32
+#define R_PPC64_PLTREL32 R_PPC_PLTREL32
+#define R_PPC64_PLT16_LO R_PPC_PLT16_LO
+#define R_PPC64_PLT16_HI R_PPC_PLT16_HI
+#define R_PPC64_PLT16_HA R_PPC_PLT16_HA
+
+#define R_PPC64_SECTOFF R_PPC_SECTOFF
+#define R_PPC64_SECTOFF_LO R_PPC_SECTOFF_LO
+#define R_PPC64_SECTOFF_HI R_PPC_SECTOFF_HI
+#define R_PPC64_SECTOFF_HA R_PPC_SECTOFF_HA
+#define R_PPC64_ADDR30 37
+#define R_PPC64_ADDR64 38
+#define R_PPC64_ADDR16_HIGHER 39
+#define R_PPC64_ADDR16_HIGHERA 40
+#define R_PPC64_ADDR16_HIGHEST 41
+#define R_PPC64_ADDR16_HIGHESTA 42
+#define R_PPC64_UADDR64 43
+#define R_PPC64_REL64 44
+#define R_PPC64_PLT64 45
+#define R_PPC64_PLTREL64 46
+#define R_PPC64_TOC16 47
+#define R_PPC64_TOC16_LO 48
+#define R_PPC64_TOC16_HI 49
+#define R_PPC64_TOC16_HA 50
+#define R_PPC64_TOC 51
+#define R_PPC64_PLTGOT16 52
+#define R_PPC64_PLTGOT16_LO 53
+#define R_PPC64_PLTGOT16_HI 54
+#define R_PPC64_PLTGOT16_HA 55
+
+#define R_PPC64_ADDR16_DS 56
+#define R_PPC64_ADDR16_LO_DS 57
+#define R_PPC64_GOT16_DS 58
+#define R_PPC64_GOT16_LO_DS 59
+#define R_PPC64_PLT16_LO_DS 60
+#define R_PPC64_SECTOFF_DS 61
+#define R_PPC64_SECTOFF_LO_DS 62
+#define R_PPC64_TOC16_DS 63
+#define R_PPC64_TOC16_LO_DS 64
+#define R_PPC64_PLTGOT16_DS 65
+#define R_PPC64_PLTGOT16_LO_DS 66
+
+#define R_PPC64_TLS 67
+#define R_PPC64_DTPMOD64 68
+#define R_PPC64_TPREL16 69
+#define R_PPC64_TPREL16_LO 70
+#define R_PPC64_TPREL16_HI 71
+#define R_PPC64_TPREL16_HA 72
+#define R_PPC64_TPREL64 73
+#define R_PPC64_DTPREL16 74
+#define R_PPC64_DTPREL16_LO 75
+#define R_PPC64_DTPREL16_HI 76
+#define R_PPC64_DTPREL16_HA 77
+#define R_PPC64_DTPREL64 78
+#define R_PPC64_GOT_TLSGD16 79
+#define R_PPC64_GOT_TLSGD16_LO 80
+#define R_PPC64_GOT_TLSGD16_HI 81
+#define R_PPC64_GOT_TLSGD16_HA 82
+#define R_PPC64_GOT_TLSLD16 83
+#define R_PPC64_GOT_TLSLD16_LO 84
+#define R_PPC64_GOT_TLSLD16_HI 85
+#define R_PPC64_GOT_TLSLD16_HA 86
+#define R_PPC64_GOT_TPREL16_DS 87
+#define R_PPC64_GOT_TPREL16_LO_DS 88
+#define R_PPC64_GOT_TPREL16_HI 89
+#define R_PPC64_GOT_TPREL16_HA 90
+#define R_PPC64_GOT_DTPREL16_DS 91
+#define R_PPC64_GOT_DTPREL16_LO_DS 92
+#define R_PPC64_GOT_DTPREL16_HI 93
+#define R_PPC64_GOT_DTPREL16_HA 94
+#define R_PPC64_TPREL16_DS 95
+#define R_PPC64_TPREL16_LO_DS 96
+#define R_PPC64_TPREL16_HIGHER 97
+#define R_PPC64_TPREL16_HIGHERA 98
+#define R_PPC64_TPREL16_HIGHEST 99
+#define R_PPC64_TPREL16_HIGHESTA 100
+#define R_PPC64_DTPREL16_DS 101
+#define R_PPC64_DTPREL16_LO_DS 102
+#define R_PPC64_DTPREL16_HIGHER 103
+#define R_PPC64_DTPREL16_HIGHERA 104
+#define R_PPC64_DTPREL16_HIGHEST 105
+#define R_PPC64_DTPREL16_HIGHESTA 106
+
+#define R_PPC64_JMP_IREL 247
+#define R_PPC64_IRELATIVE 248
+#define R_PPC64_REL16 249
+#define R_PPC64_REL16_LO 250
+#define R_PPC64_REL16_HI 251
+#define R_PPC64_REL16_HA 252
+
+#define DT_PPC64_GLINK (DT_LOPROC + 0)
+#define DT_PPC64_OPD (DT_LOPROC + 1)
+#define DT_PPC64_OPDSZ (DT_LOPROC + 2)
+#define DT_PPC64_NUM 3
+
+#define EF_ARM_RELEXEC 0x01
+#define EF_ARM_HASENTRY 0x02
+#define EF_ARM_INTERWORK 0x04
+#define EF_ARM_APCS_26 0x08
+#define EF_ARM_APCS_FLOAT 0x10
+#define EF_ARM_PIC 0x20
+#define EF_ARM_ALIGN8 0x40
+#define EF_ARM_NEW_ABI 0x80
+#define EF_ARM_OLD_ABI 0x100
+#define EF_ARM_SOFT_FLOAT 0x200
+#define EF_ARM_VFP_FLOAT 0x400
+#define EF_ARM_MAVERICK_FLOAT 0x800
+
+#define EF_ARM_ABI_FLOAT_SOFT 0x200
+#define EF_ARM_ABI_FLOAT_HARD 0x400
+
+#define EF_ARM_SYMSARESORTED 0x04
+#define EF_ARM_DYNSYMSUSESEGIDX 0x08
+#define EF_ARM_MAPSYMSFIRST 0x10
+#define EF_ARM_EABIMASK 0XFF000000
+
+#define EF_ARM_BE8 0x00800000
+#define EF_ARM_LE8 0x00400000
+
+#define EF_ARM_EABI_VERSION(flags) ((flags)&EF_ARM_EABIMASK)
+#define EF_ARM_EABI_UNKNOWN 0x00000000
+#define EF_ARM_EABI_VER1 0x01000000
+#define EF_ARM_EABI_VER2 0x02000000
+#define EF_ARM_EABI_VER3 0x03000000
+#define EF_ARM_EABI_VER4 0x04000000
+#define EF_ARM_EABI_VER5 0x05000000
+
+#define STT_ARM_TFUNC STT_LOPROC
+#define STT_ARM_16BIT STT_HIPROC
+
+#define SHF_ARM_ENTRYSECT 0x10000000
+#define SHF_ARM_COMDEF 0x80000000
+
+#define PF_ARM_SB 0x10000000
+
+#define PF_ARM_PI 0x20000000
+#define PF_ARM_ABS 0x40000000
+
+#define PT_ARM_EXIDX (PT_LOPROC + 1)
+
+#define SHT_ARM_EXIDX (SHT_LOPROC + 1)
+#define SHT_ARM_PREEMPTMAP (SHT_LOPROC + 2)
+#define SHT_ARM_ATTRIBUTES (SHT_LOPROC + 3)
+
+#define R_AARCH64_NONE 0
+#define R_AARCH64_ABS64 257
+#define R_AARCH64_ABS32 258
+#define R_AARCH64_ABS16 259
+#define R_AARCH64_PREL64 260
+#define R_AARCH64_PREL32 261
+#define R_AARCH64_PREL16 262
+#define R_AARCH64_MOVW_UABS_G0 263
+#define R_AARCH64_MOVW_UABS_G0_NC 264
+#define R_AARCH64_MOVW_UABS_G1 265
+#define R_AARCH64_MOVW_UABS_G1_NC 266
+#define R_AARCH64_MOVW_UABS_G2 267
+#define R_AARCH64_MOVW_UABS_G2_NC 268
+#define R_AARCH64_MOVW_UABS_G3 269
+#define R_AARCH64_MOVW_SABS_G0 270
+#define R_AARCH64_MOVW_SABS_G1 271
+#define R_AARCH64_MOVW_SABS_G2 272
+#define R_AARCH64_LD_PREL_LO19 273
+#define R_AARCH64_ADR_PREL_LO21 274
+#define R_AARCH64_ADR_PREL_PG_HI21 275
+#define R_AARCH64_ADR_PREL_PG_HI21_NC 276
+#define R_AARCH64_ADD_ABS_LO12_NC 277
+#define R_AARCH64_LDST8_ABS_LO12_NC 278
+#define R_AARCH64_TSTBR14 279
+#define R_AARCH64_CONDBR19 280
+#define R_AARCH64_JUMP26 282
+#define R_AARCH64_CALL26 283
+#define R_AARCH64_LDST16_ABS_LO12_NC 284
+#define R_AARCH64_LDST32_ABS_LO12_NC 285
+#define R_AARCH64_LDST64_ABS_LO12_NC 286
+#define R_AARCH64_MOVW_PREL_G0 287
+#define R_AARCH64_MOVW_PREL_G0_NC 288
+#define R_AARCH64_MOVW_PREL_G1 289
+#define R_AARCH64_MOVW_PREL_G1_NC 290
+#define R_AARCH64_MOVW_PREL_G2 291
+#define R_AARCH64_MOVW_PREL_G2_NC 292
+#define R_AARCH64_MOVW_PREL_G3 293
+#define R_AARCH64_LDST128_ABS_LO12_NC 299
+#define R_AARCH64_MOVW_GOTOFF_G0 300
+#define R_AARCH64_MOVW_GOTOFF_G0_NC 301
+#define R_AARCH64_MOVW_GOTOFF_G1 302
+#define R_AARCH64_MOVW_GOTOFF_G1_NC 303
+#define R_AARCH64_MOVW_GOTOFF_G2 304
+#define R_AARCH64_MOVW_GOTOFF_G2_NC 305
+#define R_AARCH64_MOVW_GOTOFF_G3 306
+#define R_AARCH64_GOTREL64 307
+#define R_AARCH64_GOTREL32 308
+#define R_AARCH64_GOT_LD_PREL19 309
+#define R_AARCH64_LD64_GOTOFF_LO15 310
+#define R_AARCH64_ADR_GOT_PAGE 311
+#define R_AARCH64_LD64_GOT_LO12_NC 312
+#define R_AARCH64_LD64_GOTPAGE_LO15 313
+#define R_AARCH64_TLSGD_ADR_PREL21 512
+#define R_AARCH64_TLSGD_ADR_PAGE21 513
+#define R_AARCH64_TLSGD_ADD_LO12_NC 514
+#define R_AARCH64_TLSGD_MOVW_G1 515
+#define R_AARCH64_TLSGD_MOVW_G0_NC 516
+#define R_AARCH64_TLSLD_ADR_PREL21 517
+#define R_AARCH64_TLSLD_ADR_PAGE21 518
+#define R_AARCH64_TLSLD_ADD_LO12_NC 519
+#define R_AARCH64_TLSLD_MOVW_G1 520
+#define R_AARCH64_TLSLD_MOVW_G0_NC 521
+#define R_AARCH64_TLSLD_LD_PREL19 522
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527
+#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540
+#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541
+#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542
+#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543
+#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548
+#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559
+#define R_AARCH64_TLSDESC_LD_PREL19 560
+#define R_AARCH64_TLSDESC_ADR_PREL21 561
+#define R_AARCH64_TLSDESC_ADR_PAGE21 562
+#define R_AARCH64_TLSDESC_LD64_LO12 563
+#define R_AARCH64_TLSDESC_ADD_LO12 564
+#define R_AARCH64_TLSDESC_OFF_G1 565
+#define R_AARCH64_TLSDESC_OFF_G0_NC 566
+#define R_AARCH64_TLSDESC_LDR 567
+#define R_AARCH64_TLSDESC_ADD 568
+#define R_AARCH64_TLSDESC_CALL 569
+#define R_AARCH64_TLSLE_LDST128_TPREL_LO12 570
+#define R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC 571
+#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12 572
+#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC 573
+#define R_AARCH64_COPY 1024
+#define R_AARCH64_GLOB_DAT 1025
+#define R_AARCH64_JUMP_SLOT 1026
+#define R_AARCH64_RELATIVE 1027
+#define R_AARCH64_TLS_DTPMOD64 1028
+#define R_AARCH64_TLS_DTPREL64 1029
+#define R_AARCH64_TLS_TPREL64 1030
+#define R_AARCH64_TLSDESC 1031
+
+#define R_ARM_NONE 0
+#define R_ARM_PC24 1
+#define R_ARM_ABS32 2
+#define R_ARM_REL32 3
+#define R_ARM_PC13 4
+#define R_ARM_ABS16 5
+#define R_ARM_ABS12 6
+#define R_ARM_THM_ABS5 7
+#define R_ARM_ABS8 8
+#define R_ARM_SBREL32 9
+#define R_ARM_THM_PC22 10
+#define R_ARM_THM_PC8 11
+#define R_ARM_AMP_VCALL9 12
+#define R_ARM_TLS_DESC 13
+#define R_ARM_THM_SWI8 14
+#define R_ARM_XPC25 15
+#define R_ARM_THM_XPC22 16
+#define R_ARM_TLS_DTPMOD32 17
+#define R_ARM_TLS_DTPOFF32 18
+#define R_ARM_TLS_TPOFF32 19
+#define R_ARM_COPY 20
+#define R_ARM_GLOB_DAT 21
+#define R_ARM_JUMP_SLOT 22
+#define R_ARM_RELATIVE 23
+#define R_ARM_GOTOFF 24
+#define R_ARM_GOTPC 25
+#define R_ARM_GOT32 26
+#define R_ARM_PLT32 27
+#define R_ARM_CALL 28
+#define R_ARM_JUMP24 29
+#define R_ARM_THM_JUMP24 30
+#define R_ARM_BASE_ABS 31
+#define R_ARM_ALU_PCREL_7_0 32
+#define R_ARM_ALU_PCREL_15_8 33
+#define R_ARM_ALU_PCREL_23_15 34
+#define R_ARM_LDR_SBREL_11_0 35
+#define R_ARM_ALU_SBREL_19_12 36
+#define R_ARM_ALU_SBREL_27_20 37
+#define R_ARM_TARGET1 38
+#define R_ARM_SBREL31 39
+#define R_ARM_V4BX 40
+#define R_ARM_TARGET2 41
+#define R_ARM_PREL31 42
+#define R_ARM_MOVW_ABS_NC 43
+#define R_ARM_MOVT_ABS 44
+#define R_ARM_MOVW_PREL_NC 45
+#define R_ARM_MOVT_PREL 46
+#define R_ARM_THM_MOVW_ABS_NC 47
+#define R_ARM_THM_MOVT_ABS 48
+#define R_ARM_THM_MOVW_PREL_NC 49
+#define R_ARM_THM_MOVT_PREL 50
+#define R_ARM_THM_JUMP19 51
+#define R_ARM_THM_JUMP6 52
+#define R_ARM_THM_ALU_PREL_11_0 53
+#define R_ARM_THM_PC12 54
+#define R_ARM_ABS32_NOI 55
+#define R_ARM_REL32_NOI 56
+#define R_ARM_ALU_PC_G0_NC 57
+#define R_ARM_ALU_PC_G0 58
+#define R_ARM_ALU_PC_G1_NC 59
+#define R_ARM_ALU_PC_G1 60
+#define R_ARM_ALU_PC_G2 61
+#define R_ARM_LDR_PC_G1 62
+#define R_ARM_LDR_PC_G2 63
+#define R_ARM_LDRS_PC_G0 64
+#define R_ARM_LDRS_PC_G1 65
+#define R_ARM_LDRS_PC_G2 66
+#define R_ARM_LDC_PC_G0 67
+#define R_ARM_LDC_PC_G1 68
+#define R_ARM_LDC_PC_G2 69
+#define R_ARM_ALU_SB_G0_NC 70
+#define R_ARM_ALU_SB_G0 71
+#define R_ARM_ALU_SB_G1_NC 72
+#define R_ARM_ALU_SB_G1 73
+#define R_ARM_ALU_SB_G2 74
+#define R_ARM_LDR_SB_G0 75
+#define R_ARM_LDR_SB_G1 76
+#define R_ARM_LDR_SB_G2 77
+#define R_ARM_LDRS_SB_G0 78
+#define R_ARM_LDRS_SB_G1 79
+#define R_ARM_LDRS_SB_G2 80
+#define R_ARM_LDC_SB_G0 81
+#define R_ARM_LDC_SB_G1 82
+#define R_ARM_LDC_SB_G2 83
+#define R_ARM_MOVW_BREL_NC 84
+#define R_ARM_MOVT_BREL 85
+#define R_ARM_MOVW_BREL 86
+#define R_ARM_THM_MOVW_BREL_NC 87
+#define R_ARM_THM_MOVT_BREL 88
+#define R_ARM_THM_MOVW_BREL 89
+#define R_ARM_TLS_GOTDESC 90
+#define R_ARM_TLS_CALL 91
+#define R_ARM_TLS_DESCSEQ 92
+#define R_ARM_THM_TLS_CALL 93
+#define R_ARM_PLT32_ABS 94
+#define R_ARM_GOT_ABS 95
+#define R_ARM_GOT_PREL 96
+#define R_ARM_GOT_BREL12 97
+#define R_ARM_GOTOFF12 98
+#define R_ARM_GOTRELAX 99
+#define R_ARM_GNU_VTENTRY 100
+#define R_ARM_GNU_VTINHERIT 101
+#define R_ARM_THM_PC11 102
+#define R_ARM_THM_PC9 103
+#define R_ARM_TLS_GD32 104
+
+#define R_ARM_TLS_LDM32 105
+
+#define R_ARM_TLS_LDO32 106
+
+#define R_ARM_TLS_IE32 107
+
+#define R_ARM_TLS_LE32 108
+#define R_ARM_TLS_LDO12 109
+#define R_ARM_TLS_LE12 110
+#define R_ARM_TLS_IE12GP 111
+#define R_ARM_ME_TOO 128
+#define R_ARM_THM_TLS_DESCSEQ 129
+#define R_ARM_THM_TLS_DESCSEQ16 129
+#define R_ARM_THM_TLS_DESCSEQ32 130
+#define R_ARM_THM_GOT_BREL12 131
+#define R_ARM_IRELATIVE 160
+#define R_ARM_RXPC25 249
+#define R_ARM_RSBREL32 250
+#define R_ARM_THM_RPC22 251
+#define R_ARM_RREL32 252
+#define R_ARM_RABS22 253
+#define R_ARM_RPC24 254
+#define R_ARM_RBASE 255
+
+#define R_ARM_NUM 256
+
+#define EF_IA_64_MASKOS 0x0000000f
+#define EF_IA_64_ABI64 0x00000010
+#define EF_IA_64_ARCH 0xff000000
+
+#define PT_IA_64_ARCHEXT (PT_LOPROC + 0)
+#define PT_IA_64_UNWIND (PT_LOPROC + 1)
+#define PT_IA_64_HP_OPT_ANOT (PT_LOOS + 0x12)
+#define PT_IA_64_HP_HSL_ANOT (PT_LOOS + 0x13)
+#define PT_IA_64_HP_STACK (PT_LOOS + 0x14)
+
+#define PF_IA_64_NORECOV 0x80000000
+
+#define SHT_IA_64_EXT (SHT_LOPROC + 0)
+#define SHT_IA_64_UNWIND (SHT_LOPROC + 1)
+
+#define SHF_IA_64_SHORT 0x10000000
+#define SHF_IA_64_NORECOV 0x20000000
+
+#define DT_IA_64_PLT_RESERVE (DT_LOPROC + 0)
+#define DT_IA_64_NUM 1
+
+#define R_IA64_NONE 0x00
+#define R_IA64_IMM14 0x21
+#define R_IA64_IMM22 0x22
+#define R_IA64_IMM64 0x23
+#define R_IA64_DIR32MSB 0x24
+#define R_IA64_DIR32LSB 0x25
+#define R_IA64_DIR64MSB 0x26
+#define R_IA64_DIR64LSB 0x27
+#define R_IA64_GPREL22 0x2a
+#define R_IA64_GPREL64I 0x2b
+#define R_IA64_GPREL32MSB 0x2c
+#define R_IA64_GPREL32LSB 0x2d
+#define R_IA64_GPREL64MSB 0x2e
+#define R_IA64_GPREL64LSB 0x2f
+#define R_IA64_LTOFF22 0x32
+#define R_IA64_LTOFF64I 0x33
+#define R_IA64_PLTOFF22 0x3a
+#define R_IA64_PLTOFF64I 0x3b
+#define R_IA64_PLTOFF64MSB 0x3e
+#define R_IA64_PLTOFF64LSB 0x3f
+#define R_IA64_FPTR64I 0x43
+#define R_IA64_FPTR32MSB 0x44
+#define R_IA64_FPTR32LSB 0x45
+#define R_IA64_FPTR64MSB 0x46
+#define R_IA64_FPTR64LSB 0x47
+#define R_IA64_PCREL60B 0x48
+#define R_IA64_PCREL21B 0x49
+#define R_IA64_PCREL21M 0x4a
+#define R_IA64_PCREL21F 0x4b
+#define R_IA64_PCREL32MSB 0x4c
+#define R_IA64_PCREL32LSB 0x4d
+#define R_IA64_PCREL64MSB 0x4e
+#define R_IA64_PCREL64LSB 0x4f
+#define R_IA64_LTOFF_FPTR22 0x52
+#define R_IA64_LTOFF_FPTR64I 0x53
+#define R_IA64_LTOFF_FPTR32MSB 0x54
+#define R_IA64_LTOFF_FPTR32LSB 0x55
+#define R_IA64_LTOFF_FPTR64MSB 0x56
+#define R_IA64_LTOFF_FPTR64LSB 0x57
+#define R_IA64_SEGREL32MSB 0x5c
+#define R_IA64_SEGREL32LSB 0x5d
+#define R_IA64_SEGREL64MSB 0x5e
+#define R_IA64_SEGREL64LSB 0x5f
+#define R_IA64_SECREL32MSB 0x64
+#define R_IA64_SECREL32LSB 0x65
+#define R_IA64_SECREL64MSB 0x66
+#define R_IA64_SECREL64LSB 0x67
+#define R_IA64_REL32MSB 0x6c
+#define R_IA64_REL32LSB 0x6d
+#define R_IA64_REL64MSB 0x6e
+#define R_IA64_REL64LSB 0x6f
+#define R_IA64_LTV32MSB 0x74
+#define R_IA64_LTV32LSB 0x75
+#define R_IA64_LTV64MSB 0x76
+#define R_IA64_LTV64LSB 0x77
+#define R_IA64_PCREL21BI 0x79
+#define R_IA64_PCREL22 0x7a
+#define R_IA64_PCREL64I 0x7b
+#define R_IA64_IPLTMSB 0x80
+#define R_IA64_IPLTLSB 0x81
+#define R_IA64_COPY 0x84
+#define R_IA64_SUB 0x85
+#define R_IA64_LTOFF22X 0x86
+#define R_IA64_LDXMOV 0x87
+#define R_IA64_TPREL14 0x91
+#define R_IA64_TPREL22 0x92
+#define R_IA64_TPREL64I 0x93
+#define R_IA64_TPREL64MSB 0x96
+#define R_IA64_TPREL64LSB 0x97
+#define R_IA64_LTOFF_TPREL22 0x9a
+#define R_IA64_DTPMOD64MSB 0xa6
+#define R_IA64_DTPMOD64LSB 0xa7
+#define R_IA64_LTOFF_DTPMOD22 0xaa
+#define R_IA64_DTPREL14 0xb1
+#define R_IA64_DTPREL22 0xb2
+#define R_IA64_DTPREL64I 0xb3
+#define R_IA64_DTPREL32MSB 0xb4
+#define R_IA64_DTPREL32LSB 0xb5
+#define R_IA64_DTPREL64MSB 0xb6
+#define R_IA64_DTPREL64LSB 0xb7
+#define R_IA64_LTOFF_DTPREL22 0xba
+
+#define R_SH_NONE 0
+#define R_SH_DIR32 1
+#define R_SH_REL32 2
+#define R_SH_DIR8WPN 3
+#define R_SH_IND12W 4
+#define R_SH_DIR8WPL 5
+#define R_SH_DIR8WPZ 6
+#define R_SH_DIR8BP 7
+#define R_SH_DIR8W 8
+#define R_SH_DIR8L 9
+#define R_SH_SWITCH16 25
+#define R_SH_SWITCH32 26
+#define R_SH_USES 27
+#define R_SH_COUNT 28
+#define R_SH_ALIGN 29
+#define R_SH_CODE 30
+#define R_SH_DATA 31
+#define R_SH_LABEL 32
+#define R_SH_SWITCH8 33
+#define R_SH_GNU_VTINHERIT 34
+#define R_SH_GNU_VTENTRY 35
+#define R_SH_TLS_GD_32 144
+#define R_SH_TLS_LD_32 145
+#define R_SH_TLS_LDO_32 146
+#define R_SH_TLS_IE_32 147
+#define R_SH_TLS_LE_32 148
+#define R_SH_TLS_DTPMOD32 149
+#define R_SH_TLS_DTPOFF32 150
+#define R_SH_TLS_TPOFF32 151
+#define R_SH_GOT32 160
+#define R_SH_PLT32 161
+#define R_SH_COPY 162
+#define R_SH_GLOB_DAT 163
+#define R_SH_JMP_SLOT 164
+#define R_SH_RELATIVE 165
+#define R_SH_GOTOFF 166
+#define R_SH_GOTPC 167
+#define R_SH_GOT20 201
+#define R_SH_GOTOFF20 202
+#define R_SH_GOTFUNCDESC 203
+#define R_SH_GOTFUNCDEST20 204
+#define R_SH_GOTOFFFUNCDESC 205
+#define R_SH_GOTOFFFUNCDEST20 206
+#define R_SH_FUNCDESC 207
+#define R_SH_FUNCDESC_VALUE 208
+
+#define R_SH_NUM 256
+
+#define R_390_NONE 0
+#define R_390_8 1
+#define R_390_12 2
+#define R_390_16 3
+#define R_390_32 4
+#define R_390_PC32 5
+#define R_390_GOT12 6
+#define R_390_GOT32 7
+#define R_390_PLT32 8
+#define R_390_COPY 9
+#define R_390_GLOB_DAT 10
+#define R_390_JMP_SLOT 11
+#define R_390_RELATIVE 12
+#define R_390_GOTOFF32 13
+#define R_390_GOTPC 14
+#define R_390_GOT16 15
+#define R_390_PC16 16
+#define R_390_PC16DBL 17
+#define R_390_PLT16DBL 18
+#define R_390_PC32DBL 19
+#define R_390_PLT32DBL 20
+#define R_390_GOTPCDBL 21
+#define R_390_64 22
+#define R_390_PC64 23
+#define R_390_GOT64 24
+#define R_390_PLT64 25
+#define R_390_GOTENT 26
+#define R_390_GOTOFF16 27
+#define R_390_GOTOFF64 28
+#define R_390_GOTPLT12 29
+#define R_390_GOTPLT16 30
+#define R_390_GOTPLT32 31
+#define R_390_GOTPLT64 32
+#define R_390_GOTPLTENT 33
+#define R_390_PLTOFF16 34
+#define R_390_PLTOFF32 35
+#define R_390_PLTOFF64 36
+#define R_390_TLS_LOAD 37
+#define R_390_TLS_GDCALL 38
+
+#define R_390_TLS_LDCALL 39
+
+#define R_390_TLS_GD32 40
+
+#define R_390_TLS_GD64 41
+
+#define R_390_TLS_GOTIE12 42
+
+#define R_390_TLS_GOTIE32 43
+
+#define R_390_TLS_GOTIE64 44
+
+#define R_390_TLS_LDM32 45
+
+#define R_390_TLS_LDM64 46
+
+#define R_390_TLS_IE32 47
+
+#define R_390_TLS_IE64 48
+
+#define R_390_TLS_IEENT 49
+
+#define R_390_TLS_LE32 50
+
+#define R_390_TLS_LE64 51
+
+#define R_390_TLS_LDO32 52
+
+#define R_390_TLS_LDO64 53
+
+#define R_390_TLS_DTPMOD 54
+#define R_390_TLS_DTPOFF 55
+#define R_390_TLS_TPOFF 56
+
+#define R_390_20 57
+#define R_390_GOT20 58
+#define R_390_GOTPLT20 59
+#define R_390_TLS_GOTIE20 60
+
+#define R_390_NUM 61
+
+#define R_CRIS_NONE 0
+#define R_CRIS_8 1
+#define R_CRIS_16 2
+#define R_CRIS_32 3
+#define R_CRIS_8_PCREL 4
+#define R_CRIS_16_PCREL 5
+#define R_CRIS_32_PCREL 6
+#define R_CRIS_GNU_VTINHERIT 7
+#define R_CRIS_GNU_VTENTRY 8
+#define R_CRIS_COPY 9
+#define R_CRIS_GLOB_DAT 10
+#define R_CRIS_JUMP_SLOT 11
+#define R_CRIS_RELATIVE 12
+#define R_CRIS_16_GOT 13
+#define R_CRIS_32_GOT 14
+#define R_CRIS_16_GOTPLT 15
+#define R_CRIS_32_GOTPLT 16
+#define R_CRIS_32_GOTREL 17
+#define R_CRIS_32_PLT_GOTREL 18
+#define R_CRIS_32_PLT_PCREL 19
+
+#define R_CRIS_NUM 20
+
+#define R_X86_64_NONE 0
+#define R_X86_64_64 1
+#define R_X86_64_PC32 2
+#define R_X86_64_GOT32 3
+#define R_X86_64_PLT32 4
+#define R_X86_64_COPY 5
+#define R_X86_64_GLOB_DAT 6
+#define R_X86_64_JUMP_SLOT 7
+#define R_X86_64_RELATIVE 8
+#define R_X86_64_GOTPCREL 9
+
+#define R_X86_64_32 10
+#define R_X86_64_32S 11
+#define R_X86_64_16 12
+#define R_X86_64_PC16 13
+#define R_X86_64_8 14
+#define R_X86_64_PC8 15
+#define R_X86_64_DTPMOD64 16
+#define R_X86_64_DTPOFF64 17
+#define R_X86_64_TPOFF64 18
+#define R_X86_64_TLSGD 19
+
+#define R_X86_64_TLSLD 20
+
+#define R_X86_64_DTPOFF32 21
+#define R_X86_64_GOTTPOFF 22
+
+#define R_X86_64_TPOFF32 23
+#define R_X86_64_PC64 24
+#define R_X86_64_GOTOFF64 25
+#define R_X86_64_GOTPC32 26
+#define R_X86_64_GOT64 27
+#define R_X86_64_GOTPCREL64 28
+#define R_X86_64_GOTPC64 29
+#define R_X86_64_GOTPLT64 30
+#define R_X86_64_PLTOFF64 31
+#define R_X86_64_SIZE32 32
+#define R_X86_64_SIZE64 33
+
+#define R_X86_64_GOTPC32_TLSDESC 34
+#define R_X86_64_TLSDESC_CALL 35
+
+#define R_X86_64_TLSDESC 36
+#define R_X86_64_IRELATIVE 37
+#define R_X86_64_RELATIVE64 38
+#define R_X86_64_NUM 39
+
+#define R_MN10300_NONE 0
+#define R_MN10300_32 1
+#define R_MN10300_16 2
+#define R_MN10300_8 3
+#define R_MN10300_PCREL32 4
+#define R_MN10300_PCREL16 5
+#define R_MN10300_PCREL8 6
+#define R_MN10300_GNU_VTINHERIT 7
+#define R_MN10300_GNU_VTENTRY 8
+#define R_MN10300_24 9
+#define R_MN10300_GOTPC32 10
+#define R_MN10300_GOTPC16 11
+#define R_MN10300_GOTOFF32 12
+#define R_MN10300_GOTOFF24 13
+#define R_MN10300_GOTOFF16 14
+#define R_MN10300_PLT32 15
+#define R_MN10300_PLT16 16
+#define R_MN10300_GOT32 17
+#define R_MN10300_GOT24 18
+#define R_MN10300_GOT16 19
+#define R_MN10300_COPY 20
+#define R_MN10300_GLOB_DAT 21
+#define R_MN10300_JMP_SLOT 22
+#define R_MN10300_RELATIVE 23
+
+#define R_MN10300_NUM 24
+
+#define R_M32R_NONE 0
+#define R_M32R_16 1
+#define R_M32R_32 2
+#define R_M32R_24 3
+#define R_M32R_10_PCREL 4
+#define R_M32R_18_PCREL 5
+#define R_M32R_26_PCREL 6
+#define R_M32R_HI16_ULO 7
+#define R_M32R_HI16_SLO 8
+#define R_M32R_LO16 9
+#define R_M32R_SDA16 10
+#define R_M32R_GNU_VTINHERIT 11
+#define R_M32R_GNU_VTENTRY 12
+
+#define R_M32R_16_RELA 33
+#define R_M32R_32_RELA 34
+#define R_M32R_24_RELA 35
+#define R_M32R_10_PCREL_RELA 36
+#define R_M32R_18_PCREL_RELA 37
+#define R_M32R_26_PCREL_RELA 38
+#define R_M32R_HI16_ULO_RELA 39
+#define R_M32R_HI16_SLO_RELA 40
+#define R_M32R_LO16_RELA 41
+#define R_M32R_SDA16_RELA 42
+#define R_M32R_RELA_GNU_VTINHERIT 43
+#define R_M32R_RELA_GNU_VTENTRY 44
+#define R_M32R_REL32 45
+
+#define R_M32R_GOT24 48
+#define R_M32R_26_PLTREL 49
+#define R_M32R_COPY 50
+#define R_M32R_GLOB_DAT 51
+#define R_M32R_JMP_SLOT 52
+#define R_M32R_RELATIVE 53
+#define R_M32R_GOTOFF 54
+#define R_M32R_GOTPC24 55
+#define R_M32R_GOT16_HI_ULO 56
+
+#define R_M32R_GOT16_HI_SLO 57
+
+#define R_M32R_GOT16_LO 58
+#define R_M32R_GOTPC_HI_ULO 59
+
+#define R_M32R_GOTPC_HI_SLO 60
+
+#define R_M32R_GOTPC_LO 61
+
+#define R_M32R_GOTOFF_HI_ULO 62
+
+#define R_M32R_GOTOFF_HI_SLO 63
+
+#define R_M32R_GOTOFF_LO 64
+#define R_M32R_NUM 256
+
+#define R_MICROBLAZE_NONE 0
+#define R_MICROBLAZE_32 1
+#define R_MICROBLAZE_32_PCREL 2
+#define R_MICROBLAZE_64_PCREL 3
+#define R_MICROBLAZE_32_PCREL_LO 4
+#define R_MICROBLAZE_64 5
+#define R_MICROBLAZE_32_LO 6
+#define R_MICROBLAZE_SRO32 7
+#define R_MICROBLAZE_SRW32 8
+#define R_MICROBLAZE_64_NONE 9
+#define R_MICROBLAZE_32_SYM_OP_SYM 10
+#define R_MICROBLAZE_GNU_VTINHERIT 11
+#define R_MICROBLAZE_GNU_VTENTRY 12
+#define R_MICROBLAZE_GOTPC_64 13
+#define R_MICROBLAZE_GOT_64 14
+#define R_MICROBLAZE_PLT_64 15
+#define R_MICROBLAZE_REL 16
+#define R_MICROBLAZE_JUMP_SLOT 17
+#define R_MICROBLAZE_GLOB_DAT 18
+#define R_MICROBLAZE_GOTOFF_64 19
+#define R_MICROBLAZE_GOTOFF_32 20
+#define R_MICROBLAZE_COPY 21
+#define R_MICROBLAZE_TLS 22
+#define R_MICROBLAZE_TLSGD 23
+#define R_MICROBLAZE_TLSLD 24
+#define R_MICROBLAZE_TLSDTPMOD32 25
+#define R_MICROBLAZE_TLSDTPREL32 26
+#define R_MICROBLAZE_TLSDTPREL64 27
+#define R_MICROBLAZE_TLSGOTTPREL32 28
+#define R_MICROBLAZE_TLSTPREL32 29
+
+#define R_OR1K_NONE 0
+#define R_OR1K_32 1
+#define R_OR1K_16 2
+#define R_OR1K_8 3
+#define R_OR1K_LO_16_IN_INSN 4
+#define R_OR1K_HI_16_IN_INSN 5
+#define R_OR1K_INSN_REL_26 6
+#define R_OR1K_GNU_VTENTRY 7
+#define R_OR1K_GNU_VTINHERIT 8
+#define R_OR1K_32_PCREL 9
+#define R_OR1K_16_PCREL 10
+#define R_OR1K_8_PCREL 11
+#define R_OR1K_GOTPC_HI16 12
+#define R_OR1K_GOTPC_LO16 13
+#define R_OR1K_GOT16 14
+#define R_OR1K_PLT26 15
+#define R_OR1K_GOTOFF_HI16 16
+#define R_OR1K_GOTOFF_LO16 17
+#define R_OR1K_COPY 18
+#define R_OR1K_GLOB_DAT 19
+#define R_OR1K_JMP_SLOT 20
+#define R_OR1K_RELATIVE 21
+#define R_OR1K_TLS_GD_HI16 22
+#define R_OR1K_TLS_GD_LO16 23
+#define R_OR1K_TLS_LDM_HI16 24
+#define R_OR1K_TLS_LDM_LO16 25
+#define R_OR1K_TLS_LDO_HI16 26
+#define R_OR1K_TLS_LDO_LO16 27
+#define R_OR1K_TLS_IE_HI16 28
+#define R_OR1K_TLS_IE_LO16 29
+#define R_OR1K_TLS_LE_HI16 30
+#define R_OR1K_TLS_LE_LO16 31
+#define R_OR1K_TLS_TPOFF 32
+#define R_OR1K_TLS_DTPOFF 33
+#define R_OR1K_TLS_DTPMOD 34
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_ELF_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/endian.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/endian.h
new file mode 100644
index 0000000..5ca6625
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/endian.h
@@ -0,0 +1,77 @@
+#ifndef SYSROOT_ENDIAN_H_
+#define SYSROOT_ENDIAN_H_
+
+#include <features.h>
+
+#define __LITTLE_ENDIAN 1234
+#define __BIG_ENDIAN 4321
+#define __PDP_ENDIAN 3412
+
+#if defined(__GNUC__) && defined(__BYTE_ORDER__)
+#define __BYTE_ORDER __BYTE_ORDER__
+#else
+#include <bits/endian.h>
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#define BIG_ENDIAN __BIG_ENDIAN
+#define LITTLE_ENDIAN __LITTLE_ENDIAN
+#define PDP_ENDIAN __PDP_ENDIAN
+#define BYTE_ORDER __BYTE_ORDER
+
+#include <stdint.h>
+
+static __inline uint16_t __bswap16(uint16_t __x) { return (uint16_t)(__x << 8 | __x >> 8); }
+
+static __inline uint32_t __bswap32(uint32_t __x) {
+ return (uint32_t)(__x >> 24 | ((__x >> 8) & 0xff00) | ((__x << 8) & 0xff0000) | __x << 24);
+}
+
+static __inline uint64_t __bswap64(uint64_t __x) {
+ return ((uint64_t)__bswap32((uint32_t)__x)) << 32 | (uint64_t)__bswap32((uint32_t)(__x >> 32));
+}
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define htobe16(x) __bswap16(x)
+#define be16toh(x) __bswap16(x)
+#define betoh16(x) __bswap16(x)
+#define htobe32(x) __bswap32(x)
+#define be32toh(x) __bswap32(x)
+#define betoh32(x) __bswap32(x)
+#define htobe64(x) __bswap64(x)
+#define be64toh(x) __bswap64(x)
+#define betoh64(x) __bswap64(x)
+#define htole16(x) (uint16_t)(x)
+#define le16toh(x) (uint16_t)(x)
+#define letoh16(x) (uint16_t)(x)
+#define htole32(x) (uint32_t)(x)
+#define le32toh(x) (uint32_t)(x)
+#define letoh32(x) (uint32_t)(x)
+#define htole64(x) (uint64_t)(x)
+#define le64toh(x) (uint64_t)(x)
+#define letoh64(x) (uint64_t)(x)
+#else
+#define htobe16(x) (uint16_t)(x)
+#define be16toh(x) (uint16_t)(x)
+#define betoh16(x) (uint16_t)(x)
+#define htobe32(x) (uint32_t)(x)
+#define be32toh(x) (uint32_t)(x)
+#define betoh32(x) (uint32_t)(x)
+#define htobe64(x) (uint64_t)(x)
+#define be64toh(x) (uint64_t)(x)
+#define betoh64(x) (uint64_t)(x)
+#define htole16(x) __bswap16(x)
+#define le16toh(x) __bswap16(x)
+#define letoh16(x) __bswap16(x)
+#define htole32(x) __bswap32(x)
+#define le32toh(x) __bswap32(x)
+#define letoh32(x) __bswap32(x)
+#define htole64(x) __bswap64(x)
+#define le64toh(x) __bswap64(x)
+#define letoh64(x) __bswap64(x)
+#endif
+
+#endif
+
+#endif // SYSROOT_ENDIAN_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/err.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/err.h
new file mode 100644
index 0000000..29842fe
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/err.h
@@ -0,0 +1,25 @@
+#ifndef SYSROOT_ERR_H_
+#define SYSROOT_ERR_H_
+
+#include <features.h>
+#include <stdarg.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void warn(const char*, ...);
+void vwarn(const char*, va_list);
+void warnx(const char*, ...);
+void vwarnx(const char*, va_list);
+
+_Noreturn void err(int, const char*, ...);
+_Noreturn void verr(int, const char*, va_list);
+_Noreturn void errx(int, const char*, ...);
+_Noreturn void verrx(int, const char*, va_list);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_ERR_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/errno.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/errno.h
new file mode 100644
index 0000000..af13f58
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/errno.h
@@ -0,0 +1,23 @@
+#ifndef SYSROOT_ERRNO_H_
+#define SYSROOT_ERRNO_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <bits/errno.h>
+
+int* __errno_location(void);
+#define errno (*__errno_location())
+
+#ifdef _GNU_SOURCE
+extern char *program_invocation_short_name, *program_invocation_name;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_ERRNO_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/fcntl.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/fcntl.h
new file mode 100644
index 0000000..e5e47bd
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/fcntl.h
@@ -0,0 +1,224 @@
+#ifndef SYSROOT_FCNTL_H_
+#define SYSROOT_FCNTL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_off_t
+#define __NEED_pid_t
+#define __NEED_mode_t
+
+#ifdef _GNU_SOURCE
+#define __NEED_size_t
+#define __NEED_ssize_t
+#define __NEED_struct_iovec
+#endif
+
+#include <bits/alltypes.h>
+
+struct flock {
+ short l_type;
+ short l_whence;
+ off_t l_start;
+ off_t l_len;
+ pid_t l_pid;
+};
+
+int creat(const char*, mode_t);
+int fcntl(int, int, ...);
+int open(const char*, int, ...);
+int openat(int, const char*, int, ...);
+int posix_fadvise(int, off_t, off_t, int);
+int posix_fallocate(int, off_t, off_t);
+
+#define O_SEARCH O_PATH
+#define O_EXEC O_PATH
+
+// clang-format off
+#define O_ACCMODE (03 | O_SEARCH)
+#define O_RDONLY 00
+#define O_WRONLY 01
+#define O_RDWR 02
+
+// Flags which align with ZXIO_FS_*
+// system/ulib/fdio/unistd.c asserts that these flags are aligned
+// with the ZXIO_FS_* versions.
+#define O_CREAT 0x00010000
+#define O_EXCL 0x00020000
+#define O_TRUNC 0x00040000
+#define O_DIRECTORY 0x00080000
+#define O_APPEND 0x00100000
+#define O_PATH 0x00400000
+#ifdef _ALL_SOURCE
+#define O_NOREMOTE 0x00200000
+#define O_ADMIN 0x00000004
+#endif
+
+// Flags which do not align with ZXIO_FS_*
+#define O_NONBLOCK 0x00000010
+#define O_DSYNC 0x00000020
+#define O_SYNC (0x00000040 | O_DSYNC)
+#define O_RSYNC O_SYNC
+#define O_NOFOLLOW 0x00000080
+#define O_CLOEXEC 0x00000100
+#define O_NOCTTY 0x00000200
+#define O_ASYNC 0x00000400
+#define O_DIRECT 0x00000800
+#define O_LARGEFILE 0x00001000
+#define O_NOATIME 0x00002000
+#define O_TMPFILE 0x00004000
+
+// clang-format on
+
+#define O_NDELAY O_NONBLOCK
+
+#define F_DUPFD 0
+#define F_GETFD 1
+#define F_SETFD 2
+#define F_GETFL 3
+#define F_SETFL 4
+
+#define F_GETLK 5
+#define F_SETLK 6
+#define F_SETLKW 7
+
+#define F_SETOWN 8
+#define F_GETOWN 9
+#define F_SETSIG 10
+#define F_GETSIG 11
+
+#define F_SETOWN_EX 15
+#define F_GETOWN_EX 16
+
+#define F_GETOWNER_UIDS 17
+
+#define F_OFD_GETLK 36
+#define F_OFD_SETLK 37
+#define F_OFD_SETLKW 38
+
+#define F_DUPFD_CLOEXEC 1030
+
+#define F_RDLCK 0
+#define F_WRLCK 1
+#define F_UNLCK 2
+
+#define FD_CLOEXEC 1
+
+#define AT_FDCWD (-100)
+#define AT_SYMLINK_NOFOLLOW 0x100
+#define AT_REMOVEDIR 0x200
+#define AT_SYMLINK_FOLLOW 0x400
+#define AT_EACCESS 0x200
+
+#define POSIX_FADV_NORMAL 0
+#define POSIX_FADV_RANDOM 1
+#define POSIX_FADV_SEQUENTIAL 2
+#define POSIX_FADV_WILLNEED 3
+#define POSIX_FADV_DONTNEED 4
+#define POSIX_FADV_NOREUSE 5
+
+#undef SEEK_SET
+#undef SEEK_CUR
+#undef SEEK_END
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
+#ifndef S_IRUSR
+#define S_ISUID 04000
+#define S_ISGID 02000
+#define S_ISVTX 01000
+#define S_IRUSR 0400
+#define S_IWUSR 0200
+#define S_IXUSR 0100
+#define S_IRWXU 0700
+#define S_IRGRP 0040
+#define S_IWGRP 0020
+#define S_IXGRP 0010
+#define S_IRWXG 0070
+#define S_IROTH 0004
+#define S_IWOTH 0002
+#define S_IXOTH 0001
+#define S_IRWXO 0007
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define AT_NO_AUTOMOUNT 0x800
+#define AT_EMPTY_PATH 0x1000
+
+#define FAPPEND O_APPEND
+#define FFSYNC O_FSYNC
+#define FASYNC O_ASYNC
+#define FNONBLOCK O_NONBLOCK
+#define FNDELAY O_NDELAY
+
+#define F_OK 0
+#define R_OK 4
+#define W_OK 2
+#define X_OK 1
+#define F_ULOCK 0
+#define F_LOCK 1
+#define F_TLOCK 2
+#define F_TEST 3
+
+#define F_SETLEASE 1024
+#define F_GETLEASE 1025
+#define F_NOTIFY 1026
+#define F_CANCELLK 1029
+#define F_SETPIPE_SZ 1031
+#define F_GETPIPE_SZ 1032
+#define F_ADD_SEALS 1033
+#define F_GET_SEALS 1034
+
+#define F_SEAL_SEAL 0x0001
+#define F_SEAL_SHRINK 0x0002
+#define F_SEAL_GROW 0x0004
+#define F_SEAL_WRITE 0x0008
+
+#define DN_ACCESS 0x00000001
+#define DN_MODIFY 0x00000002
+#define DN_CREATE 0x00000004
+#define DN_DELETE 0x00000008
+#define DN_RENAME 0x00000010
+#define DN_ATTRIB 0x00000020
+#define DN_MULTISHOT 0x80000000
+
+int lockf(int, int, off_t);
+#endif
+
+#if defined(_GNU_SOURCE)
+#define F_OWNER_TID 0
+#define F_OWNER_PID 1
+#define F_OWNER_PGRP 2
+#define F_OWNER_GID 2
+struct f_owner_ex {
+ int type;
+ pid_t pid;
+};
+#define FALLOC_FL_KEEP_SIZE 1
+#define FALLOC_FL_PUNCH_HOLE 2
+#define SYNC_FILE_RANGE_WAIT_BEFORE 1
+#define SYNC_FILE_RANGE_WRITE 2
+#define SYNC_FILE_RANGE_WAIT_AFTER 4
+#define SPLICE_F_MOVE 1
+#define SPLICE_F_NONBLOCK 2
+#define SPLICE_F_MORE 4
+#define SPLICE_F_GIFT 8
+int fallocate(int, int, off_t, off_t);
+#define fallocate64 fallocate
+ssize_t readahead(int, off_t, size_t);
+int sync_file_range(int, off_t, off_t, unsigned);
+ssize_t vmsplice(int, const struct iovec*, size_t, unsigned);
+ssize_t splice(int, off_t*, int, off_t*, size_t, unsigned);
+ssize_t tee(int, int, size_t, unsigned);
+#define loff_t off_t
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_FCNTL_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/features.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/features.h
new file mode 100644
index 0000000..1520efb
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/features.h
@@ -0,0 +1,35 @@
+#ifndef SYSROOT_FEATURES_H_
+#define SYSROOT_FEATURES_H_
+
+#if defined(_ALL_SOURCE) && !defined(_GNU_SOURCE)
+#define _GNU_SOURCE 1
+#endif
+
+#if !defined(_BSD_SOURCE)
+#define _BSD_SOURCE 1
+#endif
+
+#if !defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE) && \
+ !defined(_GNU_SOURCE) && !defined(_BSD_SOURCE) && !defined(__STRICT_ANSI__)
+#define _BSD_SOURCE 1
+#define _XOPEN_SOURCE 700
+#endif
+
+#if __STDC_VERSION__ >= 199901L
+#define __restrict restrict
+#elif !defined(__GNUC__)
+#define __restrict
+#endif
+
+#if __STDC_VERSION__ >= 199901L || defined(__cplusplus)
+#define __inline inline
+#endif
+
+#if __STDC_VERSION__ >= 201112L
+#elif defined(__GNUC__)
+#define _Noreturn __attribute__((__noreturn__))
+#else
+#define _Noreturn
+#endif
+
+#endif // SYSROOT_FEATURES_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/fenv.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/fenv.h
new file mode 100644
index 0000000..391f59f
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/fenv.h
@@ -0,0 +1,28 @@
+#ifndef SYSROOT_FENV_H_
+#define SYSROOT_FENV_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <bits/fenv.h>
+
+int feclearexcept(int);
+int fegetexceptflag(fexcept_t*, int);
+int feraiseexcept(int);
+int fesetexceptflag(const fexcept_t*, int);
+int fetestexcept(int);
+
+int fegetround(void);
+int fesetround(int);
+
+int fegetenv(fenv_t*);
+int feholdexcept(fenv_t*);
+int fesetenv(const fenv_t*);
+int feupdateenv(const fenv_t*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_FENV_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/fmtmsg.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/fmtmsg.h
new file mode 100644
index 0000000..51abcc5
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/fmtmsg.h
@@ -0,0 +1,47 @@
+#ifndef SYSROOT_FMTMSG_H_
+#define SYSROOT_FMTMSG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MM_HARD 1
+#define MM_SOFT 2
+#define MM_FIRM 4
+
+#define MM_APPL 8
+#define MM_UTIL 16
+#define MM_OPSYS 32
+
+#define MM_RECOVER 64
+#define MM_NRECOV 128
+
+#define MM_PRINT 256
+#define MM_CONSOLE 512
+
+#define MM_NULLMC 0L
+
+#define MM_HALT 1
+#define MM_ERROR 2
+#define MM_WARNING 3
+#define MM_INFO 4
+#define MM_NOSEV 0
+
+#define MM_OK 0
+#define MM_NOTOK (-1)
+#define MM_NOMSG 1
+#define MM_NOCON 4
+
+#define MM_NULLLBL ((char*)0)
+#define MM_NULLTXT ((char*)0)
+#define MM_NULLACT ((char*)0)
+#define MM_NULLTAG ((char*)0)
+#define MM_NULLSEV 0
+
+int fmtmsg(long, const char*, int, const char*, const char*, const char*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_FMTMSG_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/fnmatch.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/fnmatch.h
new file mode 100644
index 0000000..2e0f6cc
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/fnmatch.h
@@ -0,0 +1,24 @@
+#ifndef SYSROOT_FNMATCH_H_
+#define SYSROOT_FNMATCH_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define FNM_PATHNAME 0x1
+#define FNM_NOESCAPE 0x2
+#define FNM_PERIOD 0x4
+#define FNM_LEADING_DIR 0x8
+#define FNM_CASEFOLD 0x10
+#define FNM_FILE_NAME FNM_PATHNAME
+
+#define FNM_NOMATCH 1
+#define FNM_NOSYS (-1)
+
+int fnmatch(const char*, const char*, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_FNMATCH_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/getopt.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/getopt.h
new file mode 100644
index 0000000..bcc632d
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/getopt.h
@@ -0,0 +1,30 @@
+#ifndef SYSROOT_GETOPT_H_
+#define SYSROOT_GETOPT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int getopt(int, char* const[], const char*);
+extern char* optarg;
+extern int optind, opterr, optopt, optreset;
+
+struct option {
+ const char* name;
+ int has_arg;
+ int* flag;
+ int val;
+};
+
+int getopt_long(int, char* const*, const char*, const struct option*, int*);
+int getopt_long_only(int, char* const*, const char*, const struct option*, int*);
+
+#define no_argument 0
+#define required_argument 1
+#define optional_argument 2
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_GETOPT_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/glob.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/glob.h
new file mode 100644
index 0000000..98ff3f6
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/glob.h
@@ -0,0 +1,43 @@
+#ifndef SYSROOT_GLOB_H_
+#define SYSROOT_GLOB_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+typedef struct {
+ size_t gl_pathc;
+ char** gl_pathv;
+ size_t gl_offs;
+ int __dummy1;
+ void* __dummy2[5];
+} glob_t;
+
+int glob(const char* __restrict, int, int (*)(const char*, int), glob_t* __restrict);
+void globfree(glob_t*);
+
+#define GLOB_ERR 0x01
+#define GLOB_MARK 0x02
+#define GLOB_NOSORT 0x04
+#define GLOB_DOOFFS 0x08
+#define GLOB_NOCHECK 0x10
+#define GLOB_APPEND 0x20
+#define GLOB_NOESCAPE 0x40
+#define GLOB_PERIOD 0x80
+
+#define GLOB_NOSPACE 1
+#define GLOB_ABORTED 2
+#define GLOB_NOMATCH 3
+#define GLOB_NOSYS 4
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_GLOB_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/grp.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/grp.h
new file mode 100644
index 0000000..4cfdd08
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/grp.h
@@ -0,0 +1,51 @@
+#ifndef SYSROOT_GRP_H_
+#define SYSROOT_GRP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+#define __NEED_gid_t
+
+#ifdef _GNU_SOURCE
+#define __NEED_FILE
+#endif
+
+#include <bits/alltypes.h>
+
+struct group {
+ char* gr_name;
+ char* gr_passwd;
+ gid_t gr_gid;
+ char** gr_mem;
+};
+
+struct group* getgrgid(gid_t);
+struct group* getgrnam(const char*);
+
+int getgrgid_r(gid_t, struct group*, char*, size_t, struct group**);
+int getgrnam_r(const char*, struct group*, char*, size_t, struct group**);
+
+struct group* getgrent(void);
+void endgrent(void);
+void setgrent(void);
+
+#ifdef _GNU_SOURCE
+struct group* fgetgrent(FILE* stream);
+int putgrent(const struct group*, FILE*);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+int getgrouplist(const char*, gid_t, gid_t*, int*);
+int setgroups(size_t, const gid_t*);
+int initgroups(const char*, gid_t);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_GRP_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/iconv.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/iconv.h
new file mode 100644
index 0000000..c0c056b
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/iconv.h
@@ -0,0 +1,24 @@
+#ifndef SYSROOT_ICONV_H_
+#define SYSROOT_ICONV_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+typedef void* iconv_t;
+
+iconv_t iconv_open(const char*, const char*);
+size_t iconv(iconv_t, char** __restrict, size_t* __restrict, char** __restrict, size_t* __restrict);
+int iconv_close(iconv_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_ICONV_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/ifaddrs.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/ifaddrs.h
new file mode 100644
index 0000000..908945e
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/ifaddrs.h
@@ -0,0 +1,34 @@
+#ifndef SYSROOT_IFADDRS_H_
+#define SYSROOT_IFADDRS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+
+struct ifaddrs {
+ struct ifaddrs* ifa_next;
+ char* ifa_name;
+ unsigned ifa_flags;
+ struct sockaddr* ifa_addr;
+ struct sockaddr* ifa_netmask;
+ union {
+ struct sockaddr* ifu_broadaddr;
+ struct sockaddr* ifu_dstaddr;
+ } ifa_ifu;
+ void* ifa_data;
+};
+#define ifa_broadaddr ifa_ifu.ifu_broadaddr
+#define ifa_dstaddr ifa_ifu.ifu_dstaddr
+
+void freeifaddrs(struct ifaddrs* ifp);
+int getifaddrs(struct ifaddrs** ifap);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_IFADDRS_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/inttypes.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/inttypes.h
new file mode 100644
index 0000000..43bf604
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/inttypes.h
@@ -0,0 +1,356 @@
+#ifndef SYSROOT_INTTYPES_H_
+#define SYSROOT_INTTYPES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#define __NEED_wchar_t
+#include <bits/alltypes.h>
+
+typedef struct {
+ intmax_t quot, rem;
+} imaxdiv_t;
+
+intmax_t imaxabs(intmax_t);
+imaxdiv_t imaxdiv(intmax_t, intmax_t);
+
+intmax_t strtoimax(const char* __restrict, char** __restrict, int);
+uintmax_t strtoumax(const char* __restrict, char** __restrict, int);
+
+intmax_t wcstoimax(const wchar_t* __restrict, wchar_t** __restrict, int);
+uintmax_t wcstoumax(const wchar_t* __restrict, wchar_t** __restrict, int);
+
+// Clang predefines macros __<type>_FMT<letter>__ for each type,
+// with <letter> being i and for signed types, and o, u, x, and X
+// for unsigned types. That lets <inttypes.h> do its work without
+// any special knowledge of what the underlying types are.
+// Unfortunately, GCC does not define these macros.
+#ifndef __INTMAX_FMTd__
+
+#define __INT8_FMT_MODIFIER__ "hh"
+#define __INT16_FMT_MODIFIER__ "h"
+#define __INT32_FMT_MODIFIER__ ""
+
+#define __INT_LEAST8_FMT_MODIFIER__ __INT8_FMT_MODIFIER__
+#define __INT_LEAST16_FMT_MODIFIER__ __INT16_FMT_MODIFIER__
+#define __INT_LEAST32_FMT_MODIFIER__ __INT32_FMT_MODIFIER__
+#define __INT_LEAST64_FMT_MODIFIER__ __INT64_FMT_MODIFIER__
+
+// The *-elf and arm-eabi GCC targets use 'int' for the fast{8,16,32}
+// types. On LP64 systems, 'long' is used for the fast64 type.
+#define __INT_FAST8_FMT_MODIFIER__ ""
+#define __INT_FAST16_FMT_MODIFIER__ ""
+#define __INT_FAST32_FMT_MODIFIER__ ""
+#define __INT_FAST64_FMT_MODIFIER__ "l"
+
+// On machines where 'long' types are 64 bits, the compiler defines
+// __INT64_TYPE__ et al using 'long', not 'long long', though both are
+// 64-bit types.
+#define __INT64_FMT_MODIFIER__ "l"
+#define __INTPTR_FMT_MODIFIER__ "l"
+
+#define __INTMAX_FMT_MODIFIER__ __INT64_FMT_MODIFIER__
+
+#define __INTMAX_FMTd__ __INTMAX_FMT_MODIFIER__ "d"
+#define __INTMAX_FMTi__ __INTMAX_FMT_MODIFIER__ "i"
+#define __UINTMAX_FMTo__ __INTMAX_FMT_MODIFIER__ "o"
+#define __UINTMAX_FMTu__ __INTMAX_FMT_MODIFIER__ "u"
+#define __UINTMAX_FMTx__ __INTMAX_FMT_MODIFIER__ "x"
+#define __UINTMAX_FMTX__ __INTMAX_FMT_MODIFIER__ "X"
+#define __INTPTR_FMTd__ __INTPTR_FMT_MODIFIER__ "d"
+#define __INTPTR_FMTi__ __INTPTR_FMT_MODIFIER__ "i"
+#define __UINTPTR_FMTo__ __INTPTR_FMT_MODIFIER__ "o"
+#define __UINTPTR_FMTu__ __INTPTR_FMT_MODIFIER__ "u"
+#define __UINTPTR_FMTx__ __INTPTR_FMT_MODIFIER__ "x"
+#define __UINTPTR_FMTX__ __INTPTR_FMT_MODIFIER__ "X"
+#define __INT8_FMTd__ __INT8_FMT_MODIFIER__ "d"
+#define __INT8_FMTi__ __INT8_FMT_MODIFIER__ "i"
+#define __INT16_FMTd__ __INT16_FMT_MODIFIER__ "d"
+#define __INT16_FMTi__ __INT16_FMT_MODIFIER__ "i"
+#define __INT32_FMTd__ __INT32_FMT_MODIFIER__ "d"
+#define __INT32_FMTi__ __INT32_FMT_MODIFIER__ "i"
+#define __INT64_FMTd__ __INT64_FMT_MODIFIER__ "d"
+#define __INT64_FMTi__ __INT64_FMT_MODIFIER__ "i"
+#define __UINT8_FMTo__ __INT8_FMT_MODIFIER__ "o"
+#define __UINT8_FMTu__ __INT8_FMT_MODIFIER__ "u"
+#define __UINT8_FMTx__ __INT8_FMT_MODIFIER__ "x"
+#define __UINT8_FMTX__ __INT8_FMT_MODIFIER__ "X"
+#define __UINT16_FMTo__ __INT16_FMT_MODIFIER__ "o"
+#define __UINT16_FMTu__ __INT16_FMT_MODIFIER__ "u"
+#define __UINT16_FMTx__ __INT16_FMT_MODIFIER__ "x"
+#define __UINT16_FMTX__ __INT16_FMT_MODIFIER__ "X"
+#define __UINT32_FMTo__ __INT32_FMT_MODIFIER__ "o"
+#define __UINT32_FMTu__ __INT32_FMT_MODIFIER__ "u"
+#define __UINT32_FMTx__ __INT32_FMT_MODIFIER__ "x"
+#define __UINT32_FMTX__ __INT32_FMT_MODIFIER__ "X"
+#define __UINT64_FMTo__ __INT64_FMT_MODIFIER__ "o"
+#define __UINT64_FMTu__ __INT64_FMT_MODIFIER__ "u"
+#define __UINT64_FMTx__ __INT64_FMT_MODIFIER__ "x"
+#define __UINT64_FMTX__ __INT64_FMT_MODIFIER__ "X"
+#define __INT_LEAST8_FMTd__ __INT_LEAST8_FMT_MODIFIER__ "d"
+#define __INT_LEAST8_FMTi__ __INT_LEAST8_FMT_MODIFIER__ "i"
+#define __UINT_LEAST8_FMTo__ __INT_LEAST8_FMT_MODIFIER__ "o"
+#define __UINT_LEAST8_FMTu__ __INT_LEAST8_FMT_MODIFIER__ "u"
+#define __UINT_LEAST8_FMTx__ __INT_LEAST8_FMT_MODIFIER__ "x"
+#define __UINT_LEAST8_FMTX__ __INT_LEAST8_FMT_MODIFIER__ "X"
+#define __INT_LEAST16_FMTd__ __INT_LEAST16_FMT_MODIFIER__ "d"
+#define __INT_LEAST16_FMTi__ __INT_LEAST16_FMT_MODIFIER__ "i"
+#define __UINT_LEAST16_FMTo__ __INT_LEAST16_FMT_MODIFIER__ "o"
+#define __UINT_LEAST16_FMTu__ __INT_LEAST16_FMT_MODIFIER__ "u"
+#define __UINT_LEAST16_FMTx__ __INT_LEAST16_FMT_MODIFIER__ "x"
+#define __UINT_LEAST16_FMTX__ __INT_LEAST16_FMT_MODIFIER__ "X"
+#define __INT_LEAST32_FMTd__ __INT_LEAST32_FMT_MODIFIER__ "d"
+#define __INT_LEAST32_FMTi__ __INT_LEAST32_FMT_MODIFIER__ "i"
+#define __UINT_LEAST32_FMTo__ __INT_LEAST32_FMT_MODIFIER__ "o"
+#define __UINT_LEAST32_FMTu__ __INT_LEAST32_FMT_MODIFIER__ "u"
+#define __UINT_LEAST32_FMTx__ __INT_LEAST32_FMT_MODIFIER__ "x"
+#define __UINT_LEAST32_FMTX__ __INT_LEAST32_FMT_MODIFIER__ "X"
+#define __INT_LEAST64_FMTd__ __INT_LEAST64_FMT_MODIFIER__ "d"
+#define __INT_LEAST64_FMTi__ __INT_LEAST64_FMT_MODIFIER__ "i"
+#define __UINT_LEAST64_FMTo__ __INT_LEAST64_FMT_MODIFIER__ "o"
+#define __UINT_LEAST64_FMTu__ __INT_LEAST64_FMT_MODIFIER__ "u"
+#define __UINT_LEAST64_FMTx__ __INT_LEAST64_FMT_MODIFIER__ "x"
+#define __UINT_LEAST64_FMTX__ __INT_LEAST64_FMT_MODIFIER__ "X"
+#define __INT_FAST8_FMTd__ __INT_FAST8_FMT_MODIFIER__ "d"
+#define __INT_FAST8_FMTi__ __INT_FAST8_FMT_MODIFIER__ "i"
+#define __UINT_FAST8_FMTo__ __INT_FAST8_FMT_MODIFIER__ "o"
+#define __UINT_FAST8_FMTu__ __INT_FAST8_FMT_MODIFIER__ "u"
+#define __UINT_FAST8_FMTx__ __INT_FAST8_FMT_MODIFIER__ "x"
+#define __UINT_FAST8_FMTX__ __INT_FAST8_FMT_MODIFIER__ "X"
+#define __INT_FAST16_FMTd__ __INT_FAST16_FMT_MODIFIER__ "d"
+#define __INT_FAST16_FMTi__ __INT_FAST16_FMT_MODIFIER__ "i"
+#define __UINT_FAST16_FMTo__ __INT_FAST16_FMT_MODIFIER__ "o"
+#define __UINT_FAST16_FMTu__ __INT_FAST16_FMT_MODIFIER__ "u"
+#define __UINT_FAST16_FMTx__ __INT_FAST16_FMT_MODIFIER__ "x"
+#define __UINT_FAST16_FMTX__ __INT_FAST16_FMT_MODIFIER__ "X"
+#define __INT_FAST32_FMTd__ __INT_FAST32_FMT_MODIFIER__ "d"
+#define __INT_FAST32_FMTi__ __INT_FAST32_FMT_MODIFIER__ "i"
+#define __UINT_FAST32_FMTo__ __INT_FAST32_FMT_MODIFIER__ "o"
+#define __UINT_FAST32_FMTu__ __INT_FAST32_FMT_MODIFIER__ "u"
+#define __UINT_FAST32_FMTx__ __INT_FAST32_FMT_MODIFIER__ "x"
+#define __UINT_FAST32_FMTX__ __INT_FAST32_FMT_MODIFIER__ "X"
+#define __INT_FAST64_FMTd__ __INT_FAST64_FMT_MODIFIER__ "d"
+#define __INT_FAST64_FMTi__ __INT_FAST64_FMT_MODIFIER__ "i"
+#define __UINT_FAST64_FMTo__ __INT_FAST64_FMT_MODIFIER__ "o"
+#define __UINT_FAST64_FMTu__ __INT_FAST64_FMT_MODIFIER__ "u"
+#define __UINT_FAST64_FMTx__ __INT_FAST64_FMT_MODIFIER__ "x"
+#define __UINT_FAST64_FMTX__ __INT_FAST64_FMT_MODIFIER__ "X"
+
+#endif
+
+#define PRId8 __INT8_FMTd__
+#define PRId16 __INT16_FMTd__
+#define PRId32 __INT32_FMTd__
+#define PRId64 __INT64_FMTd__
+
+#define PRIdLEAST8 __INT_LEAST8_FMTd__
+#define PRIdLEAST16 __INT_LEAST16_FMTd__
+#define PRIdLEAST32 __INT_LEAST32_FMTd__
+#define PRIdLEAST64 __INT_LEAST64_FMTd__
+
+#define PRIdFAST8 __INT_FAST8_FMTd__
+#define PRIdFAST16 __INT_FAST16_FMTd__
+#define PRIdFAST32 __INT_FAST32_FMTd__
+#define PRIdFAST64 __INT_FAST64_FMTd__
+
+#define PRIi8 __INT8_FMTi__
+#define PRIi16 __INT16_FMTi__
+#define PRIi32 __INT32_FMTi__
+#define PRIi64 __INT64_FMTi__
+
+#define PRIiLEAST8 __INT_LEAST8_FMTi__
+#define PRIiLEAST16 __INT_LEAST16_FMTi__
+#define PRIiLEAST32 __INT_LEAST32_FMTi__
+#define PRIiLEAST64 __INT_LEAST64_FMTi__
+
+#define PRIiFAST8 __INT_FAST8_FMTi__
+#define PRIiFAST16 __INT_FAST16_FMTi__
+#define PRIiFAST32 __INT_FAST32_FMTi__
+#define PRIiFAST64 __INT_FAST64_FMTi__
+
+#define PRIo8 __UINT8_FMTo__
+#define PRIo16 __UINT16_FMTo__
+#define PRIo32 __UINT32_FMTo__
+#define PRIo64 __UINT64_FMTo__
+
+#define PRIoLEAST8 __UINT_LEAST8_FMTo__
+#define PRIoLEAST16 __UINT_LEAST16_FMTo__
+#define PRIoLEAST32 __UINT_LEAST32_FMTo__
+#define PRIoLEAST64 __UINT_LEAST64_FMTo__
+
+#define PRIoFAST8 __UINT_FAST8_FMTo__
+#define PRIoFAST16 __UINT_FAST16_FMTo__
+#define PRIoFAST32 __UINT_FAST32_FMTo__
+#define PRIoFAST64 __UINT_FAST64_FMTo__
+
+#define PRIu8 __UINT8_FMTu__
+#define PRIu16 __UINT16_FMTu__
+#define PRIu32 __UINT32_FMTu__
+#define PRIu64 __UINT64_FMTu__
+
+#define PRIuLEAST8 __UINT_LEAST8_FMTu__
+#define PRIuLEAST16 __UINT_LEAST16_FMTu__
+#define PRIuLEAST32 __UINT_LEAST32_FMTu__
+#define PRIuLEAST64 __UINT_LEAST64_FMTu__
+
+#define PRIuFAST8 __UINT_FAST8_FMTu__
+#define PRIuFAST16 __UINT_FAST16_FMTu__
+#define PRIuFAST32 __UINT_FAST32_FMTu__
+#define PRIuFAST64 __UINT_FAST64_FMTu__
+
+#define PRIx8 __UINT8_FMTx__
+#define PRIx16 __UINT16_FMTx__
+#define PRIx32 __UINT32_FMTx__
+#define PRIx64 __UINT64_FMTx__
+
+#define PRIxLEAST8 __UINT_LEAST8_FMTx__
+#define PRIxLEAST16 __UINT_LEAST16_FMTx__
+#define PRIxLEAST32 __UINT_LEAST32_FMTx__
+#define PRIxLEAST64 __UINT_LEAST64_FMTx__
+
+#define PRIxFAST8 __UINT_FAST8_FMTx__
+#define PRIxFAST16 __UINT_FAST16_FMTx__
+#define PRIxFAST32 __UINT_FAST32_FMTx__
+#define PRIxFAST64 __UINT_FAST64_FMTx__
+
+#define PRIX8 __UINT8_FMTX__
+#define PRIX16 __UINT16_FMTX__
+#define PRIX32 __UINT32_FMTX__
+#define PRIX64 __UINT64_FMTX__
+
+#define PRIXLEAST8 __UINT_LEAST8_FMTX__
+#define PRIXLEAST16 __UINT_LEAST16_FMTX__
+#define PRIXLEAST32 __UINT_LEAST32_FMTX__
+#define PRIXLEAST64 __UINT_LEAST64_FMTX__
+
+#define PRIXFAST8 __UINT_FAST8_FMTX__
+#define PRIXFAST16 __UINT_FAST16_FMTX__
+#define PRIXFAST32 __UINT_FAST32_FMTX__
+#define PRIXFAST64 __UINT_FAST64_FMTX__
+
+#define PRIdMAX __INTMAX_FMTd__
+#define PRIiMAX __INTMAX_FMTi__
+#define PRIoMAX __UINTMAX_FMTo__
+#define PRIuMAX __UINTMAX_FMTu__
+#define PRIxMAX __UINTMAX_FMTx__
+#define PRIXMAX __UINTMAX_FMTX__
+
+#define PRIdPTR __INTPTR_FMTd__
+#define PRIiPTR __INTPTR_FMTi__
+#define PRIoPTR __UINTPTR_FMTo__
+#define PRIuPTR __UINTPTR_FMTu__
+#define PRIxPTR __UINTPTR_FMTx__
+#define PRIXPTR __UINTPTR_FMTX__
+
+#define SCNd8 __INT8_FMTd__
+#define SCNd16 __INT16_FMTd__
+#define SCNd32 __INT32_FMTd__
+#define SCNd64 __INT64_FMTd__
+
+#define SCNdLEAST8 __INT_LEAST8_FMTd__
+#define SCNdLEAST16 __INT_LEAST16_FMTd__
+#define SCNdLEAST32 __INT_LEAST32_FMTd__
+#define SCNdLEAST64 __INT_LEAST64_FMTd__
+
+#define SCNdFAST8 __INT_FAST8_FMTd__
+#define SCNdFAST16 __INT_FAST16_FMTd__
+#define SCNdFAST32 __INT_FAST32_FMTd__
+#define SCNdFAST64 __INT_FAST64_FMTd__
+
+#define SCNi8 __INT8_FMTi__
+#define SCNi16 __INT16_FMTi__
+#define SCNi32 __INT32_FMTi__
+#define SCNi64 __INT64_FMTi__
+
+#define SCNiLEAST8 __INT_LEAST8_FMTi__
+#define SCNiLEAST16 __INT_LEAST16_FMTi__
+#define SCNiLEAST32 __INT_LEAST32_FMTi__
+#define SCNiLEAST64 __INT_LEAST64_FMTi__
+
+#define SCNiFAST8 __INT_FAST8_FMTi__
+#define SCNiFAST16 __INT_FAST16_FMTi__
+#define SCNiFAST32 __INT_FAST32_FMTi__
+#define SCNiFAST64 __INT_FAST64_FMTi__
+
+#define SCNo8 __UINT8_FMTo__
+#define SCNo16 __UINT16_FMTo__
+#define SCNo32 __UINT32_FMTo__
+#define SCNo64 __UINT64_FMTo__
+
+#define SCNoLEAST8 __UINT_LEAST8_FMTo__
+#define SCNoLEAST16 __UINT_LEAST16_FMTo__
+#define SCNoLEAST32 __UINT_LEAST32_FMTo__
+#define SCNoLEAST64 __UINT_LEAST64_FMTo__
+
+#define SCNoFAST8 __UINT_FAST8_FMTo__
+#define SCNoFAST16 __UINT_FAST16_FMTo__
+#define SCNoFAST32 __UINT_FAST32_FMTo__
+#define SCNoFAST64 __UINT_FAST64_FMTo__
+
+#define SCNu8 __UINT8_FMTu__
+#define SCNu16 __UINT16_FMTu__
+#define SCNu32 __UINT32_FMTu__
+#define SCNu64 __UINT64_FMTu__
+
+#define SCNuLEAST8 __UINT_LEAST8_FMTu__
+#define SCNuLEAST16 __UINT_LEAST16_FMTu__
+#define SCNuLEAST32 __UINT_LEAST32_FMTu__
+#define SCNuLEAST64 __UINT_LEAST64_FMTu__
+
+#define SCNuFAST8 __UINT_FAST8_FMTu__
+#define SCNuFAST16 __UINT_FAST16_FMTu__
+#define SCNuFAST32 __UINT_FAST32_FMTu__
+#define SCNuFAST64 __UINT_FAST64_FMTu__
+
+#define SCNx8 __UINT8_FMTx__
+#define SCNx16 __UINT16_FMTx__
+#define SCNx32 __UINT32_FMTx__
+#define SCNx64 __UINT64_FMTx__
+
+#define SCNxLEAST8 __UINT_LEAST8_FMTx__
+#define SCNxLEAST16 __UINT_LEAST16_FMTx__
+#define SCNxLEAST32 __UINT_LEAST32_FMTx__
+#define SCNxLEAST64 __UINT_LEAST64_FMTx__
+
+#define SCNxFAST8 __UINT_FAST8_FMTx__
+#define SCNxFAST16 __UINT_FAST16_FMTx__
+#define SCNxFAST32 __UINT_FAST32_FMTx__
+#define SCNxFAST64 __UINT_FAST64_FMTx__
+
+#define SCNX8 __UINT8_FMTX__
+#define SCNX16 __UINT16_FMTX__
+#define SCNX32 __UINT32_FMTX__
+#define SCNX64 __UINT64_FMTX__
+
+#define SCNXLEAST8 __UINT_LEAST8_FMTX__
+#define SCNXLEAST16 __UINT_LEAST16_FMTX__
+#define SCNXLEAST32 __UINT_LEAST32_FMTX__
+#define SCNXLEAST64 __UINT_LEAST64_FMTX__
+
+#define SCNXFAST8 __UINT_FAST8_FMTX__
+#define SCNXFAST16 __UINT_FAST16_FMTX__
+#define SCNXFAST32 __UINT_FAST32_FMTX__
+#define SCNXFAST64 __UINT_FAST64_FMTX__
+
+#define SCNdMAX __INTMAX_FMTd__
+#define SCNiMAX __INTMAX_FMTi__
+#define SCNoMAX __UINTMAX_FMTo__
+#define SCNuMAX __UINTMAX_FMTu__
+#define SCNxMAX __UINTMAX_FMTx__
+#define SCNXMAX __UINTMAX_FMTX__
+
+#define SCNdPTR __INTPTR_FMTd__
+#define SCNiPTR __INTPTR_FMTi__
+#define SCNoPTR __UINTPTR_FMTo__
+#define SCNuPTR __UINTPTR_FMTu__
+#define SCNxPTR __UINTPTR_FMTx__
+#define SCNXPTR __UINTPTR_FMTX__
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_INTTYPES_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/iso646.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/iso646.h
new file mode 100644
index 0000000..8b7dda8
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/iso646.h
@@ -0,0 +1,20 @@
+#ifndef SYSROOT_ISO646_H_
+#define SYSROOT_ISO646_H_
+
+#ifndef __cplusplus
+
+#define and &&
+#define and_eq &=
+#define bitand &
+#define bitor |
+#define compl ~
+#define not !
+#define not_eq !=
+#define or ||
+#define or_eq |=
+#define xor ^
+#define xor_eq ^=
+
+#endif
+
+#endif // SYSROOT_ISO646_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/langinfo.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/langinfo.h
new file mode 100644
index 0000000..a14fcfd
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/langinfo.h
@@ -0,0 +1,92 @@
+#ifndef SYSROOT_LANGINFO_H_
+#define SYSROOT_LANGINFO_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <nl_types.h>
+
+#define __NEED_locale_t
+
+#include <bits/alltypes.h>
+
+#define ABDAY_1 0x20000
+#define ABDAY_2 0x20001
+#define ABDAY_3 0x20002
+#define ABDAY_4 0x20003
+#define ABDAY_5 0x20004
+#define ABDAY_6 0x20005
+#define ABDAY_7 0x20006
+
+#define DAY_1 0x20007
+#define DAY_2 0x20008
+#define DAY_3 0x20009
+#define DAY_4 0x2000A
+#define DAY_5 0x2000B
+#define DAY_6 0x2000C
+#define DAY_7 0x2000D
+
+#define ABMON_1 0x2000E
+#define ABMON_2 0x2000F
+#define ABMON_3 0x20010
+#define ABMON_4 0x20011
+#define ABMON_5 0x20012
+#define ABMON_6 0x20013
+#define ABMON_7 0x20014
+#define ABMON_8 0x20015
+#define ABMON_9 0x20016
+#define ABMON_10 0x20017
+#define ABMON_11 0x20018
+#define ABMON_12 0x20019
+
+#define MON_1 0x2001A
+#define MON_2 0x2001B
+#define MON_3 0x2001C
+#define MON_4 0x2001D
+#define MON_5 0x2001E
+#define MON_6 0x2001F
+#define MON_7 0x20020
+#define MON_8 0x20021
+#define MON_9 0x20022
+#define MON_10 0x20023
+#define MON_11 0x20024
+#define MON_12 0x20025
+
+#define AM_STR 0x20026
+#define PM_STR 0x20027
+
+#define D_T_FMT 0x20028
+#define D_FMT 0x20029
+#define T_FMT 0x2002A
+#define T_FMT_AMPM 0x2002B
+
+#define ERA 0x2002C
+#define ERA_D_FMT 0x2002E
+#define ALT_DIGITS 0x2002F
+#define ERA_D_T_FMT 0x20030
+#define ERA_T_FMT 0x20031
+
+#define CODESET 14
+
+#define CRNCYSTR 0x4000F
+
+#define RADIXCHAR 0x10000
+#define THOUSEP 0x10001
+#define YESEXPR 0x50000
+#define NOEXPR 0x50001
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define YESSTR 0x50002
+#define NOSTR 0x50003
+#endif
+
+char* nl_langinfo(nl_item);
+char* nl_langinfo_l(nl_item, locale_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_LANGINFO_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/libgen.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/libgen.h
new file mode 100644
index 0000000..f7f79b6
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/libgen.h
@@ -0,0 +1,15 @@
+#ifndef SYSROOT_LIBGEN_H_
+#define SYSROOT_LIBGEN_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+char* dirname(char*);
+char* basename(char*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_LIBGEN_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/limits.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/limits.h
new file mode 100644
index 0000000..cf60386
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/limits.h
@@ -0,0 +1,153 @@
+#ifndef SYSROOT_LIMITS_H_
+#define SYSROOT_LIMITS_H_
+
+#include <features.h>
+
+/* Most limits are system-specific */
+
+#include <bits/limits.h>
+
+/* Support signed or unsigned plain-char */
+
+#if '\0' - 1 > 0
+#define CHAR_MIN 0
+#define CHAR_MAX 255
+#else
+#define CHAR_MIN (-128)
+#define CHAR_MAX 127
+#endif
+
+/* Some universal constants... */
+
+#define CHAR_BIT 8
+#define SCHAR_MIN (-128)
+#define SCHAR_MAX 127
+#define UCHAR_MAX 255
+#define SHRT_MIN (-1 - 0x7fff)
+#define SHRT_MAX 0x7fff
+#define USHRT_MAX 0xffff
+#define INT_MIN (-1 - 0x7fffffff)
+#define INT_MAX 0x7fffffff
+#define UINT_MAX 0xffffffffU
+#define LONG_MIN (-LONG_MAX - 1)
+#define ULONG_MAX (2UL * LONG_MAX + 1)
+#define LLONG_MIN (-LLONG_MAX - 1)
+#define ULLONG_MAX (2ULL * LLONG_MAX + 1)
+
+#define MB_LEN_MAX 4
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#define PIPE_BUF 4096
+#ifdef PAGE_SIZE
+#define PAGESIZE PAGE_SIZE
+#endif
+#define FILESIZEBITS 64
+#define NAME_MAX 255
+#define SYMLINK_MAX 255
+#define PATH_MAX 4096
+#define NZERO 20
+#define NGROUPS_MAX 32
+#define IOV_MAX 1024
+#define SYMLOOP_MAX 40
+#define WORD_BIT 32
+#define SSIZE_MAX LONG_MAX
+#define TZNAME_MAX 6
+#define TTY_NAME_MAX 32
+#define HOST_NAME_MAX 255
+
+/* Implementation choices... */
+
+#define PTHREAD_KEYS_MAX 128
+#define PTHREAD_STACK_MIN 3072
+#define PTHREAD_DESTRUCTOR_ITERATIONS 4
+#define SEM_VALUE_MAX 0x7fffffff
+#define SEM_NSEMS_MAX 256
+#define DELAYTIMER_MAX 0x7fffffff
+#define MQ_PRIO_MAX 32768
+#define LOGIN_NAME_MAX 256
+
+/* Arbitrary numbers... */
+
+#define BC_BASE_MAX 99
+#define BC_DIM_MAX 2048
+#define BC_SCALE_MAX 99
+#define BC_STRING_MAX 1000
+#define CHARCLASS_NAME_MAX 14
+#define COLL_WEIGHTS_MAX 2
+#define EXPR_NEST_MAX 32
+#define LINE_MAX 4096
+#define RE_DUP_MAX 255
+
+#define NL_ARGMAX 9
+#define NL_LANGMAX 32
+#define NL_MSGMAX 32767
+#define NL_SETMAX 255
+#define NL_TEXTMAX 2048
+
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || \
+ (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE + 0 < 700)
+
+#define NL_NMAX 16
+
+#endif
+
+/* POSIX/SUS requirements follow. These numbers come directly
+ * from SUS and have nothing to do with the host system. */
+
+#define _POSIX_AIO_LISTIO_MAX 2
+#define _POSIX_AIO_MAX 1
+#define _POSIX_ARG_MAX 4096
+#define _POSIX_CHILD_MAX 25
+#define _POSIX_CLOCKRES_MIN 20000000
+#define _POSIX_DELAYTIMER_MAX 32
+#define _POSIX_HOST_NAME_MAX 255
+#define _POSIX_LINK_MAX 8
+#define _POSIX_LOGIN_NAME_MAX 9
+#define _POSIX_MAX_CANON 255
+#define _POSIX_MAX_INPUT 255
+#define _POSIX_MQ_OPEN_MAX 8
+#define _POSIX_MQ_PRIO_MAX 32
+#define _POSIX_NAME_MAX 14
+#define _POSIX_NGROUPS_MAX 8
+#define _POSIX_OPEN_MAX 20
+#define _POSIX_PATH_MAX 256
+#define _POSIX_PIPE_BUF 512
+#define _POSIX_RE_DUP_MAX 255
+#define _POSIX_RTSIG_MAX 8
+#define _POSIX_SEM_NSEMS_MAX 256
+#define _POSIX_SEM_VALUE_MAX 32767
+#define _POSIX_SIGQUEUE_MAX 32
+#define _POSIX_SSIZE_MAX 32767
+#define _POSIX_STREAM_MAX 8
+#define _POSIX_SS_REPL_MAX 4
+#define _POSIX_SYMLINK_MAX 255
+#define _POSIX_SYMLOOP_MAX 8
+#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4
+#define _POSIX_THREAD_KEYS_MAX 128
+#define _POSIX_THREAD_THREADS_MAX 64
+#define _POSIX_TIMER_MAX 32
+#define _POSIX_TRACE_EVENT_NAME_MAX 30
+#define _POSIX_TRACE_NAME_MAX 8
+#define _POSIX_TRACE_SYS_MAX 8
+#define _POSIX_TRACE_USER_EVENT_MAX 32
+#define _POSIX_TTY_NAME_MAX 9
+#define _POSIX_TZNAME_MAX 6
+#define _POSIX2_BC_BASE_MAX 99
+#define _POSIX2_BC_DIM_MAX 2048
+#define _POSIX2_BC_SCALE_MAX 99
+#define _POSIX2_BC_STRING_MAX 1000
+#define _POSIX2_CHARCLASS_NAME_MAX 14
+#define _POSIX2_COLL_WEIGHTS_MAX 2
+#define _POSIX2_EXPR_NEST_MAX 32
+#define _POSIX2_LINE_MAX 2048
+#define _POSIX2_RE_DUP_MAX 255
+
+#define _XOPEN_IOV_MAX 16
+#define _XOPEN_NAME_MAX 255
+#define _XOPEN_PATH_MAX 1024
+
+#endif // SYSROOT_LIMITS_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/link.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/link.h
new file mode 100644
index 0000000..78ebd48
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/link.h
@@ -0,0 +1,61 @@
+#ifndef SYSROOT_LINK_H_
+#define SYSROOT_LINK_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <elf.h>
+#define __NEED_size_t
+#define __NEED_uint32_t
+#include <bits/alltypes.h>
+
+#define ElfW(type) Elf64_##type
+
+/* this is the same everywhere except alpha and s390 */
+typedef uint32_t Elf_Symndx;
+
+struct dl_phdr_info {
+ ElfW(Addr) dlpi_addr;
+ const char* dlpi_name;
+ const ElfW(Phdr) * dlpi_phdr;
+ ElfW(Half) dlpi_phnum;
+ unsigned long long int dlpi_adds;
+ unsigned long long int dlpi_subs;
+ size_t dlpi_tls_modid;
+ void* dlpi_tls_data;
+};
+
+struct link_map {
+ ElfW(Addr) l_addr;
+ char* l_name;
+ ElfW(Dyn) * l_ld;
+ struct link_map *l_next, *l_prev;
+};
+
+struct r_debug {
+ int r_version;
+ struct link_map* r_map;
+ ElfW(Addr) r_brk;
+
+ /* This is the address of a function internal to the run-time linker
+ that triggers a debug trap. This function will always be called
+ when the linker begins to map in a library or unmap it, and again
+ when the mapping change is complete.
+
+ The debugger can compare the address of a sw exception to this value
+ to determine whether the debug trap was triggered by the run-time
+ linker. */
+ ElfW(Addr) r_brk_on_load;
+
+ enum { RT_CONSISTENT, RT_ADD, RT_DELETE } r_state;
+ ElfW(Addr) r_ldbase;
+};
+
+int dl_iterate_phdr(int (*)(struct dl_phdr_info*, size_t, void*), void*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_LINK_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/locale.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/locale.h
new file mode 100644
index 0000000..ce78a02
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/locale.h
@@ -0,0 +1,79 @@
+#ifndef SYSROOT_LOCALE_H_
+#define SYSROOT_LOCALE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <bits/null.h>
+
+#define LC_CTYPE 0
+#define LC_NUMERIC 1
+#define LC_TIME 2
+#define LC_COLLATE 3
+#define LC_MONETARY 4
+#define LC_MESSAGES 5
+#define LC_ALL 6
+
+struct lconv {
+ char* decimal_point;
+ char* thousands_sep;
+ char* grouping;
+
+ char* int_curr_symbol;
+ char* currency_symbol;
+ char* mon_decimal_point;
+ char* mon_thousands_sep;
+ char* mon_grouping;
+ char* positive_sign;
+ char* negative_sign;
+ char int_frac_digits;
+ char frac_digits;
+ char p_cs_precedes;
+ char p_sep_by_space;
+ char n_cs_precedes;
+ char n_sep_by_space;
+ char p_sign_posn;
+ char n_sign_posn;
+ char int_p_cs_precedes;
+ char int_p_sep_by_space;
+ char int_n_cs_precedes;
+ char int_n_sep_by_space;
+ char int_p_sign_posn;
+ char int_n_sign_posn;
+};
+
+char* setlocale(int, const char*);
+struct lconv* localeconv(void);
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#define __NEED_locale_t
+
+#include <bits/alltypes.h>
+
+#define LC_GLOBAL_LOCALE ((locale_t)-1)
+
+#define LC_CTYPE_MASK (1 << LC_CTYPE)
+#define LC_NUMERIC_MASK (1 << LC_NUMERIC)
+#define LC_TIME_MASK (1 << LC_TIME)
+#define LC_COLLATE_MASK (1 << LC_COLLATE)
+#define LC_MONETARY_MASK (1 << LC_MONETARY)
+#define LC_MESSAGES_MASK (1 << LC_MESSAGES)
+#define LC_ALL_MASK 0x7fffffff
+
+locale_t duplocale(locale_t);
+void freelocale(locale_t);
+locale_t newlocale(int, const char*, locale_t);
+locale_t uselocale(locale_t);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_LOCALE_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/malloc.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/malloc.h
new file mode 100644
index 0000000..6abb854
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/malloc.h
@@ -0,0 +1,25 @@
+#ifndef SYSROOT_MALLOC_H_
+#define SYSROOT_MALLOC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+void* malloc(size_t);
+void* calloc(size_t, size_t);
+void* realloc(void*, size_t);
+void free(void*);
+void* valloc(size_t);
+void* memalign(size_t, size_t);
+
+size_t malloc_usable_size(void*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_MALLOC_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/math.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/math.h
new file mode 100644
index 0000000..089c266
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/math.h
@@ -0,0 +1,430 @@
+#ifndef SYSROOT_MATH_H_
+#define SYSROOT_MATH_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_float_t
+#define __NEED_double_t
+#include <bits/alltypes.h>
+
+#if 100 * __GNUC__ + __GNUC_MINOR__ >= 303
+#define NAN __builtin_nanf("")
+#define INFINITY __builtin_inff()
+#else
+#define NAN (0.0f / 0.0f)
+#define INFINITY 1e5000f
+#endif
+
+#define HUGE_VALF INFINITY
+#define HUGE_VAL ((double)INFINITY)
+#define HUGE_VALL ((long double)INFINITY)
+
+#define MATH_ERRNO 1
+#define MATH_ERREXCEPT 2
+#define math_errhandling 2
+
+#define FP_ILOGBNAN (-1 - (int)(((unsigned)-1) >> 1))
+#define FP_ILOGB0 FP_ILOGBNAN
+
+#define FP_NAN 0
+#define FP_INFINITE 1
+#define FP_ZERO 2
+#define FP_SUBNORMAL 3
+#define FP_NORMAL 4
+
+int __fpclassify(double);
+int __fpclassifyf(float);
+int __fpclassifyl(long double);
+
+static __inline unsigned __FLOAT_BITS(float __f) {
+ union {
+ float __f;
+ unsigned __i;
+ } __u;
+ __u.__f = __f;
+ return __u.__i;
+}
+static __inline unsigned long long __DOUBLE_BITS(double __f) {
+ union {
+ double __f;
+ unsigned long long __i;
+ } __u;
+ __u.__f = __f;
+ return __u.__i;
+}
+
+#define fpclassify(x) \
+ (sizeof(x) == sizeof(float) ? __fpclassifyf(x) \
+ : sizeof(x) == sizeof(double) ? __fpclassify(x) : __fpclassifyl(x))
+
+#define isinf(x) \
+ (sizeof(x) == sizeof(float) \
+ ? (__FLOAT_BITS(x) & 0x7fffffff) == 0x7f800000 \
+ : sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL >> 1) == 0x7ffULL << 52 \
+ : __fpclassifyl(x) == FP_INFINITE)
+
+#define isnan(x) \
+ (sizeof(x) == sizeof(float) \
+ ? (__FLOAT_BITS(x) & 0x7fffffff) > 0x7f800000 \
+ : sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL >> 1) > 0x7ffULL << 52 \
+ : __fpclassifyl(x) == FP_NAN)
+
+#define isnormal(x) \
+ (sizeof(x) == sizeof(float) ? ((__FLOAT_BITS(x) + 0x00800000) & 0x7fffffff) >= 0x01000000 \
+ : sizeof(x) == sizeof(double) ? ((__DOUBLE_BITS(x) + (1ULL << 52)) & \
+ -1ULL >> 1) >= 1ULL << 53 \
+ : __fpclassifyl(x) == FP_NORMAL)
+
+#define isfinite(x) \
+ (sizeof(x) == sizeof(float) \
+ ? (__FLOAT_BITS(x) & 0x7fffffff) < 0x7f800000 \
+ : sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL >> 1) < 0x7ffULL << 52 \
+ : __fpclassifyl(x) > FP_INFINITE)
+
+int __signbit(double);
+int __signbitf(float);
+int __signbitl(long double);
+
+#define signbit(x) \
+ (sizeof(x) == sizeof(float) \
+ ? (int)(__FLOAT_BITS(x) >> 31) \
+ : sizeof(x) == sizeof(double) ? (int)(__DOUBLE_BITS(x) >> 63) : __signbitl(x))
+
+#define isunordered(x, y) __builtin_isunordered(x, y)
+
+#define __ISREL_DEF(rel, op, type) \
+ static __inline int __is##rel(type __x, type __y) { return !isunordered(__x, __y) && __x op __y; }
+
+__ISREL_DEF(lessf, <, float_t)
+__ISREL_DEF(less, <, double_t)
+__ISREL_DEF(lessl, <, long double)
+__ISREL_DEF(lessequalf, <=, float_t)
+__ISREL_DEF(lessequal, <=, double_t)
+__ISREL_DEF(lessequall, <=, long double)
+__ISREL_DEF(lessgreaterf, !=, float_t)
+__ISREL_DEF(lessgreater, !=, double_t)
+__ISREL_DEF(lessgreaterl, !=, long double)
+__ISREL_DEF(greaterf, >, float_t)
+__ISREL_DEF(greater, >, double_t)
+__ISREL_DEF(greaterl, >, long double)
+__ISREL_DEF(greaterequalf, >=, float_t)
+__ISREL_DEF(greaterequal, >=, double_t)
+__ISREL_DEF(greaterequall, >=, long double)
+
+#define isless(x, y) __builtin_isless(x, y)
+#define islessequal(x, y) __builtin_islessequal(x, y)
+#define islessgreater(x, y) __builtin_islessgreater(x, y)
+#define isgreater(x, y) __builtin_isgreater(x, y)
+#define isgreaterequal(x, y) __builtin_isgreaterequal(x, y)
+
+double acos(double);
+float acosf(float);
+long double acosl(long double);
+
+double acosh(double);
+float acoshf(float);
+long double acoshl(long double);
+
+double asin(double);
+float asinf(float);
+long double asinl(long double);
+
+double asinh(double);
+float asinhf(float);
+long double asinhl(long double);
+
+double atan(double);
+float atanf(float);
+long double atanl(long double);
+
+double atan2(double, double);
+float atan2f(float, float);
+long double atan2l(long double, long double);
+
+double atanh(double);
+float atanhf(float);
+long double atanhl(long double);
+
+double cbrt(double);
+float cbrtf(float);
+long double cbrtl(long double);
+
+double ceil(double);
+float ceilf(float);
+long double ceill(long double);
+
+double copysign(double, double);
+float copysignf(float, float);
+long double copysignl(long double, long double);
+
+double cos(double);
+float cosf(float);
+long double cosl(long double);
+
+double cosh(double);
+float coshf(float);
+long double coshl(long double);
+
+double erf(double);
+float erff(float);
+long double erfl(long double);
+
+double erfc(double);
+float erfcf(float);
+long double erfcl(long double);
+
+double exp(double);
+float expf(float);
+long double expl(long double);
+
+double exp2(double);
+float exp2f(float);
+long double exp2l(long double);
+
+double expm1(double);
+float expm1f(float);
+long double expm1l(long double);
+
+double fabs(double);
+float fabsf(float);
+long double fabsl(long double);
+
+double fdim(double, double);
+float fdimf(float, float);
+long double fdiml(long double, long double);
+
+double floor(double);
+float floorf(float);
+long double floorl(long double);
+
+double fma(double, double, double);
+float fmaf(float, float, float);
+long double fmal(long double, long double, long double);
+
+double fmax(double, double);
+float fmaxf(float, float);
+long double fmaxl(long double, long double);
+
+double fmin(double, double);
+float fminf(float, float);
+long double fminl(long double, long double);
+
+double fmod(double, double);
+float fmodf(float, float);
+long double fmodl(long double, long double);
+
+double frexp(double, int*);
+float frexpf(float, int*);
+long double frexpl(long double, int*);
+
+double hypot(double, double);
+float hypotf(float, float);
+long double hypotl(long double, long double);
+
+int ilogb(double);
+int ilogbf(float);
+int ilogbl(long double);
+
+double ldexp(double, int);
+float ldexpf(float, int);
+long double ldexpl(long double, int);
+
+double lgamma(double);
+float lgammaf(float);
+long double lgammal(long double);
+
+long long llrint(double);
+long long llrintf(float);
+long long llrintl(long double);
+
+long long llround(double);
+long long llroundf(float);
+long long llroundl(long double);
+
+double log(double);
+float logf(float);
+long double logl(long double);
+
+double log10(double);
+float log10f(float);
+long double log10l(long double);
+
+double log1p(double);
+float log1pf(float);
+long double log1pl(long double);
+
+double log2(double);
+float log2f(float);
+long double log2l(long double);
+
+double logb(double);
+float logbf(float);
+long double logbl(long double);
+
+long lrint(double);
+long lrintf(float);
+long lrintl(long double);
+
+long lround(double);
+long lroundf(float);
+long lroundl(long double);
+
+double modf(double, double*);
+float modff(float, float*);
+long double modfl(long double, long double*);
+
+double nan(const char*);
+float nanf(const char*);
+long double nanl(const char*);
+
+double nearbyint(double);
+float nearbyintf(float);
+long double nearbyintl(long double);
+
+double nextafter(double, double);
+float nextafterf(float, float);
+long double nextafterl(long double, long double);
+
+double nexttoward(double, long double);
+float nexttowardf(float, long double);
+long double nexttowardl(long double, long double);
+
+double pow(double, double);
+float powf(float, float);
+long double powl(long double, long double);
+
+double remainder(double, double);
+float remainderf(float, float);
+long double remainderl(long double, long double);
+
+double remquo(double, double, int*);
+float remquof(float, float, int*);
+long double remquol(long double, long double, int*);
+
+double rint(double);
+float rintf(float);
+long double rintl(long double);
+
+double round(double);
+float roundf(float);
+long double roundl(long double);
+
+double scalbln(double, long);
+float scalblnf(float, long);
+long double scalblnl(long double, long);
+
+double scalbn(double, int);
+float scalbnf(float, int);
+long double scalbnl(long double, int);
+
+double sin(double);
+float sinf(float);
+long double sinl(long double);
+
+double sinh(double);
+float sinhf(float);
+long double sinhl(long double);
+
+double sqrt(double);
+float sqrtf(float);
+long double sqrtl(long double);
+
+double tan(double);
+float tanf(float);
+long double tanl(long double);
+
+double tanh(double);
+float tanhf(float);
+long double tanhl(long double);
+
+double tgamma(double);
+float tgammaf(float);
+long double tgammal(long double);
+
+double trunc(double);
+float truncf(float);
+long double truncl(long double);
+
+#if defined(_XOPEN_SOURCE) || defined(_BSD_SOURCE)
+#undef MAXFLOAT
+#define MAXFLOAT 3.40282346638528859812e+38F
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define M_E 2.7182818284590452354 /* e */
+#define M_LOG2E 1.4426950408889634074 /* log_2 e */
+#define M_LOG10E 0.43429448190325182765 /* log_10 e */
+#define M_LN2 0.69314718055994530942 /* log_e 2 */
+#define M_LN10 2.30258509299404568402 /* log_e 10 */
+#define M_PI 3.14159265358979323846 /* pi */
+#define M_PI_2 1.57079632679489661923 /* pi/2 */
+#define M_PI_4 0.78539816339744830962 /* pi/4 */
+#define M_1_PI 0.31830988618379067154 /* 1/pi */
+#define M_2_PI 0.63661977236758134308 /* 2/pi */
+#define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */
+#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */
+#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
+
+extern int signgam;
+
+double j0(double);
+double j1(double);
+double jn(int, double);
+
+double y0(double);
+double y1(double);
+double yn(int, double);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define HUGE 3.40282346638528859812e+38F
+
+double drem(double, double);
+float dremf(float, float);
+
+int finite(double);
+int finitef(float);
+
+double scalb(double, double);
+float scalbf(float, float);
+
+double significand(double);
+float significandf(float);
+
+double lgamma_r(double, int*);
+float lgammaf_r(float, int*);
+
+float j0f(float);
+float j1f(float);
+float jnf(int, float);
+
+float y0f(float);
+float y1f(float);
+float ynf(int, float);
+#endif
+
+#ifdef _GNU_SOURCE
+long double lgammal_r(long double, int*);
+
+void sincos(double, double*, double*);
+void sincosf(float, float*, float*);
+void sincosl(long double, long double*, long double*);
+
+double exp10(double);
+float exp10f(float);
+long double exp10l(long double);
+
+double pow10(double);
+float pow10f(float);
+long double pow10l(long double);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_MATH_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/memory.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/memory.h
new file mode 100644
index 0000000..3b2f590
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/memory.h
@@ -0,0 +1 @@
+#include <string.h>
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/monetary.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/monetary.h
new file mode 100644
index 0000000..d1955fa
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/monetary.h
@@ -0,0 +1,23 @@
+#ifndef SYSROOT_MONETARY_H_
+#define SYSROOT_MONETARY_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_ssize_t
+#define __NEED_size_t
+#define __NEED_locale_t
+
+#include <bits/alltypes.h>
+
+ssize_t strfmon(char* __restrict, size_t, const char* __restrict, ...);
+ssize_t strfmon_l(char* __restrict, size_t, locale_t, const char* __restrict, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_MONETARY_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/net/ethernet.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/net/ethernet.h
new file mode 100644
index 0000000..9cee87d
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/net/ethernet.h
@@ -0,0 +1,53 @@
+#ifndef SYSROOT_NET_ETHERNET_H_
+#define SYSROOT_NET_ETHERNET_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <netinet/if_ether.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+struct ether_addr {
+ uint8_t ether_addr_octet[ETH_ALEN];
+};
+
+struct ether_header {
+ uint8_t ether_dhost[ETH_ALEN];
+ uint8_t ether_shost[ETH_ALEN];
+ uint16_t ether_type;
+};
+
+#define ETHERTYPE_PUP 0x0200
+#define ETHERTYPE_SPRITE 0x0500
+#define ETHERTYPE_IP 0x0800
+#define ETHERTYPE_ARP 0x0806
+#define ETHERTYPE_REVARP 0x8035
+#define ETHERTYPE_AT 0x809B
+#define ETHERTYPE_AARP 0x80F3
+#define ETHERTYPE_VLAN 0x8100
+#define ETHERTYPE_IPX 0x8137
+#define ETHERTYPE_IPV6 0x86dd
+#define ETHERTYPE_LOOPBACK 0x9000
+
+#define ETHER_ADDR_LEN ETH_ALEN
+#define ETHER_TYPE_LEN 2
+#define ETHER_CRC_LEN 4
+#define ETHER_HDR_LEN ETH_HLEN
+#define ETHER_MIN_LEN (ETH_ZLEN + ETHER_CRC_LEN)
+#define ETHER_MAX_LEN (ETH_FRAME_LEN + ETHER_CRC_LEN)
+
+#define ETHER_IS_VALID_LEN(foo) ((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN)
+
+#define ETHERTYPE_TRAIL 0x1000
+#define ETHERTYPE_NTRAILER 16
+
+#define ETHERMTU ETH_DATA_LEN
+#define ETHERMIN (ETHER_MIN_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_NET_ETHERNET_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/net/if.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/net/if.h
new file mode 100644
index 0000000..e97c3ee
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/net/if.h
@@ -0,0 +1,132 @@
+#ifndef SYSROOT_NET_IF_H_
+#define SYSROOT_NET_IF_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define IF_NAMESIZE 16
+
+struct if_nameindex {
+ unsigned int if_index;
+ char* if_name;
+};
+
+unsigned int if_nametoindex(const char*);
+char* if_indextoname(unsigned int, char*);
+struct if_nameindex* if_nameindex(void);
+void if_freenameindex(struct if_nameindex*);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#include <sys/socket.h>
+
+#define IFF_UP 0x1
+#define IFF_BROADCAST 0x2
+#define IFF_DEBUG 0x4
+#define IFF_LOOPBACK 0x8
+#define IFF_POINTOPOINT 0x10
+#define IFF_NOTRAILERS 0x20
+#define IFF_RUNNING 0x40
+#define IFF_NOARP 0x80
+#define IFF_PROMISC 0x100
+#define IFF_ALLMULTI 0x200
+#define IFF_MASTER 0x400
+#define IFF_SLAVE 0x800
+#define IFF_MULTICAST 0x1000
+#define IFF_PORTSEL 0x2000
+#define IFF_AUTOMEDIA 0x4000
+#define IFF_DYNAMIC 0x8000
+#define IFF_LOWER_UP 0x10000
+#define IFF_DORMANT 0x20000
+#define IFF_ECHO 0x40000
+#define IFF_VOLATILE \
+ (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_BROADCAST | IFF_ECHO | IFF_MASTER | IFF_SLAVE | \
+ IFF_RUNNING | IFF_LOWER_UP | IFF_DORMANT)
+
+struct ifaddr {
+ struct sockaddr ifa_addr;
+ union {
+ struct sockaddr ifu_broadaddr;
+ struct sockaddr ifu_dstaddr;
+ } ifa_ifu;
+ struct iface* ifa_ifp;
+ struct ifaddr* ifa_next;
+};
+
+#define ifa_broadaddr ifa_ifu.ifu_broadaddr
+#define ifa_dstaddr ifa_ifu.ifu_dstaddr
+
+struct ifmap {
+ unsigned long int mem_start;
+ unsigned long int mem_end;
+ unsigned short int base_addr;
+ unsigned char irq;
+ unsigned char dma;
+ unsigned char port;
+};
+
+#define IFHWADDRLEN 6
+#define IFNAMSIZ IF_NAMESIZE
+
+struct ifreq {
+ union {
+ char ifrn_name[IFNAMSIZ];
+ } ifr_ifrn;
+ union {
+ struct sockaddr ifru_addr;
+ struct sockaddr ifru_dstaddr;
+ struct sockaddr ifru_broadaddr;
+ struct sockaddr ifru_netmask;
+ struct sockaddr ifru_hwaddr;
+ short int ifru_flags;
+ int ifru_ivalue;
+ int ifru_mtu;
+ struct ifmap ifru_map;
+ char ifru_slave[IFNAMSIZ];
+ char ifru_newname[IFNAMSIZ];
+ void* ifru_data;
+ } ifr_ifru;
+};
+
+#define ifr_name ifr_ifrn.ifrn_name
+#define ifr_hwaddr ifr_ifru.ifru_hwaddr
+#define ifr_addr ifr_ifru.ifru_addr
+#define ifr_dstaddr ifr_ifru.ifru_dstaddr
+#define ifr_broadaddr ifr_ifru.ifru_broadaddr
+#define ifr_netmask ifr_ifru.ifru_netmask
+#define ifr_flags ifr_ifru.ifru_flags
+#define ifr_metric ifr_ifru.ifru_ivalue
+#define ifr_mtu ifr_ifru.ifru_mtu
+#define ifr_map ifr_ifru.ifru_map
+#define ifr_slave ifr_ifru.ifru_slave
+#define ifr_data ifr_ifru.ifru_data
+#define ifr_ifindex ifr_ifru.ifru_ivalue
+#define ifr_bandwidth ifr_ifru.ifru_ivalue
+#define ifr_qlen ifr_ifru.ifru_ivalue
+#define ifr_newname ifr_ifru.ifru_newname
+#define _IOT_ifreq _IOT(_IOTS(char), IFNAMSIZ, _IOTS(char), 16, 0, 0)
+#define _IOT_ifreq_short _IOT(_IOTS(char), IFNAMSIZ, _IOTS(short), 1, 0, 0)
+#define _IOT_ifreq_int _IOT(_IOTS(char), IFNAMSIZ, _IOTS(int), 1, 0, 0)
+
+struct ifconf {
+ int ifc_len;
+ union {
+ void* ifcu_buf;
+ struct ifreq* ifcu_req;
+ } ifc_ifcu;
+};
+
+#define ifc_buf ifc_ifcu.ifcu_buf
+#define ifc_req ifc_ifcu.ifcu_req
+#define _IOT_ifconf _IOT(_IOTS(struct ifconf), 1, 0, 0, 0, 0)
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_NET_IF_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/net/if_arp.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/net/if_arp.h
new file mode 100644
index 0000000..40b902d
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/net/if_arp.h
@@ -0,0 +1,139 @@
+/* Nonstandard header */
+
+#ifndef SYSROOT_NET_IF_ARP_H_
+#define SYSROOT_NET_IF_ARP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <inttypes.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#define MAX_ADDR_LEN 7
+
+#define ARPOP_REQUEST 1
+#define ARPOP_REPLY 2
+#define ARPOP_RREQUEST 3
+#define ARPOP_RREPLY 4
+#define ARPOP_InREQUEST 8
+#define ARPOP_InREPLY 9
+#define ARPOP_NAK 10
+
+struct arphdr {
+ uint16_t ar_hrd;
+ uint16_t ar_pro;
+ uint8_t ar_hln;
+ uint8_t ar_pln;
+ uint16_t ar_op;
+};
+
+#define ARPHRD_NETROM 0
+#define ARPHRD_ETHER 1
+#define ARPHRD_EETHER 2
+#define ARPHRD_AX25 3
+#define ARPHRD_PRONET 4
+#define ARPHRD_CHAOS 5
+#define ARPHRD_IEEE802 6
+#define ARPHRD_ARCNET 7
+#define ARPHRD_APPLETLK 8
+#define ARPHRD_DLCI 15
+#define ARPHRD_ATM 19
+#define ARPHRD_METRICOM 23
+#define ARPHRD_IEEE1394 24
+#define ARPHRD_EUI64 27
+#define ARPHRD_INFINIBAND 32
+#define ARPHRD_SLIP 256
+#define ARPHRD_CSLIP 257
+#define ARPHRD_SLIP6 258
+#define ARPHRD_CSLIP6 259
+#define ARPHRD_RSRVD 260
+#define ARPHRD_ADAPT 264
+#define ARPHRD_ROSE 270
+#define ARPHRD_X25 271
+#define ARPHRD_HWX25 272
+#define ARPHRD_CAN 280
+#define ARPHRD_PPP 512
+#define ARPHRD_CISCO 513
+#define ARPHRD_HDLC ARPHRD_CISCO
+#define ARPHRD_LAPB 516
+#define ARPHRD_DDCMP 517
+#define ARPHRD_RAWHDLC 518
+
+#define ARPHRD_TUNNEL 768
+#define ARPHRD_TUNNEL6 769
+#define ARPHRD_FRAD 770
+#define ARPHRD_SKIP 771
+#define ARPHRD_LOOPBACK 772
+#define ARPHRD_LOCALTLK 773
+#define ARPHRD_FDDI 774
+#define ARPHRD_BIF 775
+#define ARPHRD_SIT 776
+#define ARPHRD_IPDDP 777
+#define ARPHRD_IPGRE 778
+#define ARPHRD_PIMREG 779
+#define ARPHRD_HIPPI 780
+#define ARPHRD_ASH 781
+#define ARPHRD_ECONET 782
+#define ARPHRD_IRDA 783
+#define ARPHRD_FCPP 784
+#define ARPHRD_FCAL 785
+#define ARPHRD_FCPL 786
+#define ARPHRD_FCFABRIC 787
+#define ARPHRD_IEEE802_TR 800
+#define ARPHRD_IEEE80211 801
+#define ARPHRD_IEEE80211_PRISM 802
+#define ARPHRD_IEEE80211_RADIOTAP 803
+#define ARPHRD_IEEE802154 804
+#define ARPHRD_IEEE802154_MONITOR 805
+#define ARPHRD_PHONET 820
+#define ARPHRD_PHONET_PIPE 821
+#define ARPHRD_CAIF 822
+#define ARPHRD_IP6GRE 823
+#define ARPHRD_NETLINK 824
+
+#define ARPHRD_VOID 0xFFFF
+#define ARPHRD_NONE 0xFFFE
+
+struct arpreq {
+ struct sockaddr arp_pa;
+ struct sockaddr arp_ha;
+ int arp_flags;
+ struct sockaddr arp_netmask;
+ char arp_dev[16];
+};
+
+struct arpreq_old {
+ struct sockaddr arp_pa;
+ struct sockaddr arp_ha;
+ int arp_flags;
+ struct sockaddr arp_netmask;
+};
+
+#define ATF_COM 0x02
+#define ATF_PERM 0x04
+#define ATF_PUBL 0x08
+#define ATF_USETRAILERS 0x10
+#define ATF_NETMASK 0x20
+#define ATF_DONTPUB 0x40
+#define ATF_MAGIC 0x80
+
+#define ARPD_UPDATE 0x01
+#define ARPD_LOOKUP 0x02
+#define ARPD_FLUSH 0x03
+
+struct arpd_request {
+ unsigned short req;
+ uint32_t ip;
+ unsigned long dev;
+ unsigned long stamp;
+ unsigned long updated;
+ unsigned char ha[MAX_ADDR_LEN];
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_NET_IF_ARP_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/net/route.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/net/route.h
new file mode 100644
index 0000000..dc5960b
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/net/route.h
@@ -0,0 +1,119 @@
+#ifndef SYSROOT_NET_ROUTE_H_
+#define SYSROOT_NET_ROUTE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <netinet/in.h>
+#include <stdint.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+struct rtentry {
+ unsigned long int rt_pad1;
+ struct sockaddr rt_dst;
+ struct sockaddr rt_gateway;
+ struct sockaddr rt_genmask;
+ unsigned short int rt_flags;
+ short int rt_pad2;
+ unsigned long int rt_pad3;
+ unsigned char rt_tos;
+ unsigned char rt_class;
+ short int rt_pad4[sizeof(long) / 2 - 1];
+ short int rt_metric;
+ char* rt_dev;
+ unsigned long int rt_mtu;
+ unsigned long int rt_window;
+ unsigned short int rt_irtt;
+};
+
+#define rt_mss rt_mtu
+
+struct in6_rtmsg {
+ struct in6_addr rtmsg_dst;
+ struct in6_addr rtmsg_src;
+ struct in6_addr rtmsg_gateway;
+ uint32_t rtmsg_type;
+ uint16_t rtmsg_dst_len;
+ uint16_t rtmsg_src_len;
+ uint32_t rtmsg_metric;
+ unsigned long int rtmsg_info;
+ uint32_t rtmsg_flags;
+ int rtmsg_ifindex;
+};
+
+#define RTF_UP 0x0001
+#define RTF_GATEWAY 0x0002
+
+#define RTF_HOST 0x0004
+#define RTF_REINSTATE 0x0008
+#define RTF_DYNAMIC 0x0010
+#define RTF_MODIFIED 0x0020
+#define RTF_MTU 0x0040
+#define RTF_MSS RTF_MTU
+#define RTF_WINDOW 0x0080
+#define RTF_IRTT 0x0100
+#define RTF_REJECT 0x0200
+#define RTF_STATIC 0x0400
+#define RTF_XRESOLVE 0x0800
+#define RTF_NOFORWARD 0x1000
+#define RTF_THROW 0x2000
+#define RTF_NOPMTUDISC 0x4000
+
+#define RTF_DEFAULT 0x00010000
+#define RTF_ALLONLINK 0x00020000
+#define RTF_ADDRCONF 0x00040000
+
+#define RTF_LINKRT 0x00100000
+#define RTF_NONEXTHOP 0x00200000
+
+#define RTF_CACHE 0x01000000
+#define RTF_FLOW 0x02000000
+#define RTF_POLICY 0x04000000
+
+#define RTCF_VALVE 0x00200000
+#define RTCF_MASQ 0x00400000
+#define RTCF_NAT 0x00800000
+#define RTCF_DOREDIRECT 0x01000000
+#define RTCF_LOG 0x02000000
+#define RTCF_DIRECTSRC 0x04000000
+
+#define RTF_LOCAL 0x80000000
+#define RTF_INTERFACE 0x40000000
+#define RTF_MULTICAST 0x20000000
+#define RTF_BROADCAST 0x10000000
+#define RTF_NAT 0x08000000
+
+#define RTF_ADDRCLASSMASK 0xF8000000
+#define RT_ADDRCLASS(flags) ((uint32_t)flags >> 23)
+
+#define RT_TOS(tos) ((tos)&IPTOS_TOS_MASK)
+
+#define RT_LOCALADDR(flags) ((flags & RTF_ADDRCLASSMASK) == (RTF_LOCAL | RTF_INTERFACE))
+
+#define RT_CLASS_UNSPEC 0
+#define RT_CLASS_DEFAULT 253
+
+#define RT_CLASS_MAIN 254
+#define RT_CLASS_LOCAL 255
+#define RT_CLASS_MAX 255
+
+#define RTMSG_ACK NLMSG_ACK
+#define RTMSG_OVERRUN NLMSG_OVERRUN
+
+#define RTMSG_NEWDEVICE 0x11
+#define RTMSG_DELDEVICE 0x12
+#define RTMSG_NEWROUTE 0x21
+#define RTMSG_DELROUTE 0x22
+#define RTMSG_NEWRULE 0x31
+#define RTMSG_DELRULE 0x32
+#define RTMSG_CONTROL 0x40
+
+#define RTMSG_AR_FAILED 0x51
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_NET_ROUTE_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netdb.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netdb.h
new file mode 100644
index 0000000..d5bb5ef
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netdb.h
@@ -0,0 +1,155 @@
+#ifndef SYSROOT_NETDB_H_
+#define SYSROOT_NETDB_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <netinet/in.h>
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __NEED_size_t
+#include <bits/alltypes.h>
+#endif
+
+struct addrinfo {
+ int ai_flags;
+ int ai_family;
+ int ai_socktype;
+ int ai_protocol;
+ socklen_t ai_addrlen;
+ struct sockaddr* ai_addr;
+ char* ai_canonname;
+ struct addrinfo* ai_next;
+};
+
+#define IPPORT_RESERVED 1024
+
+#define AI_PASSIVE 0x01
+#define AI_CANONNAME 0x02
+#define AI_NUMERICHOST 0x04
+#define AI_V4MAPPED 0x08
+#define AI_ALL 0x10
+#define AI_ADDRCONFIG 0x20
+#define AI_NUMERICSERV 0x400
+
+#define NI_NUMERICHOST 0x01
+#define NI_NUMERICSERV 0x02
+#define NI_NOFQDN 0x04
+#define NI_NAMEREQD 0x08
+#define NI_DGRAM 0x10
+#define NI_NUMERICSCOPE 0x100
+
+#define EAI_BADFLAGS -1
+#define EAI_NONAME -2
+#define EAI_AGAIN -3
+#define EAI_FAIL -4
+#define EAI_FAMILY -6
+#define EAI_SOCKTYPE -7
+#define EAI_SERVICE -8
+#define EAI_MEMORY -10
+#define EAI_SYSTEM -11
+#define EAI_OVERFLOW -12
+
+int getaddrinfo(const char* __restrict, const char* __restrict, const struct addrinfo* __restrict,
+ struct addrinfo** __restrict);
+void freeaddrinfo(struct addrinfo*);
+int getnameinfo(const struct sockaddr* __restrict, socklen_t, char* __restrict, socklen_t,
+ char* __restrict, socklen_t, int);
+const char* gai_strerror(int);
+
+/* Legacy functions follow (marked OBsolete in SUS) */
+
+struct netent {
+ char* n_name;
+ char** n_aliases;
+ int n_addrtype;
+ uint32_t n_net;
+};
+
+struct hostent {
+ char* h_name;
+ char** h_aliases;
+ int h_addrtype;
+ int h_length;
+ char** h_addr_list;
+};
+#define h_addr h_addr_list[0]
+
+struct servent {
+ char* s_name;
+ char** s_aliases;
+ int s_port;
+ char* s_proto;
+};
+
+struct protoent {
+ char* p_name;
+ char** p_aliases;
+ int p_proto;
+};
+
+void sethostent(int);
+void endhostent(void);
+struct hostent* gethostent(void);
+
+void setnetent(int);
+void endnetent(void);
+struct netent* getnetent(void);
+struct netent* getnetbyaddr(uint32_t, int);
+struct netent* getnetbyname(const char*);
+
+void setservent(int);
+void endservent(void);
+struct servent* getservent(void);
+struct servent* getservbyname(const char*, const char*);
+struct servent* getservbyport(int, const char*);
+
+void setprotoent(int);
+void endprotoent(void);
+struct protoent* getprotoent(void);
+struct protoent* getprotobyname(const char*);
+struct protoent* getprotobynumber(int);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_POSIX_SOURCE) || \
+ (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE + 0 < 200809L) || \
+ (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE + 0 < 700)
+struct hostent* gethostbyname(const char*);
+struct hostent* gethostbyaddr(const void*, socklen_t, int);
+int* __h_errno_location(void);
+#define h_errno (*__h_errno_location())
+#define HOST_NOT_FOUND 1
+#define TRY_AGAIN 2
+#define NO_RECOVERY 3
+#define NO_DATA 4
+#define NO_ADDRESS NO_DATA
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+void herror(const char*);
+const char* hstrerror(int);
+int gethostbyname_r(const char*, struct hostent*, char*, size_t, struct hostent**, int*);
+int gethostbyname2_r(const char*, int, struct hostent*, char*, size_t, struct hostent**, int*);
+struct hostent* gethostbyname2(const char*, int);
+int gethostbyaddr_r(const void*, socklen_t, int, struct hostent*, char*, size_t, struct hostent**,
+ int*);
+int getservbyport_r(int, const char*, struct servent*, char*, size_t, struct servent**);
+int getservbyname_r(const char*, const char*, struct servent*, char*, size_t, struct servent**);
+#define EAI_NODATA -5
+#define EAI_ADDRFAMILY -9
+#define EAI_INPROGRESS -100
+#define EAI_CANCELED -101
+#define EAI_NOTCANCELED -102
+#define EAI_ALLDONE -103
+#define EAI_INTR -104
+#define EAI_IDN_ENCODE -105
+#define NI_MAXHOST 255
+#define NI_MAXSERV 32
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_NETDB_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/ether.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/ether.h
new file mode 100644
index 0000000..74668fb
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/ether.h
@@ -0,0 +1,22 @@
+#ifndef SYSROOT_NETINET_ETHER_H_
+#define SYSROOT_NETINET_ETHER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <netinet/if_ether.h>
+
+char* ether_ntoa(const struct ether_addr*);
+struct ether_addr* ether_aton(const char*);
+char* ether_ntoa_r(const struct ether_addr*, char*);
+struct ether_addr* ether_aton_r(const char*, struct ether_addr*);
+int ether_line(const char*, struct ether_addr*, char*);
+int ether_ntohost(char*, const struct ether_addr*);
+int ether_hostton(const char*, struct ether_addr*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_NETINET_ETHER_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/icmp6.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/icmp6.h
new file mode 100644
index 0000000..dde64cb
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/icmp6.h
@@ -0,0 +1,303 @@
+#ifndef SYSROOT_NETINET_ICMP6_H_
+#define SYSROOT_NETINET_ICMP6_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <netinet/in.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+
+#define ICMP6_FILTER 1
+
+#define ICMP6_FILTER_BLOCK 1
+#define ICMP6_FILTER_PASS 2
+#define ICMP6_FILTER_BLOCKOTHERS 3
+#define ICMP6_FILTER_PASSONLY 4
+
+struct icmp6_filter {
+ uint32_t icmp6_filt[8];
+};
+
+struct icmp6_hdr {
+ uint8_t icmp6_type;
+ uint8_t icmp6_code;
+ uint16_t icmp6_cksum;
+ union {
+ uint32_t icmp6_un_data32[1];
+ uint16_t icmp6_un_data16[2];
+ uint8_t icmp6_un_data8[4];
+ } icmp6_dataun;
+};
+
+#define icmp6_data32 icmp6_dataun.icmp6_un_data32
+#define icmp6_data16 icmp6_dataun.icmp6_un_data16
+#define icmp6_data8 icmp6_dataun.icmp6_un_data8
+#define icmp6_pptr icmp6_data32[0]
+#define icmp6_mtu icmp6_data32[0]
+#define icmp6_id icmp6_data16[0]
+#define icmp6_seq icmp6_data16[1]
+#define icmp6_maxdelay icmp6_data16[0]
+
+#define ICMP6_DST_UNREACH 1
+#define ICMP6_PACKET_TOO_BIG 2
+#define ICMP6_TIME_EXCEEDED 3
+#define ICMP6_PARAM_PROB 4
+
+#define ICMP6_INFOMSG_MASK 0x80
+
+#define ICMP6_ECHO_REQUEST 128
+#define ICMP6_ECHO_REPLY 129
+#define MLD_LISTENER_QUERY 130
+#define MLD_LISTENER_REPORT 131
+#define MLD_LISTENER_REDUCTION 132
+
+#define ICMP6_DST_UNREACH_NOROUTE 0
+#define ICMP6_DST_UNREACH_ADMIN 1
+#define ICMP6_DST_UNREACH_BEYONDSCOPE 2
+#define ICMP6_DST_UNREACH_ADDR 3
+#define ICMP6_DST_UNREACH_NOPORT 4
+
+#define ICMP6_TIME_EXCEED_TRANSIT 0
+#define ICMP6_TIME_EXCEED_REASSEMBLY 1
+
+#define ICMP6_PARAMPROB_HEADER 0
+#define ICMP6_PARAMPROB_NEXTHEADER 1
+#define ICMP6_PARAMPROB_OPTION 2
+
+#define ICMP6_FILTER_WILLPASS(type, filterp) \
+ ((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type)&31))) == 0)
+
+#define ICMP6_FILTER_WILLBLOCK(type, filterp) \
+ ((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type)&31))) != 0)
+
+#define ICMP6_FILTER_SETPASS(type, filterp) \
+ ((((filterp)->icmp6_filt[(type) >> 5]) &= ~(1 << ((type)&31))))
+
+#define ICMP6_FILTER_SETBLOCK(type, filterp) \
+ ((((filterp)->icmp6_filt[(type) >> 5]) |= (1 << ((type)&31))))
+
+#define ICMP6_FILTER_SETPASSALL(filterp) memset(filterp, 0, sizeof(struct icmp6_filter));
+
+#define ICMP6_FILTER_SETBLOCKALL(filterp) memset(filterp, 0xFF, sizeof(struct icmp6_filter));
+
+#define ND_ROUTER_SOLICIT 133
+#define ND_ROUTER_ADVERT 134
+#define ND_NEIGHBOR_SOLICIT 135
+#define ND_NEIGHBOR_ADVERT 136
+#define ND_REDIRECT 137
+
+struct nd_router_solicit {
+ struct icmp6_hdr nd_rs_hdr;
+};
+
+#define nd_rs_type nd_rs_hdr.icmp6_type
+#define nd_rs_code nd_rs_hdr.icmp6_code
+#define nd_rs_cksum nd_rs_hdr.icmp6_cksum
+#define nd_rs_reserved nd_rs_hdr.icmp6_data32[0]
+
+struct nd_router_advert {
+ struct icmp6_hdr nd_ra_hdr;
+ uint32_t nd_ra_reachable;
+ uint32_t nd_ra_retransmit;
+};
+
+#define nd_ra_type nd_ra_hdr.icmp6_type
+#define nd_ra_code nd_ra_hdr.icmp6_code
+#define nd_ra_cksum nd_ra_hdr.icmp6_cksum
+#define nd_ra_curhoplimit nd_ra_hdr.icmp6_data8[0]
+#define nd_ra_flags_reserved nd_ra_hdr.icmp6_data8[1]
+#define ND_RA_FLAG_MANAGED 0x80
+#define ND_RA_FLAG_OTHER 0x40
+#define ND_RA_FLAG_HOME_AGENT 0x20
+#define nd_ra_router_lifetime nd_ra_hdr.icmp6_data16[1]
+
+struct nd_neighbor_solicit {
+ struct icmp6_hdr nd_ns_hdr;
+ struct in6_addr nd_ns_target;
+};
+
+#define nd_ns_type nd_ns_hdr.icmp6_type
+#define nd_ns_code nd_ns_hdr.icmp6_code
+#define nd_ns_cksum nd_ns_hdr.icmp6_cksum
+#define nd_ns_reserved nd_ns_hdr.icmp6_data32[0]
+
+struct nd_neighbor_advert {
+ struct icmp6_hdr nd_na_hdr;
+ struct in6_addr nd_na_target;
+};
+
+#define nd_na_type nd_na_hdr.icmp6_type
+#define nd_na_code nd_na_hdr.icmp6_code
+#define nd_na_cksum nd_na_hdr.icmp6_cksum
+#define nd_na_flags_reserved nd_na_hdr.icmp6_data32[0]
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define ND_NA_FLAG_ROUTER 0x80000000
+#define ND_NA_FLAG_SOLICITED 0x40000000
+#define ND_NA_FLAG_OVERRIDE 0x20000000
+#else
+#define ND_NA_FLAG_ROUTER 0x00000080
+#define ND_NA_FLAG_SOLICITED 0x00000040
+#define ND_NA_FLAG_OVERRIDE 0x00000020
+#endif
+
+struct nd_redirect {
+ struct icmp6_hdr nd_rd_hdr;
+ struct in6_addr nd_rd_target;
+ struct in6_addr nd_rd_dst;
+};
+
+#define nd_rd_type nd_rd_hdr.icmp6_type
+#define nd_rd_code nd_rd_hdr.icmp6_code
+#define nd_rd_cksum nd_rd_hdr.icmp6_cksum
+#define nd_rd_reserved nd_rd_hdr.icmp6_data32[0]
+
+struct nd_opt_hdr {
+ uint8_t nd_opt_type;
+ uint8_t nd_opt_len;
+};
+
+#define ND_OPT_SOURCE_LINKADDR 1
+#define ND_OPT_TARGET_LINKADDR 2
+#define ND_OPT_PREFIX_INFORMATION 3
+#define ND_OPT_REDIRECTED_HEADER 4
+#define ND_OPT_MTU 5
+#define ND_OPT_RTR_ADV_INTERVAL 7
+#define ND_OPT_HOME_AGENT_INFO 8
+
+struct nd_opt_prefix_info {
+ uint8_t nd_opt_pi_type;
+ uint8_t nd_opt_pi_len;
+ uint8_t nd_opt_pi_prefix_len;
+ uint8_t nd_opt_pi_flags_reserved;
+ uint32_t nd_opt_pi_valid_time;
+ uint32_t nd_opt_pi_preferred_time;
+ uint32_t nd_opt_pi_reserved2;
+ struct in6_addr nd_opt_pi_prefix;
+};
+
+#define ND_OPT_PI_FLAG_ONLINK 0x80
+#define ND_OPT_PI_FLAG_AUTO 0x40
+#define ND_OPT_PI_FLAG_RADDR 0x20
+
+struct nd_opt_rd_hdr {
+ uint8_t nd_opt_rh_type;
+ uint8_t nd_opt_rh_len;
+ uint16_t nd_opt_rh_reserved1;
+ uint32_t nd_opt_rh_reserved2;
+};
+
+struct nd_opt_mtu {
+ uint8_t nd_opt_mtu_type;
+ uint8_t nd_opt_mtu_len;
+ uint16_t nd_opt_mtu_reserved;
+ uint32_t nd_opt_mtu_mtu;
+};
+
+struct mld_hdr {
+ struct icmp6_hdr mld_icmp6_hdr;
+ struct in6_addr mld_addr;
+};
+
+#define mld_type mld_icmp6_hdr.icmp6_type
+#define mld_code mld_icmp6_hdr.icmp6_code
+#define mld_cksum mld_icmp6_hdr.icmp6_cksum
+#define mld_maxdelay mld_icmp6_hdr.icmp6_data16[0]
+#define mld_reserved mld_icmp6_hdr.icmp6_data16[1]
+
+#define ICMP6_ROUTER_RENUMBERING 138
+
+struct icmp6_router_renum {
+ struct icmp6_hdr rr_hdr;
+ uint8_t rr_segnum;
+ uint8_t rr_flags;
+ uint16_t rr_maxdelay;
+ uint32_t rr_reserved;
+};
+
+#define rr_type rr_hdr.icmp6_type
+#define rr_code rr_hdr.icmp6_code
+#define rr_cksum rr_hdr.icmp6_cksum
+#define rr_seqnum rr_hdr.icmp6_data32[0]
+
+#define ICMP6_RR_FLAGS_TEST 0x80
+#define ICMP6_RR_FLAGS_REQRESULT 0x40
+#define ICMP6_RR_FLAGS_FORCEAPPLY 0x20
+#define ICMP6_RR_FLAGS_SPECSITE 0x10
+#define ICMP6_RR_FLAGS_PREVDONE 0x08
+
+struct rr_pco_match {
+ uint8_t rpm_code;
+ uint8_t rpm_len;
+ uint8_t rpm_ordinal;
+ uint8_t rpm_matchlen;
+ uint8_t rpm_minlen;
+ uint8_t rpm_maxlen;
+ uint16_t rpm_reserved;
+ struct in6_addr rpm_prefix;
+};
+
+#define RPM_PCO_ADD 1
+#define RPM_PCO_CHANGE 2
+#define RPM_PCO_SETGLOBAL 3
+
+struct rr_pco_use {
+ uint8_t rpu_uselen;
+ uint8_t rpu_keeplen;
+ uint8_t rpu_ramask;
+ uint8_t rpu_raflags;
+ uint32_t rpu_vltime;
+ uint32_t rpu_pltime;
+ uint32_t rpu_flags;
+ struct in6_addr rpu_prefix;
+};
+
+#define ICMP6_RR_PCOUSE_RAFLAGS_ONLINK 0x20
+#define ICMP6_RR_PCOUSE_RAFLAGS_AUTO 0x10
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80000000
+#define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40000000
+#else
+#define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80
+#define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40
+#endif
+
+struct rr_result {
+ uint16_t rrr_flags;
+ uint8_t rrr_ordinal;
+ uint8_t rrr_matchedlen;
+ uint32_t rrr_ifid;
+ struct in6_addr rrr_prefix;
+};
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define ICMP6_RR_RESULT_FLAGS_OOB 0x0002
+#define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0001
+#else
+#define ICMP6_RR_RESULT_FLAGS_OOB 0x0200
+#define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0100
+#endif
+
+struct nd_opt_adv_interval {
+ uint8_t nd_opt_adv_interval_type;
+ uint8_t nd_opt_adv_interval_len;
+ uint16_t nd_opt_adv_interval_reserved;
+ uint32_t nd_opt_adv_interval_ival;
+};
+
+struct nd_opt_home_agent_info {
+ uint8_t nd_opt_home_agent_info_type;
+ uint8_t nd_opt_home_agent_info_len;
+ uint16_t nd_opt_home_agent_info_reserved;
+ uint16_t nd_opt_home_agent_info_preference;
+ uint16_t nd_opt_home_agent_info_lifetime;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_NETINET_ICMP6_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/if_ether.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/if_ether.h
new file mode 100644
index 0000000..f826e96
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/if_ether.h
@@ -0,0 +1,128 @@
+#ifndef SYSROOT_NETINET_IF_ETHER_H_
+#define SYSROOT_NETINET_IF_ETHER_H_
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#define ETH_ALEN 6
+#define ETH_HLEN 14
+#define ETH_ZLEN 60
+#define ETH_DATA_LEN 1500
+#define ETH_FRAME_LEN 1514
+#define ETH_FCS_LEN 4
+
+#define ETH_P_LOOP 0x0060
+#define ETH_P_PUP 0x0200
+#define ETH_P_PUPAT 0x0201
+#define ETH_P_IP 0x0800
+#define ETH_P_X25 0x0805
+#define ETH_P_ARP 0x0806
+#define ETH_P_BPQ 0x08FF
+#define ETH_P_IEEEPUP 0x0a00
+#define ETH_P_IEEEPUPAT 0x0a01
+#define ETH_P_BATMAN 0x4305
+#define ETH_P_DEC 0x6000
+#define ETH_P_DNA_DL 0x6001
+#define ETH_P_DNA_RC 0x6002
+#define ETH_P_DNA_RT 0x6003
+#define ETH_P_LAT 0x6004
+#define ETH_P_DIAG 0x6005
+#define ETH_P_CUST 0x6006
+#define ETH_P_SCA 0x6007
+#define ETH_P_TEB 0x6558
+#define ETH_P_RARP 0x8035
+#define ETH_P_ATALK 0x809B
+#define ETH_P_AARP 0x80F3
+#define ETH_P_8021Q 0x8100
+#define ETH_P_IPX 0x8137
+#define ETH_P_IPV6 0x86DD
+#define ETH_P_PAUSE 0x8808
+#define ETH_P_SLOW 0x8809
+#define ETH_P_WCCP 0x883E
+#define ETH_P_MPLS_UC 0x8847
+#define ETH_P_MPLS_MC 0x8848
+#define ETH_P_ATMMPOA 0x884c
+#define ETH_P_PPP_DISC 0x8863
+#define ETH_P_PPP_SES 0x8864
+#define ETH_P_LINK_CTL 0x886c
+#define ETH_P_ATMFATE 0x8884
+#define ETH_P_PAE 0x888E
+#define ETH_P_AOE 0x88A2
+#define ETH_P_8021AD 0x88A8
+#define ETH_P_802_EX1 0x88B5
+#define ETH_P_TIPC 0x88CA
+#define ETH_P_8021AH 0x88E7
+#define ETH_P_MVRP 0x88F5
+#define ETH_P_1588 0x88F7
+#define ETH_P_PRP 0x88FB
+#define ETH_P_FCOE 0x8906
+#define ETH_P_TDLS 0x890D
+#define ETH_P_FIP 0x8914
+#define ETH_P_80221 0x8917
+#define ETH_P_LOOPBACK 0x9000
+#define ETH_P_QINQ1 0x9100
+#define ETH_P_QINQ2 0x9200
+#define ETH_P_QINQ3 0x9300
+#define ETH_P_EDSA 0xDADA
+#define ETH_P_AF_IUCV 0xFBFB
+
+#define ETH_P_802_3_MIN 0x0600
+
+#define ETH_P_802_3 0x0001
+#define ETH_P_AX25 0x0002
+#define ETH_P_ALL 0x0003
+#define ETH_P_802_2 0x0004
+#define ETH_P_SNAP 0x0005
+#define ETH_P_DDCMP 0x0006
+#define ETH_P_WAN_PPP 0x0007
+#define ETH_P_PPP_MP 0x0008
+#define ETH_P_LOCALTALK 0x0009
+#define ETH_P_CAN 0x000C
+#define ETH_P_CANFD 0x000D
+#define ETH_P_PPPTALK 0x0010
+#define ETH_P_TR_802_2 0x0011
+#define ETH_P_MOBITEX 0x0015
+#define ETH_P_CONTROL 0x0016
+#define ETH_P_IRDA 0x0017
+#define ETH_P_ECONET 0x0018
+#define ETH_P_HDLC 0x0019
+#define ETH_P_ARCNET 0x001A
+#define ETH_P_DSA 0x001B
+#define ETH_P_TRAILER 0x001C
+#define ETH_P_PHONET 0x00F5
+#define ETH_P_IEEE802154 0x00F6
+#define ETH_P_CAIF 0x00F7
+
+struct ethhdr {
+ uint8_t h_dest[ETH_ALEN];
+ uint8_t h_source[ETH_ALEN];
+ uint16_t h_proto;
+};
+
+#include <net/ethernet.h>
+#include <net/if_arp.h>
+
+struct ether_arp {
+ struct arphdr ea_hdr;
+ uint8_t arp_sha[ETH_ALEN];
+ uint8_t arp_spa[4];
+ uint8_t arp_tha[ETH_ALEN];
+ uint8_t arp_tpa[4];
+};
+#define arp_hrd ea_hdr.ar_hrd
+#define arp_pro ea_hdr.ar_pro
+#define arp_hln ea_hdr.ar_hln
+#define arp_pln ea_hdr.ar_pln
+#define arp_op ea_hdr.ar_op
+
+#define ETHER_MAP_IP_MULTICAST(ipaddr, enaddr) \
+ do { \
+ (enaddr)[0] = 0x01; \
+ (enaddr)[1] = 0x00; \
+ (enaddr)[2] = 0x5e; \
+ (enaddr)[3] = ((uint8_t*)ipaddr)[1] & 0x7f; \
+ (enaddr)[4] = ((uint8_t*)ipaddr)[2]; \
+ (enaddr)[5] = ((uint8_t*)ipaddr)[3]; \
+ } while (0)
+
+#endif // SYSROOT_NETINET_IF_ETHER_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/igmp.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/igmp.h
new file mode 100644
index 0000000..99eb989
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/igmp.h
@@ -0,0 +1,45 @@
+#ifndef SYSROOT_NETINET_IGMP_H_
+#define SYSROOT_NETINET_IGMP_H_
+
+#include <netinet/in.h>
+#include <stdint.h>
+
+struct igmp {
+ uint8_t igmp_type;
+ uint8_t igmp_code;
+ uint16_t igmp_cksum;
+ struct in_addr igmp_group;
+};
+
+#define IGMP_MINLEN 8
+
+#define IGMP_MEMBERSHIP_QUERY 0x11
+#define IGMP_V1_MEMBERSHIP_REPORT 0x12
+#define IGMP_V2_MEMBERSHIP_REPORT 0x16
+#define IGMP_V2_LEAVE_GROUP 0x17
+
+#define IGMP_DVMRP 0x13
+#define IGMP_PIM 0x14
+#define IGMP_TRACE 0x15
+
+#define IGMP_MTRACE_RESP 0x1e
+#define IGMP_MTRACE 0x1f
+
+#define IGMP_MAX_HOST_REPORT_DELAY 10
+#define IGMP_TIMER_SCALE 10
+
+#define IGMP_DELAYING_MEMBER 1
+#define IGMP_IDLE_MEMBER 2
+#define IGMP_LAZY_MEMBER 3
+#define IGMP_SLEEPING_MEMBER 4
+#define IGMP_AWAKENING_MEMBER 5
+
+#define IGMP_v1_ROUTER 1
+#define IGMP_v2_ROUTER 2
+
+#define IGMP_HOST_MEMBERSHIP_QUERY IGMP_MEMBERSHIP_QUERY
+#define IGMP_HOST_MEMBERSHIP_REPORT IGMP_V1_MEMBERSHIP_REPORT
+#define IGMP_HOST_NEW_MEMBERSHIP_REPORT IGMP_V2_MEMBERSHIP_REPORT
+#define IGMP_HOST_LEAVE_MESSAGE IGMP_V2_LEAVE_GROUP
+
+#endif // SYSROOT_NETINET_IGMP_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/in.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/in.h
new file mode 100644
index 0000000..6d18e44
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/in.h
@@ -0,0 +1,397 @@
+#ifndef SYSROOT_NETINET_IN_H_
+#define SYSROOT_NETINET_IN_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <inttypes.h>
+#include <sys/socket.h>
+
+typedef uint16_t in_port_t;
+typedef uint32_t in_addr_t;
+struct in_addr {
+ in_addr_t s_addr;
+};
+
+struct sockaddr_in {
+ sa_family_t sin_family;
+ in_port_t sin_port;
+ struct in_addr sin_addr;
+ uint8_t sin_zero[8];
+};
+
+struct in6_addr {
+ union {
+ uint8_t __s6_addr[16];
+ uint16_t __s6_addr16[8];
+ uint32_t __s6_addr32[4];
+ } __in6_union;
+};
+#define s6_addr __in6_union.__s6_addr
+#define s6_addr16 __in6_union.__s6_addr16
+#define s6_addr32 __in6_union.__s6_addr32
+
+struct sockaddr_in6 {
+ sa_family_t sin6_family;
+ in_port_t sin6_port;
+ uint32_t sin6_flowinfo;
+ struct in6_addr sin6_addr;
+ uint32_t sin6_scope_id;
+};
+
+struct ipv6_mreq {
+ struct in6_addr ipv6mr_multiaddr;
+ unsigned ipv6mr_interface;
+};
+
+#define INADDR_ANY ((in_addr_t)0x00000000)
+#define INADDR_BROADCAST ((in_addr_t)0xffffffff)
+#define INADDR_NONE ((in_addr_t)0xffffffff)
+#define INADDR_LOOPBACK ((in_addr_t)0x7f000001)
+
+#define INADDR_UNSPEC_GROUP ((in_addr_t)0xe0000000)
+#define INADDR_ALLHOSTS_GROUP ((in_addr_t)0xe0000001)
+#define INADDR_ALLRTRS_GROUP ((in_addr_t)0xe0000002)
+#define INADDR_MAX_LOCAL_GROUP ((in_addr_t)0xe00000ff)
+
+#define IN6ADDR_ANY_INIT \
+ { \
+ { \
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } \
+ } \
+ }
+#define IN6ADDR_LOOPBACK_INIT \
+ { \
+ { \
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } \
+ } \
+ }
+
+extern const struct in6_addr in6addr_any, in6addr_loopback;
+
+#undef INET_ADDRSTRLEN
+#undef INET6_ADDRSTRLEN
+#define INET_ADDRSTRLEN 16
+#define INET6_ADDRSTRLEN 46
+
+uint32_t htonl(uint32_t);
+uint16_t htons(uint16_t);
+uint32_t ntohl(uint32_t);
+uint16_t ntohs(uint16_t);
+
+#define IPPROTO_IP 0
+#define IPPROTO_HOPOPTS 0
+#define IPPROTO_ICMP 1
+#define IPPROTO_IGMP 2
+#define IPPROTO_IPIP 4
+#define IPPROTO_TCP 6
+#define IPPROTO_EGP 8
+#define IPPROTO_PUP 12
+#define IPPROTO_UDP 17
+#define IPPROTO_IDP 22
+#define IPPROTO_TP 29
+#define IPPROTO_DCCP 33
+#define IPPROTO_IPV6 41
+#define IPPROTO_ROUTING 43
+#define IPPROTO_FRAGMENT 44
+#define IPPROTO_RSVP 46
+#define IPPROTO_GRE 47
+#define IPPROTO_ESP 50
+#define IPPROTO_AH 51
+#define IPPROTO_ICMPV6 58
+#define IPPROTO_NONE 59
+#define IPPROTO_DSTOPTS 60
+#define IPPROTO_MTP 92
+#define IPPROTO_BEETPH 94
+#define IPPROTO_ENCAP 98
+#define IPPROTO_PIM 103
+#define IPPROTO_COMP 108
+#define IPPROTO_SCTP 132
+#define IPPROTO_MH 135
+#define IPPROTO_UDPLITE 136
+#define IPPROTO_MPLS 137
+#define IPPROTO_RAW 255
+#define IPPROTO_MAX 256
+
+#define IN6_IS_ADDR_UNSPECIFIED(a) \
+ (((uint32_t*)(a))[0] == 0 && ((uint32_t*)(a))[1] == 0 && ((uint32_t*)(a))[2] == 0 && \
+ ((uint32_t*)(a))[3] == 0)
+
+#define IN6_IS_ADDR_LOOPBACK(a) \
+ (((uint32_t*)(a))[0] == 0 && ((uint32_t*)(a))[1] == 0 && ((uint32_t*)(a))[2] == 0 && \
+ ((uint8_t*)(a))[12] == 0 && ((uint8_t*)(a))[13] == 0 && ((uint8_t*)(a))[14] == 0 && \
+ ((uint8_t*)(a))[15] == 1)
+
+#define IN6_IS_ADDR_MULTICAST(a) (((uint8_t*)(a))[0] == 0xff)
+
+#define IN6_IS_ADDR_LINKLOCAL(a) \
+ ((((uint8_t*)(a))[0]) == 0xfe && (((uint8_t*)(a))[1] & 0xc0) == 0x80)
+
+#define IN6_IS_ADDR_SITELOCAL(a) \
+ ((((uint8_t*)(a))[0]) == 0xfe && (((uint8_t*)(a))[1] & 0xc0) == 0xc0)
+
+#define IN6_IS_ADDR_V4MAPPED(a) \
+ (((uint32_t*)(a))[0] == 0 && ((uint32_t*)(a))[1] == 0 && ((uint8_t*)(a))[8] == 0 && \
+ ((uint8_t*)(a))[9] == 0 && ((uint8_t*)(a))[10] == 0xff && ((uint8_t*)(a))[11] == 0xff)
+
+#define IN6_IS_ADDR_V4COMPAT(a) \
+ (((uint32_t*)(a))[0] == 0 && ((uint32_t*)(a))[1] == 0 && ((uint32_t*)(a))[2] == 0 && \
+ ((uint8_t*)(a))[15] > 1)
+
+#define IN6_IS_ADDR_MC_NODELOCAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t*)(a))[1] & 0xf) == 0x1))
+
+#define IN6_IS_ADDR_MC_LINKLOCAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t*)(a))[1] & 0xf) == 0x2))
+
+#define IN6_IS_ADDR_MC_SITELOCAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t*)(a))[1] & 0xf) == 0x5))
+
+#define IN6_IS_ADDR_MC_ORGLOCAL(a) (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t*)(a))[1] & 0xf) == 0x8))
+
+#define IN6_IS_ADDR_MC_GLOBAL(a) (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t*)(a))[1] & 0xf) == 0xe))
+
+#define __ARE_4_EQUAL(a, b) \
+ (!((0 [a] - 0 [b]) | (1 [a] - 1 [b]) | (2 [a] - 2 [b]) | (3 [a] - 3 [b])))
+#define IN6_ARE_ADDR_EQUAL(a, b) __ARE_4_EQUAL((const uint32_t*)(a), (const uint32_t*)(b))
+
+#define IN_CLASSA(a) ((((in_addr_t)(a)) & 0x80000000) == 0)
+#define IN_CLASSA_NET 0xff000000
+#define IN_CLASSA_NSHIFT 24
+#define IN_CLASSA_HOST (0xffffffff & ~IN_CLASSA_NET)
+#define IN_CLASSA_MAX 128
+#define IN_CLASSB(a) ((((in_addr_t)(a)) & 0xc0000000) == 0x80000000)
+#define IN_CLASSB_NET 0xffff0000
+#define IN_CLASSB_NSHIFT 16
+#define IN_CLASSB_HOST (0xffffffff & ~IN_CLASSB_NET)
+#define IN_CLASSB_MAX 65536
+#define IN_CLASSC(a) ((((in_addr_t)(a)) & 0xe0000000) == 0xc0000000)
+#define IN_CLASSC_NET 0xffffff00
+#define IN_CLASSC_NSHIFT 8
+#define IN_CLASSC_HOST (0xffffffff & ~IN_CLASSC_NET)
+#define IN_CLASSD(a) ((((in_addr_t)(a)) & 0xf0000000) == 0xe0000000)
+#define IN_MULTICAST(a) IN_CLASSD(a)
+#define IN_EXPERIMENTAL(a) ((((in_addr_t)(a)) & 0xe0000000) == 0xe0000000)
+#define IN_BADCLASS(a) ((((in_addr_t)(a)) & 0xf0000000) == 0xf0000000)
+
+#define IN_LOOPBACKNET 127
+
+#define IP_TOS 1
+#define IP_TTL 2
+#define IP_HDRINCL 3
+#define IP_OPTIONS 4
+#define IP_ROUTER_ALERT 5
+#define IP_RECVOPTS 6
+#define IP_RETOPTS 7
+#define IP_PKTINFO 8
+#define IP_PKTOPTIONS 9
+#define IP_PMTUDISC 10
+#define IP_MTU_DISCOVER 10
+#define IP_RECVERR 11
+#define IP_RECVTTL 12
+#define IP_RECVTOS 13
+#define IP_MTU 14
+#define IP_FREEBIND 15
+#define IP_IPSEC_POLICY 16
+#define IP_XFRM_POLICY 17
+#define IP_PASSSEC 18
+#define IP_TRANSPARENT 19
+#define IP_ORIGDSTADDR 20
+#define IP_RECVORIGDSTADDR IP_ORIGDSTADDR
+#define IP_MINTTL 21
+#define IP_NODEFRAG 22
+#define IP_CHECKSUM 23
+#define IP_BIND_ADDRESS_NO_PORT 24
+#define IP_MULTICAST_IF 32
+#define IP_MULTICAST_TTL 33
+#define IP_MULTICAST_LOOP 34
+#define IP_ADD_MEMBERSHIP 35
+#define IP_DROP_MEMBERSHIP 36
+#define IP_UNBLOCK_SOURCE 37
+#define IP_BLOCK_SOURCE 38
+#define IP_ADD_SOURCE_MEMBERSHIP 39
+#define IP_DROP_SOURCE_MEMBERSHIP 40
+#define IP_MSFILTER 41
+#define IP_MULTICAST_ALL 49
+#define IP_UNICAST_IF 50
+
+#define IP_RECVRETOPTS IP_RETOPTS
+
+#define IP_PMTUDISC_DONT 0
+#define IP_PMTUDISC_WANT 1
+#define IP_PMTUDISC_DO 2
+#define IP_PMTUDISC_PROBE 3
+#define IP_PMTUDISC_INTERFACE 4
+#define IP_PMTUDISC_OMIT 5
+
+#define IP_DEFAULT_MULTICAST_TTL 1
+#define IP_DEFAULT_MULTICAST_LOOP 1
+#define IP_MAX_MEMBERSHIPS 20
+
+struct ip_opts {
+ struct in_addr ip_dst;
+ char ip_opts[40];
+};
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#define MCAST_JOIN_GROUP 42
+#define MCAST_BLOCK_SOURCE 43
+#define MCAST_UNBLOCK_SOURCE 44
+#define MCAST_LEAVE_GROUP 45
+#define MCAST_JOIN_SOURCE_GROUP 46
+#define MCAST_LEAVE_SOURCE_GROUP 47
+#define MCAST_MSFILTER 48
+
+#define MCAST_EXCLUDE 0
+#define MCAST_INCLUDE 1
+
+struct ip_mreq {
+ struct in_addr imr_multiaddr;
+ struct in_addr imr_interface;
+};
+
+struct ip_mreqn {
+ struct in_addr imr_multiaddr;
+ struct in_addr imr_address;
+ int imr_ifindex;
+};
+
+struct ip_mreq_source {
+ struct in_addr imr_multiaddr;
+ struct in_addr imr_interface;
+ struct in_addr imr_sourceaddr;
+};
+
+struct ip_msfilter {
+ struct in_addr imsf_multiaddr;
+ struct in_addr imsf_interface;
+ uint32_t imsf_fmode;
+ uint32_t imsf_numsrc;
+ struct in_addr imsf_slist[1];
+};
+#define IP_MSFILTER_SIZE(numsrc) \
+ (sizeof(struct ip_msfilter) - sizeof(struct in_addr) + (numsrc) * sizeof(struct in_addr))
+
+struct group_req {
+ uint32_t gr_interface;
+ struct sockaddr_storage gr_group;
+};
+
+struct group_source_req {
+ uint32_t gsr_interface;
+ struct sockaddr_storage gsr_group;
+ struct sockaddr_storage gsr_source;
+};
+
+struct group_filter {
+ uint32_t gf_interface;
+ struct sockaddr_storage gf_group;
+ uint32_t gf_fmode;
+ uint32_t gf_numsrc;
+ struct sockaddr_storage gf_slist[1];
+};
+#define GROUP_FILTER_SIZE(numsrc) \
+ (sizeof(struct group_filter) - sizeof(struct sockaddr_storage) + \
+ (numsrc) * sizeof(struct sockaddr_storage))
+
+struct in_pktinfo {
+ int ipi_ifindex;
+ struct in_addr ipi_spec_dst;
+ struct in_addr ipi_addr;
+};
+
+struct in6_pktinfo {
+ struct in6_addr ipi6_addr;
+ unsigned ipi6_ifindex;
+};
+
+struct ip6_mtuinfo {
+ struct sockaddr_in6 ip6m_addr;
+ uint32_t ip6m_mtu;
+};
+#endif
+
+#define IPV6_ADDRFORM 1
+#define IPV6_2292PKTINFO 2
+#define IPV6_2292HOPOPTS 3
+#define IPV6_2292DSTOPTS 4
+#define IPV6_2292RTHDR 5
+#define IPV6_2292PKTOPTIONS 6
+#define IPV6_CHECKSUM 7
+#define IPV6_2292HOPLIMIT 8
+#define IPV6_NEXTHOP 9
+#define IPV6_AUTHHDR 10
+#define IPV6_UNICAST_HOPS 16
+#define IPV6_MULTICAST_IF 17
+#define IPV6_MULTICAST_HOPS 18
+#define IPV6_MULTICAST_LOOP 19
+#define IPV6_JOIN_GROUP 20
+#define IPV6_LEAVE_GROUP 21
+#define IPV6_ROUTER_ALERT 22
+#define IPV6_MTU_DISCOVER 23
+#define IPV6_MTU 24
+#define IPV6_RECVERR 25
+#define IPV6_V6ONLY 26
+#define IPV6_JOIN_ANYCAST 27
+#define IPV6_LEAVE_ANYCAST 28
+#define IPV6_IPSEC_POLICY 34
+#define IPV6_XFRM_POLICY 35
+#define IPV6_HDRINCL 36
+
+#define IPV6_RECVPKTINFO 49
+#define IPV6_PKTINFO 50
+#define IPV6_RECVHOPLIMIT 51
+#define IPV6_HOPLIMIT 52
+#define IPV6_RECVHOPOPTS 53
+#define IPV6_HOPOPTS 54
+#define IPV6_RTHDRDSTOPTS 55
+#define IPV6_RECVRTHDR 56
+#define IPV6_RTHDR 57
+#define IPV6_RECVDSTOPTS 58
+#define IPV6_DSTOPTS 59
+#define IPV6_RECVPATHMTU 60
+#define IPV6_PATHMTU 61
+#define IPV6_DONTFRAG 62
+#define IPV6_RECVTCLASS 66
+#define IPV6_TCLASS 67
+#define IPV6_AUTOFLOWLABEL 70
+#define IPV6_ADDR_PREFERENCES 72
+#define IPV6_MINHOPCOUNT 73
+#define IPV6_ORIGDSTADDR 74
+#define IPV6_RECVORIGDSTADDR IPV6_ORIGDSTADDR
+#define IPV6_TRANSPARENT 75
+#define IPV6_UNICAST_IF 76
+
+#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
+#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
+#define IPV6_RXHOPOPTS IPV6_HOPOPTS
+#define IPV6_RXDSTOPTS IPV6_DSTOPTS
+
+#define IPV6_PMTUDISC_DONT 0
+#define IPV6_PMTUDISC_WANT 1
+#define IPV6_PMTUDISC_DO 2
+#define IPV6_PMTUDISC_PROBE 3
+#define IPV6_PMTUDISC_INTERFACE 4
+#define IPV6_PMTUDISC_OMIT 5
+
+#define IPV6_PREFER_SRC_TMP 0x0001
+#define IPV6_PREFER_SRC_PUBLIC 0x0002
+#define IPV6_PREFER_SRC_PUBTMP_DEFAULT 0x0100
+#define IPV6_PREFER_SRC_COA 0x0004
+#define IPV6_PREFER_SRC_HOME 0x0400
+#define IPV6_PREFER_SRC_CGA 0x0008
+#define IPV6_PREFER_SRC_NONCGA 0x0800
+
+#define IPV6_RTHDR_LOOSE 0
+#define IPV6_RTHDR_STRICT 1
+
+#define IPV6_RTHDR_TYPE_0 0
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_NETINET_IN_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/in_systm.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/in_systm.h
new file mode 100644
index 0000000..8e688ab
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/in_systm.h
@@ -0,0 +1,9 @@
+#ifndef SYSROOT_NETINET_IN_SYSTM_H_
+#define SYSROOT_NETINET_IN_SYSTM_H_
+
+#include <stdint.h>
+
+typedef uint16_t n_short;
+typedef uint32_t n_long, n_time;
+
+#endif // SYSROOT_NETINET_IN_SYSTM_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/ip.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/ip.h
new file mode 100644
index 0000000..c795ef0
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/ip.h
@@ -0,0 +1,198 @@
+#ifndef SYSROOT_NETINET_IP_H_
+#define SYSROOT_NETINET_IP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <endian.h>
+#include <netinet/in.h>
+#include <stdint.h>
+
+struct timestamp {
+ uint8_t len;
+ uint8_t ptr;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int flags : 4;
+ unsigned int overflow : 4;
+#else
+ unsigned int overflow : 4;
+ unsigned int flags : 4;
+#endif
+ uint32_t data[9];
+};
+
+struct iphdr {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int ihl : 4;
+ unsigned int version : 4;
+#else
+ unsigned int version : 4;
+ unsigned int ihl : 4;
+#endif
+ uint8_t tos;
+ uint16_t tot_len;
+ uint16_t id;
+ uint16_t frag_off;
+ uint8_t ttl;
+ uint8_t protocol;
+ uint16_t check;
+ uint32_t saddr;
+ uint32_t daddr;
+};
+
+struct ip {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int ip_hl : 4;
+ unsigned int ip_v : 4;
+#else
+ unsigned int ip_v : 4;
+ unsigned int ip_hl : 4;
+#endif
+ uint8_t ip_tos;
+ uint16_t ip_len;
+ uint16_t ip_id;
+ uint16_t ip_off;
+ uint8_t ip_ttl;
+ uint8_t ip_p;
+ uint16_t ip_sum;
+ struct in_addr ip_src, ip_dst;
+};
+
+#define IP_RF 0x8000
+#define IP_DF 0x4000
+#define IP_MF 0x2000
+#define IP_OFFMASK 0x1fff
+
+struct ip_timestamp {
+ uint8_t ipt_code;
+ uint8_t ipt_len;
+ uint8_t ipt_ptr;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int ipt_flg : 4;
+ unsigned int ipt_oflw : 4;
+#else
+ unsigned int ipt_oflw : 4;
+ unsigned int ipt_flg : 4;
+#endif
+ uint32_t data[9];
+};
+
+#define IPVERSION 4
+#define IP_MAXPACKET 65535
+
+#define IPTOS_ECN_MASK 0x03
+#define IPTOS_ECN(x) ((x)&IPTOS_ECN_MASK)
+#define IPTOS_ECN_NOT_ECT 0x00
+#define IPTOS_ECN_ECT1 0x01
+#define IPTOS_ECN_ECT0 0x02
+#define IPTOS_ECN_CE 0x03
+
+#define IPTOS_DSCP_MASK 0xfc
+#define IPTOS_DSCP(x) ((x)&IPTOS_DSCP_MASK)
+#define IPTOS_DSCP_AF11 0x28
+#define IPTOS_DSCP_AF12 0x30
+#define IPTOS_DSCP_AF13 0x38
+#define IPTOS_DSCP_AF21 0x48
+#define IPTOS_DSCP_AF22 0x50
+#define IPTOS_DSCP_AF23 0x58
+#define IPTOS_DSCP_AF31 0x68
+#define IPTOS_DSCP_AF32 0x70
+#define IPTOS_DSCP_AF33 0x78
+#define IPTOS_DSCP_AF41 0x88
+#define IPTOS_DSCP_AF42 0x90
+#define IPTOS_DSCP_AF43 0x98
+#define IPTOS_DSCP_EF 0xb8
+
+#define IPTOS_CLASS_MASK 0xe0
+#define IPTOS_CLASS(x) ((x)&IPTOS_CLASS_MASK)
+#define IPTOS_CLASS_CS0 0x00
+#define IPTOS_CLASS_CS1 0x20
+#define IPTOS_CLASS_CS2 0x40
+#define IPTOS_CLASS_CS3 0x60
+#define IPTOS_CLASS_CS4 0x80
+#define IPTOS_CLASS_CS5 0xa0
+#define IPTOS_CLASS_CS6 0xc0
+#define IPTOS_CLASS_CS7 0xe0
+#define IPTOS_CLASS_DEFAULT IPTOS_CLASS_CS0
+
+#define IPTOS_TOS_MASK 0x1E
+#define IPTOS_TOS(tos) ((tos)&IPTOS_TOS_MASK)
+#define IPTOS_LOWDELAY 0x10
+#define IPTOS_THROUGHPUT 0x08
+#define IPTOS_RELIABILITY 0x04
+#define IPTOS_LOWCOST 0x02
+#define IPTOS_MINCOST IPTOS_LOWCOST
+
+#define IPTOS_PREC_MASK 0xe0
+#define IPTOS_PREC(tos) ((tos)&IPTOS_PREC_MASK)
+#define IPTOS_PREC_NETCONTROL 0xe0
+#define IPTOS_PREC_INTERNETCONTROL 0xc0
+#define IPTOS_PREC_CRITIC_ECP 0xa0
+#define IPTOS_PREC_FLASHOVERRIDE 0x80
+#define IPTOS_PREC_FLASH 0x60
+#define IPTOS_PREC_IMMEDIATE 0x40
+#define IPTOS_PREC_PRIORITY 0x20
+#define IPTOS_PREC_ROUTINE 0x00
+
+#define IPOPT_COPY 0x80
+#define IPOPT_CLASS_MASK 0x60
+#define IPOPT_NUMBER_MASK 0x1f
+
+#define IPOPT_COPIED(o) ((o)&IPOPT_COPY)
+#define IPOPT_CLASS(o) ((o)&IPOPT_CLASS_MASK)
+#define IPOPT_NUMBER(o) ((o)&IPOPT_NUMBER_MASK)
+
+#define IPOPT_CONTROL 0x00
+#define IPOPT_RESERVED1 0x20
+#define IPOPT_DEBMEAS 0x40
+#define IPOPT_MEASUREMENT IPOPT_DEBMEAS
+#define IPOPT_RESERVED2 0x60
+
+#define IPOPT_EOL 0
+#define IPOPT_END IPOPT_EOL
+#define IPOPT_NOP 1
+#define IPOPT_NOOP IPOPT_NOP
+
+#define IPOPT_RR 7
+#define IPOPT_TS 68
+#define IPOPT_TIMESTAMP IPOPT_TS
+#define IPOPT_SECURITY 130
+#define IPOPT_SEC IPOPT_SECURITY
+#define IPOPT_LSRR 131
+#define IPOPT_SATID 136
+#define IPOPT_SID IPOPT_SATID
+#define IPOPT_SSRR 137
+#define IPOPT_RA 148
+
+#define IPOPT_OPTVAL 0
+#define IPOPT_OLEN 1
+#define IPOPT_OFFSET 2
+#define IPOPT_MINOFF 4
+
+#define MAX_IPOPTLEN 40
+
+#define IPOPT_TS_TSONLY 0
+#define IPOPT_TS_TSANDADDR 1
+#define IPOPT_TS_PRESPEC 3
+
+#define IPOPT_SECUR_UNCLASS 0x0000
+#define IPOPT_SECUR_CONFID 0xf135
+#define IPOPT_SECUR_EFTO 0x789a
+#define IPOPT_SECUR_MMMM 0xbc4d
+#define IPOPT_SECUR_RESTR 0xaf13
+#define IPOPT_SECUR_SECRET 0xd788
+#define IPOPT_SECUR_TOPSECRET 0x6bc5
+
+#define MAXTTL 255
+#define IPDEFTTL 64
+#define IPFRAGTTL 60
+#define IPTTLDEC 1
+
+#define IP_MSS 576
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_NETINET_IP_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/ip6.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/ip6.h
new file mode 100644
index 0000000..45f1c68
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/ip6.h
@@ -0,0 +1,142 @@
+#ifndef SYSROOT_NETINET_IP6_H_
+#define SYSROOT_NETINET_IP6_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <endian.h>
+#include <netinet/in.h>
+#include <stdint.h>
+
+struct ip6_hdr {
+ union {
+ struct ip6_hdrctl {
+ uint32_t ip6_un1_flow;
+ uint16_t ip6_un1_plen;
+ uint8_t ip6_un1_nxt;
+ uint8_t ip6_un1_hlim;
+ } ip6_un1;
+ uint8_t ip6_un2_vfc;
+ } ip6_ctlun;
+ struct in6_addr ip6_src;
+ struct in6_addr ip6_dst;
+};
+
+#define ip6_vfc ip6_ctlun.ip6_un2_vfc
+#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow
+#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen
+#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt
+#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim
+#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim
+
+struct ip6_ext {
+ uint8_t ip6e_nxt;
+ uint8_t ip6e_len;
+};
+
+struct ip6_hbh {
+ uint8_t ip6h_nxt;
+ uint8_t ip6h_len;
+};
+
+struct ip6_dest {
+ uint8_t ip6d_nxt;
+ uint8_t ip6d_len;
+};
+
+struct ip6_rthdr {
+ uint8_t ip6r_nxt;
+ uint8_t ip6r_len;
+ uint8_t ip6r_type;
+ uint8_t ip6r_segleft;
+};
+
+struct ip6_rthdr0 {
+ uint8_t ip6r0_nxt;
+ uint8_t ip6r0_len;
+ uint8_t ip6r0_type;
+ uint8_t ip6r0_segleft;
+ uint8_t ip6r0_reserved;
+ uint8_t ip6r0_slmap[3];
+ struct in6_addr ip6r0_addr[];
+};
+
+struct ip6_frag {
+ uint8_t ip6f_nxt;
+ uint8_t ip6f_reserved;
+ uint16_t ip6f_offlg;
+ uint32_t ip6f_ident;
+};
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define IP6F_OFF_MASK 0xfff8
+#define IP6F_RESERVED_MASK 0x0006
+#define IP6F_MORE_FRAG 0x0001
+#else
+#define IP6F_OFF_MASK 0xf8ff
+#define IP6F_RESERVED_MASK 0x0600
+#define IP6F_MORE_FRAG 0x0100
+#endif
+
+struct ip6_opt {
+ uint8_t ip6o_type;
+ uint8_t ip6o_len;
+};
+
+#define IP6OPT_TYPE(o) ((o)&0xc0)
+#define IP6OPT_TYPE_SKIP 0x00
+#define IP6OPT_TYPE_DISCARD 0x40
+#define IP6OPT_TYPE_FORCEICMP 0x80
+#define IP6OPT_TYPE_ICMP 0xc0
+#define IP6OPT_TYPE_MUTABLE 0x20
+
+#define IP6OPT_PAD1 0
+#define IP6OPT_PADN 1
+
+#define IP6OPT_JUMBO 0xc2
+#define IP6OPT_NSAP_ADDR 0xc3
+#define IP6OPT_TUNNEL_LIMIT 0x04
+#define IP6OPT_ROUTER_ALERT 0x05
+
+struct ip6_opt_jumbo {
+ uint8_t ip6oj_type;
+ uint8_t ip6oj_len;
+ uint8_t ip6oj_jumbo_len[4];
+};
+#define IP6OPT_JUMBO_LEN 6
+
+struct ip6_opt_nsap {
+ uint8_t ip6on_type;
+ uint8_t ip6on_len;
+ uint8_t ip6on_src_nsap_len;
+ uint8_t ip6on_dst_nsap_len;
+};
+
+struct ip6_opt_tunnel {
+ uint8_t ip6ot_type;
+ uint8_t ip6ot_len;
+ uint8_t ip6ot_encap_limit;
+};
+
+struct ip6_opt_router {
+ uint8_t ip6or_type;
+ uint8_t ip6or_len;
+ uint8_t ip6or_value[2];
+};
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define IP6_ALERT_MLD 0x0000
+#define IP6_ALERT_RSVP 0x0001
+#define IP6_ALERT_AN 0x0002
+#else
+#define IP6_ALERT_MLD 0x0000
+#define IP6_ALERT_RSVP 0x0100
+#define IP6_ALERT_AN 0x0200
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_NETINET_IP6_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/ip_icmp.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/ip_icmp.h
new file mode 100644
index 0000000..c239456
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/ip_icmp.h
@@ -0,0 +1,189 @@
+#ifndef SYSROOT_NETINET_IP_ICMP_H_
+#define SYSROOT_NETINET_IP_ICMP_H_
+
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct icmphdr {
+ uint8_t type;
+ uint8_t code;
+ uint16_t checksum;
+ union {
+ struct {
+ uint16_t id;
+ uint16_t sequence;
+ } echo;
+ uint32_t gateway;
+ struct {
+ uint16_t __unused;
+ uint16_t mtu;
+ } frag;
+ } un;
+};
+
+#define ICMP_ECHOREPLY 0
+#define ICMP_DEST_UNREACH 3
+#define ICMP_SOURCE_QUENCH 4
+#define ICMP_REDIRECT 5
+#define ICMP_ECHO 8
+#define ICMP_TIME_EXCEEDED 11
+#define ICMP_PARAMETERPROB 12
+#define ICMP_TIMESTAMP 13
+#define ICMP_TIMESTAMPREPLY 14
+#define ICMP_INFO_REQUEST 15
+#define ICMP_INFO_REPLY 16
+#define ICMP_ADDRESS 17
+#define ICMP_ADDRESSREPLY 18
+#define NR_ICMP_TYPES 18
+
+#define ICMP_NET_UNREACH 0
+#define ICMP_HOST_UNREACH 1
+#define ICMP_PROT_UNREACH 2
+#define ICMP_PORT_UNREACH 3
+#define ICMP_FRAG_NEEDED 4
+#define ICMP_SR_FAILED 5
+#define ICMP_NET_UNKNOWN 6
+#define ICMP_HOST_UNKNOWN 7
+#define ICMP_HOST_ISOLATED 8
+#define ICMP_NET_ANO 9
+#define ICMP_HOST_ANO 10
+#define ICMP_NET_UNR_TOS 11
+#define ICMP_HOST_UNR_TOS 12
+#define ICMP_PKT_FILTERED 13
+#define ICMP_PREC_VIOLATION 14
+#define ICMP_PREC_CUTOFF 15
+#define NR_ICMP_UNREACH 15
+
+#define ICMP_REDIR_NET 0
+#define ICMP_REDIR_HOST 1
+#define ICMP_REDIR_NETTOS 2
+#define ICMP_REDIR_HOSTTOS 3
+
+#define ICMP_EXC_TTL 0
+#define ICMP_EXC_FRAGTIME 1
+
+struct icmp_ra_addr {
+ uint32_t ira_addr;
+ uint32_t ira_preference;
+};
+
+struct icmp {
+ uint8_t icmp_type;
+ uint8_t icmp_code;
+ uint16_t icmp_cksum;
+ union {
+ uint8_t ih_pptr;
+ struct in_addr ih_gwaddr;
+ struct ih_idseq {
+ uint16_t icd_id;
+ uint16_t icd_seq;
+ } ih_idseq;
+ uint32_t ih_void;
+
+ struct ih_pmtu {
+ uint16_t ipm_void;
+ uint16_t ipm_nextmtu;
+ } ih_pmtu;
+
+ struct ih_rtradv {
+ uint8_t irt_num_addrs;
+ uint8_t irt_wpa;
+ uint16_t irt_lifetime;
+ } ih_rtradv;
+ } icmp_hun;
+ union {
+ struct {
+ uint32_t its_otime;
+ uint32_t its_rtime;
+ uint32_t its_ttime;
+ } id_ts;
+ struct {
+ struct ip idi_ip;
+ } id_ip;
+ struct icmp_ra_addr id_radv;
+ uint32_t id_mask;
+ uint8_t id_data[1];
+ } icmp_dun;
+};
+
+#define icmp_pptr icmp_hun.ih_pptr
+#define icmp_gwaddr icmp_hun.ih_gwaddr
+#define icmp_id icmp_hun.ih_idseq.icd_id
+#define icmp_seq icmp_hun.ih_idseq.icd_seq
+#define icmp_void icmp_hun.ih_void
+#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void
+#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu
+#define icmp_num_addrs icmp_hun.ih_rtradv.irt_num_addrs
+#define icmp_wpa icmp_hun.ih_rtradv.irt_wpa
+#define icmp_lifetime icmp_hun.ih_rtradv.irt_lifetime
+#define icmp_otime icmp_dun.id_ts.its_otime
+#define icmp_rtime icmp_dun.id_ts.its_rtime
+#define icmp_ttime icmp_dun.id_ts.its_ttime
+#define icmp_ip icmp_dun.id_ip.idi_ip
+#define icmp_radv icmp_dun.id_radv
+#define icmp_mask icmp_dun.id_mask
+#define icmp_data icmp_dun.id_data
+
+#define ICMP_MINLEN 8
+#define ICMP_TSLEN (8 + 3 * sizeof(n_time))
+#define ICMP_MASKLEN 12
+#define ICMP_ADVLENMIN (8 + sizeof(struct ip) + 8)
+#define ICMP_ADVLEN(p) (8 + ((p)->icmp_ip.ip_hl << 2) + 8)
+
+#define ICMP_UNREACH 3
+#define ICMP_SOURCEQUENCH 4
+#define ICMP_ROUTERADVERT 9
+#define ICMP_ROUTERSOLICIT 10
+#define ICMP_TIMXCEED 11
+#define ICMP_PARAMPROB 12
+#define ICMP_TSTAMP 13
+#define ICMP_TSTAMPREPLY 14
+#define ICMP_IREQ 15
+#define ICMP_IREQREPLY 16
+#define ICMP_MASKREQ 17
+#define ICMP_MASKREPLY 18
+#define ICMP_MAXTYPE 18
+
+#define ICMP_UNREACH_NET 0
+#define ICMP_UNREACH_HOST 1
+#define ICMP_UNREACH_PROTOCOL 2
+#define ICMP_UNREACH_PORT 3
+#define ICMP_UNREACH_NEEDFRAG 4
+#define ICMP_UNREACH_SRCFAIL 5
+#define ICMP_UNREACH_NET_UNKNOWN 6
+#define ICMP_UNREACH_HOST_UNKNOWN 7
+#define ICMP_UNREACH_ISOLATED 8
+#define ICMP_UNREACH_NET_PROHIB 9
+#define ICMP_UNREACH_HOST_PROHIB 10
+#define ICMP_UNREACH_TOSNET 11
+#define ICMP_UNREACH_TOSHOST 12
+#define ICMP_UNREACH_FILTER_PROHIB 13
+#define ICMP_UNREACH_HOST_PRECEDENCE 14
+#define ICMP_UNREACH_PRECEDENCE_CUTOFF 15
+
+#define ICMP_REDIRECT_NET 0
+#define ICMP_REDIRECT_HOST 1
+#define ICMP_REDIRECT_TOSNET 2
+#define ICMP_REDIRECT_TOSHOST 3
+
+#define ICMP_TIMXCEED_INTRANS 0
+#define ICMP_TIMXCEED_REASS 1
+
+#define ICMP_PARAMPROB_OPTABSENT 1
+
+#define ICMP_INFOTYPE(type) \
+ ((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || (type) == ICMP_ROUTERADVERT || \
+ (type) == ICMP_ROUTERSOLICIT || (type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \
+ (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || (type) == ICMP_MASKREQ || \
+ (type) == ICMP_MASKREPLY)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_NETINET_IP_ICMP_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/tcp.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/tcp.h
new file mode 100644
index 0000000..e892dd2
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/tcp.h
@@ -0,0 +1,201 @@
+#ifndef SYSROOT_NETINET_TCP_H_
+#define SYSROOT_NETINET_TCP_H_
+
+#include <features.h>
+
+#define TCP_NODELAY 1
+#define TCP_MAXSEG 2
+#define TCP_CORK 3
+#define TCP_KEEPIDLE 4
+#define TCP_KEEPINTVL 5
+#define TCP_KEEPCNT 6
+#define TCP_SYNCNT 7
+#define TCP_LINGER2 8
+#define TCP_DEFER_ACCEPT 9
+#define TCP_WINDOW_CLAMP 10
+#define TCP_INFO 11
+#define TCP_QUICKACK 12
+#define TCP_CONGESTION 13
+#define TCP_MD5SIG 14
+#define TCP_THIN_LINEAR_TIMEOUTS 16
+#define TCP_THIN_DUPACK 17
+#define TCP_USER_TIMEOUT 18
+#define TCP_REPAIR 19
+#define TCP_REPAIR_QUEUE 20
+#define TCP_QUEUE_SEQ 21
+#define TCP_REPAIR_OPTIONS 22
+#define TCP_FASTOPEN 23
+#define TCP_TIMESTAMP 24
+#define TCP_NOTSENT_LOWAT 25
+#define TCP_CC_INFO 26
+#define TCP_SAVE_SYN 27
+#define TCP_SAVED_SYN 28
+
+#define TCP_ESTABLISHED 1
+#define TCP_SYN_SENT 2
+#define TCP_SYN_RECV 3
+#define TCP_FIN_WAIT1 4
+#define TCP_FIN_WAIT2 5
+#define TCP_TIME_WAIT 6
+#define TCP_CLOSE 7
+#define TCP_CLOSE_WAIT 8
+#define TCP_LAST_ACK 9
+#define TCP_LISTEN 10
+#define TCP_CLOSING 11
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define TCPOPT_EOL 0
+#define TCPOPT_NOP 1
+#define TCPOPT_MAXSEG 2
+#define TCPOPT_WINDOW 3
+#define TCPOPT_SACK_PERMITTED 4
+#define TCPOPT_SACK 5
+#define TCPOPT_TIMESTAMP 8
+#define TCPOLEN_SACK_PERMITTED 2
+#define TCPOLEN_WINDOW 3
+#define TCPOLEN_MAXSEG 4
+#define TCPOLEN_TIMESTAMP 10
+
+#define SOL_TCP 6
+
+#include <endian.h>
+#include <stdint.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+typedef uint32_t tcp_seq;
+
+#define TH_FIN 0x01
+#define TH_SYN 0x02
+#define TH_RST 0x04
+#define TH_PUSH 0x08
+#define TH_ACK 0x10
+#define TH_URG 0x20
+
+struct tcphdr {
+#ifdef _GNU_SOURCE
+#ifdef __GNUC__
+ __extension__
+#endif
+ union {
+ struct {
+ uint16_t source;
+ uint16_t dest;
+ uint32_t seq;
+ uint32_t ack_seq;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ uint16_t res1 : 4;
+ uint16_t doff : 4;
+ uint16_t fin : 1;
+ uint16_t syn : 1;
+ uint16_t rst : 1;
+ uint16_t psh : 1;
+ uint16_t ack : 1;
+ uint16_t urg : 1;
+ uint16_t res2 : 2;
+#else
+ uint16_t doff : 4;
+ uint16_t res1 : 4;
+ uint16_t res2 : 2;
+ uint16_t urg : 1;
+ uint16_t ack : 1;
+ uint16_t psh : 1;
+ uint16_t rst : 1;
+ uint16_t syn : 1;
+ uint16_t fin : 1;
+#endif
+ uint16_t window;
+ uint16_t check;
+ uint16_t urg_ptr;
+ };
+ struct {
+#endif
+
+ uint16_t th_sport;
+ uint16_t th_dport;
+ uint32_t th_seq;
+ uint32_t th_ack;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ uint8_t th_x2 : 4;
+ uint8_t th_off : 4;
+#else
+ uint8_t th_off : 4;
+ uint8_t th_x2 : 4;
+#endif
+ uint8_t th_flags;
+ uint16_t th_win;
+ uint16_t th_sum;
+ uint16_t th_urp;
+
+#ifdef _GNU_SOURCE
+ };
+ };
+#endif
+};
+#endif
+
+#ifdef _GNU_SOURCE
+#define TCPI_OPT_TIMESTAMPS 1
+#define TCPI_OPT_SACK 2
+#define TCPI_OPT_WSCALE 4
+#define TCPI_OPT_ECN 8
+
+#define TCP_CA_Open 0
+#define TCP_CA_Disorder 1
+#define TCP_CA_CWR 2
+#define TCP_CA_Recovery 3
+#define TCP_CA_Loss 4
+
+struct tcp_info {
+ uint8_t tcpi_state;
+ uint8_t tcpi_ca_state;
+ uint8_t tcpi_retransmits;
+ uint8_t tcpi_probes;
+ uint8_t tcpi_backoff;
+ uint8_t tcpi_options;
+ uint8_t tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4;
+ uint32_t tcpi_rto;
+ uint32_t tcpi_ato;
+ uint32_t tcpi_snd_mss;
+ uint32_t tcpi_rcv_mss;
+ uint32_t tcpi_unacked;
+ uint32_t tcpi_sacked;
+ uint32_t tcpi_lost;
+ uint32_t tcpi_retrans;
+ uint32_t tcpi_fackets;
+ uint32_t tcpi_last_data_sent;
+ uint32_t tcpi_last_ack_sent;
+ uint32_t tcpi_last_data_recv;
+ uint32_t tcpi_last_ack_recv;
+ uint32_t tcpi_pmtu;
+ uint32_t tcpi_rcv_ssthresh;
+ uint32_t tcpi_rtt;
+ uint32_t tcpi_rttvar;
+ uint32_t tcpi_snd_ssthresh;
+ uint32_t tcpi_snd_cwnd;
+ uint32_t tcpi_advmss;
+ uint32_t tcpi_reordering;
+ uint32_t tcpi_rcv_rtt;
+ uint32_t tcpi_rcv_space;
+ uint32_t tcpi_total_retrans;
+ uint64_t tcpi_pacing_rate;
+ uint64_t tcpi_max_pacing_rate;
+ uint64_t tcpi_bytes_acked;
+ uint64_t tcpi_bytes_received;
+ uint32_t tcpi_segs_out;
+ uint32_t tcpi_segs_in;
+};
+
+#define TCP_MD5SIG_MAXKEYLEN 80
+
+struct tcp_md5sig {
+ struct sockaddr_storage tcpm_addr;
+ uint16_t __tcpm_pad1;
+ uint16_t tcpm_keylen;
+ uint32_t __tcpm_pad2;
+ uint8_t tcpm_key[TCP_MD5SIG_MAXKEYLEN];
+};
+
+#endif
+
+#endif // SYSROOT_NETINET_TCP_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/udp.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/udp.h
new file mode 100644
index 0000000..1a0fba7
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netinet/udp.h
@@ -0,0 +1,38 @@
+#ifndef SYSROOT_NETINET_UDP_H_
+#define SYSROOT_NETINET_UDP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <stdint.h>
+
+#ifdef _GNU_SOURCE
+#define uh_sport source
+#define uh_dport dest
+#define uh_ulen len
+#define uh_sum check
+#endif
+
+struct udphdr {
+ uint16_t uh_sport;
+ uint16_t uh_dport;
+ uint16_t uh_ulen;
+ uint16_t uh_sum;
+};
+
+#define UDP_CORK 1
+#define UDP_ENCAP 100
+
+#define UDP_ENCAP_ESPINUDP_NON_IKE 1
+#define UDP_ENCAP_ESPINUDP 2
+#define UDP_ENCAP_L2TPINUDP 3
+
+#define SOL_UDP 17
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_NETINET_UDP_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netpacket/packet.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netpacket/packet.h
new file mode 100644
index 0000000..3066046
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/netpacket/packet.h
@@ -0,0 +1,61 @@
+#ifndef SYSROOT_NETPACKET_PACKET_H_
+#define SYSROOT_NETPACKET_PACKET_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct sockaddr_ll {
+ unsigned short sll_family, sll_protocol;
+ int sll_ifindex;
+ unsigned short sll_hatype;
+ unsigned char sll_pkttype, sll_halen;
+ unsigned char sll_addr[8];
+};
+
+struct packet_mreq {
+ int mr_ifindex;
+ unsigned short int mr_type, mr_alen;
+ unsigned char mr_address[8];
+};
+
+#define PACKET_HOST 0
+#define PACKET_BROADCAST 1
+#define PACKET_MULTICAST 2
+#define PACKET_OTHERHOST 3
+#define PACKET_OUTGOING 4
+#define PACKET_LOOPBACK 5
+#define PACKET_FASTROUTE 6
+
+#define PACKET_ADD_MEMBERSHIP 1
+#define PACKET_DROP_MEMBERSHIP 2
+#define PACKET_RECV_OUTPUT 3
+#define PACKET_RX_RING 5
+#define PACKET_STATISTICS 6
+#define PACKET_COPY_THRESH 7
+#define PACKET_AUXDATA 8
+#define PACKET_ORIGDEV 9
+#define PACKET_VERSION 10
+#define PACKET_HDRLEN 11
+#define PACKET_RESERVE 12
+#define PACKET_TX_RING 13
+#define PACKET_LOSS 14
+#define PACKET_VNET_HDR 15
+#define PACKET_TX_TIMESTAMP 16
+#define PACKET_TIMESTAMP 17
+#define PACKET_FANOUT 18
+#define PACKET_TX_HAS_OFF 19
+#define PACKET_QDISC_BYPASS 20
+#define PACKET_ROLLOVER_STATS 21
+#define PACKET_FANOUT_DATA 22
+
+#define PACKET_MR_MULTICAST 0
+#define PACKET_MR_PROMISC 1
+#define PACKET_MR_ALLMULTI 2
+#define PACKET_MR_UNICAST 3
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_NETPACKET_PACKET_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/nl_types.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/nl_types.h
new file mode 100644
index 0000000..e30f86e
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/nl_types.h
@@ -0,0 +1,22 @@
+#ifndef SYSROOT_NL_TYPES_H_
+#define SYSROOT_NL_TYPES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NL_SETD 1
+#define NL_CAT_LOCALE 1
+
+typedef int nl_item;
+typedef void* nl_catd;
+
+nl_catd catopen(const char*, int);
+char* catgets(nl_catd, int, int, const char*);
+int catclose(nl_catd);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_NL_TYPES_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/paths.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/paths.h
new file mode 100644
index 0000000..0ff06aa
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/paths.h
@@ -0,0 +1,28 @@
+#ifndef SYSROOT_PATHS_H_
+#define SYSROOT_PATHS_H_
+
+#define _PATH_DEFPATH "/usr/local/bin:/bin:/usr/bin"
+#define _PATH_STDPATH "/bin:/usr/bin:/sbin:/usr/sbin"
+
+#define _PATH_BSHELL "/bin/sh"
+#define _PATH_CONSOLE "/dev/console"
+#define _PATH_DEVNULL "/dev/null"
+#define _PATH_KLOG "/proc/kmsg"
+#define _PATH_MAILDIR "/var/mail"
+#define _PATH_MAN "/usr/share/man"
+#define _PATH_MNTTAB "/etc/fstab"
+#define _PATH_MOUNTED "/etc/mtab"
+#define _PATH_NOLOGIN "/etc/nologin"
+#define _PATH_SENDMAIL "/usr/sbin/sendmail"
+#define _PATH_SHELLS "/etc/shells"
+#define _PATH_TTY "/dev/tty"
+#define _PATH_VI "/usr/bin/vi"
+#define _PATH_WTMP "/dev/null/wtmp"
+
+#define _PATH_DEV "/dev/"
+#define _PATH_TMP "/tmp/"
+#define _PATH_VARDB "/var/lib/misc/"
+#define _PATH_VARRUN "/var/run/"
+#define _PATH_VARTMP "/var/tmp/"
+
+#endif // SYSROOT_PATHS_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/poll.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/poll.h
new file mode 100644
index 0000000..4c7c800
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/poll.h
@@ -0,0 +1,51 @@
+#ifndef SYSROOT_POLL_H_
+#define SYSROOT_POLL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <bits/poll.h>
+
+#define POLLIN 0x001
+#define POLLPRI 0x002
+#define POLLOUT 0x004
+#define POLLERR 0x008
+#define POLLHUP 0x010
+#define POLLNVAL 0x020
+#define POLLRDNORM 0x040
+#define POLLRDBAND 0x080
+#ifndef POLLWRNORM
+#define POLLWRNORM 0x100
+#define POLLWRBAND 0x200
+#endif
+#ifndef POLLMSG
+#define POLLMSG 0x400
+#define POLLRDHUP 0x2000
+#endif
+
+typedef unsigned long nfds_t;
+
+struct pollfd {
+ int fd;
+ short events;
+ short revents;
+};
+
+int poll(struct pollfd*, nfds_t, int);
+
+#ifdef _GNU_SOURCE
+#define __NEED_time_t
+#define __NEED_struct_timespec
+#define __NEED_sigset_t
+#include <bits/alltypes.h>
+int ppoll(struct pollfd*, nfds_t, const struct timespec*, const sigset_t*);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_POLL_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/pthread.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/pthread.h
new file mode 100644
index 0000000..d4b9f00
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/pthread.h
@@ -0,0 +1,200 @@
+#ifndef SYSROOT_PTHREAD_H_
+#define SYSROOT_PTHREAD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_time_t
+#define __NEED_clockid_t
+#define __NEED_struct_timespec
+#define __NEED_sigset_t
+#define __NEED_pthread_t
+#define __NEED_pthread_attr_t
+#define __NEED_pthread_mutexattr_t
+#define __NEED_pthread_condattr_t
+#define __NEED_pthread_rwlockattr_t
+#define __NEED_pthread_barrierattr_t
+#define __NEED_pthread_mutex_t
+#define __NEED_pthread_cond_t
+#define __NEED_pthread_rwlock_t
+#define __NEED_pthread_barrier_t
+#define __NEED_pthread_spinlock_t
+#define __NEED_pthread_key_t
+#define __NEED_pthread_once_t
+#define __NEED_size_t
+
+#include <sched.h>
+#include <time.h>
+
+#include <bits/alltypes.h>
+
+#define PTHREAD_CREATE_JOINABLE 0
+#define PTHREAD_CREATE_DETACHED 1
+
+#define PTHREAD_MUTEX_NORMAL 0
+#define PTHREAD_MUTEX_DEFAULT 0
+#define PTHREAD_MUTEX_RECURSIVE 1
+#define PTHREAD_MUTEX_ERRORCHECK 2
+
+#define PTHREAD_MUTEX_STALLED 0
+#define PTHREAD_MUTEX_ROBUST 1
+
+#define PTHREAD_PRIO_NONE 0
+#define PTHREAD_PRIO_INHERIT 1
+#define PTHREAD_PRIO_PROTECT 2
+
+#define PTHREAD_INHERIT_SCHED 0
+#define PTHREAD_EXPLICIT_SCHED 1
+
+#define PTHREAD_SCOPE_SYSTEM 0
+#define PTHREAD_SCOPE_PROCESS 1
+
+#define PTHREAD_PROCESS_PRIVATE 0
+
+#define PTHREAD_MUTEX_INITIALIZER \
+ {}
+#define PTHREAD_RWLOCK_INITIALIZER \
+ {}
+#define PTHREAD_COND_INITIALIZER \
+ {}
+#define PTHREAD_ONCE_INIT 0
+
+#define PTHREAD_CANCEL_ENABLE 0
+#define PTHREAD_CANCEL_DISABLE 1
+#define PTHREAD_CANCEL_MASKED 2
+
+#define PTHREAD_CANCEL_DEFERRED 0
+#define PTHREAD_CANCEL_ASYNCHRONOUS 1
+
+#define PTHREAD_CANCELED ((void*)-1)
+
+#define PTHREAD_BARRIER_SERIAL_THREAD (-1)
+
+int pthread_create(pthread_t* __restrict, const pthread_attr_t* __restrict, void* (*)(void*),
+ void* __restrict);
+int pthread_detach(pthread_t);
+_Noreturn void pthread_exit(void*);
+int pthread_join(pthread_t, void**);
+
+pthread_t pthread_self(void);
+
+int pthread_equal(pthread_t, pthread_t);
+#ifndef __cplusplus
+#define pthread_equal(x, y) ((x) == (y))
+#endif
+
+int pthread_setcancelstate(int, int*);
+int pthread_setcanceltype(int, int*);
+void pthread_testcancel(void);
+int pthread_cancel(pthread_t);
+
+int pthread_once(pthread_once_t*, void (*)(void));
+
+int pthread_mutex_init(pthread_mutex_t* __restrict, const pthread_mutexattr_t* __restrict);
+int pthread_mutex_lock(pthread_mutex_t*);
+int pthread_mutex_unlock(pthread_mutex_t*);
+int pthread_mutex_trylock(pthread_mutex_t*);
+int pthread_mutex_timedlock(pthread_mutex_t* __restrict, const struct timespec* __restrict);
+int pthread_mutex_destroy(pthread_mutex_t*);
+int pthread_mutex_consistent(pthread_mutex_t*);
+
+int pthread_mutex_getprioceiling(const pthread_mutex_t* __restrict, int* __restrict);
+int pthread_mutex_setprioceiling(pthread_mutex_t* __restrict, int, int* __restrict);
+
+int pthread_cond_init(pthread_cond_t* __restrict, const pthread_condattr_t* __restrict);
+int pthread_cond_destroy(pthread_cond_t*);
+int pthread_cond_wait(pthread_cond_t* __restrict, pthread_mutex_t* __restrict);
+int pthread_cond_timedwait(pthread_cond_t* __restrict, pthread_mutex_t* __restrict,
+ const struct timespec* __restrict);
+int pthread_cond_broadcast(pthread_cond_t*);
+int pthread_cond_signal(pthread_cond_t*);
+
+int pthread_rwlock_init(pthread_rwlock_t* __restrict, const pthread_rwlockattr_t* __restrict);
+int pthread_rwlock_destroy(pthread_rwlock_t*);
+int pthread_rwlock_rdlock(pthread_rwlock_t*);
+int pthread_rwlock_tryrdlock(pthread_rwlock_t*);
+int pthread_rwlock_timedrdlock(pthread_rwlock_t* __restrict, const struct timespec* __restrict);
+int pthread_rwlock_wrlock(pthread_rwlock_t*);
+int pthread_rwlock_trywrlock(pthread_rwlock_t*);
+int pthread_rwlock_timedwrlock(pthread_rwlock_t* __restrict, const struct timespec* __restrict);
+int pthread_rwlock_unlock(pthread_rwlock_t*);
+
+int pthread_spin_init(pthread_spinlock_t*, int);
+int pthread_spin_destroy(pthread_spinlock_t*);
+int pthread_spin_lock(pthread_spinlock_t*);
+int pthread_spin_trylock(pthread_spinlock_t*);
+int pthread_spin_unlock(pthread_spinlock_t*);
+
+int pthread_barrier_init(pthread_barrier_t* __restrict, const pthread_barrierattr_t* __restrict,
+ unsigned);
+int pthread_barrier_destroy(pthread_barrier_t*);
+int pthread_barrier_wait(pthread_barrier_t*);
+
+int pthread_key_create(pthread_key_t*, void (*)(void*));
+int pthread_key_delete(pthread_key_t);
+void* pthread_getspecific(pthread_key_t);
+int pthread_setspecific(pthread_key_t, const void*);
+
+int pthread_attr_init(pthread_attr_t*);
+int pthread_attr_destroy(pthread_attr_t*);
+
+int pthread_attr_getguardsize(const pthread_attr_t* __restrict, size_t* __restrict);
+int pthread_attr_setguardsize(pthread_attr_t*, size_t);
+int pthread_attr_getstacksize(const pthread_attr_t* __restrict, size_t* __restrict);
+int pthread_attr_setstacksize(pthread_attr_t*, size_t);
+int pthread_attr_getdetachstate(const pthread_attr_t*, int*);
+int pthread_attr_setdetachstate(pthread_attr_t*, int);
+int pthread_attr_getstack(const pthread_attr_t* __restrict, void** __restrict, size_t* __restrict);
+int pthread_attr_setstack(pthread_attr_t*, void*, size_t) __attribute__((__deprecated__(
+ "pthread_attr_setstack is not available in Fuchsia; perhaps pthread_attr_setstacksize and/or "
+ "pthread_attr_setguardsize is sufficient for your needs?")));
+int pthread_attr_getschedparam(const pthread_attr_t* __restrict, struct sched_param* __restrict);
+int pthread_attr_setschedparam(pthread_attr_t* __restrict, const struct sched_param* __restrict);
+
+int pthread_mutexattr_destroy(pthread_mutexattr_t*);
+int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t* __restrict, int* __restrict);
+int pthread_mutexattr_getprotocol(const pthread_mutexattr_t* __restrict, int* __restrict);
+int pthread_mutexattr_getrobust(const pthread_mutexattr_t* __restrict, int* __restrict);
+int pthread_mutexattr_gettype(const pthread_mutexattr_t* __restrict, int* __restrict);
+int pthread_mutexattr_init(pthread_mutexattr_t*);
+int pthread_mutexattr_setprioceiling(pthread_mutexattr_t*, int);
+int pthread_mutexattr_setprotocol(pthread_mutexattr_t*, int);
+int pthread_mutexattr_setrobust(pthread_mutexattr_t*, int);
+int pthread_mutexattr_settype(pthread_mutexattr_t*, int);
+
+int pthread_condattr_init(pthread_condattr_t*);
+int pthread_condattr_destroy(pthread_condattr_t*);
+int pthread_condattr_setclock(pthread_condattr_t*, clockid_t);
+int pthread_condattr_getclock(const pthread_condattr_t* __restrict, clockid_t* __restrict);
+
+int pthread_rwlockattr_init(pthread_rwlockattr_t*);
+int pthread_rwlockattr_destroy(pthread_rwlockattr_t*);
+
+int pthread_barrierattr_destroy(pthread_barrierattr_t*);
+int pthread_barrierattr_init(pthread_barrierattr_t*);
+
+int pthread_atfork(void (*)(void), void (*)(void), void (*)(void));
+
+int pthread_getconcurrency(void);
+int pthread_setconcurrency(int);
+
+int pthread_getcpuclockid(pthread_t, clockid_t*);
+
+#define pthread_cleanup_push(f, x)
+#define pthread_cleanup_pop(r)
+
+#ifdef _GNU_SOURCE
+struct cpu_set_t;
+int pthread_getaffinity_np(pthread_t, size_t, struct cpu_set_t*);
+int pthread_setaffinity_np(pthread_t, size_t, const struct cpu_set_t*);
+int pthread_getattr_np(pthread_t, pthread_attr_t*);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_PTHREAD_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/pwd.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/pwd.h
new file mode 100644
index 0000000..213eefa
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/pwd.h
@@ -0,0 +1,48 @@
+#ifndef SYSROOT_PWD_H_
+#define SYSROOT_PWD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+#define __NEED_uid_t
+#define __NEED_gid_t
+
+#ifdef _GNU_SOURCE
+#define __NEED_FILE
+#endif
+
+#include <bits/alltypes.h>
+
+struct passwd {
+ char* pw_name;
+ char* pw_passwd;
+ uid_t pw_uid;
+ gid_t pw_gid;
+ char* pw_gecos;
+ char* pw_dir;
+ char* pw_shell;
+};
+
+void setpwent(void);
+void endpwent(void);
+struct passwd* getpwent(void);
+
+struct passwd* getpwuid(uid_t);
+struct passwd* getpwnam(const char*);
+int getpwuid_r(uid_t, struct passwd*, char*, size_t, struct passwd**);
+int getpwnam_r(const char*, struct passwd*, char*, size_t, struct passwd**);
+
+#ifdef _GNU_SOURCE
+struct passwd* fgetpwent(FILE*);
+int putpwent(const struct passwd*, FILE*);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_PWD_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/regex.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/regex.h
new file mode 100644
index 0000000..53fac22
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/regex.h
@@ -0,0 +1,62 @@
+#ifndef SYSROOT_REGEX_H_
+#define SYSROOT_REGEX_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_regoff_t
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+typedef struct re_pattern_buffer {
+ size_t re_nsub;
+ void *__opaque, *__padding[4];
+ size_t __nsub2;
+ char __padding2;
+} regex_t;
+
+typedef struct {
+ regoff_t rm_so;
+ regoff_t rm_eo;
+} regmatch_t;
+
+#define REG_EXTENDED 1
+#define REG_ICASE 2
+#define REG_NEWLINE 4
+#define REG_NOSUB 8
+
+#define REG_NOTBOL 1
+#define REG_NOTEOL 2
+
+#define REG_OK 0
+#define REG_NOMATCH 1
+#define REG_BADPAT 2
+#define REG_ECOLLATE 3
+#define REG_ECTYPE 4
+#define REG_EESCAPE 5
+#define REG_ESUBREG 6
+#define REG_EBRACK 7
+#define REG_EPAREN 8
+#define REG_EBRACE 9
+#define REG_BADBR 10
+#define REG_ERANGE 11
+#define REG_ESPACE 12
+#define REG_BADRPT 13
+
+#define REG_ENOSYS -1
+
+int regcomp(regex_t* __restrict, const char* __restrict, int);
+int regexec(const regex_t* __restrict, const char* __restrict, size_t, regmatch_t* __restrict, int);
+void regfree(regex_t*);
+
+size_t regerror(int, const regex_t* __restrict, char* __restrict, size_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_REGEX_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/resolv.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/resolv.h
new file mode 100644
index 0000000..a90e0e8
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/resolv.h
@@ -0,0 +1,143 @@
+#ifndef SYSROOT_RESOLV_H_
+#define SYSROOT_RESOLV_H_
+
+#include <arpa/nameser.h>
+#include <netinet/in.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAXNS 3
+#define MAXDFLSRCH 3
+#define MAXDNSRCH 6
+#define LOCALDOMAINPARTS 2
+
+#define RES_TIMEOUT 5
+#define MAXRESOLVSORT 10
+#define RES_MAXNDOTS 15
+#define RES_MAXRETRANS 30
+#define RES_MAXRETRY 5
+#define RES_DFLRETRY 2
+#define RES_MAXTIME 65535
+
+/* unused; purely for broken apps */
+typedef struct __res_state {
+ int retrans;
+ int retry;
+ unsigned long options;
+ int nscount;
+ struct sockaddr_in nsaddr_list[MAXNS];
+#define nsaddr nsaddr_list[0]
+ unsigned short id;
+ char* dnsrch[MAXDNSRCH + 1];
+ char defdname[256];
+ unsigned long pfcode;
+ unsigned ndots : 4;
+ unsigned nsort : 4;
+ unsigned ipv6_unavail : 1;
+ unsigned unused : 23;
+ struct {
+ struct in_addr addr;
+ uint32_t mask;
+ } sort_list[MAXRESOLVSORT];
+ void* qhook;
+ void* rhook;
+ int res_h_errno;
+ int _vcsock;
+ unsigned _flags;
+ union {
+ char pad[52];
+ struct {
+ uint16_t nscount;
+ uint16_t nsmap[MAXNS];
+ int nssocks[MAXNS];
+ uint16_t nscount6;
+ uint16_t nsinit;
+ struct sockaddr_in6* nsaddrs[MAXNS];
+ unsigned int _initstamp[2];
+ } _ext;
+ } _u;
+} * res_state;
+
+#define __RES 19991006
+
+#ifndef _PATH_RESCONF
+#define _PATH_RESCONF "/etc/resolv.conf"
+#endif
+
+struct res_sym {
+ int number;
+ char* name;
+ char* humanname;
+};
+
+#define RES_F_VC 0x00000001
+#define RES_F_CONN 0x00000002
+#define RES_F_EDNS0ERR 0x00000004
+
+#define RES_EXHAUSTIVE 0x00000001
+
+#define RES_INIT 0x00000001
+#define RES_DEBUG 0x00000002
+#define RES_AAONLY 0x00000004
+#define RES_USEVC 0x00000008
+#define RES_PRIMARY 0x00000010
+#define RES_IGNTC 0x00000020
+#define RES_RECURSE 0x00000040
+#define RES_DEFNAMES 0x00000080
+#define RES_STAYOPEN 0x00000100
+#define RES_DNSRCH 0x00000200
+#define RES_INSECURE1 0x00000400
+#define RES_INSECURE2 0x00000800
+#define RES_NOALIASES 0x00001000
+#define RES_USE_INET6 0x00002000
+#define RES_ROTATE 0x00004000
+#define RES_NOCHECKNAME 0x00008000
+#define RES_KEEPTSIG 0x00010000
+#define RES_BLAST 0x00020000
+#define RES_USEBSTRING 0x00040000
+#define RES_NOIP6DOTINT 0x00080000
+#define RES_USE_EDNS0 0x00100000
+#define RES_SNGLKUP 0x00200000
+#define RES_SNGLKUPREOP 0x00400000
+#define RES_USE_DNSSEC 0x00800000
+
+#define RES_DEFAULT (RES_RECURSE | RES_DEFNAMES | RES_DNSRCH | RES_NOIP6DOTINT)
+
+#define RES_PRF_STATS 0x00000001
+#define RES_PRF_UPDATE 0x00000002
+#define RES_PRF_CLASS 0x00000004
+#define RES_PRF_CMD 0x00000008
+#define RES_PRF_QUES 0x00000010
+#define RES_PRF_ANS 0x00000020
+#define RES_PRF_AUTH 0x00000040
+#define RES_PRF_ADD 0x00000080
+#define RES_PRF_HEAD1 0x00000100
+#define RES_PRF_HEAD2 0x00000200
+#define RES_PRF_TTLID 0x00000400
+#define RES_PRF_HEADX 0x00000800
+#define RES_PRF_QUERY 0x00001000
+#define RES_PRF_REPLY 0x00002000
+#define RES_PRF_INIT 0x00004000
+
+struct __res_state* __res_state(void);
+#define _res (*__res_state())
+
+int res_init(void);
+int res_query(const char*, int, int, unsigned char*, int);
+int res_querydomain(const char*, const char*, int, int, unsigned char*, int);
+int res_search(const char*, int, int, unsigned char*, int);
+int res_mkquery(int, const char*, int, int, const unsigned char*, int, const unsigned char*,
+ unsigned char*, int);
+int res_send(const unsigned char*, int, unsigned char*, int);
+int dn_comp(const char*, unsigned char*, int, unsigned char**, unsigned char**);
+int dn_expand(const unsigned char*, const unsigned char*, const unsigned char*, char*, int);
+int dn_skipname(const unsigned char*, const unsigned char*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_RESOLV_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sched.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sched.h
new file mode 100644
index 0000000..ac06166
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sched.h
@@ -0,0 +1,110 @@
+#ifndef SYSROOT_SCHED_H_
+#define SYSROOT_SCHED_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_struct_timespec
+#define __NEED_pid_t
+#define __NEED_time_t
+
+#ifdef _GNU_SOURCE
+#define __NEED_size_t
+#endif
+
+#include <bits/alltypes.h>
+
+struct sched_param {
+ int sched_priority;
+ int sched_ss_low_priority;
+ struct timespec sched_ss_repl_period;
+ struct timespec sched_ss_init_budget;
+ int sched_ss_max_repl;
+};
+
+int sched_get_priority_max(int);
+int sched_get_priority_min(int);
+int sched_getparam(pid_t, struct sched_param*);
+int sched_getscheduler(pid_t);
+int sched_rr_get_interval(pid_t, struct timespec*);
+int sched_setparam(pid_t, const struct sched_param*);
+int sched_setscheduler(pid_t, int, const struct sched_param*);
+int sched_yield(void);
+
+#define SCHED_OTHER 0
+#define SCHED_FIFO 1
+#define SCHED_RR 2
+#define SCHED_BATCH 3
+#define SCHED_IDLE 5
+#define SCHED_DEADLINE 6
+#define SCHED_RESET_ON_FORK 0x40000000
+
+#ifdef _GNU_SOURCE
+void* memcpy(void* __restrict, const void* __restrict, size_t);
+int memcmp(const void*, const void*, size_t);
+void* calloc(size_t, size_t);
+void free(void*);
+
+typedef struct cpu_set_t {
+ unsigned long __bits[128 / sizeof(long)];
+} cpu_set_t;
+int __sched_cpucount(size_t, const cpu_set_t*);
+int sched_getcpu(void);
+int sched_getaffinity(pid_t, size_t, cpu_set_t*);
+int sched_setaffinity(pid_t, size_t, const cpu_set_t*);
+
+#define __CPU_op_S(i, size, set, op) \
+ ((i) / 8U >= (size) \
+ ? 0 \
+ : ((set)->__bits[(i) / 8 / sizeof(long)] op(1UL << ((i) % (8 * sizeof(long))))))
+
+#define CPU_SET_S(i, size, set) __CPU_op_S(i, size, set, |=)
+#define CPU_CLR_S(i, size, set) __CPU_op_S(i, size, set, &= ~)
+#define CPU_ISSET_S(i, size, set) __CPU_op_S(i, size, set, &)
+
+#define __CPU_op_func_S(func, op) \
+ static __inline void __CPU_##func##_S(size_t __size, cpu_set_t* __dest, const cpu_set_t* __src1, \
+ const cpu_set_t* __src2) { \
+ size_t __i; \
+ for (__i = 0; __i < __size / sizeof(long); __i++) \
+ __dest->__bits[__i] = __src1->__bits[__i] op __src2->__bits[__i]; \
+ }
+
+__CPU_op_func_S(AND, &) __CPU_op_func_S(OR, |) __CPU_op_func_S(XOR, ^)
+
+#define CPU_AND_S(a, b, c, d) __CPU_AND_S(a, b, c, d)
+#define CPU_OR_S(a, b, c, d) __CPU_OR_S(a, b, c, d)
+#define CPU_XOR_S(a, b, c, d) __CPU_XOR_S(a, b, c, d)
+
+#define CPU_COUNT_S(size, set) __sched_cpucount(size, set)
+#define CPU_ZERO_S(size, set) memset(set, 0, size)
+#define CPU_EQUAL_S(size, set1, set2) (!memcmp(set1, set2, size))
+
+#define CPU_ALLOC_SIZE(n) \
+ (sizeof(long) * ((n) / (8 * sizeof(long)) + \
+ ((n) % (8 * sizeof(long)) + 8 * sizeof(long) - 1) / (8 * sizeof(long))))
+#define CPU_ALLOC(n) ((cpu_set_t*)calloc(1, CPU_ALLOC_SIZE(n)))
+#define CPU_FREE(set) free(set)
+
+#define CPU_SETSIZE 128
+
+#define CPU_SET(i, set) CPU_SET_S(i, sizeof(cpu_set_t), set)
+#define CPU_CLR(i, set) CPU_CLR_S(i, sizeof(cpu_set_t), set)
+#define CPU_ISSET(i, set) CPU_ISSET_S(i, sizeof(cpu_set_t), set)
+#define CPU_AND(d, s1, s2) CPU_AND_S(sizeof(cpu_set_t), d, s1, s2)
+#define CPU_OR(d, s1, s2) CPU_OR_S(sizeof(cpu_set_t), d, s1, s2)
+#define CPU_XOR(d, s1, s2) CPU_XOR_S(sizeof(cpu_set_t), d, s1, s2)
+#define CPU_COUNT(set) CPU_COUNT_S(sizeof(cpu_set_t), set)
+#define CPU_ZERO(set) CPU_ZERO_S(sizeof(cpu_set_t), set)
+#define CPU_EQUAL(s1, s2) CPU_EQUAL_S(sizeof(cpu_set_t), s1, s2)
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SCHED_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/search.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/search.h
new file mode 100644
index 0000000..5348eab
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/search.h
@@ -0,0 +1,61 @@
+#ifndef SYSROOT_SEARCH_H_
+#define SYSROOT_SEARCH_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+#include <bits/alltypes.h>
+
+typedef enum { FIND, ENTER } ACTION;
+typedef enum { preorder, postorder, endorder, leaf } VISIT;
+
+typedef struct entry {
+ char* key;
+ void* data;
+} ENTRY;
+
+int hcreate(size_t);
+void hdestroy(void);
+ENTRY* hsearch(ENTRY, ACTION);
+
+#ifdef _GNU_SOURCE
+struct hsearch_data {
+ struct __tab* __tab;
+ unsigned int __unused1;
+ unsigned int __unused2;
+};
+
+int hcreate_r(size_t, struct hsearch_data*);
+void hdestroy_r(struct hsearch_data*);
+int hsearch_r(ENTRY, ACTION, ENTRY**, struct hsearch_data*);
+#endif
+
+void insque(void*, void*);
+void remque(void*);
+
+void* lsearch(const void*, void*, size_t*, size_t, int (*)(const void*, const void*));
+void* lfind(const void*, const void*, size_t*, size_t, int (*)(const void*, const void*));
+
+void* tdelete(const void* __restrict, void** __restrict, int (*)(const void*, const void*));
+void* tfind(const void*, void* const*, int (*)(const void*, const void*));
+void* tsearch(const void*, void**, int (*)(const void*, const void*));
+void twalk(const void*, void (*)(const void*, VISIT, int));
+
+#ifdef _GNU_SOURCE
+struct qelem {
+ struct qelem *q_forw, *q_back;
+ char q_data[1];
+};
+
+void tdestroy(void*, void (*)(void*));
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SEARCH_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/semaphore.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/semaphore.h
new file mode 100644
index 0000000..d9e996e
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/semaphore.h
@@ -0,0 +1,34 @@
+#ifndef SYSROOT_SEMAPHORE_H_
+#define SYSROOT_SEMAPHORE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_sem_t
+#define __NEED_time_t
+#define __NEED_struct_timespec
+#include <fcntl.h>
+
+#include <bits/alltypes.h>
+
+#define SEM_FAILED ((sem_t*)0)
+
+int sem_close(sem_t*);
+int sem_destroy(sem_t*);
+int sem_getvalue(sem_t* __restrict, int* __restrict);
+int sem_init(sem_t*, int, unsigned);
+sem_t* sem_open(const char*, int, ...);
+int sem_post(sem_t*);
+int sem_timedwait(sem_t* __restrict, const struct timespec* __restrict);
+int sem_trywait(sem_t*);
+int sem_unlink(const char*);
+int sem_wait(sem_t*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SEMAPHORE_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/setjmp.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/setjmp.h
new file mode 100644
index 0000000..65971b7
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/setjmp.h
@@ -0,0 +1,39 @@
+#ifndef SYSROOT_SETJMP_H_
+#define SYSROOT_SETJMP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <bits/setjmp.h>
+
+typedef struct __jmp_buf_tag {
+ __jmp_buf __jb;
+ unsigned long __fl;
+ unsigned long __ss[128 / sizeof(long)];
+} jmp_buf[1];
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+typedef jmp_buf sigjmp_buf;
+int sigsetjmp(sigjmp_buf, int);
+_Noreturn void siglongjmp(sigjmp_buf, int);
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+int _setjmp(jmp_buf);
+_Noreturn void _longjmp(jmp_buf, int);
+#endif
+
+int setjmp(jmp_buf);
+_Noreturn void longjmp(jmp_buf, int);
+
+#define setjmp setjmp
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SETJMP_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/signal.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/signal.h
new file mode 100644
index 0000000..594cf80
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/signal.h
@@ -0,0 +1,263 @@
+#ifndef SYSROOT_SIGNAL_H_
+#define SYSROOT_SIGNAL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#ifdef _GNU_SOURCE
+#define __ucontext ucontext
+#endif
+
+#define __NEED_size_t
+#define __NEED_pid_t
+#define __NEED_uid_t
+#define __NEED_struct_timespec
+#define __NEED_pthread_t
+#define __NEED_pthread_attr_t
+#define __NEED_time_t
+#define __NEED_clock_t
+#define __NEED_sigset_t
+
+#include <bits/alltypes.h>
+
+#define SIG_BLOCK 0
+#define SIG_UNBLOCK 1
+#define SIG_SETMASK 2
+
+#define SI_ASYNCNL (-60)
+#define SI_TKILL (-6)
+#define SI_SIGIO (-5)
+#define SI_ASYNCIO (-4)
+#define SI_MESGQ (-3)
+#define SI_TIMER (-2)
+#define SI_QUEUE (-1)
+#define SI_USER 0
+#define SI_KERNEL 128
+
+typedef struct sigaltstack stack_t;
+
+#endif
+
+#include <bits/signal.h>
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#define SIG_HOLD ((void (*)(int))2)
+
+#define FPE_INTDIV 1
+#define FPE_INTOVF 2
+#define FPE_FLTDIV 3
+#define FPE_FLTOVF 4
+#define FPE_FLTUND 5
+#define FPE_FLTRES 6
+#define FPE_FLTINV 7
+#define FPE_FLTSUB 8
+
+#define ILL_ILLOPC 1
+#define ILL_ILLOPN 2
+#define ILL_ILLADR 3
+#define ILL_ILLTRP 4
+#define ILL_PRVOPC 5
+#define ILL_PRVREG 6
+#define ILL_COPROC 7
+#define ILL_BADSTK 8
+
+#define SEGV_MAPERR 1
+#define SEGV_ACCERR 2
+#define SEGV_BNDERR 3
+
+#define BUS_ADRALN 1
+#define BUS_ADRERR 2
+#define BUS_OBJERR 3
+#define BUS_MCEERR_AR 4
+#define BUS_MCEERR_AO 5
+
+#define CLD_EXITED 1
+#define CLD_KILLED 2
+#define CLD_DUMPED 3
+#define CLD_TRAPPED 4
+#define CLD_STOPPED 5
+#define CLD_CONTINUED 6
+
+union sigval {
+ int sival_int;
+ void* sival_ptr;
+};
+
+typedef struct {
+#ifdef __SI_SWAP_ERRNO_CODE
+ int si_signo, si_code, si_errno;
+#else
+ int si_signo, si_errno, si_code;
+#endif
+ union {
+ char __pad[128 - 2 * sizeof(int) - sizeof(long)];
+ struct {
+ union {
+ struct {
+ pid_t si_pid;
+ uid_t si_uid;
+ } __piduid;
+ struct {
+ int si_timerid;
+ int si_overrun;
+ } __timer;
+ } __first;
+ union {
+ union sigval si_value;
+ struct {
+ int si_status;
+ clock_t si_utime, si_stime;
+ } __sigchld;
+ } __second;
+ } __si_common;
+ struct {
+ void* si_addr;
+ short si_addr_lsb;
+ struct {
+ void* si_lower;
+ void* si_upper;
+ } __addr_bnd;
+ } __sigfault;
+ struct {
+ long si_band;
+ int si_fd;
+ } __sigpoll;
+ struct {
+ void* si_call_addr;
+ int si_syscall;
+ unsigned si_arch;
+ } __sigsys;
+ } __si_fields;
+} siginfo_t;
+#define si_pid __si_fields.__si_common.__first.__piduid.si_pid
+#define si_uid __si_fields.__si_common.__first.__piduid.si_uid
+#define si_status __si_fields.__si_common.__second.__sigchld.si_status
+#define si_utime __si_fields.__si_common.__second.__sigchld.si_utime
+#define si_stime __si_fields.__si_common.__second.__sigchld.si_stime
+#define si_value __si_fields.__si_common.__second.si_value
+#define si_addr __si_fields.__sigfault.si_addr
+#define si_addr_lsb __si_fields.__sigfault.si_addr_lsb
+#define si_lower __si_fields.__sigfault.__addr_bnd.si_lower
+#define si_upper __si_fields.__sigfault.__addr_bnd.si_upper
+#define si_band __si_fields.__sigpoll.si_band
+#define si_fd __si_fields.__sigpoll.si_fd
+#define si_timerid __si_fields.__si_common.__first.__timer.si_timerid
+#define si_overrun __si_fields.__si_common.__first.__timer.si_overrun
+#define si_ptr si_value.sival_ptr
+#define si_int si_value.sival_int
+#define si_call_addr __si_fields.__sigsys.si_call_addr
+#define si_syscall __si_fields.__sigsys.si_syscall
+#define si_arch __si_fields.__sigsys.si_arch
+
+struct sigaction {
+ union {
+ void (*sa_handler)(int);
+ void (*sa_sigaction)(int, siginfo_t*, void*);
+ } __sa_handler;
+ sigset_t sa_mask;
+ int sa_flags;
+ void (*sa_restorer)(void);
+};
+#define sa_handler __sa_handler.sa_handler
+#define sa_sigaction __sa_handler.sa_sigaction
+
+struct sigevent {
+ union sigval sigev_value;
+ int sigev_signo;
+ int sigev_notify;
+ void (*sigev_notify_function)(union sigval);
+ pthread_attr_t* sigev_notify_attributes;
+ char __pad[56 - 3 * sizeof(long)];
+};
+
+#define SIGEV_SIGNAL 0
+#define SIGEV_NONE 1
+#define SIGEV_THREAD 2
+
+int __libc_current_sigrtmin(void);
+int __libc_current_sigrtmax(void);
+
+#define SIGRTMIN (__libc_current_sigrtmin())
+#define SIGRTMAX (__libc_current_sigrtmax())
+
+int kill(pid_t, int);
+
+int sigemptyset(sigset_t*);
+int sigfillset(sigset_t*);
+int sigaddset(sigset_t*, int);
+int sigdelset(sigset_t*, int);
+int sigismember(const sigset_t*, int);
+
+int sigprocmask(int, const sigset_t* __restrict, sigset_t* __restrict);
+int sigsuspend(const sigset_t*);
+int sigaction(int, const struct sigaction* __restrict, struct sigaction* __restrict);
+int sigpending(sigset_t*);
+int sigwait(const sigset_t* __restrict, int* __restrict);
+int sigwaitinfo(const sigset_t* __restrict, siginfo_t* __restrict);
+int sigtimedwait(const sigset_t* __restrict, siginfo_t* __restrict,
+ const struct timespec* __restrict);
+int sigqueue(pid_t, int, const union sigval);
+
+int pthread_sigmask(int, const sigset_t* __restrict, sigset_t* __restrict);
+int pthread_kill(pthread_t, int);
+
+void psiginfo(const siginfo_t*, const char*);
+void psignal(int, const char*);
+
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+int killpg(pid_t, int);
+int sigaltstack(const stack_t* __restrict, stack_t* __restrict);
+int siginterrupt(int, int);
+int sigpause(int);
+#define TRAP_BRKPT 1
+#define TRAP_TRACE 2
+#define POLL_IN 1
+#define POLL_OUT 2
+#define POLL_MSG 3
+#define POLL_ERR 4
+#define POLL_PRI 5
+#define POLL_HUP 6
+#define SS_ONSTACK 1
+#define SS_DISABLE 2
+#endif
+
+#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+#define NSIG _NSIG
+typedef void (*sig_t)(int);
+#endif
+
+#ifdef _GNU_SOURCE
+typedef void (*sighandler_t)(int);
+void (*bsd_signal(int, void (*)(int)))(int);
+int sigisemptyset(const sigset_t*);
+int sigorset(sigset_t*, const sigset_t*, const sigset_t*);
+int sigandset(sigset_t*, const sigset_t*, const sigset_t*);
+
+#define SA_NOMASK SA_NODEFER
+#define SA_ONESHOT SA_RESETHAND
+#endif
+
+#define SIG_ERR ((void (*)(int)) - 1)
+#define SIG_DFL ((void (*)(int))0)
+#define SIG_IGN ((void (*)(int))1)
+
+typedef int sig_atomic_t;
+
+void (*signal(int, void (*)(int)))(int);
+int raise(int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SIGNAL_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/spawn.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/spawn.h
new file mode 100644
index 0000000..1c70bb2
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/spawn.h
@@ -0,0 +1,79 @@
+#ifndef SYSROOT_SPAWN_H_
+#define SYSROOT_SPAWN_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_mode_t
+#define __NEED_pid_t
+#define __NEED_sigset_t
+
+#include <bits/alltypes.h>
+
+struct sched_param;
+
+#define POSIX_SPAWN_RESETIDS 1
+#define POSIX_SPAWN_SETPGROUP 2
+#define POSIX_SPAWN_SETSIGDEF 4
+#define POSIX_SPAWN_SETSIGMASK 8
+#define POSIX_SPAWN_SETSCHEDPARAM 16
+#define POSIX_SPAWN_SETSCHEDULER 32
+
+typedef struct {
+ int __flags;
+ pid_t __pgrp;
+ sigset_t __def, __mask;
+ int __prio, __pol, __pad[16];
+} posix_spawnattr_t;
+
+typedef struct {
+ int __pad0[2];
+ void* __actions;
+ int __pad[16];
+} posix_spawn_file_actions_t;
+
+int posix_spawn(pid_t* __restrict, const char* __restrict, const posix_spawn_file_actions_t*,
+ const posix_spawnattr_t* __restrict, char* const* __restrict,
+ char* const* __restrict);
+int posix_spawnp(pid_t* __restrict, const char* __restrict, const posix_spawn_file_actions_t*,
+ const posix_spawnattr_t* __restrict, char* const* __restrict,
+ char* const* __restrict);
+
+int posix_spawnattr_init(posix_spawnattr_t*);
+int posix_spawnattr_destroy(posix_spawnattr_t*);
+
+int posix_spawnattr_setflags(posix_spawnattr_t*, short);
+int posix_spawnattr_getflags(const posix_spawnattr_t* __restrict, short* __restrict);
+
+int posix_spawnattr_setpgroup(posix_spawnattr_t*, pid_t);
+int posix_spawnattr_getpgroup(const posix_spawnattr_t* __restrict, pid_t* __restrict);
+
+int posix_spawnattr_setsigmask(posix_spawnattr_t* __restrict, const sigset_t* __restrict);
+int posix_spawnattr_getsigmask(const posix_spawnattr_t* __restrict, sigset_t* __restrict);
+
+int posix_spawnattr_setsigdefault(posix_spawnattr_t* __restrict, const sigset_t* __restrict);
+int posix_spawnattr_getsigdefault(const posix_spawnattr_t* __restrict, sigset_t* __restrict);
+
+int posix_spawnattr_setschedparam(posix_spawnattr_t* __restrict,
+ const struct sched_param* __restrict);
+int posix_spawnattr_getschedparam(const posix_spawnattr_t* __restrict,
+ struct sched_param* __restrict);
+int posix_spawnattr_setschedpolicy(posix_spawnattr_t*, int);
+int posix_spawnattr_getschedpolicy(const posix_spawnattr_t* __restrict, int* __restrict);
+
+int posix_spawn_file_actions_init(posix_spawn_file_actions_t*);
+int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t*);
+
+int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t* __restrict, int,
+ const char* __restrict, int, mode_t);
+int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t*, int);
+int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t*, int, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SPAWN_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/stdio.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/stdio.h
new file mode 100644
index 0000000..c08aba0
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/stdio.h
@@ -0,0 +1,185 @@
+#ifndef SYSROOT_STDIO_H_
+#define SYSROOT_STDIO_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __printflike(__fmt, __varargs) __attribute__((__format__(__printf__, __fmt, __varargs)))
+#define __scanflike(__fmt, __varargs) __attribute__((__format__(__scanf__, __fmt, __varargs)))
+
+#define __NEED_FILE
+#define __NEED___isoc_va_list
+#define __NEED_size_t
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __NEED_ssize_t
+#define __NEED_off_t
+#define __NEED_va_list
+#endif
+
+#include <bits/alltypes.h>
+#include <bits/null.h>
+
+#undef EOF
+#define EOF (-1)
+
+#undef SEEK_SET
+#undef SEEK_CUR
+#undef SEEK_END
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
+#define _IOFBF 0
+#define _IOLBF 1
+#define _IONBF 2
+
+#define BUFSIZ 1024
+#define FILENAME_MAX 4096
+#define FOPEN_MAX 1000
+#define TMP_MAX 10000
+#define L_tmpnam 20
+
+typedef union _G_fpos64_t {
+ char __opaque[16];
+ double __align;
+} fpos_t;
+
+extern FILE* const stdin;
+extern FILE* const stdout;
+extern FILE* const stderr;
+
+#define stdin (stdin)
+#define stdout (stdout)
+#define stderr (stderr)
+
+FILE* fopen(const char* __restrict, const char* __restrict);
+FILE* freopen(const char* __restrict, const char* __restrict, FILE* __restrict);
+int fclose(FILE*);
+
+int remove(const char*);
+int rename(const char*, const char*);
+
+int feof(FILE*);
+int ferror(FILE*);
+int fflush(FILE*);
+void clearerr(FILE*);
+
+int fseek(FILE*, long, int);
+long ftell(FILE*);
+void rewind(FILE*);
+
+int fgetpos(FILE* __restrict, fpos_t* __restrict);
+int fsetpos(FILE*, const fpos_t*);
+
+size_t fread(void* __restrict, size_t, size_t, FILE* __restrict);
+size_t fwrite(const void* __restrict, size_t, size_t, FILE* __restrict);
+
+int fgetc(FILE*);
+int getc(FILE*);
+int getchar(void);
+int ungetc(int, FILE*);
+
+int fputc(int, FILE*);
+int putc(int, FILE*);
+int putchar(int);
+
+char* fgets(char* __restrict, int, FILE* __restrict);
+#if __STDC_VERSION__ < 201112L
+char* gets(char*);
+#endif
+
+int fputs(const char* __restrict, FILE* __restrict);
+int puts(const char*);
+
+int printf(const char* __restrict, ...) __printflike(1, 2);
+int fprintf(FILE* __restrict, const char* __restrict, ...) __printflike(2, 3);
+int sprintf(char* __restrict, const char* __restrict, ...) __printflike(2, 3);
+int snprintf(char* __restrict, size_t, const char* __restrict, ...) __printflike(3, 4);
+
+int vprintf(const char* __restrict, __isoc_va_list) __printflike(1, 0);
+int vfprintf(FILE* __restrict, const char* __restrict, __isoc_va_list) __printflike(2, 0);
+int vsprintf(char* __restrict, const char* __restrict, __isoc_va_list) __printflike(2, 0);
+int vsnprintf(char* __restrict, size_t, const char* __restrict, __isoc_va_list) __printflike(3, 0);
+
+int scanf(const char* __restrict, ...) __scanflike(1, 2);
+int fscanf(FILE* __restrict, const char* __restrict, ...) __scanflike(2, 3);
+int sscanf(const char* __restrict, const char* __restrict, ...) __scanflike(2, 3);
+int vscanf(const char* __restrict, __isoc_va_list) __scanflike(1, 0);
+int vfscanf(FILE* __restrict, const char* __restrict, __isoc_va_list) __scanflike(2, 0);
+int vsscanf(const char* __restrict, const char* __restrict, __isoc_va_list) __scanflike(2, 0);
+
+void perror(const char*);
+
+int setvbuf(FILE* __restrict, char* __restrict, int, size_t);
+void setbuf(FILE* __restrict, char* __restrict);
+
+char* tmpnam(char*);
+FILE* tmpfile(void);
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+FILE* fmemopen(void* __restrict, size_t, const char* __restrict);
+FILE* open_memstream(char**, size_t*);
+FILE* fdopen(int, const char*);
+FILE* popen(const char*, const char*);
+int pclose(FILE*);
+int fileno(FILE*);
+int fseeko(FILE*, off_t, int);
+off_t ftello(FILE*);
+int dprintf(int, const char* __restrict, ...) __printflike(2, 3);
+int vdprintf(int, const char* __restrict, __isoc_va_list) __printflike(2, 0);
+void flockfile(FILE*);
+int ftrylockfile(FILE*);
+void funlockfile(FILE*);
+int getc_unlocked(FILE*);
+int getchar_unlocked(void);
+int putc_unlocked(int, FILE*);
+int putchar_unlocked(int);
+ssize_t getdelim(char** __restrict, size_t* __restrict, int, FILE* __restrict);
+ssize_t getline(char** __restrict, size_t* __restrict, FILE* __restrict);
+int renameat(int, const char*, int, const char*);
+char* ctermid(char*);
+#define L_ctermid 20
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define P_tmpdir "/tmp"
+char* tempnam(const char*, const char*);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define L_cuserid 20
+char* cuserid(char*);
+void setlinebuf(FILE*);
+void setbuffer(FILE*, char*, size_t);
+int fgetc_unlocked(FILE*);
+int fputc_unlocked(int, FILE*);
+int fflush_unlocked(FILE*);
+size_t fread_unlocked(void*, size_t, size_t, FILE*);
+size_t fwrite_unlocked(const void*, size_t, size_t, FILE*);
+void clearerr_unlocked(FILE*);
+int feof_unlocked(FILE*);
+int ferror_unlocked(FILE*);
+int fileno_unlocked(FILE*);
+int getw(FILE*);
+int putw(int, FILE*);
+char* fgetln(FILE*, size_t*);
+int asprintf(char**, const char*, ...) __printflike(2, 3);
+int vasprintf(char**, const char*, __isoc_va_list) __printflike(2, 0);
+#endif
+
+#ifdef _GNU_SOURCE
+char* fgets_unlocked(char*, int, FILE*);
+int fputs_unlocked(const char*, FILE*);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_STDIO_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/stdlib.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/stdlib.h
new file mode 100644
index 0000000..862c83f
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/stdlib.h
@@ -0,0 +1,157 @@
+#ifndef SYSROOT_STDLIB_H_
+#define SYSROOT_STDLIB_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <bits/null.h>
+
+#define __NEED_size_t
+#define __NEED_wchar_t
+
+#include <bits/alltypes.h>
+
+int atoi(const char*);
+long atol(const char*);
+long long atoll(const char*);
+double atof(const char*);
+
+float strtof(const char* __restrict, char** __restrict);
+double strtod(const char* __restrict, char** __restrict);
+long double strtold(const char* __restrict, char** __restrict);
+
+long strtol(const char* __restrict, char** __restrict, int);
+unsigned long strtoul(const char* __restrict, char** __restrict, int);
+long long strtoll(const char* __restrict, char** __restrict, int);
+unsigned long long strtoull(const char* __restrict, char** __restrict, int);
+
+int rand(void);
+void srand(unsigned);
+
+void* malloc(size_t);
+void* calloc(size_t, size_t);
+void* realloc(void*, size_t);
+void free(void*);
+void* aligned_alloc(size_t alignment, size_t size);
+
+_Noreturn void abort(void);
+int atexit(void (*)(void));
+_Noreturn void exit(int);
+_Noreturn void _Exit(int);
+int at_quick_exit(void (*)(void));
+_Noreturn void quick_exit(int);
+
+char* getenv(const char*);
+
+int system(const char*);
+
+void* bsearch(const void*, const void*, size_t, size_t, int (*)(const void*, const void*));
+void qsort(void*, size_t, size_t, int (*)(const void*, const void*));
+
+int abs(int);
+long labs(long);
+long long llabs(long long);
+
+typedef struct {
+ int quot, rem;
+} div_t;
+typedef struct {
+ long quot, rem;
+} ldiv_t;
+typedef struct {
+ long long quot, rem;
+} lldiv_t;
+
+div_t div(int, int);
+ldiv_t ldiv(long, long);
+lldiv_t lldiv(long long, long long);
+
+int mblen(const char*, size_t);
+int mbtowc(wchar_t* __restrict, const char* __restrict, size_t);
+int wctomb(char*, wchar_t);
+size_t mbstowcs(wchar_t* __restrict, const char* __restrict, size_t);
+size_t wcstombs(char* __restrict, const wchar_t* __restrict, size_t);
+
+#define EXIT_FAILURE 1
+#define EXIT_SUCCESS 0
+
+size_t __ctype_get_mb_cur_max(void);
+#define MB_CUR_MAX (__ctype_get_mb_cur_max())
+
+#define RAND_MAX (0x7fffffff)
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#define WNOHANG 1
+#define WUNTRACED 2
+
+#define WEXITSTATUS(s) (((s)&0xff00) >> 8)
+#define WTERMSIG(s) ((s)&0x7f)
+#define WSTOPSIG(s) WEXITSTATUS(s)
+#define WIFEXITED(s) (!WTERMSIG(s))
+#define WIFSTOPPED(s) ((short)((((s)&0xffff) * 0x10001) >> 8) > 0x7f00)
+#define WIFSIGNALED(s) (((s)&0xffff) - 1U < 0xffu)
+
+int posix_memalign(void**, size_t, size_t);
+int setenv(const char*, const char*, int);
+int unsetenv(const char*);
+int mkstemp(char*);
+int mkostemp(char*, int);
+char* mkdtemp(char*);
+int getsubopt(char**, char* const*, char**);
+int rand_r(unsigned*);
+
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+char* realpath(const char* __restrict, char* __restrict);
+long int random(void);
+void srandom(unsigned int);
+char* initstate(unsigned int, char*, size_t);
+char* setstate(char*);
+int putenv(char*);
+int posix_openpt(int);
+int grantpt(int);
+int unlockpt(int);
+char* ptsname(int);
+long a64l(const char*);
+void setkey(const char*);
+double drand48(void);
+double erand48(unsigned short[3]);
+long int lrand48(void);
+long int nrand48(unsigned short[3]);
+long mrand48(void);
+long jrand48(unsigned short[3]);
+void srand48(long);
+unsigned short* seed48(unsigned short[3]);
+void lcong48(unsigned short[7]);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#include <alloca.h>
+char* mktemp(char*);
+int mkstemps(char*, int);
+int mkostemps(char*, int, int);
+void* valloc(size_t);
+void* memalign(size_t, size_t);
+int clearenv(void);
+#define WCOREDUMP(s) ((s)&0x80)
+#define WIFCONTINUED(s) ((s) == 0xffff)
+#endif
+
+#ifdef _GNU_SOURCE
+int ptsname_r(int, char*, size_t);
+char* ecvt(double, int, int*, int*);
+char* fcvt(double, int, int*, int*);
+char* gcvt(double, int, char*);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_STDLIB_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/string.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/string.h
new file mode 100644
index 0000000..0265b57
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/string.h
@@ -0,0 +1,90 @@
+#ifndef SYSROOT_STRING_H_
+#define SYSROOT_STRING_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <bits/null.h>
+
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+void* memcpy(void* __restrict, const void* __restrict, size_t);
+void* memmove(void*, const void*, size_t);
+void* memset(void*, int, size_t);
+int memcmp(const void*, const void*, size_t);
+void* memchr(const void*, int, size_t);
+
+char* strcpy(char* __restrict, const char* __restrict);
+char* strncpy(char* __restrict, const char* __restrict, size_t);
+
+char* strcat(char* __restrict, const char* __restrict);
+char* strncat(char* __restrict, const char* __restrict, size_t);
+
+int strcmp(const char*, const char*);
+int strncmp(const char*, const char*, size_t);
+
+int strcoll(const char*, const char*);
+size_t strxfrm(char* __restrict, const char* __restrict, size_t);
+
+char* strchr(const char*, int);
+char* strrchr(const char*, int);
+
+size_t strcspn(const char*, const char*);
+size_t strspn(const char*, const char*);
+char* strpbrk(const char*, const char*);
+char* strstr(const char*, const char*);
+char* strtok(char* __restrict, const char* __restrict);
+
+size_t strlen(const char*);
+
+char* strerror(int);
+
+#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+#include <strings.h>
+#endif
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+char* strtok_r(char* __restrict, const char* __restrict, char** __restrict);
+int strerror_r(int, char*, size_t);
+char* stpcpy(char* __restrict, const char* __restrict);
+char* stpncpy(char* __restrict, const char* __restrict, size_t);
+size_t strnlen(const char*, size_t);
+char* strdup(const char*);
+char* strndup(const char*, size_t);
+char* strsignal(int);
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+void* memccpy(void* __restrict, const void* __restrict, int, size_t);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+char* strsep(char**, const char*);
+size_t strlcat(char*, const char*, size_t);
+size_t strlcpy(char*, const char*, size_t);
+#endif
+
+#ifdef _GNU_SOURCE
+#define strdupa(x) strcpy(alloca(strlen(x) + 1), x)
+int strverscmp(const char*, const char*);
+char* strchrnul(const char*, int);
+char* strcasestr(const char*, const char*);
+void* memmem(const void*, size_t, const void*, size_t);
+void* memrchr(const void*, int, size_t);
+void* mempcpy(void*, const void*, size_t);
+#ifndef __cplusplus
+char* basename(char*);
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_STRING_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/strings.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/strings.h
new file mode 100644
index 0000000..eb703d1
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/strings.h
@@ -0,0 +1,38 @@
+#ifndef SYSROOT_STRINGS_H_
+#define SYSROOT_STRINGS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_size_t
+#define __NEED_locale_t
+#include <bits/alltypes.h>
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_POSIX_SOURCE) || \
+ (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE + 0 < 200809L) || \
+ (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE + 0 < 700)
+int bcmp(const void*, const void*, size_t);
+void bcopy(const void*, void*, size_t);
+void bzero(void*, size_t);
+char* index(const char*, int);
+char* rindex(const char*, int);
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+int ffs(int);
+int ffsl(long);
+int ffsll(long long);
+#endif
+
+int strcasecmp(const char*, const char*);
+int strncasecmp(const char*, const char*, size_t);
+
+int strcasecmp_l(const char*, const char*, locale_t);
+int strncasecmp_l(const char*, const char*, size_t, locale_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_STRINGS_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/stropts.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/stropts.h
new file mode 100644
index 0000000..92eb968
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/stropts.h
@@ -0,0 +1,139 @@
+#ifndef SYSROOT_STROPTS_H_
+#define SYSROOT_STROPTS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __SID ('S' << 8)
+
+#define I_NREAD (__SID | 1)
+#define I_PUSH (__SID | 2)
+#define I_POP (__SID | 3)
+#define I_LOOK (__SID | 4)
+#define I_FLUSH (__SID | 5)
+#define I_SRDOPT (__SID | 6)
+#define I_GRDOPT (__SID | 7)
+#define I_STR (__SID | 8)
+#define I_SETSIG (__SID | 9)
+#define I_GETSIG (__SID | 10)
+#define I_FIND (__SID | 11)
+#define I_LINK (__SID | 12)
+#define I_UNLINK (__SID | 13)
+#define I_PEEK (__SID | 15)
+#define I_FDINSERT (__SID | 16)
+#define I_SENDFD (__SID | 17)
+#define I_RECVFD (__SID | 14)
+#define I_SWROPT (__SID | 19)
+#define I_GWROPT (__SID | 20)
+#define I_LIST (__SID | 21)
+#define I_PLINK (__SID | 22)
+#define I_PUNLINK (__SID | 23)
+#define I_FLUSHBAND (__SID | 28)
+#define I_CKBAND (__SID | 29)
+#define I_GETBAND (__SID | 30)
+#define I_ATMARK (__SID | 31)
+#define I_SETCLTIME (__SID | 32)
+#define I_GETCLTIME (__SID | 33)
+#define I_CANPUT (__SID | 34)
+
+#define FMNAMESZ 8
+
+#define FLUSHR 0x01
+#define FLUSHW 0x02
+#define FLUSHRW 0x03
+#define FLUSHBAND 0x04
+
+#define S_INPUT 0x0001
+#define S_HIPRI 0x0002
+#define S_OUTPUT 0x0004
+#define S_MSG 0x0008
+#define S_ERROR 0x0010
+#define S_HANGUP 0x0020
+#define S_RDNORM 0x0040
+#define S_WRNORM S_OUTPUT
+#define S_RDBAND 0x0080
+#define S_WRBAND 0x0100
+#define S_BANDURG 0x0200
+
+#define RS_HIPRI 0x01
+
+#define RNORM 0x0000
+#define RMSGD 0x0001
+#define RMSGN 0x0002
+#define RPROTDAT 0x0004
+#define RPROTDIS 0x0008
+#define RPROTNORM 0x0010
+#define RPROTMASK 0x001C
+
+#define SNDZERO 0x001
+#define SNDPIPE 0x002
+
+#define ANYMARK 0x01
+#define LASTMARK 0x02
+
+#define MUXID_ALL (-1)
+
+#define MSG_HIPRI 0x01
+#define MSG_ANY 0x02
+#define MSG_BAND 0x04
+
+#define MORECTL 1
+#define MOREDATA 2
+
+struct bandinfo {
+ unsigned char bi_pri;
+ int bi_flag;
+};
+
+struct strbuf {
+ int maxlen;
+ int len;
+ char* buf;
+};
+
+struct strpeek {
+ struct strbuf ctlbuf;
+ struct strbuf databuf;
+ unsigned flags;
+};
+
+struct strfdinsert {
+ struct strbuf ctlbuf;
+ struct strbuf databuf;
+ unsigned flags;
+ int fildes;
+ int offset;
+};
+
+struct strioctl {
+ int ic_cmd;
+ int ic_timout;
+ int ic_len;
+ char* ic_dp;
+};
+
+struct strrecvfd {
+ int fd;
+ int uid;
+ int gid;
+ char __fill[8];
+};
+
+struct str_mlist {
+ char l_name[FMNAMESZ + 1];
+};
+
+struct str_list {
+ int sl_nmods;
+ struct str_mlist* sl_modlist;
+};
+
+int isastream(int);
+int ioctl(int, int, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_STROPTS_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/acct.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/acct.h
new file mode 100644
index 0000000..8561ad0
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/acct.h
@@ -0,0 +1,72 @@
+#ifndef SYSROOT_SYS_ACCT_H_
+#define SYSROOT_SYS_ACCT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <endian.h>
+#include <features.h>
+#include <stdint.h>
+#include <time.h>
+
+#define ACCT_COMM 16
+
+typedef uint16_t comp_t;
+
+struct acct {
+ char ac_flag;
+ uint16_t ac_uid;
+ uint16_t ac_gid;
+ uint16_t ac_tty;
+ uint32_t ac_btime;
+ comp_t ac_utime;
+ comp_t ac_stime;
+ comp_t ac_etime;
+ comp_t ac_mem;
+ comp_t ac_io;
+ comp_t ac_rw;
+ comp_t ac_minflt;
+ comp_t ac_majflt;
+ comp_t ac_swaps;
+ uint32_t ac_exitcode;
+ char ac_comm[ACCT_COMM + 1];
+ char ac_pad[10];
+};
+
+struct acct_v3 {
+ char ac_flag;
+ char ac_version;
+ uint16_t ac_tty;
+ uint32_t ac_exitcode;
+ uint32_t ac_uid;
+ uint32_t ac_gid;
+ uint32_t ac_pid;
+ uint32_t ac_ppid;
+ uint32_t ac_btime;
+ float ac_etime;
+ comp_t ac_utime;
+ comp_t ac_stime;
+ comp_t ac_mem;
+ comp_t ac_io;
+ comp_t ac_rw;
+ comp_t ac_minflt;
+ comp_t ac_majflt;
+ comp_t ac_swaps;
+ char ac_comm[ACCT_COMM];
+};
+
+#define AFORK 1
+#define ASU 2
+#define ACORE 8
+#define AXSIG 16
+#define ACCT_BYTEORDER (128 * (__BYTE_ORDER == __BIG_ENDIAN))
+#define AHZ 100
+
+int acct(const char*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_ACCT_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/auxv.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/auxv.h
new file mode 100644
index 0000000..61ddea0
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/auxv.h
@@ -0,0 +1,16 @@
+#ifndef SYSROOT_SYS_AUXV_H_
+#define SYSROOT_SYS_AUXV_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <elf.h>
+
+unsigned long getauxval(unsigned long);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_AUXV_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/dir.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/dir.h
new file mode 100644
index 0000000..9ba1c79
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/dir.h
@@ -0,0 +1,2 @@
+#include <dirent.h>
+#define direct dirent
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/errno.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/errno.h
new file mode 100644
index 0000000..35a3e5a
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/errno.h
@@ -0,0 +1,2 @@
+#warning redirecting incorrect #include <sys/errno.h> to <errno.h>
+#include <errno.h>
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/eventfd.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/eventfd.h
new file mode 100644
index 0000000..4259bac
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/eventfd.h
@@ -0,0 +1,25 @@
+#ifndef SYSROOT_SYS_EVENTFD_H_
+#define SYSROOT_SYS_EVENTFD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <fcntl.h>
+#include <stdint.h>
+
+typedef uint64_t eventfd_t;
+
+#define EFD_SEMAPHORE 1
+#define EFD_CLOEXEC O_CLOEXEC
+#define EFD_NONBLOCK O_NONBLOCK
+
+int eventfd(unsigned int, int);
+int eventfd_read(int, eventfd_t*);
+int eventfd_write(int, eventfd_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_EVENTFD_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/fcntl.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/fcntl.h
new file mode 100644
index 0000000..3dd928e
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/fcntl.h
@@ -0,0 +1,2 @@
+#warning redirecting incorrect #include <sys/fcntl.h> to <fcntl.h>
+#include <fcntl.h>
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/file.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/file.h
new file mode 100644
index 0000000..fe17290
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/file.h
@@ -0,0 +1,23 @@
+#ifndef SYSROOT_SYS_FILE_H_
+#define SYSROOT_SYS_FILE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LOCK_SH 1
+#define LOCK_EX 2
+#define LOCK_NB 4
+#define LOCK_UN 8
+
+#define L_SET 0
+#define L_INCR 1
+#define L_XTND 2
+
+int flock(int, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_FILE_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/fsuid.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/fsuid.h
new file mode 100644
index 0000000..a9f654c
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/fsuid.h
@@ -0,0 +1,20 @@
+#ifndef SYSROOT_SYS_FSUID_H_
+#define SYSROOT_SYS_FSUID_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_uid_t
+#define __NEED_gid_t
+
+#include <bits/alltypes.h>
+
+int setfsuid(uid_t);
+int setfsgid(gid_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_FSUID_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/io.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/io.h
new file mode 100644
index 0000000..89617e5
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/io.h
@@ -0,0 +1,19 @@
+#ifndef SYSROOT_SYS_IO_H_
+#define SYSROOT_SYS_IO_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <bits/io.h>
+
+int iopl(int);
+int ioperm(unsigned long, unsigned long, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_IO_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/ioctl.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/ioctl.h
new file mode 100644
index 0000000..ad22a3b
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/ioctl.h
@@ -0,0 +1,16 @@
+#ifndef SYSROOT_SYS_IOCTL_H_
+#define SYSROOT_SYS_IOCTL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <bits/ioctl.h>
+
+int ioctl(int, int, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_IOCTL_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/ipc.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/ipc.h
new file mode 100644
index 0000000..5d019f4
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/ipc.h
@@ -0,0 +1,44 @@
+#ifndef SYSROOT_SYS_IPC_H_
+#define SYSROOT_SYS_IPC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_uid_t
+#define __NEED_gid_t
+#define __NEED_mode_t
+#define __NEED_key_t
+
+#include <bits/alltypes.h>
+
+#define __ipc_perm_key __key
+#define __ipc_perm_seq __seq
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __key key
+#define __seq seq
+#endif
+
+#include <bits/ipc.h>
+
+#define IPC_CREAT 01000
+#define IPC_EXCL 02000
+#define IPC_NOWAIT 04000
+
+#define IPC_RMID 0
+#define IPC_SET 1
+#define IPC_STAT 2
+#define IPC_INFO 3
+
+#define IPC_PRIVATE ((key_t)0)
+
+key_t ftok(const char*, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_IPC_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/klog.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/klog.h
new file mode 100644
index 0000000..b182302
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/klog.h
@@ -0,0 +1,14 @@
+#ifndef SYSROOT_SYS_KLOG_H_
+#define SYSROOT_SYS_KLOG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int klogctl(int, char*, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_KLOG_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/mman.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/mman.h
new file mode 100644
index 0000000..7a913ae
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/mman.h
@@ -0,0 +1,102 @@
+#ifndef SYSROOT_SYS_MMAN_H_
+#define SYSROOT_SYS_MMAN_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_mode_t
+#define __NEED_size_t
+#define __NEED_off_t
+
+#include <bits/alltypes.h>
+
+#define MAP_FAILED ((void*)-1)
+
+#define MAP_SHARED 0x01
+#define MAP_PRIVATE 0x02
+#define MAP_TYPE 0x0f
+#define MAP_FIXED 0x10
+#define MAP_ANON 0x20
+#define MAP_ANONYMOUS MAP_ANON
+#define MAP_NORESERVE 0x4000
+#define MAP_GROWSDOWN 0x0100
+#define MAP_DENYWRITE 0x0800
+#define MAP_EXECUTABLE 0x1000
+#define MAP_LOCKED 0x2000
+#define MAP_POPULATE 0x8000
+#define MAP_NONBLOCK 0x10000
+#define MAP_STACK 0x20000
+#define MAP_HUGETLB 0x40000
+#define MAP_JIT 0x80000
+#define MAP_FILE 0
+
+#define PROT_NONE 0
+#define PROT_READ 1
+#define PROT_WRITE 2
+#define PROT_EXEC 4
+#define PROT_GROWSDOWN 0x01000000
+#define PROT_GROWSUP 0x02000000
+
+#define MS_ASYNC 1
+#define MS_INVALIDATE 2
+#define MS_SYNC 4
+
+#define MCL_CURRENT 1
+#define MCL_FUTURE 2
+#define MCL_ONFAULT 4
+
+#define POSIX_MADV_NORMAL 0
+#define POSIX_MADV_RANDOM 1
+#define POSIX_MADV_SEQUENTIAL 2
+#define POSIX_MADV_WILLNEED 3
+#define POSIX_MADV_DONTNEED 4
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define MADV_NORMAL 0
+#define MADV_RANDOM 1
+#define MADV_SEQUENTIAL 2
+#define MADV_WILLNEED 3
+#define MADV_DONTNEED 4
+#define MADV_FREE 8
+#define MADV_REMOVE 9
+#define MADV_DONTFORK 10
+#define MADV_DOFORK 11
+#define MADV_MERGEABLE 12
+#define MADV_UNMERGEABLE 13
+#define MADV_HUGEPAGE 14
+#define MADV_NOHUGEPAGE 15
+#define MADV_DONTDUMP 16
+#define MADV_DODUMP 17
+#define MADV_HWPOISON 100
+#define MADV_SOFT_OFFLINE 101
+#endif
+
+void* mmap(void*, size_t, int, int, int, off_t);
+int munmap(void*, size_t);
+
+int mprotect(void*, size_t, int);
+int msync(void*, size_t, int);
+
+int posix_madvise(void*, size_t, int);
+
+int mlock(const void*, size_t);
+int munlock(const void*, size_t);
+int mlockall(int);
+int munlockall(void);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define MLOCK_ONFAULT 0x01
+int madvise(void*, size_t, int);
+#endif
+
+int shm_open(const char*, int, mode_t);
+int shm_unlink(const char*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_MMAN_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/mount.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/mount.h
new file mode 100644
index 0000000..53181ea
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/mount.h
@@ -0,0 +1,73 @@
+#ifndef SYSROOT_SYS_MOUNT_H_
+#define SYSROOT_SYS_MOUNT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/ioctl.h>
+
+#define BLKROSET _IO(0x12, 93)
+#define BLKROGET _IO(0x12, 94)
+#define BLKRRPART _IO(0x12, 95)
+#define BLKGETSIZE _IO(0x12, 96)
+#define BLKFLSBUF _IO(0x12, 97)
+#define BLKRASET _IO(0x12, 98)
+#define BLKRAGET _IO(0x12, 99)
+#define BLKFRASET _IO(0x12, 100)
+#define BLKFRAGET _IO(0x12, 101)
+#define BLKSECTSET _IO(0x12, 102)
+#define BLKSECTGET _IO(0x12, 103)
+#define BLKSSZGET _IO(0x12, 104)
+#define BLKBSZGET _IOR(0x12, 112, size_t)
+#define BLKBSZSET _IOW(0x12, 113, size_t)
+#define BLKGETSIZE64 _IOR(0x12, 114, size_t)
+
+#define MS_RDONLY 1
+#define MS_NOSUID 2
+#define MS_NODEV 4
+#define MS_NOEXEC 8
+#define MS_SYNCHRONOUS 16
+#define MS_REMOUNT 32
+#define MS_MANDLOCK 64
+#define MS_DIRSYNC 128
+#define MS_NOATIME 1024
+#define MS_NODIRATIME 2048
+#define MS_BIND 4096
+#define MS_MOVE 8192
+#define MS_REC 16384
+#define MS_SILENT 32768
+#define MS_POSIXACL (1 << 16)
+#define MS_UNBINDABLE (1 << 17)
+#define MS_PRIVATE (1 << 18)
+#define MS_SLAVE (1 << 19)
+#define MS_SHARED (1 << 20)
+#define MS_RELATIME (1 << 21)
+#define MS_KERNMOUNT (1 << 22)
+#define MS_I_VERSION (1 << 23)
+#define MS_STRICTATIME (1 << 24)
+#define MS_LAZYTIME (1 << 25)
+#define MS_NOSEC (1 << 28)
+#define MS_BORN (1 << 29)
+#define MS_ACTIVE (1 << 30)
+#define MS_NOUSER (1U << 31)
+
+#define MS_RMT_MASK (MS_RDONLY | MS_SYNCHRONOUS | MS_MANDLOCK | MS_I_VERSION | MS_LAZYTIME)
+
+#define MS_MGC_VAL 0xc0ed0000
+#define MS_MGC_MSK 0xffff0000
+
+#define MNT_FORCE 1
+#define MNT_DETACH 2
+#define MNT_EXPIRE 4
+#define UMOUNT_NOFOLLOW 8
+
+int mount(const char*, const char*, const char*, unsigned long, const void*);
+int umount(const char*);
+int umount2(const char*, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_MOUNT_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/msg.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/msg.h
new file mode 100644
index 0000000..be0114b
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/msg.h
@@ -0,0 +1,52 @@
+#ifndef SYSROOT_SYS_MSG_H_
+#define SYSROOT_SYS_MSG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/ipc.h>
+
+#define __NEED_pid_t
+#define __NEED_key_t
+#define __NEED_time_t
+#define __NEED_size_t
+#define __NEED_ssize_t
+
+#include <bits/alltypes.h>
+
+typedef unsigned long msgqnum_t;
+typedef unsigned long msglen_t;
+
+#include <bits/msg.h>
+
+#define __msg_cbytes msg_cbytes
+
+#define MSG_NOERROR 010000
+#define MSG_EXCEPT 020000
+
+#define MSG_STAT 11
+#define MSG_INFO 12
+
+struct msginfo {
+ int msgpool, msgmap, msgmax, msgmnb, msgmni, msgssz, msgtql;
+ unsigned short msgseg;
+};
+
+int msgctl(int, int, struct msqid_ds*);
+int msgget(key_t, int);
+ssize_t msgrcv(int, void*, size_t, long, int);
+int msgsnd(int, const void*, size_t, int);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+struct msgbuf {
+ long mtype;
+ char mtext[1];
+};
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_MSG_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/mtio.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/mtio.h
new file mode 100644
index 0000000..3d9f753
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/mtio.h
@@ -0,0 +1,183 @@
+#ifndef SYSROOT_SYS_MTIO_H_
+#define SYSROOT_SYS_MTIO_H_
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+
+struct mtop {
+ short mt_op;
+ int mt_count;
+};
+
+#define _IOT_mtop _IOT(_IOTS(short), 1, _IOTS(int), 1, 0, 0)
+#define _IOT_mtget _IOT(_IOTS(long), 7, 0, 0, 0, 0)
+#define _IOT_mtpos _IOT_SIMPLE(long)
+#define _IOT_mtconfiginfo _IOT(_IOTS(long), 2, _IOTS(short), 3, _IOTS(long), 1)
+
+#define MTRESET 0
+#define MTFSF 1
+#define MTBSF 2
+#define MTFSR 3
+#define MTBSR 4
+#define MTWEOF 5
+#define MTREW 6
+#define MTOFFL 7
+#define MTNOP 8
+#define MTRETEN 9
+#define MTBSFM 10
+#define MTFSFM 11
+#define MTEOM 12
+#define MTERASE 13
+#define MTRAS1 14
+#define MTRAS2 15
+#define MTRAS3 16
+#define MTSETBLK 20
+#define MTSETDENSITY 21
+#define MTSEEK 22
+#define MTTELL 23
+#define MTSETDRVBUFFER 24
+#define MTFSS 25
+#define MTBSS 26
+#define MTWSM 27
+#define MTLOCK 28
+#define MTUNLOCK 29
+#define MTLOAD 30
+#define MTUNLOAD 31
+#define MTCOMPRESSION 32
+#define MTSETPART 33
+#define MTMKPART 34
+
+struct mtget {
+ long mt_type;
+ long mt_resid;
+ long mt_dsreg;
+ long mt_gstat;
+ long mt_erreg;
+ int mt_fileno;
+ int mt_blkno;
+};
+
+#define MT_ISUNKNOWN 0x01
+#define MT_ISQIC02 0x02
+#define MT_ISWT5150 0x03
+#define MT_ISARCHIVE_5945L2 0x04
+#define MT_ISCMSJ500 0x05
+#define MT_ISTDC3610 0x06
+#define MT_ISARCHIVE_VP60I 0x07
+#define MT_ISARCHIVE_2150L 0x08
+#define MT_ISARCHIVE_2060L 0x09
+#define MT_ISARCHIVESC499 0x0A
+#define MT_ISQIC02_ALL_FEATURES 0x0F
+#define MT_ISWT5099EEN24 0x11
+#define MT_ISTEAC_MT2ST 0x12
+#define MT_ISEVEREX_FT40A 0x32
+#define MT_ISDDS1 0x51
+#define MT_ISDDS2 0x52
+#define MT_ISSCSI1 0x71
+#define MT_ISSCSI2 0x72
+#define MT_ISFTAPE_UNKNOWN 0x800000
+#define MT_ISFTAPE_FLAG 0x800000
+
+struct mt_tape_info {
+ long t_type;
+ char* t_name;
+};
+
+#define MT_TAPE_INFO \
+ { \
+ {MT_ISUNKNOWN, "Unknown type of tape device"}, {MT_ISQIC02, "Generic QIC-02 tape streamer"}, \
+ {MT_ISWT5150, "Wangtek 5150, QIC-150"}, {MT_ISARCHIVE_5945L2, "Archive 5945L-2"}, \
+ {MT_ISCMSJ500, "CMS Jumbo 500"}, {MT_ISTDC3610, "Tandberg TDC 3610, QIC-24"}, \
+ {MT_ISARCHIVE_VP60I, "Archive VP60i, QIC-02"}, \
+ {MT_ISARCHIVE_2150L, "Archive Viper 2150L"}, {MT_ISARCHIVE_2060L, "Archive Viper 2060L"}, \
+ {MT_ISARCHIVESC499, "Archive SC-499 QIC-36 controller"}, \
+ {MT_ISQIC02_ALL_FEATURES, "Generic QIC-02 tape, all features"}, \
+ {MT_ISWT5099EEN24, "Wangtek 5099-een24, 60MB"}, \
+ {MT_ISTEAC_MT2ST, "Teac MT-2ST 155mb data cassette drive"}, \
+ {MT_ISEVEREX_FT40A, "Everex FT40A, QIC-40"}, {MT_ISSCSI1, "Generic SCSI-1 tape"}, \
+ {MT_ISSCSI2, "Generic SCSI-2 tape"}, { \
+ 0, 0 \
+ } \
+ }
+
+struct mtpos {
+ long mt_blkno;
+};
+
+struct mtconfiginfo {
+ long mt_type;
+ long ifc_type;
+ unsigned short irqnr;
+ unsigned short dmanr;
+ unsigned short port;
+ unsigned long debug;
+ unsigned have_dens : 1;
+ unsigned have_bsf : 1;
+ unsigned have_fsr : 1;
+ unsigned have_bsr : 1;
+ unsigned have_eod : 1;
+ unsigned have_seek : 1;
+ unsigned have_tell : 1;
+ unsigned have_ras1 : 1;
+ unsigned have_ras2 : 1;
+ unsigned have_ras3 : 1;
+ unsigned have_qfa : 1;
+ unsigned pad1 : 5;
+ char reserved[10];
+};
+
+#define MTIOCTOP _IOW('m', 1, struct mtop)
+#define MTIOCGET _IOR('m', 2, struct mtget)
+#define MTIOCPOS _IOR('m', 3, struct mtpos)
+
+#define MTIOCGETCONFIG _IOR('m', 4, struct mtconfiginfo)
+#define MTIOCSETCONFIG _IOW('m', 5, struct mtconfiginfo)
+
+#define GMT_EOF(x) ((x)&0x80000000)
+#define GMT_BOT(x) ((x)&0x40000000)
+#define GMT_EOT(x) ((x)&0x20000000)
+#define GMT_SM(x) ((x)&0x10000000)
+#define GMT_EOD(x) ((x)&0x08000000)
+#define GMT_WR_PROT(x) ((x)&0x04000000)
+#define GMT_ONLINE(x) ((x)&0x01000000)
+#define GMT_D_6250(x) ((x)&0x00800000)
+#define GMT_D_1600(x) ((x)&0x00400000)
+#define GMT_D_800(x) ((x)&0x00200000)
+#define GMT_DR_OPEN(x) ((x)&0x00040000)
+#define GMT_IM_REP_EN(x) ((x)&0x00010000)
+
+#define MT_ST_BLKSIZE_SHIFT 0
+#define MT_ST_BLKSIZE_MASK 0xffffff
+#define MT_ST_DENSITY_SHIFT 24
+#define MT_ST_DENSITY_MASK 0xff000000
+#define MT_ST_SOFTERR_SHIFT 0
+#define MT_ST_SOFTERR_MASK 0xffff
+#define MT_ST_OPTIONS 0xf0000000
+#define MT_ST_BOOLEANS 0x10000000
+#define MT_ST_SETBOOLEANS 0x30000000
+#define MT_ST_CLEARBOOLEANS 0x40000000
+#define MT_ST_WRITE_THRESHOLD 0x20000000
+#define MT_ST_DEF_BLKSIZE 0x50000000
+#define MT_ST_DEF_OPTIONS 0x60000000
+#define MT_ST_BUFFER_WRITES 0x1
+#define MT_ST_ASYNC_WRITES 0x2
+#define MT_ST_READ_AHEAD 0x4
+#define MT_ST_DEBUGGING 0x8
+#define MT_ST_TWO_FM 0x10
+#define MT_ST_FAST_MTEOM 0x20
+#define MT_ST_AUTO_LOCK 0x40
+#define MT_ST_DEF_WRITES 0x80
+#define MT_ST_CAN_BSR 0x100
+#define MT_ST_NO_BLKLIMS 0x200
+#define MT_ST_CAN_PARTITIONS 0x400
+#define MT_ST_SCSI2LOGICAL 0x800
+#define MT_ST_CLEAR_DEFAULT 0xfffff
+#define MT_ST_DEF_DENSITY (MT_ST_DEF_OPTIONS | 0x100000)
+#define MT_ST_DEF_COMPRESSION (MT_ST_DEF_OPTIONS | 0x200000)
+#define MT_ST_DEF_DRVBUFFER (MT_ST_DEF_OPTIONS | 0x300000)
+#define MT_ST_HPLOADER_OFFSET 10000
+#ifndef DEFTAPE
+#define DEFTAPE "/dev/tape"
+#endif
+
+#endif // SYSROOT_SYS_MTIO_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/param.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/param.h
new file mode 100644
index 0000000..301bba7
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/param.h
@@ -0,0 +1,34 @@
+#ifndef SYSROOT_SYS_PARAM_H_
+#define SYSROOT_SYS_PARAM_H_
+
+#define MAXSYMLINKS 20
+#define MAXHOSTNAMELEN 64
+#define MAXNAMLEN 255
+#define MAXPATHLEN 4096
+#define NBBY 8
+#define NGROUPS 32
+#define CANBSIZE 255
+#define NOFILE 256
+#define NCARGS 131072
+#define DEV_BSIZE 512
+#define NOGROUP (-1)
+
+#undef MIN
+#undef MAX
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+
+#define __bitop(x, i, o) ((x)[(i) / 8] o(1 << (i) % 8))
+#define setbit(x, i) __bitop(x, i, |=)
+#define clrbit(x, i) __bitop(x, i, &= ~)
+#define isset(x, i) __bitop(x, i, &)
+#define isclr(x, i) !isset(x, i)
+
+#define howmany(n, d) (((n) + ((d)-1)) / (d))
+#define roundup(n, d) (howmany(n, d) * (d))
+#define powerof2(n) !(((n)-1) & (n))
+
+#include <endian.h>
+#include <limits.h>
+
+#endif // SYSROOT_SYS_PARAM_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/personality.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/personality.h
new file mode 100644
index 0000000..b32d1eb
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/personality.h
@@ -0,0 +1,47 @@
+#ifndef SYSROOT_SYS_PERSONALITY_H_
+#define SYSROOT_SYS_PERSONALITY_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ADDR_NO_RANDOMIZE 0x0040000
+#define MMAP_PAGE_ZERO 0x0100000
+#define ADDR_COMPAT_LAYOUT 0x0200000
+#define READ_IMPLIES_EXEC 0x0400000
+#define ADDR_LIMIT_32BIT 0x0800000
+#define SHORT_INODE 0x1000000
+#define WHOLE_SECONDS 0x2000000
+#define STICKY_TIMEOUTS 0x4000000
+#define ADDR_LIMIT_3GB 0x8000000
+
+#define PER_LINUX 0
+#define PER_LINUX_32BIT ADDR_LIMIT_32BIT
+#define PER_SVR4 (1 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO)
+#define PER_SVR3 (2 | STICKY_TIMEOUTS | SHORT_INODE)
+#define PER_SCOSVR3 (3 | STICKY_TIMEOUTS | WHOLE_SECONDS | SHORT_INODE)
+#define PER_OSR5 (3 | STICKY_TIMEOUTS | WHOLE_SECONDS)
+#define PER_WYSEV386 (4 | STICKY_TIMEOUTS | SHORT_INODE)
+#define PER_ISCR4 (5 | STICKY_TIMEOUTS)
+#define PER_BSD 6
+#define PER_SUNOS (6 | STICKY_TIMEOUTS)
+#define PER_XENIX (7 | STICKY_TIMEOUTS | SHORT_INODE)
+#define PER_LINUX32 8
+#define PER_LINUX32_3GB (8 | ADDR_LIMIT_3GB)
+#define PER_IRIX32 (9 | STICKY_TIMEOUTS)
+#define PER_IRIXN32 (0xa | STICKY_TIMEOUTS)
+#define PER_IRIX64 (0x0b | STICKY_TIMEOUTS)
+#define PER_RISCOS 0xc
+#define PER_SOLARIS (0xd | STICKY_TIMEOUTS)
+#define PER_UW7 (0xe | STICKY_TIMEOUTS | MMAP_PAGE_ZERO)
+#define PER_OSF4 0xf
+#define PER_HPUX 0x10
+#define PER_MASK 0xff
+
+int personality(unsigned long);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_PERSONALITY_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/poll.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/poll.h
new file mode 100644
index 0000000..9917040
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/poll.h
@@ -0,0 +1,2 @@
+#warning redirecting incorrect #include <sys/poll.h> to <poll.h>
+#include <poll.h>
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/quota.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/quota.h
new file mode 100644
index 0000000..aec5dc9
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/quota.h
@@ -0,0 +1,102 @@
+#ifndef SYSROOT_SYS_QUOTA_H_
+#define SYSROOT_SYS_QUOTA_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#define _LINUX_QUOTA_VERSION 2
+
+#define dbtob(num) ((num) << 10)
+#define btodb(num) ((num) >> 10)
+#define fs_to_dq_blocks(num, blksize) (((num) * (blksize)) / 1024)
+
+#define MAX_IQ_TIME 604800
+#define MAX_DQ_TIME 604800
+
+#define MAXQUOTAS 2
+#define USRQUOTA 0
+#define GRPQUOTA 1
+
+#define INITQFNAMES {"user", "group", "undefined"};
+
+#define QUOTAFILENAME "quota"
+#define QUOTAGROUP "staff"
+
+#define NR_DQHASH 43
+#define NR_DQUOTS 256
+
+#define SUBCMDMASK 0x00ff
+#define SUBCMDSHIFT 8
+#define QCMD(cmd, type) (((cmd) << SUBCMDSHIFT) | ((type)&SUBCMDMASK))
+
+#define Q_SYNC 0x800001
+#define Q_QUOTAON 0x800002
+#define Q_QUOTAOFF 0x800003
+#define Q_GETFMT 0x800004
+#define Q_GETINFO 0x800005
+#define Q_SETINFO 0x800006
+#define Q_GETQUOTA 0x800007
+#define Q_SETQUOTA 0x800008
+
+#define QFMT_VFS_OLD 1
+#define QFMT_VFS_V0 2
+#define QFMT_OCFS2 3
+#define QFMT_VFS_V1 4
+
+#define QIF_BLIMITS 1
+#define QIF_SPACE 2
+#define QIF_ILIMITS 4
+#define QIF_INODES 8
+#define QIF_BTIME 16
+#define QIF_ITIME 32
+#define QIF_LIMITS (QIF_BLIMITS | QIF_ILIMITS)
+#define QIF_USAGE (QIF_SPACE | QIF_INODES)
+#define QIF_TIMES (QIF_BTIME | QIF_ITIME)
+#define QIF_ALL (QIF_LIMITS | QIF_USAGE | QIF_TIMES)
+
+struct dqblk {
+ uint64_t dqb_bhardlimit;
+ uint64_t dqb_bsoftlimit;
+ uint64_t dqb_curspace;
+ uint64_t dqb_ihardlimit;
+ uint64_t dqb_isoftlimit;
+ uint64_t dqb_curinodes;
+ uint64_t dqb_btime;
+ uint64_t dqb_itime;
+ uint32_t dqb_valid;
+};
+
+#define dq_bhardlimit dq_dqb.dqb_bhardlimit
+#define dq_bsoftlimit dq_dqb.dqb_bsoftlimit
+#define dq_curspace dq_dqb.dqb_curspace
+#define dq_valid dq_dqb.dqb_valid
+#define dq_ihardlimit dq_dqb.dqb_ihardlimit
+#define dq_isoftlimit dq_dqb.dqb_isoftlimit
+#define dq_curinodes dq_dqb.dqb_curinodes
+#define dq_btime dq_dqb.dqb_btime
+#define dq_itime dq_dqb.dqb_itime
+
+#define dqoff(UID) ((long long)(UID) * sizeof(struct dqblk))
+
+#define IIF_BGRACE 1
+#define IIF_IGRACE 2
+#define IIF_FLAGS 4
+#define IIF_ALL (IIF_BGRACE | IIF_IGRACE | IIF_FLAGS)
+
+struct dqinfo {
+ uint64_t dqi_bgrace;
+ uint64_t dqi_igrace;
+ uint32_t dqi_flags;
+ uint32_t dqi_valid;
+};
+
+int quotactl(int, const char*, int, char*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_QUOTA_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/random.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/random.h
new file mode 100644
index 0000000..258201d
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/random.h
@@ -0,0 +1,16 @@
+#ifndef SYSROOT_SYS_RANDOM_H_
+#define SYSROOT_SYS_RANDOM_H_
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int getentropy(void* buffer, size_t length) __attribute__((__warn_unused_result__));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_RANDOM_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/reboot.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/reboot.h
new file mode 100644
index 0000000..a83629c
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/reboot.h
@@ -0,0 +1,22 @@
+#ifndef SYSROOT_SYS_REBOOT_H_
+#define SYSROOT_SYS_REBOOT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RB_AUTOBOOT 0x01234567
+#define RB_HALT_SYSTEM 0xcdef0123
+#define RB_ENABLE_CAD 0x89abcdef
+#define RB_DISABLE_CAD 0
+#define RB_POWER_OFF 0x4321fedc
+#define RB_SW_SUSPEND 0xd000fce2
+#define RB_KEXEC 0x45584543
+
+int reboot(int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_REBOOT_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/reg.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/reg.h
new file mode 100644
index 0000000..0f37ffe
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/reg.h
@@ -0,0 +1,9 @@
+#ifndef SYSROOT_SYS_REG_H_
+#define SYSROOT_SYS_REG_H_
+
+#include <limits.h>
+#include <unistd.h>
+
+#include <bits/reg.h>
+
+#endif // SYSROOT_SYS_REG_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/select.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/select.h
new file mode 100644
index 0000000..5d4fd7d
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/select.h
@@ -0,0 +1,54 @@
+#ifndef SYSROOT_SYS_SELECT_H_
+#define SYSROOT_SYS_SELECT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+#define __NEED_time_t
+#define __NEED_suseconds_t
+#define __NEED_struct_timeval
+#define __NEED_struct_timespec
+#define __NEED_sigset_t
+
+#include <bits/alltypes.h>
+
+#define FD_SETSIZE 1024
+
+typedef unsigned long fd_mask;
+
+typedef struct {
+ unsigned long fds_bits[FD_SETSIZE / 8 / sizeof(long)];
+} fd_set;
+
+#define FD_ZERO(s) \
+ do { \
+ int __i; \
+ unsigned long* __b = (s)->fds_bits; \
+ for (__i = sizeof(fd_set) / sizeof(long); __i; __i--) \
+ *__b++ = 0; \
+ } while (0)
+#define FD_SET(d, s) \
+ ((s)->fds_bits[(d) / (8 * sizeof(long))] |= (1UL << ((d) % (8 * sizeof(long)))))
+#define FD_CLR(d, s) \
+ ((s)->fds_bits[(d) / (8 * sizeof(long))] &= ~(1UL << ((d) % (8 * sizeof(long)))))
+#define FD_ISSET(d, s) \
+ !!((s)->fds_bits[(d) / (8 * sizeof(long))] & (1UL << ((d) % (8 * sizeof(long)))))
+
+int select(int, fd_set* __restrict, fd_set* __restrict, fd_set* __restrict,
+ struct timeval* __restrict);
+int pselect(int, fd_set* __restrict, fd_set* __restrict, fd_set* __restrict,
+ const struct timespec* __restrict, const sigset_t* __restrict);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define NFDBITS (8 * (int)sizeof(long))
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_SELECT_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/sem.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/sem.h
new file mode 100644
index 0000000..a4330af
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/sem.h
@@ -0,0 +1,69 @@
+#ifndef SYSROOT_SYS_SEM_H_
+#define SYSROOT_SYS_SEM_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+#define __NEED_pid_t
+#define __NEED_time_t
+#ifdef _GNU_SOURCE
+#define __NEED_struct_timespec
+#endif
+#include <sys/ipc.h>
+
+#include <bits/alltypes.h>
+
+#define SEM_UNDO 0x1000
+#define GETPID 11
+#define GETVAL 12
+#define GETALL 13
+#define GETNCNT 14
+#define GETZCNT 15
+#define SETVAL 16
+#define SETALL 17
+
+#include <endian.h>
+
+#include <bits/sem.h>
+
+#define _SEM_SEMUN_UNDEFINED 1
+
+#define SEM_STAT 18
+#define SEM_INFO 19
+
+struct seminfo {
+ int semmap;
+ int semmni;
+ int semmns;
+ int semmnu;
+ int semmsl;
+ int semopm;
+ int semume;
+ int semusz;
+ int semvzx;
+ int semaem;
+};
+
+struct sembuf {
+ unsigned short sem_num;
+ short sem_op;
+ short sem_flg;
+};
+
+int semctl(int, int, int, ...);
+int semget(key_t, int, int);
+int semop(int, struct sembuf*, size_t);
+
+#ifdef _GNU_SOURCE
+int semtimedop(int, struct sembuf*, size_t, const struct timespec*);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_SEM_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/shm.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/shm.h
new file mode 100644
index 0000000..55b4389
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/shm.h
@@ -0,0 +1,54 @@
+#ifndef SYSROOT_SYS_SHM_H_
+#define SYSROOT_SYS_SHM_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_time_t
+#define __NEED_size_t
+#define __NEED_pid_t
+
+#include <sys/ipc.h>
+
+#include <bits/alltypes.h>
+
+#ifdef _GNU_SOURCE
+#define __used_ids used_ids
+#define __swap_attempts swap_attempts
+#define __swap_successes swap_successes
+#endif
+
+#include <bits/shm.h>
+
+#define SHM_R 0400
+#define SHM_W 0200
+
+#define SHM_RDONLY 010000
+#define SHM_RND 020000
+#define SHM_REMAP 040000
+#define SHM_EXEC 0100000
+
+#define SHM_LOCK 11
+#define SHM_UNLOCK 12
+#define SHM_STAT 13
+#define SHM_INFO 14
+#define SHM_DEST 01000
+#define SHM_LOCKED 02000
+#define SHM_HUGETLB 04000
+#define SHM_NORESERVE 010000
+
+typedef unsigned long shmatt_t;
+
+void* shmat(int, const void*, int);
+int shmctl(int, int, struct shmid_ds*);
+int shmdt(const void*);
+int shmget(key_t, size_t, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_SHM_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/signal.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/signal.h
new file mode 100644
index 0000000..45bdcc6
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/signal.h
@@ -0,0 +1,2 @@
+#warning redirecting incorrect #include <sys/signal.h> to <signal.h>
+#include <signal.h>
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/signalfd.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/signalfd.h
new file mode 100644
index 0000000..46a5489
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/signalfd.h
@@ -0,0 +1,45 @@
+#ifndef SYSROOT_SYS_SIGNALFD_H_
+#define SYSROOT_SYS_SIGNALFD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <fcntl.h>
+#include <stdint.h>
+
+#define __NEED_sigset_t
+
+#include <bits/alltypes.h>
+
+#define SFD_CLOEXEC O_CLOEXEC
+#define SFD_NONBLOCK O_NONBLOCK
+
+int signalfd(int, const sigset_t*, int);
+
+struct signalfd_siginfo {
+ uint32_t ssi_signo;
+ int32_t ssi_errno;
+ int32_t ssi_code;
+ uint32_t ssi_pid;
+ uint32_t ssi_uid;
+ int32_t ssi_fd;
+ uint32_t ssi_tid;
+ uint32_t ssi_band;
+ uint32_t ssi_overrun;
+ uint32_t ssi_trapno;
+ int32_t ssi_status;
+ int32_t ssi_int;
+ uint64_t ssi_ptr;
+ uint64_t ssi_utime;
+ uint64_t ssi_stime;
+ uint64_t ssi_addr;
+ uint16_t ssi_addr_lsb;
+ uint8_t pad[128 - 12 * 4 - 4 * 8 - 2];
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_SIGNALFD_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/socket.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/socket.h
new file mode 100644
index 0000000..7f68e6e
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/socket.h
@@ -0,0 +1,322 @@
+#ifndef SYSROOT_SYS_SOCKET_H_
+#define SYSROOT_SYS_SOCKET_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_socklen_t
+#define __NEED_sa_family_t
+#define __NEED_size_t
+#define __NEED_ssize_t
+#define __NEED_uid_t
+#define __NEED_pid_t
+#define __NEED_gid_t
+#define __NEED_struct_iovec
+
+#include <bits/alltypes.h>
+#include <bits/socket.h>
+
+#ifdef _GNU_SOURCE
+struct ucred {
+ pid_t pid;
+ uid_t uid;
+ gid_t gid;
+};
+
+struct mmsghdr {
+ struct msghdr msg_hdr;
+ unsigned int msg_len;
+};
+
+struct timespec;
+
+int sendmmsg(int, struct mmsghdr*, unsigned int, unsigned int);
+int recvmmsg(int, struct mmsghdr*, unsigned int, unsigned int, struct timespec*);
+#endif
+
+struct linger {
+ int l_onoff;
+ int l_linger;
+};
+
+#define SHUT_RD 0
+#define SHUT_WR 1
+#define SHUT_RDWR 2
+
+#ifndef SOCK_STREAM
+#define SOCK_STREAM 1
+#define SOCK_DGRAM 2
+#endif
+
+#define SOCK_RAW 3
+#define SOCK_RDM 4
+#define SOCK_SEQPACKET 5
+#define SOCK_DCCP 6
+#define SOCK_PACKET 10
+
+#ifndef SOCK_CLOEXEC
+#define SOCK_CLOEXEC 02000000
+#define SOCK_NONBLOCK 04000
+#endif
+
+#define PF_UNSPEC 0
+#define PF_LOCAL 1
+#define PF_UNIX PF_LOCAL
+#define PF_FILE PF_LOCAL
+#define PF_INET 2
+#define PF_AX25 3
+#define PF_IPX 4
+#define PF_APPLETALK 5
+#define PF_NETROM 6
+#define PF_BRIDGE 7
+#define PF_ATMPVC 8
+#define PF_X25 9
+#define PF_INET6 10
+#define PF_ROSE 11
+#define PF_DECnet 12
+#define PF_NETBEUI 13
+#define PF_SECURITY 14
+#define PF_KEY 15
+#define PF_NETLINK 16
+#define PF_ROUTE PF_NETLINK
+#define PF_PACKET 17
+#define PF_ASH 18
+#define PF_ECONET 19
+#define PF_ATMSVC 20
+#define PF_RDS 21
+#define PF_SNA 22
+#define PF_IRDA 23
+#define PF_PPPOX 24
+#define PF_WANPIPE 25
+#define PF_LLC 26
+#define PF_IB 27
+#define PF_MPLS 28
+#define PF_TIPC 30
+#define PF_BLUETOOTH 31
+#define PF_IUCV 32
+#define PF_RXRPC 33
+#define PF_ISDN 34
+#define PF_PHONET 35
+#define PF_IEEE802154 36
+#define PF_CAIF 37
+#define PF_ALG 38
+#define PF_NFC 39
+#define PF_VSOCK 40
+#define PF_MAX 41
+
+#define AF_UNSPEC PF_UNSPEC
+#define AF_LOCAL PF_LOCAL
+#define AF_UNIX AF_LOCAL
+#define AF_FILE AF_LOCAL
+#define AF_INET PF_INET
+#define AF_AX25 PF_AX25
+#define AF_IPX PF_IPX
+#define AF_APPLETALK PF_APPLETALK
+#define AF_NETROM PF_NETROM
+#define AF_BRIDGE PF_BRIDGE
+#define AF_ATMPVC PF_ATMPVC
+#define AF_X25 PF_X25
+#define AF_INET6 PF_INET6
+#define AF_ROSE PF_ROSE
+#define AF_DECnet PF_DECnet
+#define AF_NETBEUI PF_NETBEUI
+#define AF_SECURITY PF_SECURITY
+#define AF_KEY PF_KEY
+#define AF_NETLINK PF_NETLINK
+#define AF_ROUTE PF_ROUTE
+#define AF_PACKET PF_PACKET
+#define AF_ASH PF_ASH
+#define AF_ECONET PF_ECONET
+#define AF_ATMSVC PF_ATMSVC
+#define AF_RDS PF_RDS
+#define AF_SNA PF_SNA
+#define AF_IRDA PF_IRDA
+#define AF_PPPOX PF_PPPOX
+#define AF_WANPIPE PF_WANPIPE
+#define AF_LLC PF_LLC
+#define AF_IB PF_IB
+#define AF_MPLS PF_MPLS
+#define AF_TIPC PF_TIPC
+#define AF_BLUETOOTH PF_BLUETOOTH
+#define AF_IUCV PF_IUCV
+#define AF_RXRPC PF_RXRPC
+#define AF_ISDN PF_ISDN
+#define AF_PHONET PF_PHONET
+#define AF_IEEE802154 PF_IEEE802154
+#define AF_CAIF PF_CAIF
+#define AF_ALG PF_ALG
+#define AF_NFC PF_NFC
+#define AF_VSOCK PF_VSOCK
+#define AF_MAX PF_MAX
+
+#ifndef SO_DEBUG
+#define SO_DEBUG 1
+#define SO_REUSEADDR 2
+#define SO_TYPE 3
+#define SO_ERROR 4
+#define SO_DONTROUTE 5
+#define SO_BROADCAST 6
+#define SO_SNDBUF 7
+#define SO_RCVBUF 8
+#define SO_KEEPALIVE 9
+#define SO_OOBINLINE 10
+#define SO_NO_CHECK 11
+#define SO_PRIORITY 12
+#define SO_LINGER 13
+#define SO_BSDCOMPAT 14
+#define SO_REUSEPORT 15
+#define SO_PASSCRED 16
+#define SO_PEERCRED 17
+#define SO_RCVLOWAT 18
+#define SO_SNDLOWAT 19
+#define SO_RCVTIMEO 20
+#define SO_SNDTIMEO 21
+#define SO_ACCEPTCONN 30
+#define SO_SNDBUFFORCE 32
+#define SO_RCVBUFFORCE 33
+#define SO_PROTOCOL 38
+#define SO_DOMAIN 39
+#endif
+
+#define SO_SECURITY_AUTHENTICATION 22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT 23
+#define SO_SECURITY_ENCRYPTION_NETWORK 24
+
+#define SO_BINDTODEVICE 25
+
+#define SO_ATTACH_FILTER 26
+#define SO_DETACH_FILTER 27
+#define SO_GET_FILTER SO_ATTACH_FILTER
+
+#define SO_PEERNAME 28
+#define SO_TIMESTAMP 29
+#define SCM_TIMESTAMP SO_TIMESTAMP
+
+#define SO_PEERSEC 31
+#define SO_PASSSEC 34
+#define SO_TIMESTAMPNS 35
+#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+#define SO_MARK 36
+#define SO_TIMESTAMPING 37
+#define SCM_TIMESTAMPING SO_TIMESTAMPING
+#define SO_RXQ_OVFL 40
+#define SO_WIFI_STATUS 41
+#define SCM_WIFI_STATUS SO_WIFI_STATUS
+#define SO_PEEK_OFF 42
+#define SO_NOFCS 43
+#define SO_LOCK_FILTER 44
+#define SO_SELECT_ERR_QUEUE 45
+#define SO_BUSY_POLL 46
+#define SO_MAX_PACING_RATE 47
+#define SO_BPF_EXTENSIONS 48
+#define SO_INCOMING_CPU 49
+#define SO_ATTACH_BPF 50
+#define SO_DETACH_BPF SO_DETACH_FILTER
+#define SO_ATTACH_REUSEPORT_CBPF 51
+#define SO_ATTACH_REUSEPORT_EBPF 52
+
+#ifndef SOL_SOCKET
+#define SOL_SOCKET 1
+#endif
+
+#define SOL_IP 0
+#define SOL_IPV6 41
+#define SOL_ICMPV6 58
+
+#define SOL_RAW 255
+#define SOL_DECNET 261
+#define SOL_X25 262
+#define SOL_PACKET 263
+#define SOL_ATM 264
+#define SOL_AAL 265
+#define SOL_IRDA 266
+
+#define SOMAXCONN 128
+
+#define MSG_OOB 0x0001
+#define MSG_PEEK 0x0002
+#define MSG_DONTROUTE 0x0004
+#define MSG_CTRUNC 0x0008
+#define MSG_PROXY 0x0010
+#define MSG_TRUNC 0x0020
+#define MSG_DONTWAIT 0x0040
+#define MSG_EOR 0x0080
+#define MSG_WAITALL 0x0100
+#define MSG_FIN 0x0200
+#define MSG_SYN 0x0400
+#define MSG_CONFIRM 0x0800
+#define MSG_RST 0x1000
+#define MSG_ERRQUEUE 0x2000
+#define MSG_MORE 0x8000
+#define MSG_WAITFORONE 0x10000
+#define MSG_FASTOPEN 0x20000000
+#define MSG_CMSG_CLOEXEC 0x40000000
+
+#define __CMSG_LEN(cmsg) (((cmsg)->cmsg_len + sizeof(long) - 1) & ~(long)(sizeof(long) - 1))
+#define __CMSG_NEXT(cmsg) ((unsigned char*)(cmsg) + __CMSG_LEN(cmsg))
+#define __MHDR_END(mhdr) ((unsigned char*)(mhdr)->msg_control + (mhdr)->msg_controllen)
+
+#define CMSG_DATA(cmsg) ((unsigned char*)(((struct cmsghdr*)(cmsg)) + 1))
+#define CMSG_NXTHDR(mhdr, cmsg) \
+ ((cmsg)->cmsg_len < sizeof(struct cmsghdr) \
+ ? (struct cmsghdr*)0 \
+ : (__CMSG_NEXT(cmsg) + sizeof(struct cmsghdr) >= __MHDR_END(mhdr) \
+ ? (struct cmsghdr*)0 \
+ : ((struct cmsghdr*)__CMSG_NEXT(cmsg))))
+#define CMSG_FIRSTHDR(mhdr) \
+ ((size_t)(mhdr)->msg_controllen >= sizeof(struct cmsghdr) ? (struct cmsghdr*)(mhdr)->msg_control \
+ : (struct cmsghdr*)0)
+
+#define CMSG_ALIGN(len) (((len) + sizeof(size_t) - 1) & (size_t) ~(sizeof(size_t) - 1))
+#define CMSG_SPACE(len) (CMSG_ALIGN(len) + CMSG_ALIGN(sizeof(struct cmsghdr)))
+#define CMSG_LEN(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + (len))
+
+#define SCM_RIGHTS 0x01
+#define SCM_CREDENTIALS 0x02
+
+struct sockaddr {
+ sa_family_t sa_family;
+ char sa_data[14];
+};
+
+struct sockaddr_storage {
+ sa_family_t ss_family;
+ unsigned long __ss_align;
+ char __ss_padding[128 - 2 * sizeof(unsigned long)];
+};
+
+int socket(int, int, int);
+int socketpair(int, int, int, int[2]);
+
+int shutdown(int, int);
+
+int bind(int, const struct sockaddr*, socklen_t);
+int connect(int, const struct sockaddr*, socklen_t);
+int listen(int, int);
+int accept(int, struct sockaddr* __restrict, socklen_t* __restrict);
+int accept4(int, struct sockaddr* __restrict, socklen_t* __restrict, int);
+
+int getsockname(int, struct sockaddr* __restrict, socklen_t* __restrict);
+int getpeername(int, struct sockaddr* __restrict, socklen_t* __restrict);
+
+ssize_t send(int, const void*, size_t, int);
+ssize_t recv(int, void*, size_t, int);
+ssize_t sendto(int, const void*, size_t, int, const struct sockaddr*, socklen_t);
+ssize_t recvfrom(int, void* __restrict, size_t, int, struct sockaddr* __restrict,
+ socklen_t* __restrict);
+ssize_t sendmsg(int, const struct msghdr*, int);
+ssize_t recvmsg(int, struct msghdr*, int);
+
+int getsockopt(int, int, int, void* __restrict, socklen_t* __restrict);
+int setsockopt(int, int, int, const void*, socklen_t);
+
+int sockatmark(int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_SOCKET_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/stat.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/stat.h
new file mode 100644
index 0000000..d58e26c
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/stat.h
@@ -0,0 +1,102 @@
+#ifndef SYSROOT_SYS_STAT_H_
+#define SYSROOT_SYS_STAT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_dev_t
+#define __NEED_ino_t
+#define __NEED_mode_t
+#define __NEED_nlink_t
+#define __NEED_uid_t
+#define __NEED_gid_t
+#define __NEED_off_t
+#define __NEED_time_t
+#define __NEED_blksize_t
+#define __NEED_blkcnt_t
+#define __NEED_struct_timespec
+
+#include <bits/alltypes.h>
+#include <bits/stat.h>
+
+#define st_atime st_atim.tv_sec
+#define st_mtime st_mtim.tv_sec
+#define st_ctime st_ctim.tv_sec
+
+#define S_IFMT 0170000
+
+#define S_IFDIR 0040000
+#define S_IFCHR 0020000
+#define S_IFBLK 0060000
+#define S_IFREG 0100000
+#define S_IFIFO 0010000
+#define S_IFLNK 0120000
+#define S_IFSOCK 0140000
+
+#define S_TYPEISMQ(buf) 0
+#define S_TYPEISSEM(buf) 0
+#define S_TYPEISSHM(buf) 0
+#define S_TYPEISTMO(buf) 0
+
+#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
+#define S_ISCHR(mode) (((mode)&S_IFMT) == S_IFCHR)
+#define S_ISBLK(mode) (((mode)&S_IFMT) == S_IFBLK)
+#define S_ISREG(mode) (((mode)&S_IFMT) == S_IFREG)
+#define S_ISFIFO(mode) (((mode)&S_IFMT) == S_IFIFO)
+#define S_ISLNK(mode) (((mode)&S_IFMT) == S_IFLNK)
+#define S_ISSOCK(mode) (((mode)&S_IFMT) == S_IFSOCK)
+
+#ifndef S_IRUSR
+#define S_ISUID 04000
+#define S_ISGID 02000
+#define S_ISVTX 01000
+#define S_IRUSR 0400
+#define S_IWUSR 0200
+#define S_IXUSR 0100
+#define S_IRWXU 0700
+#define S_IRGRP 0040
+#define S_IWGRP 0020
+#define S_IXGRP 0010
+#define S_IRWXG 0070
+#define S_IROTH 0004
+#define S_IWOTH 0002
+#define S_IXOTH 0001
+#define S_IRWXO 0007
+#endif
+
+#define UTIME_NOW 0x3fffffff
+#define UTIME_OMIT 0x3ffffffe
+
+int stat(const char* __restrict, struct stat* __restrict);
+int fstat(int, struct stat*);
+int lstat(const char* __restrict, struct stat* __restrict);
+int fstatat(int, const char* __restrict, struct stat* __restrict, int);
+int chmod(const char*, mode_t);
+int fchmod(int, mode_t);
+int fchmodat(int, const char*, mode_t, int);
+mode_t umask(mode_t);
+int mkdir(const char*, mode_t);
+int mknod(const char*, mode_t, dev_t);
+int mkfifo(const char*, mode_t);
+int mkdirat(int, const char*, mode_t);
+int mknodat(int, const char*, mode_t, dev_t);
+int mkfifoat(int, const char*, mode_t);
+
+int futimens(int, const struct timespec[2]);
+int utimensat(int, const char*, const struct timespec[2], int);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+int lchmod(const char*, mode_t);
+#define S_IREAD S_IRUSR
+#define S_IWRITE S_IWUSR
+#define S_IEXEC S_IXUSR
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_STAT_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/statfs.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/statfs.h
new file mode 100644
index 0000000..1459181
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/statfs.h
@@ -0,0 +1,24 @@
+#ifndef SYSROOT_SYS_STATFS_H_
+#define SYSROOT_SYS_STATFS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <sys/statvfs.h>
+
+typedef struct __fsid_t {
+ int __val[2];
+} fsid_t;
+
+#include <bits/statfs.h>
+
+int statfs(const char*, struct statfs*);
+int fstatfs(int, struct statfs*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_STATFS_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/statvfs.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/statvfs.h
new file mode 100644
index 0000000..0423246
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/statvfs.h
@@ -0,0 +1,50 @@
+#ifndef SYSROOT_SYS_STATVFS_H_
+#define SYSROOT_SYS_STATVFS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_fsblkcnt_t
+#define __NEED_fsfilcnt_t
+#include <endian.h>
+
+#include <bits/alltypes.h>
+
+struct statvfs {
+ unsigned long f_bsize, f_frsize;
+ fsblkcnt_t f_blocks, f_bfree, f_bavail;
+ fsfilcnt_t f_files, f_ffree, f_favail;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned long f_fsid;
+ unsigned : 8 * (2 * sizeof(int) - sizeof(long));
+#else
+ unsigned : 8 * (2 * sizeof(int) - sizeof(long));
+ unsigned long f_fsid;
+#endif
+ unsigned long f_flag, f_namemax;
+ int __reserved[6];
+};
+
+int statvfs(const char* __restrict, struct statvfs* __restrict);
+int fstatvfs(int, struct statvfs*);
+
+#define ST_RDONLY 1
+#define ST_NOSUID 2
+#define ST_NODEV 4
+#define ST_NOEXEC 8
+#define ST_SYNCHRONOUS 16
+#define ST_MANDLOCK 64
+#define ST_WRITE 128
+#define ST_APPEND 256
+#define ST_IMMUTABLE 512
+#define ST_NOATIME 1024
+#define ST_NODIRATIME 2048
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_STATVFS_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/stropts.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/stropts.h
new file mode 100644
index 0000000..5b5bc02
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/stropts.h
@@ -0,0 +1 @@
+#include <stropts.h>
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/swap.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/swap.h
new file mode 100644
index 0000000..6420606
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/swap.h
@@ -0,0 +1,20 @@
+#ifndef SYSROOT_SYS_SWAP_H_
+#define SYSROOT_SYS_SWAP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SWAP_FLAG_PREFER 0x8000
+#define SWAP_FLAG_PRIO_MASK 0x7fff
+#define SWAP_FLAG_PRIO_SHIFT 0
+#define SWAP_FLAG_DISCARD 0x10000
+
+int swapon(const char*, int);
+int swapoff(const char*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_SWAP_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/syslog.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/syslog.h
new file mode 100644
index 0000000..7761ece
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/syslog.h
@@ -0,0 +1 @@
+#include <syslog.h>
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/termios.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/termios.h
new file mode 100644
index 0000000..f5f751f
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/termios.h
@@ -0,0 +1,2 @@
+#warning redirecting incorrect #include <sys/termios.h> to <termios.h>
+#include <termios.h>
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/time.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/time.h
new file mode 100644
index 0000000..a9476c7
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/time.h
@@ -0,0 +1,65 @@
+#ifndef SYSROOT_SYS_TIME_H_
+#define SYSROOT_SYS_TIME_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <sys/select.h>
+
+int gettimeofday(struct timeval* __restrict, void* __restrict);
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#define ITIMER_REAL 0
+#define ITIMER_VIRTUAL 1
+#define ITIMER_PROF 2
+
+struct itimerval {
+ struct timeval it_interval;
+ struct timeval it_value;
+};
+
+int getitimer(int, struct itimerval*);
+int setitimer(int, const struct itimerval* __restrict, struct itimerval* __restrict);
+int utimes(const char*, const struct timeval[2]);
+
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+struct timezone {
+ int tz_minuteswest;
+ int tz_dsttime;
+};
+int futimes(int, const struct timeval[2]);
+int futimesat(int, const char*, const struct timeval[2]);
+int lutimes(const char*, const struct timeval[2]);
+int settimeofday(const struct timeval*, const struct timezone*);
+int adjtime(const struct timeval*, struct timeval*);
+#define timerisset(t) ((t)->tv_sec || (t)->tv_usec)
+#define timerclear(t) ((t)->tv_sec = (t)->tv_usec = 0)
+#define timercmp(s, t, op) \
+ ((s)->tv_sec == (t)->tv_sec ? (s)->tv_usec op(t)->tv_usec : (s)->tv_sec op(t)->tv_sec)
+#define timeradd(s, t, a) \
+ (void)((a)->tv_sec = (s)->tv_sec + (t)->tv_sec, \
+ ((a)->tv_usec = (s)->tv_usec + (t)->tv_usec) >= 1000000 && \
+ ((a)->tv_usec -= 1000000, (a)->tv_sec++))
+#define timersub(s, t, a) \
+ (void)((a)->tv_sec = (s)->tv_sec - (t)->tv_sec, \
+ ((a)->tv_usec = (s)->tv_usec - (t)->tv_usec) < 0 && \
+ ((a)->tv_usec += 1000000, (a)->tv_sec--))
+#endif
+
+#if defined(_GNU_SOURCE)
+#define TIMEVAL_TO_TIMESPEC(tv, ts) \
+ ((ts)->tv_sec = (tv)->tv_sec, (ts)->tv_nsec = (tv)->tv_usec * 1000, (void)0)
+#define TIMESPEC_TO_TIMEVAL(tv, ts) \
+ ((tv)->tv_sec = (ts)->tv_sec, (tv)->tv_usec = (ts)->tv_nsec / 1000, (void)0)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_TIME_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/timeb.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/timeb.h
new file mode 100644
index 0000000..bbb7e34
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/timeb.h
@@ -0,0 +1,24 @@
+#ifndef SYSROOT_SYS_TIMEB_H_
+#define SYSROOT_SYS_TIMEB_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_time_t
+
+#include <bits/alltypes.h>
+
+struct timeb {
+ time_t time;
+ unsigned short millitm;
+ short timezone, dstflag;
+};
+
+int ftime(struct timeb*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_TIMEB_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/timerfd.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/timerfd.h
new file mode 100644
index 0000000..499a938
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/timerfd.h
@@ -0,0 +1,26 @@
+#ifndef SYSROOT_SYS_TIMERFD_H_
+#define SYSROOT_SYS_TIMERFD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <fcntl.h>
+#include <time.h>
+
+#define TFD_NONBLOCK O_NONBLOCK
+#define TFD_CLOEXEC O_CLOEXEC
+
+#define TFD_TIMER_ABSTIME 1
+
+struct itimerspec;
+
+int timerfd_create(int, int);
+int timerfd_settime(int, int, const struct itimerspec*, struct itimerspec*);
+int timerfd_gettime(int, struct itimerspec*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_TIMERFD_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/times.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/times.h
new file mode 100644
index 0000000..ec5d3d6
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/times.h
@@ -0,0 +1,24 @@
+#ifndef SYSROOT_SYS_TIMES_H_
+#define SYSROOT_SYS_TIMES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_clock_t
+#include <bits/alltypes.h>
+
+struct tms {
+ clock_t tms_utime;
+ clock_t tms_stime;
+ clock_t tms_cutime;
+ clock_t tms_cstime;
+};
+
+clock_t times(struct tms*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_TIMES_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/timex.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/timex.h
new file mode 100644
index 0000000..9981c93
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/timex.h
@@ -0,0 +1,99 @@
+#ifndef SYSROOT_SYS_TIMEX_H_
+#define SYSROOT_SYS_TIMEX_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_clockid_t
+
+#include <sys/time.h>
+
+#include <bits/alltypes.h>
+
+struct ntptimeval {
+ struct timeval time;
+ long maxerror, esterror;
+};
+
+struct timex {
+ unsigned modes;
+ long offset, freq, maxerror, esterror;
+ int status;
+ long constant, precision, tolerance;
+ struct timeval time;
+ long tick, ppsfreq, jitter;
+ int shift;
+ long stabil, jitcnt, calcnt, errcnt, stbcnt;
+ int tai;
+ int __padding[11];
+};
+
+#define ADJ_OFFSET 0x0001
+#define ADJ_FREQUENCY 0x0002
+#define ADJ_MAXERROR 0x0004
+#define ADJ_ESTERROR 0x0008
+#define ADJ_STATUS 0x0010
+#define ADJ_TIMECONST 0x0020
+#define ADJ_TAI 0x0080
+#define ADJ_SETOFFSET 0x0100
+#define ADJ_MICRO 0x1000
+#define ADJ_NANO 0x2000
+#define ADJ_TICK 0x4000
+#define ADJ_OFFSET_SINGLESHOT 0x8001
+#define ADJ_OFFSET_SS_READ 0xa001
+
+#define MOD_OFFSET ADJ_OFFSET
+#define MOD_FREQUENCY ADJ_FREQUENCY
+#define MOD_MAXERROR ADJ_MAXERROR
+#define MOD_ESTERROR ADJ_ESTERROR
+#define MOD_STATUS ADJ_STATUS
+#define MOD_TIMECONST ADJ_TIMECONST
+#define MOD_CLKB ADJ_TICK
+#define MOD_CLKA ADJ_OFFSET_SINGLESHOT
+#define MOD_TAI ADJ_TAI
+#define MOD_MICRO ADJ_MICRO
+#define MOD_NANO ADJ_NANO
+
+#define STA_PLL 0x0001
+#define STA_PPSFREQ 0x0002
+#define STA_PPSTIME 0x0004
+#define STA_FLL 0x0008
+
+#define STA_INS 0x0010
+#define STA_DEL 0x0020
+#define STA_UNSYNC 0x0040
+#define STA_FREQHOLD 0x0080
+
+#define STA_PPSSIGNAL 0x0100
+#define STA_PPSJITTER 0x0200
+#define STA_PPSWANDER 0x0400
+#define STA_PPSERROR 0x0800
+
+#define STA_CLOCKERR 0x1000
+#define STA_NANO 0x2000
+#define STA_MODE 0x4000
+#define STA_CLK 0x8000
+
+#define STA_RONLY \
+ (STA_PPSSIGNAL | STA_PPSJITTER | STA_PPSWANDER | STA_PPSERROR | STA_CLOCKERR | STA_NANO | \
+ STA_MODE | STA_CLK)
+
+#define TIME_OK 0
+#define TIME_INS 1
+#define TIME_DEL 2
+#define TIME_OOP 3
+#define TIME_WAIT 4
+#define TIME_ERROR 5
+#define TIME_BAD TIME_ERROR
+
+#define MAXTC 6
+
+int adjtimex(struct timex*);
+int clock_adjtime(clockid_t, struct timex*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_TIMEX_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/ttydefaults.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/ttydefaults.h
new file mode 100644
index 0000000..e4994fe
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/ttydefaults.h
@@ -0,0 +1,39 @@
+#ifndef SYSROOT_SYS_TTYDEFAULTS_H_
+#define SYSROOT_SYS_TTYDEFAULTS_H_
+
+#define TTYDEF_IFLAG (BRKINT | ISTRIP | ICRNL | IMAXBEL | IXON | IXANY)
+#define TTYDEF_OFLAG (OPOST | ONLCR | XTABS)
+#define TTYDEF_LFLAG (ECHO | ICANON | ISIG | IEXTEN | ECHOE | ECHOKE | ECHOCTL)
+#define TTYDEF_CFLAG (CREAD | CS7 | PARENB | HUPCL)
+#define TTYDEF_SPEED (B9600)
+#define CTRL(x) (x & 037)
+#define CEOF CTRL('d')
+
+#ifdef _POSIX_VDISABLE
+#define CEOL _POSIX_VDISABLE
+#define CSTATUS _POSIX_VDISABLE
+#else
+#define CEOL '\0'
+#define CSTATUS '\0'
+#endif
+
+#define CERASE 0177
+#define CINTR CTRL('c')
+#define CKILL CTRL('u')
+#define CMIN 1
+#define CQUIT 034
+#define CSUSP CTRL('z')
+#define CTIME 0
+#define CDSUSP CTRL('y')
+#define CSTART CTRL('q')
+#define CSTOP CTRL('s')
+#define CLNEXT CTRL('v')
+#define CDISCARD CTRL('o')
+#define CWERASE CTRL('w')
+#define CREPRINT CTRL('r')
+#define CEOT CEOF
+#define CBRK CEOL
+#define CRPRNT CREPRINT
+#define CFLUSH CDISCARD
+
+#endif // SYSROOT_SYS_TTYDEFAULTS_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/types.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/types.h
new file mode 100644
index 0000000..ea195a0
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/types.h
@@ -0,0 +1,76 @@
+#ifndef SYSROOT_SYS_TYPES_H_
+#define SYSROOT_SYS_TYPES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_ino_t
+#define __NEED_dev_t
+#define __NEED_uid_t
+#define __NEED_gid_t
+#define __NEED_mode_t
+#define __NEED_nlink_t
+#define __NEED_off_t
+#define __NEED_pid_t
+#define __NEED_size_t
+#define __NEED_ssize_t
+#define __NEED_time_t
+#define __NEED_timer_t
+#define __NEED_clockid_t
+
+#define __NEED_blkcnt_t
+#define __NEED_fsblkcnt_t
+#define __NEED_fsfilcnt_t
+
+#define __NEED_id_t
+#define __NEED_key_t
+#define __NEED_clock_t
+#define __NEED_suseconds_t
+#define __NEED_blksize_t
+
+#define __NEED_pthread_t
+#define __NEED_pthread_attr_t
+#define __NEED_pthread_mutexattr_t
+#define __NEED_pthread_condattr_t
+#define __NEED_pthread_rwlockattr_t
+#define __NEED_pthread_barrierattr_t
+#define __NEED_pthread_mutex_t
+#define __NEED_pthread_cond_t
+#define __NEED_pthread_rwlock_t
+#define __NEED_pthread_barrier_t
+#define __NEED_pthread_spinlock_t
+#define __NEED_pthread_key_t
+#define __NEED_pthread_once_t
+#define __NEED_useconds_t
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#include <stdint.h>
+#define __NEED_u_int64_t
+#define __NEED_register_t
+#endif
+
+#include <bits/alltypes.h>
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+typedef unsigned char u_int8_t;
+typedef unsigned short u_int16_t;
+typedef unsigned u_int32_t;
+typedef char* caddr_t;
+typedef unsigned char u_char;
+typedef unsigned short u_short, ushort;
+typedef unsigned u_int, uint;
+typedef unsigned long u_long, ulong;
+typedef long long quad_t;
+typedef unsigned long long u_quad_t;
+#include <endian.h>
+#include <sys/select.h>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_TYPES_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/ucontext.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/ucontext.h
new file mode 100644
index 0000000..5fdbd63
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/ucontext.h
@@ -0,0 +1 @@
+#include <ucontext.h>
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/uio.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/uio.h
new file mode 100644
index 0000000..4762083
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/uio.h
@@ -0,0 +1,34 @@
+#ifndef SYSROOT_SYS_UIO_H_
+#define SYSROOT_SYS_UIO_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+#define __NEED_ssize_t
+#define __NEED_struct_iovec
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __NEED_off_t
+#endif
+
+#include <bits/alltypes.h>
+
+#define UIO_MAXIOV 1024
+
+ssize_t readv(int, const struct iovec*, int);
+ssize_t writev(int, const struct iovec*, int);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+ssize_t preadv(int, const struct iovec*, int, off_t);
+ssize_t pwritev(int, const struct iovec*, int, off_t);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_UIO_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/un.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/un.h
new file mode 100644
index 0000000..425c801
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/un.h
@@ -0,0 +1,31 @@
+#ifndef SYSROOT_SYS_UN_H_
+#define SYSROOT_SYS_UN_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_sa_family_t
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __NEED_size_t
+#endif
+
+#include <bits/alltypes.h>
+
+struct sockaddr_un {
+ sa_family_t sun_family;
+ char sun_path[108];
+};
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+size_t strlen(const char*);
+#define SUN_LEN(s) (2 + strlen((s)->sun_path))
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_UN_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/utsname.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/utsname.h
new file mode 100644
index 0000000..5d5fee1
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/utsname.h
@@ -0,0 +1,30 @@
+#ifndef SYSROOT_SYS_UTSNAME_H_
+#define SYSROOT_SYS_UTSNAME_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <limits.h>
+
+struct utsname {
+ char sysname[65];
+ char nodename[HOST_NAME_MAX + 1];
+ char release[65];
+ char version[65];
+ char machine[65];
+#ifdef _GNU_SOURCE
+ char domainname[65];
+#else
+ char __domainname[65];
+#endif
+};
+
+int uname(struct utsname*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_UTSNAME_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/vfs.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/vfs.h
new file mode 100644
index 0000000..a899db2
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/vfs.h
@@ -0,0 +1 @@
+#include <sys/statfs.h>
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/wait.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/wait.h
new file mode 100644
index 0000000..3b33520
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sys/wait.h
@@ -0,0 +1,46 @@
+#ifndef SYSROOT_SYS_WAIT_H_
+#define SYSROOT_SYS_WAIT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_pid_t
+#define __NEED_id_t
+#include <bits/alltypes.h>
+
+typedef enum { P_ALL = 0, P_PID = 1, P_PGID = 2 } idtype_t;
+
+pid_t wait(int*);
+pid_t waitpid(pid_t, int*, int);
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#include <signal.h>
+int waitid(idtype_t, id_t, siginfo_t*, int);
+#endif
+
+#define WNOHANG 1
+#define WUNTRACED 2
+
+#define WSTOPPED 2
+#define WEXITED 4
+#define WCONTINUED 8
+#define WNOWAIT 0x1000000
+
+#define WEXITSTATUS(s) (((s)&0xff00) >> 8)
+#define WTERMSIG(s) ((s)&0x7f)
+#define WSTOPSIG(s) WEXITSTATUS(s)
+#define WCOREDUMP(s) ((s)&0x80)
+#define WIFEXITED(s) (!WTERMSIG(s))
+#define WIFSTOPPED(s) ((short)((((s)&0xffff) * 0x10001) >> 8) > 0x7f00)
+#define WIFSIGNALED(s) (((s)&0xffff) - 1U < 0xffu)
+#define WIFCONTINUED(s) ((s) == 0xffff)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_WAIT_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sysexits.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sysexits.h
new file mode 100644
index 0000000..ca2782d
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/sysexits.h
@@ -0,0 +1,23 @@
+#ifndef SYSROOT_SYSEXITS_H_
+#define SYSROOT_SYSEXITS_H_
+
+#define EX_OK 0
+#define EX__BASE 64
+#define EX_USAGE 64
+#define EX_DATAERR 65
+#define EX_NOINPUT 66
+#define EX_NOUSER 67
+#define EX_NOHOST 68
+#define EX_UNAVAILABLE 69
+#define EX_SOFTWARE 70
+#define EX_OSERR 71
+#define EX_OSFILE 72
+#define EX_CANTCREAT 73
+#define EX_IOERR 74
+#define EX_TEMPFAIL 75
+#define EX_PROTOCOL 76
+#define EX_NOPERM 77
+#define EX_CONFIG 78
+#define EX__MAX 78
+
+#endif // SYSROOT_SYSEXITS_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/syslog.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/syslog.h
new file mode 100644
index 0000000..dcb09e3
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/syslog.h
@@ -0,0 +1,121 @@
+#ifndef SYSROOT_SYSLOG_H_
+#define SYSROOT_SYSLOG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define LOG_EMERG 0
+#define LOG_ALERT 1
+#define LOG_CRIT 2
+#define LOG_ERR 3
+#define LOG_WARNING 4
+#define LOG_NOTICE 5
+#define LOG_INFO 6
+#define LOG_DEBUG 7
+
+#define LOG_PRIMASK 7
+#define LOG_PRI(p) ((p)&LOG_PRIMASK)
+#define LOG_MAKEPRI(f, p) (((f) << 3) | (p))
+
+#define LOG_MASK(p) (1 << (p))
+#define LOG_UPTO(p) ((1 << ((p) + 1)) - 1)
+
+#define LOG_KERN (0 << 3)
+#define LOG_USER (1 << 3)
+#define LOG_MAIL (2 << 3)
+#define LOG_DAEMON (3 << 3)
+#define LOG_AUTH (4 << 3)
+#define LOG_SYSLOG (5 << 3)
+#define LOG_LPR (6 << 3)
+#define LOG_NEWS (7 << 3)
+#define LOG_UUCP (8 << 3)
+#define LOG_CRON (9 << 3)
+#define LOG_AUTHPRIV (10 << 3)
+#define LOG_FTP (11 << 3)
+
+#define LOG_LOCAL0 (16 << 3)
+#define LOG_LOCAL1 (17 << 3)
+#define LOG_LOCAL2 (18 << 3)
+#define LOG_LOCAL3 (19 << 3)
+#define LOG_LOCAL4 (20 << 3)
+#define LOG_LOCAL5 (21 << 3)
+#define LOG_LOCAL6 (22 << 3)
+#define LOG_LOCAL7 (23 << 3)
+
+#define LOG_NFACILITIES 24
+#define LOG_FACMASK 0x3f8
+#define LOG_FAC(p) (((p)&LOG_FACMASK) >> 3)
+
+#define LOG_PID 0x01
+#define LOG_CONS 0x02
+#define LOG_ODELAY 0x04
+#define LOG_NDELAY 0x08
+#define LOG_NOWAIT 0x10
+#define LOG_PERROR 0x20
+
+void closelog(void);
+void openlog(const char*, int, int);
+int setlogmask(int);
+void syslog(int, const char*, ...);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define _PATH_LOG "/dev/log"
+#define __NEED_va_list
+#include <bits/alltypes.h>
+void vsyslog(int, const char*, va_list);
+#if defined(SYSLOG_NAMES)
+#define INTERNAL_NOPRI 0x10
+#define INTERNAL_MARK (LOG_NFACILITIES << 3)
+typedef struct {
+ char* c_name;
+ int c_val;
+} CODE;
+#define prioritynames \
+ ((CODE*)(const CODE[]){{"alert", LOG_ALERT}, \
+ {"crit", LOG_CRIT}, \
+ {"debug", LOG_DEBUG}, \
+ {"emerg", LOG_EMERG}, \
+ {"err", LOG_ERR}, \
+ {"error", LOG_ERR}, \
+ {"info", LOG_INFO}, \
+ {"none", INTERNAL_NOPRI}, \
+ {"notice", LOG_NOTICE}, \
+ {"panic", LOG_EMERG}, \
+ {"warn", LOG_WARNING}, \
+ {"warning", LOG_WARNING}, \
+ {0, -1}})
+#define facilitynames \
+ ((CODE*)(const CODE[]){{"auth", LOG_AUTH}, \
+ {"authpriv", LOG_AUTHPRIV}, \
+ {"cron", LOG_CRON}, \
+ {"daemon", LOG_DAEMON}, \
+ {"ftp", LOG_FTP}, \
+ {"kern", LOG_KERN}, \
+ {"lpr", LOG_LPR}, \
+ {"mail", LOG_MAIL}, \
+ {"mark", INTERNAL_MARK}, \
+ {"news", LOG_NEWS}, \
+ {"security", LOG_AUTH}, \
+ {"syslog", LOG_SYSLOG}, \
+ {"user", LOG_USER}, \
+ {"uucp", LOG_UUCP}, \
+ {"local0", LOG_LOCAL0}, \
+ {"local1", LOG_LOCAL1}, \
+ {"local2", LOG_LOCAL2}, \
+ {"local3", LOG_LOCAL3}, \
+ {"local4", LOG_LOCAL4}, \
+ {"local5", LOG_LOCAL5}, \
+ {"local6", LOG_LOCAL6}, \
+ {"local7", LOG_LOCAL7}, \
+ {0, -1}})
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYSLOG_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/tar.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/tar.h
new file mode 100644
index 0000000..2dcb983
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/tar.h
@@ -0,0 +1,33 @@
+#ifndef SYSROOT_TAR_H_
+#define SYSROOT_TAR_H_
+
+#define TSUID 04000
+#define TSGID 02000
+#define TSVTX 01000
+#define TUREAD 00400
+#define TUWRITE 00200
+#define TUEXEC 00100
+#define TGREAD 00040
+#define TGWRITE 00020
+#define TGEXEC 00010
+#define TOREAD 00004
+#define TOWRITE 00002
+#define TOEXEC 00001
+
+#define REGTYPE '0'
+#define AREGTYPE '\0'
+#define LNKTYPE '1'
+#define SYMTYPE '2'
+#define CHRTYPE '3'
+#define BLKTYPE '4'
+#define DIRTYPE '5'
+#define FIFOTYPE '6'
+#define CONTTYPE '7'
+
+#define TMAGIC "ustar"
+#define TMAGLEN 6
+
+#define TVERSION "00"
+#define TVERSLEN 2
+
+#endif // SYSROOT_TAR_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/termios.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/termios.h
new file mode 100644
index 0000000..4ccfe13
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/termios.h
@@ -0,0 +1,46 @@
+#ifndef SYSROOT_TERMIOS_H_
+#define SYSROOT_TERMIOS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_pid_t
+
+#include <bits/alltypes.h>
+
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+typedef unsigned int tcflag_t;
+
+#define NCCS 32
+
+#include <bits/termios.h>
+
+speed_t cfgetospeed(const struct termios*);
+speed_t cfgetispeed(const struct termios*);
+int cfsetospeed(struct termios*, speed_t);
+int cfsetispeed(struct termios*, speed_t);
+
+int tcgetattr(int, struct termios*);
+int tcsetattr(int, int, const struct termios*);
+
+int tcsendbreak(int, int);
+int tcdrain(int);
+int tcflush(int, int);
+int tcflow(int, int);
+
+pid_t tcgetsid(int);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+void cfmakeraw(struct termios*);
+int cfsetspeed(struct termios*, speed_t);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_TERMIOS_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/threads.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/threads.h
new file mode 100644
index 0000000..480a6f7
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/threads.h
@@ -0,0 +1,108 @@
+#ifndef SYSROOT_THREADS_H_
+#define SYSROOT_THREADS_H_
+
+#include <features.h>
+#include <time.h>
+
+#ifdef __cplusplus
+extern "C" {
+typedef unsigned long thrd_t;
+#else
+typedef struct __pthread* thrd_t;
+#define thread_local _Thread_local
+#endif
+
+typedef unsigned tss_t;
+typedef int (*thrd_start_t)(void*);
+typedef void (*tss_dtor_t)(void*);
+
+#define __NEED_cnd_t
+#define __NEED_mtx_t
+#define __NEED_once_flag
+
+#include <bits/alltypes.h>
+
+#define TSS_DTOR_ITERATIONS 4
+
+enum {
+ thrd_success = 0,
+ thrd_busy = 1,
+ thrd_error = 2,
+ thrd_nomem = 3,
+ thrd_timedout = 4,
+};
+
+// These are bitfield values; initialize with e.g. (mtx_plain|mtx_timed).
+// mtx_recursive is not implemented.
+enum {
+ mtx_plain = 0,
+ mtx_recursive = 1,
+ mtx_timed = 2,
+};
+
+#ifdef _ALL_SOURCE
+#define MTX_INIT \
+ {}
+#define CND_INIT \
+ {}
+#endif
+
+#define ONCE_FLAG_INIT 0
+
+int thrd_create(thrd_t*, thrd_start_t, void*);
+#ifdef _ALL_SOURCE
+// |name| is silently truncated to a maximum of ZX_MAX_NAME_LEN-1 characters.
+int thrd_create_with_name(thrd_t*, thrd_start_t, void*, const char* name);
+#endif
+_Noreturn void thrd_exit(int);
+
+int thrd_detach(thrd_t);
+int thrd_join(thrd_t, int*);
+
+int thrd_sleep(const struct timespec*, struct timespec*);
+void thrd_yield(void);
+
+thrd_t thrd_current(void);
+int thrd_equal(thrd_t, thrd_t);
+#ifndef __cplusplus
+#define thrd_equal(A, B) ((A) == (B))
+#endif
+
+void call_once(once_flag*, void (*)(void));
+
+int mtx_init(mtx_t*, int);
+void mtx_destroy(mtx_t*);
+
+int mtx_lock(mtx_t* __m)
+#ifdef __clang__
+ __attribute__((__acquire_capability__(__m)))
+#endif
+ ;
+int mtx_timedlock(mtx_t* __restrict, const struct timespec* __restrict);
+int mtx_trylock(mtx_t*);
+int mtx_unlock(mtx_t* __m)
+#ifdef __clang__
+ __attribute__((__release_capability__(__m)))
+#endif
+ ;
+
+int cnd_init(cnd_t*);
+void cnd_destroy(cnd_t*);
+
+int cnd_broadcast(cnd_t*);
+int cnd_signal(cnd_t*);
+
+int cnd_timedwait(cnd_t* __restrict, mtx_t* __restrict, const struct timespec* __restrict);
+int cnd_wait(cnd_t*, mtx_t*);
+
+int tss_create(tss_t*, tss_dtor_t);
+void tss_delete(tss_t key);
+
+int tss_set(tss_t, void*);
+void* tss_get(tss_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_THREADS_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/time.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/time.h
new file mode 100644
index 0000000..b81da45
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/time.h
@@ -0,0 +1,124 @@
+#ifndef SYSROOT_TIME_H_
+#define SYSROOT_TIME_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <bits/null.h>
+
+#define __NEED_size_t
+#define __NEED_time_t
+#define __NEED_clock_t
+#define __NEED_struct_timespec
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __NEED_clockid_t
+#define __NEED_timer_t
+#define __NEED_pid_t
+#endif
+
+#include <bits/alltypes.h>
+
+#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+#define __tm_gmtoff tm_gmtoff
+#define __tm_zone tm_zone
+#endif
+
+struct tm {
+ int tm_sec;
+ int tm_min;
+ int tm_hour;
+ int tm_mday;
+ int tm_mon;
+ int tm_year;
+ int tm_wday;
+ int tm_yday;
+ int tm_isdst;
+ long __tm_gmtoff;
+ const char* __tm_zone;
+};
+
+clock_t clock(void);
+time_t time(time_t*);
+double difftime(time_t, time_t);
+time_t mktime(struct tm*);
+size_t strftime(char* __restrict, size_t, const char* __restrict, const struct tm* __restrict);
+struct tm* gmtime(const time_t*);
+struct tm* localtime(const time_t*);
+char* asctime(const struct tm*);
+char* ctime(const time_t*);
+int timespec_get(struct timespec*, int);
+
+#define CLOCKS_PER_SEC 1000000L
+
+#define TIME_UTC 1
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+struct tm* gmtime_r(const time_t* __restrict, struct tm* __restrict);
+struct tm* localtime_r(const time_t* __restrict, struct tm* __restrict);
+char* asctime_r(const struct tm* __restrict, char* __restrict);
+char* ctime_r(const time_t*, char*);
+
+void tzset(void);
+
+struct itimerspec {
+ struct timespec it_interval;
+ struct timespec it_value;
+};
+
+#define CLOCK_REALTIME 0
+#define CLOCK_MONOTONIC 1
+#define CLOCK_PROCESS_CPUTIME_ID 2
+#define CLOCK_THREAD_CPUTIME_ID 3
+#define CLOCK_MONOTONIC_RAW 4
+#define CLOCK_REALTIME_COARSE 5
+#define CLOCK_MONOTONIC_COARSE 6
+#define CLOCK_BOOTTIME 7
+#define CLOCK_REALTIME_ALARM 8
+#define CLOCK_BOOTTIME_ALARM 9
+#define CLOCK_SGI_CYCLE 10
+#define CLOCK_TAI 11
+
+#define TIMER_ABSTIME 1
+
+int nanosleep(const struct timespec*, struct timespec*);
+int clock_getres(clockid_t, struct timespec*);
+int clock_gettime(clockid_t, struct timespec*);
+int clock_settime(clockid_t, const struct timespec*);
+int clock_nanosleep(clockid_t, int, const struct timespec*, struct timespec*);
+int clock_getcpuclockid(pid_t, clockid_t*);
+
+struct sigevent;
+int timer_create(clockid_t, struct sigevent* __restrict, timer_t* __restrict);
+int timer_delete(timer_t);
+int timer_settime(timer_t, int, const struct itimerspec* __restrict, struct itimerspec* __restrict);
+int timer_gettime(timer_t, struct itimerspec*);
+int timer_getoverrun(timer_t);
+
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+char* strptime(const char* __restrict, const char* __restrict, struct tm* __restrict);
+extern int daylight;
+extern long timezone;
+extern char* tzname[2];
+extern int getdate_err;
+struct tm* getdate(const char*);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+int stime(const time_t*);
+time_t timegm(struct tm*);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_TIME_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/uchar.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/uchar.h
new file mode 100644
index 0000000..79cda7c
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/uchar.h
@@ -0,0 +1,28 @@
+#ifndef SYSROOT_UCHAR_H_
+#define SYSROOT_UCHAR_H_
+
+#ifdef __cplusplus
+extern "C" {
+#else
+typedef unsigned short char16_t;
+typedef unsigned char32_t;
+#endif
+
+#define __NEED_mbstate_t
+#define __NEED_size_t
+
+#include <features.h>
+
+#include <bits/alltypes.h>
+
+size_t c16rtomb(char* __restrict, char16_t, mbstate_t* __restrict);
+size_t mbrtoc16(char16_t* __restrict, const char* __restrict, size_t, mbstate_t* __restrict);
+
+size_t c32rtomb(char* __restrict, char32_t, mbstate_t* __restrict);
+size_t mbrtoc32(char32_t* __restrict, const char* __restrict, size_t, mbstate_t* __restrict);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_UCHAR_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/ucontext.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/ucontext.h
new file mode 100644
index 0000000..ccd910f
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/ucontext.h
@@ -0,0 +1,26 @@
+#ifndef SYSROOT_UCONTEXT_H_
+#define SYSROOT_UCONTEXT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <signal.h>
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define NGREG (sizeof(gregset_t) / sizeof(greg_t))
+#endif
+
+struct __ucontext;
+
+int getcontext(struct __ucontext*);
+void makecontext(struct __ucontext*, void (*)(void), int, ...);
+int setcontext(const struct __ucontext*);
+int swapcontext(struct __ucontext*, const struct __ucontext*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_UCONTEXT_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/unistd.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/unistd.h
new file mode 100644
index 0000000..e400030
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/unistd.h
@@ -0,0 +1,436 @@
+#ifndef SYSROOT_UNISTD_H_
+#define SYSROOT_UNISTD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <bits/null.h>
+
+#define STDIN_FILENO 0
+#define STDOUT_FILENO 1
+#define STDERR_FILENO 2
+
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
+#define __NEED_size_t
+#define __NEED_ssize_t
+#define __NEED_uid_t
+#define __NEED_gid_t
+#define __NEED_off_t
+#define __NEED_pid_t
+#define __NEED_intptr_t
+#define __NEED_useconds_t
+
+#include <bits/alltypes.h>
+
+int pipe(int[2]);
+int pipe2(int[2], int);
+int close(int);
+int posix_close(int, int);
+int dup(int);
+int dup2(int, int);
+int dup3(int, int, int);
+off_t lseek(int, off_t, int);
+int fsync(int);
+int fdatasync(int);
+
+ssize_t read(int, void*, size_t);
+ssize_t write(int, const void*, size_t);
+ssize_t pread(int, void*, size_t, off_t);
+ssize_t pwrite(int, const void*, size_t, off_t);
+
+int chown(const char*, uid_t, gid_t);
+int fchown(int, uid_t, gid_t);
+int lchown(const char*, uid_t, gid_t);
+int fchownat(int, const char*, uid_t, gid_t, int);
+
+int link(const char*, const char*);
+int linkat(int, const char*, int, const char*, int);
+int symlink(const char*, const char*);
+int symlinkat(const char*, int, const char*);
+ssize_t readlink(const char* __restrict, char* __restrict, size_t);
+ssize_t readlinkat(int, const char* __restrict, char* __restrict, size_t);
+int unlink(const char*);
+int unlinkat(int, const char*, int);
+int rmdir(const char*);
+int truncate(const char*, off_t);
+int ftruncate(int, off_t);
+
+#define F_OK 0
+#define R_OK 4
+#define W_OK 2
+#define X_OK 1
+
+int access(const char*, int);
+int faccessat(int, const char*, int, int);
+
+int chdir(const char*);
+char* getcwd(char*, size_t);
+
+unsigned alarm(unsigned);
+unsigned sleep(unsigned);
+int pause(void);
+
+pid_t fork(void);
+int execve(const char*, char* const[], char* const[]);
+int execv(const char*, char* const[]);
+int execle(const char*, const char*, ...);
+int execl(const char*, const char*, ...);
+int execvp(const char*, char* const[]);
+int execlp(const char*, const char*, ...);
+int fexecve(int, char* const[], char* const[]);
+_Noreturn void _exit(int);
+
+pid_t getpid(void);
+pid_t getppid(void);
+pid_t getpgrp(void);
+pid_t getpgid(pid_t);
+int setpgid(pid_t, pid_t);
+pid_t setsid(void);
+pid_t getsid(pid_t);
+char* ttyname(int);
+int ttyname_r(int, char*, size_t);
+int isatty(int);
+pid_t tcgetpgrp(int);
+int tcsetpgrp(int, pid_t);
+
+uid_t getuid(void);
+uid_t geteuid(void);
+gid_t getgid(void);
+gid_t getegid(void);
+int getgroups(int, gid_t[]);
+int setuid(uid_t);
+int setreuid(uid_t, uid_t);
+int seteuid(uid_t);
+int setgid(gid_t);
+int setregid(gid_t, gid_t);
+int setegid(gid_t);
+
+char* getlogin(void);
+int getlogin_r(char*, size_t);
+int gethostname(char*, size_t);
+char* ctermid(char*);
+
+int getopt(int, char* const[], const char*);
+extern char* optarg;
+extern int optind, opterr, optopt;
+
+long pathconf(const char*, int);
+long fpathconf(int, int);
+long sysconf(int);
+size_t confstr(int, char*, size_t);
+
+#define F_ULOCK 0
+#define F_LOCK 1
+#define F_TLOCK 2
+#define F_TEST 3
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+int lockf(int, int, off_t);
+long gethostid(void);
+void sync(void);
+int syncfs(int);
+pid_t setpgrp(void);
+void swab(const void* __restrict, void* __restrict, ssize_t);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || \
+ (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE + 0 < 700)
+int usleep(unsigned);
+unsigned ualarm(unsigned, unsigned);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define L_SET 0
+#define L_INCR 1
+#define L_XTND 2
+int vhangup(void);
+int getpagesize(void);
+int getdtablesize(void);
+int sethostname(const char*, size_t);
+int getdomainname(char*, size_t);
+int setdomainname(const char*, size_t);
+int setgroups(size_t, const gid_t*);
+char* getpass(const char*);
+int acct(const char*);
+int execvpe(const char*, char* const[], char* const[]);
+int issetugid(void);
+#endif
+
+#ifdef _GNU_SOURCE
+extern char** environ;
+int setresuid(uid_t, uid_t, uid_t);
+int setresgid(gid_t, gid_t, gid_t);
+int getresuid(uid_t*, uid_t*, uid_t*);
+int getresgid(gid_t*, gid_t*, gid_t*);
+char* get_current_dir_name(void);
+int euidaccess(const char*, int);
+int eaccess(const char*, int);
+#endif
+
+#define POSIX_CLOSE_RESTART 0
+
+#define _XOPEN_VERSION 700
+#define _XOPEN_UNIX 1
+#define _XOPEN_ENH_I18N 1
+
+#define _POSIX_VERSION 200809L
+#define _POSIX2_VERSION _POSIX_VERSION
+
+#define _POSIX_ADVISORY_INFO _POSIX_VERSION
+#define _POSIX_CHOWN_RESTRICTED 1
+#define _POSIX_IPV6 _POSIX_VERSION
+#define _POSIX_JOB_CONTROL 1
+#define _POSIX_MAPPED_FILES _POSIX_VERSION
+#define _POSIX_MEMLOCK _POSIX_VERSION
+#define _POSIX_MEMLOCK_RANGE _POSIX_VERSION
+#define _POSIX_MEMORY_PROTECTION _POSIX_VERSION
+#define _POSIX_MESSAGE_PASSING _POSIX_VERSION
+#define _POSIX_FSYNC _POSIX_VERSION
+#define _POSIX_NO_TRUNC 1
+#define _POSIX_RAW_SOCKETS _POSIX_VERSION
+#define _POSIX_REALTIME_SIGNALS _POSIX_VERSION
+#define _POSIX_REGEXP 1
+#define _POSIX_SAVED_IDS 1
+#define _POSIX_SHELL 1
+#define _POSIX_SPAWN _POSIX_VERSION
+#define _POSIX_VDISABLE 0
+
+#define _POSIX_THREADS _POSIX_VERSION
+#define _POSIX_THREAD_PROCESS_SHARED _POSIX_VERSION
+#define _POSIX_THREAD_SAFE_FUNCTIONS _POSIX_VERSION
+#define _POSIX_THREAD_ATTR_STACKADDR _POSIX_VERSION
+#define _POSIX_THREAD_ATTR_STACKSIZE _POSIX_VERSION
+/* #define _POSIX_THREAD_PRIORITY_SCHEDULING -1 */
+#define _POSIX_THREAD_CPUTIME _POSIX_VERSION
+#define _POSIX_TIMERS _POSIX_VERSION
+#define _POSIX_TIMEOUTS _POSIX_VERSION
+#define _POSIX_MONOTONIC_CLOCK _POSIX_VERSION
+#define _POSIX_CPUTIME _POSIX_VERSION
+#define _POSIX_CLOCK_SELECTION _POSIX_VERSION
+#define _POSIX_BARRIERS _POSIX_VERSION
+#define _POSIX_SPIN_LOCKS _POSIX_VERSION
+#define _POSIX_READER_WRITER_LOCKS _POSIX_VERSION
+#define _POSIX_ASYNCHRONOUS_IO _POSIX_VERSION
+#define _POSIX_SEMAPHORES _POSIX_VERSION
+#define _POSIX_SHARED_MEMORY_OBJECTS _POSIX_VERSION
+
+#define _POSIX2_C_BIND _POSIX_VERSION
+
+#include <bits/posix.h>
+
+#define _PC_LINK_MAX 0
+#define _PC_MAX_CANON 1
+#define _PC_MAX_INPUT 2
+#define _PC_NAME_MAX 3
+#define _PC_PATH_MAX 4
+#define _PC_PIPE_BUF 5
+#define _PC_CHOWN_RESTRICTED 6
+#define _PC_NO_TRUNC 7
+#define _PC_VDISABLE 8
+#define _PC_SYNC_IO 9
+#define _PC_ASYNC_IO 10
+#define _PC_PRIO_IO 11
+#define _PC_SOCK_MAXBUF 12
+#define _PC_FILESIZEBITS 13
+#define _PC_REC_INCR_XFER_SIZE 14
+#define _PC_REC_MAX_XFER_SIZE 15
+#define _PC_REC_MIN_XFER_SIZE 16
+#define _PC_REC_XFER_ALIGN 17
+#define _PC_ALLOC_SIZE_MIN 18
+#define _PC_SYMLINK_MAX 19
+#define _PC_2_SYMLINKS 20
+
+#define _SC_ARG_MAX 0
+#define _SC_CHILD_MAX 1
+#define _SC_CLK_TCK 2
+#define _SC_NGROUPS_MAX 3
+#define _SC_OPEN_MAX 4
+#define _SC_STREAM_MAX 5
+#define _SC_TZNAME_MAX 6
+#define _SC_JOB_CONTROL 7
+#define _SC_SAVED_IDS 8
+#define _SC_REALTIME_SIGNALS 9
+#define _SC_PRIORITY_SCHEDULING 10
+#define _SC_TIMERS 11
+#define _SC_ASYNCHRONOUS_IO 12
+#define _SC_PRIORITIZED_IO 13
+#define _SC_SYNCHRONIZED_IO 14
+#define _SC_FSYNC 15
+#define _SC_MAPPED_FILES 16
+#define _SC_MEMLOCK 17
+#define _SC_MEMLOCK_RANGE 18
+#define _SC_MEMORY_PROTECTION 19
+#define _SC_MESSAGE_PASSING 20
+#define _SC_SEMAPHORES 21
+#define _SC_SHARED_MEMORY_OBJECTS 22
+#define _SC_AIO_LISTIO_MAX 23
+#define _SC_AIO_MAX 24
+#define _SC_AIO_PRIO_DELTA_MAX 25
+#define _SC_DELAYTIMER_MAX 26
+#define _SC_MQ_OPEN_MAX 27
+#define _SC_MQ_PRIO_MAX 28
+#define _SC_VERSION 29
+#define _SC_PAGE_SIZE 30
+#define _SC_PAGESIZE 30 /* !! */
+#define _SC_RTSIG_MAX 31
+#define _SC_SEM_NSEMS_MAX 32
+#define _SC_SEM_VALUE_MAX 33
+#define _SC_SIGQUEUE_MAX 34
+#define _SC_TIMER_MAX 35
+#define _SC_BC_BASE_MAX 36
+#define _SC_BC_DIM_MAX 37
+#define _SC_BC_SCALE_MAX 38
+#define _SC_BC_STRING_MAX 39
+#define _SC_COLL_WEIGHTS_MAX 40
+#define _SC_EXPR_NEST_MAX 42
+#define _SC_LINE_MAX 43
+#define _SC_RE_DUP_MAX 44
+#define _SC_2_VERSION 46
+#define _SC_2_C_BIND 47
+#define _SC_2_C_DEV 48
+#define _SC_2_FORT_DEV 49
+#define _SC_2_FORT_RUN 50
+#define _SC_2_SW_DEV 51
+#define _SC_2_LOCALEDEF 52
+#define _SC_UIO_MAXIOV 60 /* !! */
+#define _SC_IOV_MAX 60
+#define _SC_THREADS 67
+#define _SC_THREAD_SAFE_FUNCTIONS 68
+#define _SC_GETGR_R_SIZE_MAX 69
+#define _SC_GETPW_R_SIZE_MAX 70
+#define _SC_LOGIN_NAME_MAX 71
+#define _SC_TTY_NAME_MAX 72
+#define _SC_THREAD_DESTRUCTOR_ITERATIONS 73
+#define _SC_THREAD_KEYS_MAX 74
+#define _SC_THREAD_STACK_MIN 75
+#define _SC_THREAD_THREADS_MAX 76
+#define _SC_THREAD_ATTR_STACKADDR 77
+#define _SC_THREAD_ATTR_STACKSIZE 78
+#define _SC_THREAD_PRIORITY_SCHEDULING 79
+#define _SC_THREAD_PRIO_INHERIT 80
+#define _SC_THREAD_PRIO_PROTECT 81
+#define _SC_THREAD_PROCESS_SHARED 82
+#define _SC_NPROCESSORS_CONF 83
+#define _SC_NPROCESSORS_ONLN 84
+#define _SC_PHYS_PAGES 85
+#define _SC_AVPHYS_PAGES 86
+#define _SC_ATEXIT_MAX 87
+#define _SC_PASS_MAX 88
+#define _SC_XOPEN_VERSION 89
+#define _SC_XOPEN_XCU_VERSION 90
+#define _SC_XOPEN_UNIX 91
+#define _SC_XOPEN_CRYPT 92
+#define _SC_XOPEN_ENH_I18N 93
+#define _SC_XOPEN_SHM 94
+#define _SC_2_CHAR_TERM 95
+#define _SC_2_UPE 97
+#define _SC_XOPEN_XPG2 98
+#define _SC_XOPEN_XPG3 99
+#define _SC_XOPEN_XPG4 100
+#define _SC_NZERO 109
+#define _SC_XBS5_ILP32_OFF32 125
+#define _SC_XBS5_ILP32_OFFBIG 126
+#define _SC_XBS5_LP64_OFF64 127
+#define _SC_XBS5_LPBIG_OFFBIG 128
+#define _SC_XOPEN_LEGACY 129
+#define _SC_XOPEN_REALTIME 130
+#define _SC_XOPEN_REALTIME_THREADS 131
+#define _SC_ADVISORY_INFO 132
+#define _SC_BARRIERS 133
+#define _SC_CLOCK_SELECTION 137
+#define _SC_CPUTIME 138
+#define _SC_THREAD_CPUTIME 139
+#define _SC_MONOTONIC_CLOCK 149
+#define _SC_READER_WRITER_LOCKS 153
+#define _SC_SPIN_LOCKS 154
+#define _SC_REGEXP 155
+#define _SC_SHELL 157
+#define _SC_SPAWN 159
+#define _SC_SPORADIC_SERVER 160
+#define _SC_THREAD_SPORADIC_SERVER 161
+#define _SC_TIMEOUTS 164
+#define _SC_TYPED_MEMORY_OBJECTS 165
+#define _SC_2_PBS 168
+#define _SC_2_PBS_ACCOUNTING 169
+#define _SC_2_PBS_LOCATE 170
+#define _SC_2_PBS_MESSAGE 171
+#define _SC_2_PBS_TRACK 172
+#define _SC_SYMLOOP_MAX 173
+#define _SC_STREAMS 174
+#define _SC_2_PBS_CHECKPOINT 175
+#define _SC_V6_ILP32_OFF32 176
+#define _SC_V6_ILP32_OFFBIG 177
+#define _SC_V6_LP64_OFF64 178
+#define _SC_V6_LPBIG_OFFBIG 179
+#define _SC_HOST_NAME_MAX 180
+#define _SC_TRACE 181
+#define _SC_TRACE_EVENT_FILTER 182
+#define _SC_TRACE_INHERIT 183
+#define _SC_TRACE_LOG 184
+
+#define _SC_IPV6 235
+#define _SC_RAW_SOCKETS 236
+#define _SC_V7_ILP32_OFF32 237
+#define _SC_V7_ILP32_OFFBIG 238
+#define _SC_V7_LP64_OFF64 239
+#define _SC_V7_LPBIG_OFFBIG 240
+#define _SC_SS_REPL_MAX 241
+#define _SC_TRACE_EVENT_NAME_MAX 242
+#define _SC_TRACE_NAME_MAX 243
+#define _SC_TRACE_SYS_MAX 244
+#define _SC_TRACE_USER_EVENT_MAX 245
+#define _SC_XOPEN_STREAMS 246
+#define _SC_THREAD_ROBUST_PRIO_INHERIT 247
+#define _SC_THREAD_ROBUST_PRIO_PROTECT 248
+
+#define _CS_PATH 0
+#define _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS 1
+#define _CS_GNU_LIBC_VERSION 2
+#define _CS_GNU_LIBPTHREAD_VERSION 3
+#define _CS_POSIX_V5_WIDTH_RESTRICTED_ENVS 4
+#define _CS_POSIX_V7_WIDTH_RESTRICTED_ENVS 5
+
+#define _CS_POSIX_V6_ILP32_OFF32_CFLAGS 1116
+#define _CS_POSIX_V6_ILP32_OFF32_LDFLAGS 1117
+#define _CS_POSIX_V6_ILP32_OFF32_LIBS 1118
+#define _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS 1119
+#define _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS 1120
+#define _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS 1121
+#define _CS_POSIX_V6_ILP32_OFFBIG_LIBS 1122
+#define _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS 1123
+#define _CS_POSIX_V6_LP64_OFF64_CFLAGS 1124
+#define _CS_POSIX_V6_LP64_OFF64_LDFLAGS 1125
+#define _CS_POSIX_V6_LP64_OFF64_LIBS 1126
+#define _CS_POSIX_V6_LP64_OFF64_LINTFLAGS 1127
+#define _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS 1128
+#define _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS 1129
+#define _CS_POSIX_V6_LPBIG_OFFBIG_LIBS 1130
+#define _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS 1131
+#define _CS_POSIX_V7_ILP32_OFF32_CFLAGS 1132
+#define _CS_POSIX_V7_ILP32_OFF32_LDFLAGS 1133
+#define _CS_POSIX_V7_ILP32_OFF32_LIBS 1134
+#define _CS_POSIX_V7_ILP32_OFF32_LINTFLAGS 1135
+#define _CS_POSIX_V7_ILP32_OFFBIG_CFLAGS 1136
+#define _CS_POSIX_V7_ILP32_OFFBIG_LDFLAGS 1137
+#define _CS_POSIX_V7_ILP32_OFFBIG_LIBS 1138
+#define _CS_POSIX_V7_ILP32_OFFBIG_LINTFLAGS 1139
+#define _CS_POSIX_V7_LP64_OFF64_CFLAGS 1140
+#define _CS_POSIX_V7_LP64_OFF64_LDFLAGS 1141
+#define _CS_POSIX_V7_LP64_OFF64_LIBS 1142
+#define _CS_POSIX_V7_LP64_OFF64_LINTFLAGS 1143
+#define _CS_POSIX_V7_LPBIG_OFFBIG_CFLAGS 1144
+#define _CS_POSIX_V7_LPBIG_OFFBIG_LDFLAGS 1145
+#define _CS_POSIX_V7_LPBIG_OFFBIG_LIBS 1146
+#define _CS_POSIX_V7_LPBIG_OFFBIG_LINTFLAGS 1147
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_UNISTD_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/utime.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/utime.h
new file mode 100644
index 0000000..b4368aa
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/utime.h
@@ -0,0 +1,23 @@
+#ifndef SYSROOT_UTIME_H_
+#define SYSROOT_UTIME_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_time_t
+
+#include <bits/alltypes.h>
+
+struct utimbuf {
+ time_t actime;
+ time_t modtime;
+};
+
+int utime(const char*, const struct utimbuf*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_UTIME_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/values.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/values.h
new file mode 100644
index 0000000..0862584
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/values.h
@@ -0,0 +1,39 @@
+#ifndef SYSROOT_VALUES_H_
+#define SYSROOT_VALUES_H_
+
+#include <limits.h>
+
+#define CHARBITS (sizeof(char) * 8)
+#define SHORTBITS (sizeof(short) * 8)
+#define INTBITS (sizeof(int) * 8)
+#define LONGBITS (sizeof(long) * 8)
+#define PTRBITS (sizeof(char*) * 8)
+#define DOUBLEBITS (sizeof(double) * 8)
+#define FLOATBITS (sizeof(float) * 8)
+
+#define MINSHORT SHRT_MIN
+#define MININT INT_MIN
+#define MINLONG LONG_MIN
+
+#define MAXSHORT SHRT_MAX
+#define MAXINT INT_MAX
+#define MAXLONG LONG_MAX
+
+#define HIBITS MINSHORT
+#define HIBITL MINLONG
+
+#include <float.h>
+
+#define MAXDOUBLE DBL_MAX
+#undef MAXFLOAT
+#define MAXFLOAT FLT_MAX
+#define MINDOUBLE DBL_MIN
+#define MINFLOAT FLT_MIN
+#define DMINEXP DBL_MIN_EXP
+#define FMINEXP FLT_MIN_EXP
+#define DMAXEXP DBL_MAX_EXP
+#define FMAXEXP FLT_MAX_EXP
+
+#define BITSPERBYTE CHAR_BIT
+
+#endif // SYSROOT_VALUES_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/wait.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/wait.h
new file mode 100644
index 0000000..98396e2
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/wait.h
@@ -0,0 +1,2 @@
+#warning redirecting incorrect #include <wait.h> to <sys/wait.h>
+#include <sys/wait.h>
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/wchar.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/wchar.h
new file mode 100644
index 0000000..aaa7e9e
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/wchar.h
@@ -0,0 +1,185 @@
+#ifndef SYSROOT_WCHAR_H_
+#define SYSROOT_WCHAR_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <bits/null.h>
+
+#define __NEED_FILE
+#define __NEED___isoc_va_list
+#define __NEED_size_t
+#define __NEED_wchar_t
+#define __NEED_wint_t
+#define __NEED_mbstate_t
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __NEED_va_list
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __NEED_wctype_t
+#endif
+
+#include <bits/alltypes.h>
+
+#ifndef WCHAR_MAX
+#define WCHAR_MAX __WCHAR_MAX__
+#endif
+
+#ifndef WCHAR_MIN
+#if defined(__WCHAR_MIN__)
+#define WCHAR_MIN __WCHAR_MIN__
+#else // defined(__WCHAR_MIN__)
+#if defined(__WCHAR_UNSIGNED__)
+#define WCHAR_MIN (L'\0' + 0)
+#else
+#define WCHAR_MIN (-WCHAR_MAX - 1)
+#endif // defined (__WCHAR_UNSIGNED)
+#endif // defined(__WCHAR_MIN__)
+#endif
+
+#undef WEOF
+#define WEOF 0xffffffffU
+
+wchar_t* wcscpy(wchar_t* __restrict, const wchar_t* __restrict);
+wchar_t* wcsncpy(wchar_t* __restrict, const wchar_t* __restrict, size_t);
+
+wchar_t* wcscat(wchar_t* __restrict, const wchar_t* __restrict);
+wchar_t* wcsncat(wchar_t* __restrict, const wchar_t* __restrict, size_t);
+
+int wcscmp(const wchar_t*, const wchar_t*);
+int wcsncmp(const wchar_t*, const wchar_t*, size_t);
+
+int wcscoll(const wchar_t*, const wchar_t*);
+size_t wcsxfrm(wchar_t* __restrict, const wchar_t* __restrict, size_t n);
+
+wchar_t* wcschr(const wchar_t*, wchar_t);
+wchar_t* wcsrchr(const wchar_t*, wchar_t);
+
+size_t wcscspn(const wchar_t*, const wchar_t*);
+size_t wcsspn(const wchar_t*, const wchar_t*);
+wchar_t* wcspbrk(const wchar_t*, const wchar_t*);
+
+wchar_t* wcstok(wchar_t* __restrict, const wchar_t* __restrict, wchar_t** __restrict);
+
+size_t wcslen(const wchar_t*);
+
+wchar_t* wcsstr(const wchar_t* __restrict, const wchar_t* __restrict);
+wchar_t* wcswcs(const wchar_t*, const wchar_t*);
+
+wchar_t* wmemchr(const wchar_t*, wchar_t, size_t);
+int wmemcmp(const wchar_t*, const wchar_t*, size_t);
+wchar_t* wmemcpy(wchar_t* __restrict, const wchar_t* __restrict, size_t);
+wchar_t* wmemmove(wchar_t*, const wchar_t*, size_t);
+wchar_t* wmemset(wchar_t*, wchar_t, size_t);
+
+wint_t btowc(int);
+int wctob(wint_t);
+
+int mbsinit(const mbstate_t*);
+size_t mbrtowc(wchar_t* __restrict, const char* __restrict, size_t, mbstate_t* __restrict);
+size_t wcrtomb(char* __restrict, wchar_t, mbstate_t* __restrict);
+
+size_t mbrlen(const char* __restrict, size_t, mbstate_t* __restrict);
+
+size_t mbsrtowcs(wchar_t* __restrict, const char** __restrict, size_t, mbstate_t* __restrict);
+size_t wcsrtombs(char* __restrict, const wchar_t** __restrict, size_t, mbstate_t* __restrict);
+
+float wcstof(const wchar_t* __restrict, wchar_t** __restrict);
+double wcstod(const wchar_t* __restrict, wchar_t** __restrict);
+long double wcstold(const wchar_t* __restrict, wchar_t** __restrict);
+
+long wcstol(const wchar_t* __restrict, wchar_t** __restrict, int);
+unsigned long wcstoul(const wchar_t* __restrict, wchar_t** __restrict, int);
+
+long long wcstoll(const wchar_t* __restrict, wchar_t** __restrict, int);
+unsigned long long wcstoull(const wchar_t* __restrict, wchar_t** __restrict, int);
+
+int fwide(FILE*, int);
+
+int wprintf(const wchar_t* __restrict, ...);
+int fwprintf(FILE* __restrict, const wchar_t* __restrict, ...);
+int swprintf(wchar_t* __restrict, size_t, const wchar_t* __restrict, ...);
+
+int vwprintf(const wchar_t* __restrict, __isoc_va_list);
+int vfwprintf(FILE* __restrict, const wchar_t* __restrict, __isoc_va_list);
+int vswprintf(wchar_t* __restrict, size_t, const wchar_t* __restrict, __isoc_va_list);
+
+int wscanf(const wchar_t* __restrict, ...);
+int fwscanf(FILE* __restrict, const wchar_t* __restrict, ...);
+int swscanf(const wchar_t* __restrict, const wchar_t* __restrict, ...);
+
+int vwscanf(const wchar_t* __restrict, __isoc_va_list);
+int vfwscanf(FILE* __restrict, const wchar_t* __restrict, __isoc_va_list);
+int vswscanf(const wchar_t* __restrict, const wchar_t* __restrict, __isoc_va_list);
+
+wint_t fgetwc(FILE*);
+wint_t getwc(FILE*);
+wint_t getwchar(void);
+
+wint_t fputwc(wchar_t, FILE*);
+wint_t putwc(wchar_t, FILE*);
+wint_t putwchar(wchar_t);
+
+wchar_t* fgetws(wchar_t* __restrict, int, FILE* __restrict);
+int fputws(const wchar_t* __restrict, FILE* __restrict);
+
+wint_t ungetwc(wint_t, FILE*);
+
+struct tm;
+size_t wcsftime(wchar_t* __restrict, size_t, const wchar_t* __restrict,
+ const struct tm* __restrict);
+
+#undef iswdigit
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+FILE* open_wmemstream(wchar_t**, size_t*);
+size_t mbsnrtowcs(wchar_t* __restrict, const char** __restrict, size_t, size_t,
+ mbstate_t* __restrict);
+size_t wcsnrtombs(char* __restrict, const wchar_t** __restrict, size_t, size_t,
+ mbstate_t* __restrict);
+wchar_t* wcsdup(const wchar_t*);
+size_t wcsnlen(const wchar_t*, size_t);
+wchar_t* wcpcpy(wchar_t* __restrict, const wchar_t* __restrict);
+wchar_t* wcpncpy(wchar_t* __restrict, const wchar_t* __restrict, size_t);
+int wcscasecmp(const wchar_t*, const wchar_t*);
+int wcsncasecmp(const wchar_t*, const wchar_t*, size_t);
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+int wcwidth(wchar_t);
+int wcswidth(const wchar_t*, size_t);
+int iswalnum(wint_t);
+int iswalpha(wint_t);
+int iswblank(wint_t);
+int iswcntrl(wint_t);
+int iswdigit(wint_t);
+int iswgraph(wint_t);
+int iswlower(wint_t);
+int iswprint(wint_t);
+int iswpunct(wint_t);
+int iswspace(wint_t);
+int iswupper(wint_t);
+int iswxdigit(wint_t);
+int iswctype(wint_t, wctype_t);
+wint_t towlower(wint_t);
+wint_t towupper(wint_t);
+wctype_t wctype(const char*);
+
+#ifndef __cplusplus
+#undef iswdigit
+#define iswdigit(a) (0 ? iswdigit(a) : ((unsigned)(a) - '0') < 10)
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_WCHAR_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/wctype.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/wctype.h
new file mode 100644
index 0000000..5a04bb8
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/wctype.h
@@ -0,0 +1,60 @@
+#ifndef SYSROOT_WCTYPE_H_
+#define SYSROOT_WCTYPE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_wint_t
+#define __NEED_wctype_t
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __NEED_locale_t
+#endif
+
+#include <bits/alltypes.h>
+
+typedef const int* wctrans_t;
+
+#undef WEOF
+#define WEOF 0xffffffffU
+
+#undef iswdigit
+
+int iswalnum(wint_t);
+int iswalpha(wint_t);
+int iswblank(wint_t);
+int iswcntrl(wint_t);
+int iswdigit(wint_t);
+int iswgraph(wint_t);
+int iswlower(wint_t);
+int iswprint(wint_t);
+int iswpunct(wint_t);
+int iswspace(wint_t);
+int iswupper(wint_t);
+int iswxdigit(wint_t);
+int iswctype(wint_t, wctype_t);
+wint_t towctrans(wint_t, wctrans_t);
+wint_t towlower(wint_t);
+wint_t towupper(wint_t);
+wctrans_t wctrans(const char*);
+wctype_t wctype(const char*);
+
+#ifndef __cplusplus
+#undef iswdigit
+#define iswdigit(a) (0 ? iswdigit(a) : ((unsigned)(a) - '0') < 10)
+#endif
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_WCTYPE_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/wordexp.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/wordexp.h
new file mode 100644
index 0000000..dd6caa0
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/wordexp.h
@@ -0,0 +1,41 @@
+#ifndef SYSROOT_WORDEXP_H_
+#define SYSROOT_WORDEXP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+#define WRDE_DOOFFS 1
+#define WRDE_APPEND 2
+#define WRDE_NOCMD 4
+#define WRDE_REUSE 8
+#define WRDE_SHOWERR 16
+#define WRDE_UNDEF 32
+
+typedef struct {
+ size_t we_wordc;
+ char** we_wordv;
+ size_t we_offs;
+} wordexp_t;
+
+#define WRDE_NOSYS -1
+#define WRDE_NOSPACE 1
+#define WRDE_BADCHAR 2
+#define WRDE_BADVAL 3
+#define WRDE_CMDSUB 4
+#define WRDE_SYNTAX 5
+
+int wordexp(const char* __restrict, wordexp_t* __restrict, int);
+void wordfree(wordexp_t*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_WORDEXP_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/assert.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/assert.h
new file mode 100644
index 0000000..d53115d
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/assert.h
@@ -0,0 +1,101 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_ASSERT_
+#define SYSROOT_ZIRCON_ASSERT_
+
+// For a description of which asserts are enabled at which debug levels, see the documentation for
+// GN build argument |assert_level|.
+
+#ifdef _KERNEL
+#include <assert.h>
+#define ZX_PANIC(args...) PANIC(args)
+#define ZX_ASSERT(args...) ASSERT(args)
+#define ZX_ASSERT_MSG(args...) ASSERT_MSG(args)
+#define ZX_DEBUG_ASSERT(args...) DEBUG_ASSERT(args)
+#define ZX_DEBUG_ASSERT_MSG(args...) DEBUG_ASSERT_MSG(args)
+#define ZX_DEBUG_ASSERT_COND(args...) DEBUG_ASSERT_COND(args)
+#define ZX_DEBUG_ASSERT_MSG_COND(args...) DEBUG_ASSERT_MSG_COND(args)
+#define ZX_DEBUG_ASSERT_IMPLEMENTED DEBUG_ASSERT_IMPLEMENTED
+
+#else // #ifdef _KERNEL
+
+#include <zircon/compiler.h>
+
+__BEGIN_CDECLS
+void __zx_panic(const char* format, ...) __NO_RETURN __PRINTFLIKE(1, 2);
+__END_CDECLS
+
+#define ZX_PANIC(fmt, ...) __zx_panic((fmt), ##__VA_ARGS__)
+
+// Assert that |x| is true, else panic.
+//
+// ZX_ASSERT is always enabled and |x| will be evaluated regardless of any build arguments.
+#define ZX_ASSERT(x) \
+ do { \
+ if (unlikely(!(x))) { \
+ ZX_PANIC("ASSERT FAILED at (%s:%d): %s\n", __FILE__, __LINE__, #x); \
+ } \
+ } while (0)
+
+// Assert that |x| is true, else panic with the given message.
+//
+// ZX_ASSERT_MSG is always enabled and |x| will be evaluated regardless of any build arguments.
+#define ZX_ASSERT_MSG(x, msg, msgargs...) \
+ do { \
+ if (unlikely(!(x))) { \
+ ZX_PANIC("ASSERT FAILED at (%s:%d): %s\n" msg "\n", __FILE__, __LINE__, #x, ##msgargs); \
+ } \
+ } while (0)
+
+// Conditionally implement ZX_DEBUG_ASSERT based on ZX_ASSERT_LEVEL.
+#ifdef ZX_ASSERT_LEVEL
+
+// ZX_DEBUG_ASSERT_IMPLEMENTED is intended to be used to conditionalize code that is logically part
+// of a debug assert. It's useful for performing complex consistency checks that are difficult to
+// work into a ZX_DEBUG_ASSERT statement.
+#define ZX_DEBUG_ASSERT_IMPLEMENTED (ZX_ASSERT_LEVEL > 1)
+#else
+#define ZX_DEBUG_ASSERT_IMPLEMENTED 0
+#endif
+
+// Assert that |x| is true, else panic.
+//
+// Depending on build arguments, ZX_DEBUG_ASSERT may or may not be enabled. When disabled, |x| will
+// not be evaluated.
+#define ZX_DEBUG_ASSERT(x) \
+ do { \
+ if (ZX_DEBUG_ASSERT_IMPLEMENTED && unlikely(!(x))) { \
+ ZX_PANIC("DEBUG ASSERT FAILED at (%s:%d): %s\n", __FILE__, __LINE__, #x); \
+ } \
+ } while (0)
+
+// Assert that |x| is true, else panic with the given message.
+//
+// Depending on build arguments, ZX_DEBUG_ASSERT_MSG may or may not be enabled. When disabled, |x|
+// will not be evaluated.
+#define ZX_DEBUG_ASSERT_MSG(x, msg, msgargs...) \
+ do { \
+ if (ZX_DEBUG_ASSERT_IMPLEMENTED && unlikely(!(x))) { \
+ ZX_PANIC("DEBUG ASSERT FAILED at (%s:%d): %s\n" msg "\n", __FILE__, __LINE__, #x, \
+ ##msgargs); \
+ } \
+ } while (0)
+
+// implement _COND versions of ZX_DEBUG_ASSERT which only emit the body if
+// ZX_DEBUG_ASSERT_IMPLEMENTED is set
+#if ZX_DEBUG_ASSERT_IMPLEMENTED
+#define ZX_DEBUG_ASSERT_COND(x) ZX_DEBUG_ASSERT(x)
+#define ZX_DEBUG_ASSERT_MSG_COND(x, msg, msgargs...) ZX_DEBUG_ASSERT_MSG(x, msg, msgargs)
+#else
+#define ZX_DEBUG_ASSERT_COND(x) \
+ do { \
+ } while (0)
+#define ZX_DEBUG_ASSERT_MSG_COND(x, msg, msgargs...) \
+ do { \
+ } while (0)
+#endif
+#endif // #ifdef _KERNEL
+
+#endif // SYSROOT_ZIRCON_ASSERT_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/boot/driver-config.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/boot/driver-config.h
new file mode 100644
index 0000000..8565ba6
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/boot/driver-config.h
@@ -0,0 +1,170 @@
+// Copyright 2018 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.
+
+#ifndef SYSROOT_ZIRCON_BOOT_DRIVER_CONFIG_H_
+#define SYSROOT_ZIRCON_BOOT_DRIVER_CONFIG_H_
+
+#include <stdint.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+// ZBI_TYPE_KERNEL_DRIVER item types (for zbi_header_t.extra)
+#define KDRV_ARM_PSCI 0x49435350 // 'PSCI'
+#define KDRV_ARM_GIC_V2 0x32434947 // 'GIC2'
+#define KDRV_ARM_GIC_V3 0x33434947 // 'GIC3'
+#define KDRV_ARM_GENERIC_TIMER 0x4D495441 // 'ATIM'
+#define KDRV_PL011_UART 0x55304C50 // 'PL0U'
+#define KDRV_AMLOGIC_UART 0x554C4D41 // 'AMLU'
+#define KDRV_NXP_IMX_UART 0x55584D49 // 'IMXU'
+#define KDRV_MT8167_UART 0x5538544D // 'MT8U'
+#define KDRV_HISILICON_POWER 0x4F505348 // 'HSPO'
+#define KDRV_AMLOGIC_HDCP 0x484C4D41 // 'AMLH'
+#define KDRV_MSM_UART 0x554D534D // 'MSMU'
+#define KDRV_MSM_POWER 1347244877 // 'MSMP'
+#define KDRV_DW8250_UART 0x44573855 // 'DW8U'
+#define KDRV_AS370_POWER 0x50303733 // '370P'
+#define KDRV_AMLOGIC_RNG 0x484C4D52 // 'AMLR'
+#define KDRV_GENERIC_32BIT_WATCHDOG 0x32334457 // 'WD32'
+#define KDRV_I8250_PIO_UART 0x30353238 // '8250'
+#define KDRV_I8250_MMIO_UART 0x4d353238 // '825M'
+
+// Kernel driver struct that can be used for simple drivers.
+// Used by KDRV_PL011_UART, KDRV_AMLOGIC_UART, KDRV_NXP_IMX_UART,
+// and KDRV_I8250_MMIO_UART.
+typedef struct {
+ uint64_t mmio_phys;
+ uint32_t irq;
+} dcfg_simple_t;
+
+// Used by KDRV_I8250_PIO_UART.
+typedef struct {
+ uint16_t base;
+ uint32_t irq;
+} dcfg_simple_pio_t;
+
+// for KDRV_MT8167_UART
+typedef struct {
+ uint64_t soc_mmio_phys;
+ uint64_t uart_mmio_phys;
+ uint32_t irq;
+} dcfg_soc_uart_t;
+
+// for KDRV_ARM_PSCI
+typedef struct {
+ bool use_hvc;
+ uint64_t shutdown_args[3];
+ uint64_t reboot_args[3];
+ uint64_t reboot_bootloader_args[3];
+ uint64_t reboot_recovery_args[3];
+} dcfg_arm_psci_driver_t;
+
+typedef struct {
+ uint64_t soc_imem_phys;
+ uint64_t soc_imem_offset;
+} dcfg_msm_power_driver_t;
+
+// for KDRV_ARM_GIC_V2
+typedef struct {
+ uint64_t mmio_phys;
+ uint64_t msi_frame_phys;
+ uint64_t gicd_offset;
+ uint64_t gicc_offset;
+ uint64_t gich_offset;
+ uint64_t gicv_offset;
+ uint32_t ipi_base;
+ bool optional;
+ bool use_msi;
+} dcfg_arm_gicv2_driver_t;
+
+// for KDRV_ARM_GIC_V3
+typedef struct {
+ uint64_t mmio_phys;
+ uint64_t gicd_offset;
+ uint64_t gicr_offset;
+ uint64_t gicr_stride;
+ uint64_t mx8_gpr_phys;
+ uint32_t ipi_base;
+ bool optional;
+} dcfg_arm_gicv3_driver_t;
+
+// for KDRV_ARM_GENERIC_TIMER
+typedef struct {
+ uint32_t irq_phys;
+ uint32_t irq_virt;
+ uint32_t irq_sphys;
+ uint32_t freq_override;
+} dcfg_arm_generic_timer_driver_t;
+
+// for KDRV_HISILICON_POWER
+typedef struct {
+ uint64_t sctrl_phys;
+ uint64_t pmu_phys;
+} dcfg_hisilicon_power_driver_t;
+
+// for KDRV_AMLOGIC_HDCP
+typedef struct {
+ uint64_t preset_phys;
+ uint64_t hiu_phys;
+ uint64_t hdmitx_phys;
+} dcfg_amlogic_hdcp_driver_t;
+
+// for KDRV_AMLOGIC_RNG
+typedef struct {
+ uint64_t rng_data_phys;
+ uint64_t rng_status_phys;
+ uint64_t rng_refresh_interval_usec;
+} dcfg_amlogic_rng_driver_t;
+
+// Defines a register write action for a generic kernel watchdog driver. An
+// action consists of the following steps.
+//
+// 1) Read from the register located a physical address |addr|
+// 2) Clear all of the bits in the value which was read using the |clr_mask|
+// 3) Set all of the bits in the value using the |set_mask|
+// 4) Write this value back to the address located at addr.
+//
+typedef struct {
+ uint64_t addr;
+ uint32_t clr_mask;
+ uint32_t set_mask;
+} dcfg_generic_32bit_watchdog_action_t;
+
+#define KDRV_GENERIC_32BIT_WATCHDOG_FLAG_ENABLED ((uint32_t)0x00000001)
+#define KDRV_GENERIC_32BIT_WATCHDOG_MIN_PERIOD ZX_MSEC(1)
+
+// Definitions of actions which may be taken by a generic 32 bit watchdog timer
+// kernel driver which may be passed by a bootloader. Field definitions are as
+// follows.
+//
+// |pet_action|
+// The address and masks needed to "pet" (aka, dismiss) a hardware watchdog timer.
+//
+// |enable_action|
+// The address and masks needed to enable a hardware watchdog timer. If enable
+// is an unsupported operation, the addr of the |enable_action| shall be zero.
+//
+// |disable_action|
+// The address and masks needed to disable a hardware watchdog timer. If
+// disable is an unsupported operation, the addr of the |disable_action| shall
+// be zero.
+//
+// |watchdog_period_nsec|
+// The period of the watchdog timer given in nanoseconds. When enabled, the
+// watchdog timer driver must pet the watch dog at least this often. The value
+// must be at least 1 mSec, typically much larger (on the order of a second or
+// two)
+//
+// |flags|
+// Storage for additional flags. Currently, only one flag is defined,
+// "FLAG_ENABLED". When this flag is set, it indicates that the watchdog timer
+// was left enabled by the bootloader at startup.
+typedef struct {
+ dcfg_generic_32bit_watchdog_action_t pet_action;
+ dcfg_generic_32bit_watchdog_action_t enable_action;
+ dcfg_generic_32bit_watchdog_action_t disable_action;
+ zx_duration_t watchdog_period_nsec;
+ uint32_t flags;
+} dcfg_generic_32bit_watchdog_t;
+
+#endif // SYSROOT_ZIRCON_BOOT_DRIVER_CONFIG_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/boot/e820.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/boot/e820.h
new file mode 100644
index 0000000..f0f98f0
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/boot/e820.h
@@ -0,0 +1,23 @@
+// Copyright 2017 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.
+
+#ifndef SYSROOT_ZIRCON_BOOT_E820_H_
+#define SYSROOT_ZIRCON_BOOT_E820_H_
+
+#include <stdint.h>
+#include <zircon/compiler.h>
+
+#define E820_RAM 1
+#define E820_RESERVED 2
+#define E820_ACPI 3
+#define E820_NVS 4
+#define E820_UNUSABLE 5
+
+typedef struct e820entry {
+ uint64_t addr;
+ uint64_t size;
+ uint32_t type;
+} __PACKED e820entry_t;
+
+#endif // SYSROOT_ZIRCON_BOOT_E820_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/boot/image.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/boot/image.h
new file mode 100644
index 0000000..1e23a25
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/boot/image.h
@@ -0,0 +1,636 @@
+// Copyright 2018 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.
+
+#ifndef SYSROOT_ZIRCON_BOOT_IMAGE_H_
+#define SYSROOT_ZIRCON_BOOT_IMAGE_H_
+
+// This file contains assembly code that cannot be clang formatted.
+// clang-format off
+
+#ifndef __ASSEMBLER__
+#include <stdint.h>
+#endif
+
+// Zircon Boot Image format (ZBI).
+//
+// A Zircon Boot Image consists of a container header followed by boot
+// items. Each boot item has a header (zbi_header_t) and then a payload of
+// zbi_header_t.length bytes, which can be any size. The zbi_header_t.type
+// field indicates how to interpret the payload. Many types specify an
+// additional type-specific header that begins a variable-sized payload.
+// zbi_header_t.length does not include the zbi_header_t itself, but does
+// include any type-specific headers as part of the payload. All fields in
+// all header formats are little-endian.
+//
+// Padding bytes appear after each item as needed to align the payload size
+// up to a ZBI_ALIGNMENT (8-byte) boundary. This padding is not reflected
+// in the zbi_header_t.length value.
+//
+// A "complete" ZBI can be booted by a Zircon-compatible boot loader.
+// It contains one ZBI_TYPE_KERNEL_{ARCH} boot item that must come first,
+// followed by any number of additional boot items, which must include
+// exactly one ZBI_TYPE_STORAGE_BOOTFS item.
+//
+// A partial ZBI cannot be booted, and is only used during the build process.
+// It contains one or more boot items and can be combined with other ZBIs to
+// make a complete ZBI.
+
+// All items begin at an 8-byte aligned offset into the image.
+#ifdef __ASSEMBLER__
+#define ZBI_ALIGNMENT (8)
+#else
+#define ZBI_ALIGNMENT (8u)
+#endif
+
+// Round n up to the next 8 byte boundary
+#ifndef __ASSEMBLER__
+#ifdef __cplusplus
+constexpr
+#endif
+static inline uint32_t ZBI_ALIGN(uint32_t n) {
+ return ((n + ZBI_ALIGNMENT - 1) & -ZBI_ALIGNMENT);
+}
+#endif
+
+// LSW of sha256("bootdata")
+#define ZBI_CONTAINER_MAGIC (0x868cf7e6)
+
+// LSW of sha256("bootitem")
+#define ZBI_ITEM_MAGIC (0xb5781729)
+
+// This flag is always required.
+#define ZBI_FLAG_VERSION (0x00010000)
+
+// ZBI items with the CRC32 flag must have a valid crc32.
+// Otherwise their crc32 field must contain ZBI_ITEM_NO_CRC32
+#define ZBI_FLAG_CRC32 (0x00020000)
+
+// Value for zbi_header_t.crc32 when ZBI_FLAG_CRC32 is not set.
+#define ZBI_ITEM_NO_CRC32 (0x4a87e8d6)
+
+#ifndef __ASSEMBLER__
+// Each header must be 8-byte aligned. The length field specifies the
+// actual payload length and does not include the size of padding.
+typedef struct {
+ // ZBI_TYPE_* constant, see below.
+ uint32_t type;
+
+ // Size of the payload immediately following this header. This
+ // does not include the header itself nor any alignment padding
+ // after the payload.
+ uint32_t length;
+
+ // Type-specific extra data. Each type specifies the use of this
+ // field; see below. When not explicitly specified, it should be zero.
+ uint32_t extra;
+
+ // Flags for this item. This must always include ZBI_FLAG_VERSION.
+ // It should contain ZBI_FLAG_CRC32 for any item where it's feasible
+ // to compute the CRC32 at build time. Other flags are specific to
+ // each type; see below.
+ uint32_t flags;
+
+ // For future expansion. Set to 0.
+ uint32_t reserved0;
+ uint32_t reserved1;
+
+ // Must be ZBI_ITEM_MAGIC.
+ uint32_t magic;
+
+ // Must be the CRC32 of payload if ZBI_FLAG_CRC32 is set,
+ // otherwise must be ZBI_ITEM_NO_CRC32.
+ uint32_t crc32;
+} zbi_header_t;
+#endif
+
+// Be sure to add new types to ZBI_ALL_TYPES.
+#define ZBI_ALL_TYPES(macro) \
+ macro(ZBI_TYPE_CONTAINER, "CONTAINER", ".bin") \
+ macro(ZBI_TYPE_KERNEL_X64, "KERNEL_X64", ".bin") \
+ macro(ZBI_TYPE_KERNEL_ARM64, "KERNEL_ARM64", ".bin") \
+ macro(ZBI_TYPE_DISCARD, "DISCARD", ".bin") \
+ macro(ZBI_TYPE_STORAGE_RAMDISK, "RAMDISK", ".bin") \
+ macro(ZBI_TYPE_STORAGE_BOOTFS, "BOOTFS", ".bin") \
+ macro(ZBI_TYPE_STORAGE_BOOTFS_FACTORY, "BOOTFS_FACTORY", ".bin") \
+ macro(ZBI_TYPE_CMDLINE, "CMDLINE", ".txt") \
+ macro(ZBI_TYPE_CRASHLOG, "CRASHLOG", ".bin") \
+ macro(ZBI_TYPE_NVRAM, "NVRAM", ".bin") \
+ macro(ZBI_TYPE_PLATFORM_ID, "PLATFORM_ID", ".bin") \
+ macro(ZBI_TYPE_CPU_CONFIG, "CPU_CONFIG", ".bin") /* Deprecated */ \
+ macro(ZBI_TYPE_CPU_TOPOLOGY, "CPU_TOPOLOGY", ".bin") \
+ macro(ZBI_TYPE_MEM_CONFIG, "MEM_CONFIG", ".bin") \
+ macro(ZBI_TYPE_KERNEL_DRIVER, "KERNEL_DRIVER", ".bin") \
+ macro(ZBI_TYPE_ACPI_RSDP, "ACPI_RSDP", ".bin") \
+ macro(ZBI_TYPE_SMBIOS, "SMBIOS", ".bin") \
+ macro(ZBI_TYPE_EFI_MEMORY_MAP, "EFI_MEMORY_MAP", ".bin") \
+ macro(ZBI_TYPE_EFI_SYSTEM_TABLE, "EFI_SYSTEM_TABLE", ".bin") \
+ macro(ZBI_TYPE_E820_TABLE, "E820_TABLE", ".bin") \
+ macro(ZBI_TYPE_FRAMEBUFFER, "FRAMEBUFFER", ".bin") \
+ macro(ZBI_TYPE_DRV_MAC_ADDRESS, "DRV_MAC_ADDRESS", ".bin") \
+ macro(ZBI_TYPE_DRV_PARTITION_MAP, "DRV_PARTITION_MAP", ".bin") \
+ macro(ZBI_TYPE_DRV_BOARD_PRIVATE, "DRV_BOARD_PRIVATE", ".bin") \
+ macro(ZBI_TYPE_DRV_BOARD_INFO, "DRV_BOARD_INFO", ".bin") \
+ macro(ZBI_TYPE_IMAGE_ARGS, "IMAGE_ARGS", ".txt") \
+ macro(ZBI_TYPE_BOOT_VERSION, "BOOT_VERSION", ".bin") \
+ macro(ZBI_TYPE_HW_REBOOT_REASON, "HW_REBOOT_REASON", ".bin")
+
+// Each ZBI starts with a container header.
+// length: Total size of the image after this header.
+// This includes all item headers, payloads, and padding.
+// It does not include the container header itself.
+// Must be a multiple of ZBI_ALIGNMENT.
+// extra: Must be ZBI_CONTAINER_MAGIC.
+// flags: Must be ZBI_FLAG_VERSION and no other flags.
+#define ZBI_TYPE_CONTAINER (0x544f4f42) // BOOT
+
+// Define a container header in assembly code. The symbol name is defined
+// as a local label; use .global symbol to make it global. The length
+// argument can use assembly label arithmetic like any immediate operand.
+#ifdef __ASSEMBLER__
+#define ZBI_CONTAINER_HEADER(symbol, length) \
+ .balign ZBI_ALIGNMENT; \
+ symbol: \
+ .int ZBI_TYPE_CONTAINER; \
+ .int (length); \
+ .int ZBI_CONTAINER_MAGIC; \
+ .int ZBI_FLAG_VERSION; \
+ .int 0; \
+ .int 0; \
+ .int ZBI_ITEM_MAGIC; \
+ .int ZBI_ITEM_NO_CRC32; \
+ .size symbol, . - symbol; \
+ .type symbol, %object
+#else
+#define ZBI_CONTAINER_HEADER(length) { \
+ ZBI_TYPE_CONTAINER, \
+ (length), \
+ ZBI_CONTAINER_MAGIC, \
+ ZBI_FLAG_VERSION, \
+ 0, \
+ 0, \
+ ZBI_ITEM_MAGIC, \
+ ZBI_ITEM_NO_CRC32, \
+}
+#endif
+
+
+// The kernel image. In a complete ZBI this item must always be first,
+// immediately after the ZBI_TYPE_CONTAINER header. The contiguous memory
+// image of the kernel is formed from the ZBI_TYPE_CONTAINER header, the
+// ZBI_TYPE_KERNEL_{ARCH} header, and the payload.
+//
+// The boot loader loads the whole image starting with the container header
+// through to the end of the kernel item's payload into contiguous physical
+// memory. It then constructs a partial ZBI elsewhere in memory, which has
+// a ZBI_TYPE_CONTAINER header of its own followed by all the other items
+// that were in the booted ZBI plus other items synthesized by the boot
+// loader to describe the machine. This partial ZBI must be placed at an
+// address (where the container header is found) that is aligned to the
+// machine's page size. The precise protocol for transferring control to
+// the kernel's entry point varies by machine.
+//
+// On all machines, the kernel requires some amount of scratch memory to be
+// available immediately after the kernel image at boot. It needs this
+// space for early setup work before it has a chance to read any memory-map
+// information from the boot loader. The `reserve_memory_size` field tells
+// the boot loader how much space after the kernel's load image it must
+// leave available for the kernel's use. The boot loader must place its
+// constructed ZBI or other reserved areas at least this many bytes after
+// the kernel image.
+//
+// x86-64
+//
+// The kernel assumes it was loaded at a fixed physical address of
+// 0x100000 (1MB). zbi_kernel_t.entry is the absolute physical address
+// of the PC location where the kernel will start.
+// TODO(SEC-31): Perhaps this will change??
+// The processor is in 64-bit mode with direct virtual to physical
+// mapping covering the physical memory where the kernel and
+// bootloader-constructed ZBI were loaded.
+// The %rsi register holds the physical address of the
+// bootloader-constructed ZBI.
+// All other registers are unspecified.
+//
+// ARM64
+//
+// zbi_kernel_t.entry is an offset from the beginning of the image
+// (i.e., the ZBI_TYPE_CONTAINER header before the ZBI_TYPE_KERNEL_ARM64
+// header) to the PC location in the image where the kernel will
+// start. The processor is in physical address mode at EL1 or
+// above. The kernel image and the bootloader-constructed ZBI each
+// can be loaded anywhere in physical memory. The x0 register
+// holds the physical address of the bootloader-constructed ZBI.
+// All other registers are unspecified.
+//
+#define ZBI_TYPE_KERNEL_PREFIX (0x004e524b) // KRN\0
+#define ZBI_TYPE_KERNEL_MASK (0x00FFFFFF)
+#define ZBI_TYPE_KERNEL_X64 (0x4c4e524b) // KRNL
+#define ZBI_TYPE_KERNEL_ARM64 (0x384e524b) // KRN8
+#define ZBI_IS_KERNEL_BOOTITEM(x) (((x) & ZBI_TYPE_KERNEL_MASK) == \
+ ZBI_TYPE_KERNEL_PREFIX)
+
+#ifndef __ASSEMBLER__
+typedef struct {
+ // Entry-point address. The interpretation of this differs by machine.
+ uint64_t entry;
+ // Minimum amount (in bytes) of scratch memory that the kernel requires
+ // immediately after its load image.
+ uint64_t reserve_memory_size;
+} zbi_kernel_t;
+
+// The whole contiguous image loaded into memory by the boot loader.
+typedef struct {
+ zbi_header_t hdr_file;
+ zbi_header_t hdr_kernel;
+ zbi_kernel_t data_kernel;
+ uint8_t contents[/*hdr_kernel.length - sizeof(zbi_kernel_t)*/];
+ // data_kernel.reserve_memory_size bytes in memory are free after contents.
+} zircon_kernel_t;
+#endif
+
+
+// A discarded item that should just be ignored. This is used for an
+// item that was already processed and should be ignored by whatever
+// stage is now looking at the ZBI. An earlier stage already "consumed"
+// this information, but avoided copying data around to remove it from
+// the ZBI item stream.
+#define ZBI_TYPE_DISCARD (0x50494b53) // SKIP
+
+
+// ZBI_TYPE_STORAGE_* types represent an image that might otherwise
+// appear on some block storage device, i.e. a RAM disk of some sort.
+// All zbi_header_t fields have the same meanings for all these types.
+// The interpretation of the payload (after possible decompression) is
+// indicated by the specific zbi_header_t.type value.
+//
+// **Note:** The ZBI_TYPE_STORAGE_* types are not a long-term stable ABI.
+// - Items of these types are always packed for a specific version of the
+// kernel and userland boot services, often in the same build that compiles
+// the kernel.
+// - These item types are **not** expected to be synthesized or
+// examined by boot loaders.
+// - New versions of the `zbi` tool will usually retain the ability to
+// read old formats and non-default switches to write old formats, for
+// diagnostic use.
+//
+// The zbi_header_t.extra field always gives the exact size of the
+// original, uncompressed payload. That equals zbi_header_t.length when
+// the payload is not compressed. If ZBI_FLAG_STORAGE_COMPRESSED is set in
+// zbi_header_t.flags, then the payload is compressed.
+//
+// **Note:** Magic-number and header bytes at the start of the compressed
+// payload indicate the compression algorithm and parameters. The set of
+// compression formats is not a long-term stable ABI.
+// - Zircon [userboot](../../../../docs/userboot.md) and core services
+// do the decompression. A given kernel build's `userboot` will usually
+// only support one particular compression format.
+// - The `zbi` tool will usually retain the ability to compress and
+// decompress for old formats, and can be used to convert between formats.
+#define ZBI_FLAG_STORAGE_COMPRESSED (0x00000001)
+
+// A virtual disk image. This is meant to be treated as if it were a
+// storage device. The payload (after decompression) is the contents of
+// the storage device, in whatever format that might be.
+#define ZBI_TYPE_STORAGE_RAMDISK (0x4b534452) // RDSK
+
+// The /boot filesystem in BOOTFS format, specified in <zircon/boot/bootfs.h>.
+// A complete ZBI must have exactly one ZBI_TYPE_STORAGE_BOOTFS item.
+// Zircon [userboot](../../../../docs/userboot.md) handles the contents
+// of this filesystem.
+#define ZBI_TYPE_STORAGE_BOOTFS (0x42534642) // BFSB
+
+// Device-specific factory data, stored in BOOTFS format, specified below.
+#define ZBI_TYPE_STORAGE_BOOTFS_FACTORY (0x46534642) // BFSF
+
+// The remaining types are used to communicate information from the boot
+// loader to the kernel. Usually these are synthesized in memory by the
+// boot loader, but they can also be included in a ZBI along with the
+// kernel and BOOTFS. Some boot loaders may set the zbi_header_t flags
+// and crc32 fields to zero, though setting them to ZBI_FLAG_VERSION and
+// ZBI_ITEM_NO_CRC32 is specified. The kernel doesn't check.
+
+
+// A kernel command line fragment, a NUL-terminated UTF-8 string.
+// Multiple ZBI_TYPE_CMDLINE items can appear. They are treated as if
+// concatenated with ' ' between each item, in the order they appear:
+// first items in the complete ZBI containing the kernel; then items in
+// the ZBI synthesized by the boot loader. The kernel interprets the
+// [whole command line](../../../../docs/kernel_cmdline.md).
+#define ZBI_TYPE_CMDLINE (0x4c444d43) // CMDL
+
+// The crash log from the previous boot, a UTF-8 string.
+#define ZBI_TYPE_CRASHLOG (0x4d4f4f42) // BOOM
+
+// Physical memory region that will persist across warm boots.
+// zbi_nvram_t gives the physical base address and length in bytes.
+#define ZBI_TYPE_NVRAM (0x4c4c564e) // NVLL
+// This reflects a typo we need to support for a while.
+#define ZBI_TYPE_NVRAM_DEPRECATED (0x4c4c5643) // CVLL
+#ifndef __ASSEMBLER__
+typedef struct {
+ uint64_t base;
+ uint64_t length;
+} zbi_nvram_t;
+#endif
+
+#define ZBI_BOARD_NAME_LEN 32
+
+// Platform ID Information.
+#define ZBI_TYPE_PLATFORM_ID (0x44494C50) // PLID
+#ifndef __ASSEMBLER__
+typedef struct {
+ uint32_t vid;
+ uint32_t pid;
+ char board_name[ZBI_BOARD_NAME_LEN];
+} zbi_platform_id_t;
+#endif
+
+#define ZBI_TYPE_DRV_BOARD_INFO (0x4953426D) // mBSI
+// Board-specific information.
+#ifndef __ASSEMBLER__
+typedef struct {
+ uint32_t revision;
+} zbi_board_info_t;
+#endif
+
+// CPU configuration, a zbi_cpu_config_t header followed by one or more
+// zbi_cpu_cluster_t entries. zbi_header_t.length must equal
+// zbi_cpu_config_t.cluster_count * sizeof(zbi_cpu_cluster_t).
+#define ZBI_TYPE_CPU_CONFIG (0x43555043) // CPUC
+#ifndef __ASSEMBLER__
+typedef struct {
+ // Number of CPU cores in the cluster.
+ uint32_t cpu_count;
+
+ // Reserved for future use. Set to 0.
+ uint32_t type;
+ uint32_t flags;
+ uint32_t reserved;
+} zbi_cpu_cluster_t;
+
+typedef struct {
+ // Number of zbi_cpu_cluster_t entries following this header.
+ uint32_t cluster_count;
+
+ // Reserved for future use. Set to 0.
+ uint32_t reserved[3];
+
+ // cluster_count entries follow.
+ zbi_cpu_cluster_t clusters[];
+} zbi_cpu_config_t;
+#endif
+
+#define ZBI_TYPE_CPU_TOPOLOGY (0x544F504F) // TOPO
+
+#ifndef __ASSEMBLER__
+
+#define ZBI_MAX_SMT 4
+
+// These are Used in the flags field of zbi_topology_processor_t.
+
+// This is the processor that boots the system and the last to be shutdown.
+#define ZBI_TOPOLOGY_PROCESSOR_PRIMARY 0b1
+
+// This is the processor that handles all interrupts, some architectures will
+// not have one.
+#define ZBI_TOPOLOGY_PROCESSOR_INTERRUPT 0b10
+
+#define ZBI_TOPOLOGY_NO_PARENT 0xFFFF
+
+typedef enum {
+ ZBI_TOPOLOGY_ARCH_UNDEFINED = 0, // Intended primarily for testing.
+ ZBI_TOPOLOGY_ARCH_X86 = 1,
+ ZBI_TOPOLOGY_ARCH_ARM = 2,
+} zbi_topology_architecture_t;
+
+typedef struct {
+ // Cluster ids for each level, one being closest to the cpu.
+ // These map to aff1, aff2, and aff3 values in the ARM registers.
+ uint8_t cluster_1_id;
+ uint8_t cluster_2_id;
+ uint8_t cluster_3_id;
+
+ // Id of the cpu inside of the bottom-most cluster, aff0 value.
+ uint8_t cpu_id;
+
+ // The GIC interface number for this processor.
+ // In GIC v3+ this is not necessary as the processors are addressed by their
+ // affinity routing (all cluster ids followed by cpu_id).
+ uint8_t gic_id;
+} zbi_topology_arm_info_t;
+
+typedef struct {
+ // Indexes here correspond to the logical_ids index for the thread.
+ uint32_t apic_ids[ZBI_MAX_SMT];
+ uint32_t apic_id_count;
+} zbi_topology_x86_info_t;
+
+typedef struct {
+ uint16_t logical_ids[ZBI_MAX_SMT];
+ uint8_t logical_id_count;
+
+ uint16_t flags;
+
+ // Should be one of zbi_topology_arm_info_t.
+ // If UNDEFINED then nothing will be set in arch_info.
+ uint8_t architecture;
+ union {
+ zbi_topology_arm_info_t arm;
+ zbi_topology_x86_info_t x86;
+ } architecture_info;
+
+} zbi_topology_processor_t;
+
+typedef struct {
+ // Relative performance level of this processor in the system, with 0
+ // representing the lowest performance.
+ // For example on a two cluster ARM big.LITTLE system 0 would be the little
+ // cores and 1 would represent the big cores.
+ uint8_t performance_class;
+} zbi_topology_cluster_t;
+
+typedef struct {
+ // Starting and ending memory addresses of this numa region.
+ uint64_t start_address;
+ uint64_t end_address;
+} zbi_topology_numa_region_t;
+
+typedef enum {
+ ZBI_TOPOLOGY_ENTITY_UNDEFINED = 0, // Unused default.
+ ZBI_TOPOLOGY_ENTITY_PROCESSOR = 1,
+ ZBI_TOPOLOGY_ENTITY_CLUSTER = 2,
+ ZBI_TOPOLOGY_ENTITY_CACHE = 3,
+ ZBI_TOPOLOGY_ENTITY_DIE = 4,
+ ZBI_TOPOLOGY_ENTITY_SOCKET = 5,
+ ZBI_TOPOLOGY_ENTITY_POWER_PLANE = 6,
+ ZBI_TOPOLOGY_ENTITY_NUMA_REGION = 7,
+} zbi_topology_entity_type_t;
+
+typedef struct {
+ // Should be one of zbi_topology_entity_type_t.
+ uint8_t entity_type;
+ uint16_t parent_index;
+ union {
+ zbi_topology_processor_t processor;
+ zbi_topology_cluster_t cluster;
+ zbi_topology_numa_region_t numa_region;
+ } entity;
+} zbi_topology_node_t;
+
+#endif
+
+// Memory configuration, one or more zbi_mem_range_t entries.
+// zbi_header_t.length is sizeof(zbi_mem_range_t) times the number of entries.
+#define ZBI_TYPE_MEM_CONFIG (0x434D454D) // MEMC
+#ifndef __ASSEMBLER__
+typedef struct {
+ uint64_t paddr;
+ uint64_t length;
+ uint32_t type;
+ uint32_t reserved;
+} zbi_mem_range_t;
+#endif
+#define ZBI_MEM_RANGE_RAM (1)
+#define ZBI_MEM_RANGE_PERIPHERAL (2)
+#define ZBI_MEM_RANGE_RESERVED (3)
+
+// Kernel driver configuration. The zbi_header_t.extra field gives a
+// KDRV_* type that determines the payload format.
+// See [driver-config.h](<zircon/boot/driver-config.h>) for details.
+#define ZBI_TYPE_KERNEL_DRIVER (0x5652444B) // KDRV
+
+// ACPI Root Table Pointer, a uint64_t physical address.
+#define ZBI_TYPE_ACPI_RSDP (0x50445352) // RSDP
+
+// SMBIOS entry point, a uint64_t physical address.
+#define ZBI_TYPE_SMBIOS (0x49424d53) // SMBI
+
+// EFI memory map, a uint64_t entry size followed by a sequence of
+// EFI memory descriptors aligned on that entry size.
+#define ZBI_TYPE_EFI_MEMORY_MAP (0x4d494645) // EFIM
+
+// EFI system table, a uint64_t physical address.
+#define ZBI_TYPE_EFI_SYSTEM_TABLE (0x53494645) // EFIS
+
+// E820 memory table, an array of e820entry_t.
+#define ZBI_TYPE_E820_TABLE (0x30323845) // E820
+
+/* EFI Variable for Crash Log */
+#define ZIRCON_VENDOR_GUID \
+ {0x82305eb2, 0xd39e, 0x4575, {0xa0, 0xc8, 0x6c, 0x20, 0x72, 0xd0, 0x84, 0x4c}}
+#define ZIRCON_CRASHLOG_EFIVAR \
+ { 'c', 'r', 'a', 's', 'h', 'l', 'o', 'g', 0 }
+#define ZIRCON_CRASHLOG_EFIATTR \
+ (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS)
+
+// Framebuffer parameters, a zbi_swfb_t entry.
+#define ZBI_TYPE_FRAMEBUFFER (0x42465753) // SWFB
+
+// The image arguments, data is a trivial text format of one "key=value" per line
+// with leading whitespace stripped and "#" comment lines and blank lines ignored.
+// It is processed by bootsvc and parsed args are shared to others via Arguments service.
+// TODO: the format can be streamlined after the /config/devmgr compat support is removed.
+#define ZBI_TYPE_IMAGE_ARGS (0x47524149) // IARG
+
+// A copy of the boot version stored within the sysconfig
+// partition
+#define ZBI_TYPE_BOOT_VERSION (0x53525642) // BVRS
+
+#ifndef __ASSEMBLER__
+typedef struct {
+ // Physical memory address.
+ uint64_t base;
+
+ // Pixel layout and format.
+ // See [../pixelformat.h](<zircon/pixelformat.h>).
+ uint32_t width;
+ uint32_t height;
+ uint32_t stride;
+ uint32_t format;
+} zbi_swfb_t;
+#endif
+
+
+// ZBI_TYPE_DRV_* types (LSB is 'm') contain driver metadata.
+#define ZBI_TYPE_DRV_METADATA(type) (((type) & 0xFF) == 0x6D) // 'm'
+
+// MAC address for Ethernet, Wifi, Bluetooth, etc. zbi_header_t.extra
+// is a board-specific index to specify which device the MAC address
+// applies to. zbi_header_t.length gives the size in bytes, which
+// varies depending on the type of address appropriate for the device.
+#define ZBI_TYPE_DRV_MAC_ADDRESS (0x43414D6D) // mMAC
+
+// A partition map for a storage device, a zbi_partition_map_t header
+// followed by one or more zbi_partition_t entries. zbi_header_t.extra
+// is a board-specific index to specify which device this applies to.
+#define ZBI_TYPE_DRV_PARTITION_MAP (0x5452506D) // mPRT
+#define ZBI_PARTITION_NAME_LEN (32)
+#define ZBI_PARTITION_GUID_LEN (16)
+
+// Private information for the board driver.
+#define ZBI_TYPE_DRV_BOARD_PRIVATE (0x524F426D) // mBOR
+
+#ifndef __ASSEMBLER__
+typedef struct {
+ // GUID specifying the format and use of data stored in the partition.
+ uint8_t type_guid[ZBI_PARTITION_GUID_LEN];
+
+ // GUID unique to this partition.
+ uint8_t uniq_guid[ZBI_PARTITION_GUID_LEN];
+
+ // First and last block occupied by this partition.
+ uint64_t first_block;
+ uint64_t last_block;
+
+ // Reserved for future use. Set to 0.
+ uint64_t flags;
+
+ char name[ZBI_PARTITION_NAME_LEN];
+} zbi_partition_t;
+
+typedef struct {
+ // Total blocks used on the device.
+ uint64_t block_count;
+ // Size of each block in bytes.
+ uint64_t block_size;
+
+ // Number of partitions in the map.
+ uint32_t partition_count;
+
+ // Reserved for future use.
+ uint32_t reserved;
+
+ // Device GUID.
+ uint8_t guid[ZBI_PARTITION_GUID_LEN];
+
+ // partition_count partition entries follow.
+ zbi_partition_t partitions[];
+} zbi_partition_map_t;
+#endif
+
+
+#define ZBI_TYPE_HW_REBOOT_REASON (0x42525748) // HWRB
+
+#define ZBI_HW_REBOOT_UNDEFINED ((uint32_t)0)
+#define ZBI_HW_REBOOT_COLD ((uint32_t)1)
+#define ZBI_HW_REBOOT_WARM ((uint32_t)2)
+#define ZBI_HW_REBOOT_BROWNOUT ((uint32_t)3)
+#define ZBI_HW_REBOOT_WATCHDOG ((uint32_t)4)
+
+#ifndef __ASSEMBLER__
+#ifndef __cplusplus
+typedef uint32_t zbi_hw_reboot_reason_t;
+#else
+enum class ZbiHwRebootReason : uint32_t {
+ Undefined = ZBI_HW_REBOOT_UNDEFINED,
+ Cold = ZBI_HW_REBOOT_COLD,
+ Warm = ZBI_HW_REBOOT_WARM,
+ Brownout = ZBI_HW_REBOOT_BROWNOUT,
+ Watchdog = ZBI_HW_REBOOT_WATCHDOG,
+};
+using zbi_hw_reboot_reason_t = ZbiHwRebootReason;
+#endif // __cplusplus
+#endif // __ASSEMBLER__
+
+#endif // SYSROOT_ZIRCON_BOOT_IMAGE_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/boot/multiboot.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/boot/multiboot.h
new file mode 100644
index 0000000..85cf0a6
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/boot/multiboot.h
@@ -0,0 +1,114 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Copyright (c) 2009 Corey Tabaka
+
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SYSROOT_ZIRCON_MULTIBOOT_H_
+#define SYSROOT_ZIRCON_MULTIBOOT_H_
+
+/* magic number for multiboot header */
+#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
+
+// Flags for multiboot header:
+// 0x00000002: Boot loader should provide memory map.
+// 0x00010000: *_addr fields in multiboot_header_t are used.
+#define MULTIBOOT_HEADER_FLAGS 0x00010002
+
+/* magic number passed by multiboot-compliant boot loaders */
+#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+/* multiboot header */
+typedef struct multiboot_header {
+ uint32_t magic;
+ uint32_t flags;
+ uint32_t checksum;
+ uint32_t header_addr;
+ uint32_t load_addr;
+ uint32_t load_end_addr;
+ uint32_t bss_end_addr;
+ uint32_t entry_addr;
+} multiboot_header_t;
+
+/* symbol table for a.out */
+typedef struct aout_symbol_table {
+ uint32_t tabsize;
+ uint32_t strsize;
+ uint32_t addr;
+ uint32_t reserved;
+} aout_symbol_table_t;
+
+/* section header table for ELF */
+typedef struct elf_section_header_table {
+ uint32_t num;
+ uint32_t size;
+ uint32_t addr;
+ uint32_t shndx;
+} elf_section_header_table_t;
+
+/* multiboot info */
+typedef struct multiboot_info {
+ uint32_t flags;
+ uint32_t mem_lower;
+ uint32_t mem_upper;
+ uint32_t boot_device;
+ uint32_t cmdline;
+ uint32_t mods_count;
+ uint32_t mods_addr;
+ union {
+ aout_symbol_table_t aout_sym;
+ elf_section_header_table_t elf_sec;
+ } u;
+ uint32_t mmap_length;
+ uint32_t mmap_addr;
+ uint32_t drives_length;
+ uint32_t drives_addr;
+ uint32_t config_table;
+ uint32_t boot_loader_name;
+ uint32_t apm_table;
+} multiboot_info_t;
+
+#define MB_INFO_MEM_SIZE 0x001
+#define MB_INFO_BOOT_DEV 0x002
+#define MB_INFO_CMD_LINE 0x004
+#define MB_INFO_MODS 0x008
+#define MB_INFO_SYMS 0x010
+#define MB_INFO_SHDR 0x020
+#define MB_INFO_MMAP 0x040
+#define MB_INFO_DRIVES 0x080
+#define MB_INFO_CONFIG 0x100
+#define MB_INFO_BOOT_LOADER 0x200
+#define MB_INFO_APM_TABLE 0x400
+#define MB_INFO_VBE 0x800
+
+/* module structure */
+typedef struct module {
+ uint32_t mod_start;
+ uint32_t mod_end;
+ uint32_t string;
+ uint32_t reserved;
+} module_t;
+
+/* memory map - be careful that the offset 0 is base_addr_low without size */
+typedef struct memory_map {
+ uint32_t size;
+ uint32_t base_addr_low;
+ uint32_t base_addr_high;
+ uint32_t length_low;
+ uint32_t length_high;
+ uint32_t type;
+} memory_map_t;
+
+/* memory map entry types */
+#define MB_MMAP_TYPE_AVAILABLE 0x01
+#define MB_MMAP_TYPE_RESERVED 0x02
+#define MB_MMAP_TYPE_ACPI_RECLAIM 0x03
+#define MB_MMAP_TYPE_ACPI_NVS 0x04
+
+#endif
+
+#endif // SYSROOT_ZIRCON_BOOT_MULTIBOOT_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/boot/netboot.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/boot/netboot.h
new file mode 100644
index 0000000..edbfd53
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/boot/netboot.h
@@ -0,0 +1,150 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_BOOT_NETBOOT_H_
+#define SYSROOT_ZIRCON_BOOT_NETBOOT_H_
+
+#include <stddef.h>
+#include <stdint.h>
+#include <zircon/types.h>
+
+// clang-format off
+
+#define BOOTLOADER_VERSION "0.7.22"
+
+#define NB_MAGIC 0xAA774217
+#define NB_DEBUGLOG_MAGIC 0xAEAE1123
+
+#define NB_SERVER_PORT 33330
+#define NB_ADVERT_PORT 33331
+#define NB_CMD_PORT_START 33332
+#define NB_CMD_PORT_END 33339
+#define NB_TFTP_OUTGOING_PORT 33340
+#define NB_TFTP_INCOMING_PORT 33341
+
+
+#define NB_COMMAND 1 // arg=0, data=command
+#define NB_SEND_FILE 2 // arg=size, data=filename
+#define NB_DATA 3 // arg=offset, data=data
+#define NB_BOOT 4 // arg=0
+#define NB_QUERY 5 // arg=0, data=hostname (or "*")
+#define NB_SHELL_CMD 6 // arg=0, data=command string
+#define NB_OPEN 7 // arg=O_RDONLY|O_WRONLY, data=filename
+#define NB_READ 8 // arg=blocknum
+#define NB_WRITE 9 // arg=blocknum, data=data
+#define NB_CLOSE 10 // arg=0
+#define NB_LAST_DATA 11 // arg=offset, data=data
+#define NB_REBOOT 12 // arg=0
+#define NB_GET_ADVERT 13 // arg=0
+
+#define NB_ACK 0 // arg=0 or -err, NB_READ: data=data
+#define NB_FILE_RECEIVED 0x70000001 // arg=size
+
+#define NB_ADVERTISE 0x77777777
+
+#define NB_ERROR 0x80000000
+#define NB_ERROR_BAD_CMD 0x80000001
+#define NB_ERROR_BAD_PARAM 0x80000002
+#define NB_ERROR_TOO_LARGE 0x80000003
+#define NB_ERROR_BAD_FILE 0x80000004
+
+#define NB_VERSION_1_0 0x0001000
+#define NB_VERSION_1_1 0x0001010
+#define NB_VERSION_1_2 0x0001020
+#define NB_VERSION_1_3 0x0001030
+#define NB_VERSION_CURRENT NB_VERSION_1_3
+
+#define NB_FILENAME_PREFIX "<<netboot>>"
+#define NB_KERNEL_FILENAME NB_FILENAME_PREFIX "kernel.bin"
+#define NB_RAMDISK_FILENAME NB_FILENAME_PREFIX "ramdisk.bin"
+#define NB_CMDLINE_FILENAME NB_FILENAME_PREFIX "cmdline"
+
+#define NB_IMAGE_PREFIX "<<image>>"
+#define NB_FVM_HOST_FILENAME "sparse.fvm"
+#define NB_FVM_FILENAME NB_IMAGE_PREFIX NB_FVM_HOST_FILENAME
+#define NB_BOOTLOADER_HOST_FILENAME "bootloader.img"
+#define NB_BOOTLOADER_FILENAME NB_IMAGE_PREFIX NB_BOOTLOADER_HOST_FILENAME
+// Firmware images are slightly different, as they have an optional type suffix:
+// firmware_ <- type = "" (the default)
+// firmware_foo <- type = "foo"
+#define NB_FIRMWARE_HOST_FILENAME_PREFIX "firmware_"
+#define NB_FIRMWARE_FILENAME_PREFIX NB_IMAGE_PREFIX NB_FIRMWARE_HOST_FILENAME_PREFIX
+#define NB_ZIRCONA_HOST_FILENAME "zircona.img"
+#define NB_ZIRCONA_FILENAME NB_IMAGE_PREFIX NB_ZIRCONA_HOST_FILENAME
+#define NB_ZIRCONB_HOST_FILENAME "zirconb.img"
+#define NB_ZIRCONB_FILENAME NB_IMAGE_PREFIX NB_ZIRCONB_HOST_FILENAME
+#define NB_ZIRCONR_HOST_FILENAME "zirconr.img"
+#define NB_ZIRCONR_FILENAME NB_IMAGE_PREFIX NB_ZIRCONR_HOST_FILENAME
+#define NB_VBMETAA_HOST_FILENAME "vbmetaa.img"
+#define NB_VBMETAA_FILENAME NB_IMAGE_PREFIX NB_VBMETAA_HOST_FILENAME
+#define NB_VBMETAB_HOST_FILENAME "vbmetab.img"
+#define NB_VBMETAB_FILENAME NB_IMAGE_PREFIX NB_VBMETAB_HOST_FILENAME
+#define NB_VBMETAR_HOST_FILENAME "vbmetar.img"
+#define NB_VBMETAR_FILENAME NB_IMAGE_PREFIX NB_VBMETAR_HOST_FILENAME
+#define NB_SSHAUTH_HOST_FILENAME "authorized_keys"
+#define NB_SSHAUTH_FILENAME NB_IMAGE_PREFIX NB_SSHAUTH_HOST_FILENAME
+#define NB_BOARD_NAME_HOST_FILENAME "board_name"
+#define NB_BOARD_NAME_FILENAME NB_IMAGE_PREFIX NB_BOARD_NAME_HOST_FILENAME
+#define NB_BOARD_REVISION_HOST_FILENAME "board_revision"
+#define NB_BOARD_REVISION_FILENAME NB_IMAGE_PREFIX NB_BOARD_REVISION_HOST_FILENAME
+#define NB_BOARD_INFO_HOST_FILENAME "board_info"
+#define NB_BOARD_INFO_FILENAME NB_IMAGE_PREFIX NB_BOARD_INFO_HOST_FILENAME
+#define NB_INIT_PARTITION_TABLES_HOST_FILENAME "init_partition_tables"
+#define NB_INIT_PARTITION_TABLES_FILENAME NB_IMAGE_PREFIX NB_INIT_PARTITION_TABLES_HOST_FILENAME
+#define NB_WIPE_PARTITION_TABLES_HOST_FILENAME "wipe_partition_tables"
+#define NB_WIPE_PARTITION_TABLES_FILENAME NB_IMAGE_PREFIX NB_WIPE_PARTITION_TABLES_HOST_FILENAME
+
+// Should match paver FIDL definition.
+// Length does not include the '\0' terminator, so when allocating a character
+// buffer to hold the type use (NB_FIRMWARE_TYPE_MAX_LENGTH + 1).
+#define NB_FIRMWARE_TYPE_MAX_LENGTH 256
+
+typedef struct board_info {
+ char board_name[ZX_MAX_NAME_LEN];
+ uint32_t board_revision;
+ uint8_t mac_address[8];
+} board_info_t;
+
+typedef struct modify_partition_table_info {
+ // Path of block device to initialize or wipe.
+ char block_device_path[ZX_MAX_NAME_LEN + 1];
+} modify_partition_table_info_t;
+
+typedef struct nbmsg_t {
+ uint32_t magic;
+ uint32_t cookie;
+ uint32_t cmd;
+ uint32_t arg;
+ uint8_t data[0];
+} nbmsg;
+
+typedef struct nbfile_t {
+ uint8_t* data;
+ size_t size; // max size of buffer
+ size_t offset; // write pointer
+} nbfile;
+
+int netboot_init(const char* nodename);
+const char* netboot_nodename(void);
+int netboot_poll(void);
+void netboot_close(void);
+
+// Ask for a buffer suitable to put the file /name/ in
+// Return NULL to indicate /name/ is not wanted.
+nbfile* netboot_get_buffer(const char* name, size_t size);
+
+#define DEBUGLOG_PORT 33337
+#define DEBUGLOG_ACK_PORT 33338
+
+#define MAX_LOG_DATA 1216
+#define MAX_NODENAME_LENGTH 64
+
+typedef struct logpacket {
+ uint32_t magic;
+ uint32_t seqno;
+ char nodename[MAX_NODENAME_LENGTH];
+ char data[MAX_LOG_DATA];
+} logpacket_t;
+
+#endif // SYSROOT_ZIRCON_BOOT_NETBOOT_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/boot/sysconfig.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/boot/sysconfig.h
new file mode 100644
index 0000000..1f7d49b
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/boot/sysconfig.h
@@ -0,0 +1,29 @@
+// Copyright 2018 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.
+
+#ifndef SYSROOT_ZIRCON_BOOT_SYSCONFIG_H_
+#define SYSROOT_ZIRCON_BOOT_SYSCONFIG_H_
+
+// Zircon sysconfig partition format
+//
+// The sysconfig partition consists of four kvstore sections, each 32K in size.
+// The sections are:
+//
+// version-a: System configuration used when booting from Zircon-A.
+//
+// version-b: System configuration used when booting from Zircon-B.
+//
+// boot-default: Default bootloader configuration.
+//
+// boot-oneshot: Bootloader configuration for one-time use.
+// If present, this overrides boot-default, and the bootloader
+// deletes this section after use.
+
+#define ZX_SYSCONFIG_KVSTORE_SIZE 32768
+#define ZX_SYSCONFIG_VERSION_A_OFFSET (0 * ZX_SYSCONFIG_KVSTORE_SIZE)
+#define ZX_SYSCONFIG_VERSION_B_OFFSET (1 * ZX_SYSCONFIG_KVSTORE_SIZE)
+#define ZX_SYSCONFIG_BOOT_DEFAULT_OFFSET (2 * ZX_SYSCONFIG_KVSTORE_SIZE)
+#define ZX_SYSCONFIG_BOOT_ONESHOT_OFFSET (3 * ZX_SYSCONFIG_KVSTORE_SIZE)
+
+#endif // SYSROOT_ZIRCON_BOOT_SYSCONFIG_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/compiler.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/compiler.h
new file mode 100644
index 0000000..ce2bcea
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/compiler.h
@@ -0,0 +1,191 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_COMPILER_H_
+#define SYSROOT_ZIRCON_COMPILER_H_
+
+#ifndef __has_feature
+#define __has_feature(x) 0
+#endif
+
+#ifndef __has_cpp_attribute
+#define __has_cpp_attribute(x) 0
+#endif
+
+#ifndef __ASSEMBLER__
+
+#if !defined(__GNUC__) && !defined(__clang__)
+#error "Unrecognized compiler!"
+#endif
+
+#define likely(x) __builtin_expect(!!(x), 1)
+#define unlikely(x) __builtin_expect(!!(x), 0)
+#define __UNUSED __attribute__((__unused__))
+#define __USED __attribute__((__used__))
+#define __PACKED __attribute__((packed))
+#define __ALIGNED(x) __attribute__((aligned(x)))
+#define __PRINTFLIKE(__fmt, __varargs) __attribute__((__format__(__printf__, __fmt, __varargs)))
+#define __SCANFLIKE(__fmt, __varargs) __attribute__((__format__(__scanf__, __fmt, __varargs)))
+#define __SECTION(x) __attribute__((__section__(x)))
+#define __PURE __attribute__((__pure__))
+#define __CONST __attribute__((__const__))
+#define __NO_RETURN __attribute__((__noreturn__))
+#define __MALLOC __attribute__((__malloc__))
+#define __WEAK __attribute__((__weak__))
+#define __GNU_INLINE __attribute__((__gnu_inline__))
+#define __GET_CALLER(x) __builtin_return_address(0)
+#define __GET_FRAME(x) __builtin_frame_address(0)
+#define __NAKED __attribute__((__naked__))
+#define __ISCONSTANT(x) __builtin_constant_p(x)
+#define __NO_INLINE __attribute__((__noinline__))
+#define __SRAM __NO_INLINE __SECTION(".sram.text")
+#define __CONSTRUCTOR __attribute__((__constructor__))
+#define __DESTRUCTOR __attribute__((__destructor__))
+#define __RESTRICT __restrict
+
+#ifndef __clang__
+#define __LEAF_FN __attribute__((__leaf__))
+#define __OPTIMIZE(x) __attribute__((__optimize__(x)))
+#define __EXTERNALLY_VISIBLE __attribute__((__externally_visible__))
+#define __NO_SAFESTACK
+#define __THREAD_ANNOTATION(x)
+#else
+#define __LEAF_FN
+#define __OPTIMIZE(x)
+#define __EXTERNALLY_VISIBLE
+// The thread safety annotations are frequently used with C++ standard library
+// types in userspace, so only enable the annotations if we know that the C++
+// standard library types are annotated or if we're in kernel code.
+#if defined(_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS) || defined(_KERNEL)
+#define __THREAD_ANNOTATION(x) __attribute__((x))
+#else
+#define __THREAD_ANNOTATION(x)
+#endif // _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
+#define __NO_SAFESTACK __attribute__((__no_sanitize__("safe-stack", "shadow-call-stack")))
+#endif
+
+#define __ALWAYS_INLINE __attribute__((__always_inline__))
+#define __MAY_ALIAS __attribute__((__may_alias__))
+#define __NONNULL(x) __attribute__((__nonnull__ x))
+#define __WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
+#define __UNREACHABLE __builtin_unreachable()
+#define __WEAK_ALIAS(x) __attribute__((__weak__, __alias__(x)))
+#define __ALIAS(x) __attribute__((__alias__(x)))
+#define __EXPORT __attribute__((__visibility__("default")))
+#define __LOCAL __attribute__((__visibility__("hidden")))
+#define __THREAD __thread
+#define __offsetof(type, field) __builtin_offsetof(type, field)
+
+// Only define __NO_UNIQUE_ADDRESS for C++, since it doesn't make sense in C.
+#ifdef __cplusplus
+#if __has_cpp_attribute(no_unique_address)
+#define __NO_UNIQUE_ADDRESS [[no_unique_address]]
+#else
+#define __NO_UNIQUE_ADDRESS
+#endif
+#endif // ifdef __cplusplus
+
+#if defined(__cplusplus) && __cplusplus >= 201703L
+#define __FALLTHROUGH [[fallthrough]]
+#elif defined(__cplusplus) && defined(__clang__)
+#define __FALLTHROUGH [[clang::fallthrough]]
+// The GNU style attribute is supported by Clang for C code, but __GNUC__ for
+// clang right now is 4.
+#elif __GNUC__ >= 7 || (!defined(__cplusplus) && defined(__clang__))
+#define __FALLTHROUGH __attribute__((__fallthrough__))
+#else
+#define __FALLTHROUGH \
+ do { \
+ } while (0)
+#endif
+
+// C++17 onwards supports [[nodiscard]] on a constructor, warning if
+// a temporary object is created without a name. Such objects would be
+// immediately destroyed again, while the user's expectation might be
+// that it would last the scope.
+//
+// We could ideally just use [[nodiscard]] (or __WARN_UNUSED_RESULT)
+// directly, except GCC < 10.0 has a bug preventing it from being used
+// on constructors. __WARN_UNUSED_CONSTRUCTOR allows us to tag
+// constructors in supported compilers, and is simply ignored in older
+// compilers.
+#if defined(__cplusplus)
+// Clang and GCC versions >= 10.0 support [[nodiscard]] on constructors.
+#if __cplusplus >= 201703L && (defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 10)))
+#define __WARN_UNUSED_CONSTRUCTOR [[nodiscard]]
+#else
+#define __WARN_UNUSED_CONSTRUCTOR
+#endif
+#endif
+
+// Publicly exposed thread annotation macros. These have a long and ugly name to
+// minimize the chance of collision with consumers of Zircon's public headers.
+#define __TA_CAPABILITY(x) __THREAD_ANNOTATION(__capability__(x))
+#define __TA_GUARDED(x) __THREAD_ANNOTATION(__guarded_by__(x))
+#define __TA_ACQUIRE(...) __THREAD_ANNOTATION(__acquire_capability__(__VA_ARGS__))
+#define __TA_ACQUIRE_SHARED(...) __THREAD_ANNOTATION(__acquire_shared_capability__(__VA_ARGS__))
+#define __TA_TRY_ACQUIRE(...) __THREAD_ANNOTATION(__try_acquire_capability__(__VA_ARGS__))
+#define __TA_ACQUIRED_BEFORE(...) __THREAD_ANNOTATION(__acquired_before__(__VA_ARGS__))
+#define __TA_ACQUIRED_AFTER(...) __THREAD_ANNOTATION(__acquired_after__(__VA_ARGS__))
+#define __TA_RELEASE(...) __THREAD_ANNOTATION(__release_capability__(__VA_ARGS__))
+#define __TA_RELEASE_SHARED(...) __THREAD_ANNOTATION(__release_shared_capability__(__VA_ARGS__))
+#define __TA_REQUIRES(...) __THREAD_ANNOTATION(__requires_capability__(__VA_ARGS__))
+#define __TA_REQUIRES_SHARED(...) __THREAD_ANNOTATION(__requires_shared_capability__(__VA_ARGS__))
+#define __TA_EXCLUDES(...) __THREAD_ANNOTATION(__locks_excluded__(__VA_ARGS__))
+#define __TA_ASSERT(...) __THREAD_ANNOTATION(__assert_capability__(__VA_ARGS__))
+#define __TA_ASSERT_SHARED(...) __THREAD_ANNOTATION(__assert_shared_capability__(__VA_ARGS__))
+#define __TA_RETURN_CAPABILITY(x) __THREAD_ANNOTATION(__lock_returned__(x))
+#define __TA_SCOPED_CAPABILITY __THREAD_ANNOTATION(__scoped_lockable__)
+#define __TA_NO_THREAD_SAFETY_ANALYSIS __THREAD_ANNOTATION(__no_thread_safety_analysis__)
+
+#endif // ifndef __ASSEMBLER__
+
+#if !defined(__DEPRECATE)
+#define __DEPRECATE __attribute__((__deprecated__))
+#endif
+
+/* TODO: add type check */
+#if !defined(countof)
+#define countof(a) (sizeof(a) / sizeof((a)[0]))
+#endif
+
+/* CPP header guards */
+#ifdef __cplusplus
+#define __BEGIN_CDECLS extern "C" {
+#define __END_CDECLS }
+#else
+#define __BEGIN_CDECLS
+#define __END_CDECLS
+#endif
+
+// constexpr annotation for use in static inlines usable in both C and C++
+#ifdef __cplusplus
+#define __CONSTEXPR constexpr
+#else
+#define __CONSTEXPR
+#endif
+
+#define add_overflow(a, b, c) __builtin_add_overflow(a, b, c)
+#define sub_overflow(a, b, c) __builtin_sub_overflow(a, b, c)
+#define mul_overflow(a, b, c) __builtin_mul_overflow(a, b, c)
+
+// A workaround to help static analyzer identify assertion failures
+#if defined(__clang__)
+#define __ANALYZER_CREATE_SINK __attribute__((analyzer_noreturn))
+#else
+#define __ANALYZER_CREATE_SINK // no-op
+#endif
+
+// Lifetime analysis
+#ifndef __OWNER
+#ifdef __clang__
+#define __OWNER(x) [[gsl::Owner(x)]]
+#define __POINTER(x) [[gsl::Pointer(x)]]
+#else
+#define __OWNER(x)
+#define __POINTER(x)
+#endif
+#endif
+
+#endif // SYSROOT_ZIRCON_COMPILER_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/device/audio.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/device/audio.h
new file mode 100644
index 0000000..47da2d2
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/device/audio.h
@@ -0,0 +1,460 @@
+// Copyright 2017 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.
+
+#ifndef SYSROOT_ZIRCON_DEVICE_AUDIO_H_
+#define SYSROOT_ZIRCON_DEVICE_AUDIO_H_
+
+#include <sys/types.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+#include <cassert>
+#include <cstdio>
+
+// When communicating with an Audio driver using zx_channel_call, do not use
+// the AUDIO_INVALID_TRANSACTION_ID as your message's transaction ID. It is
+// reserved for async notifications sent from the driver to the application.
+#define AUDIO_INVALID_TRANSACTION_ID ((zx_txid_t)0)
+
+__BEGIN_CDECLS
+
+typedef uint32_t audio_cmd_t;
+
+// Commands sent on the stream channel
+#define AUDIO_STREAM_CMD_GET_FORMATS ((audio_cmd_t)0x1000)
+#define AUDIO_STREAM_CMD_SET_FORMAT ((audio_cmd_t)0x1001)
+#define AUDIO_STREAM_CMD_GET_GAIN ((audio_cmd_t)0x1002)
+#define AUDIO_STREAM_CMD_SET_GAIN ((audio_cmd_t)0x1003)
+#define AUDIO_STREAM_CMD_PLUG_DETECT ((audio_cmd_t)0x1004)
+#define AUDIO_STREAM_CMD_GET_UNIQUE_ID ((audio_cmd_t)0x1005)
+#define AUDIO_STREAM_CMD_GET_STRING ((audio_cmd_t)0x1006)
+#define AUDIO_STREAM_CMD_GET_CLOCK_DOMAIN ((audio_cmd_t)0x1007)
+
+// Async notifications sent on the stream channel.
+#define AUDIO_STREAM_PLUG_DETECT_NOTIFY ((audio_cmd_t)0x2000)
+
+// Commands sent on the ring buffer channel
+#define AUDIO_RB_CMD_GET_FIFO_DEPTH ((audio_cmd_t)0x3000)
+#define AUDIO_RB_CMD_GET_BUFFER ((audio_cmd_t)0x3001)
+#define AUDIO_RB_CMD_START ((audio_cmd_t)0x3002)
+#define AUDIO_RB_CMD_STOP ((audio_cmd_t)0x3003)
+
+// Async notifications sent on the ring buffer channel.
+#define AUDIO_RB_POSITION_NOTIFY ((audio_cmd_t)0x4000)
+
+// Flags used to modify commands.
+// The NO_ACK flag can be used with the SET_GAIN and PLUG_DETECT commands.
+#define AUDIO_FLAG_NO_ACK ((audio_cmd_t)0x80000000)
+
+typedef struct audio_cmd_hdr {
+ zx_txid_t transaction_id;
+ audio_cmd_t cmd;
+} audio_cmd_hdr_t;
+
+static_assert(sizeof(audio_cmd_hdr_t) == 8,
+ "audio_cmd_hdr_t should be 8 bytes! "
+ "If sizeof(zx_txid_t has changed from 4 to 8, "
+ "consider repacking the structs in audio.h");
+
+// audio_sample_format_t
+//
+// Bitfield which describes audio sample format as they reside in memory.
+//
+typedef uint32_t audio_sample_format_t;
+#define AUDIO_SAMPLE_FORMAT_BITSTREAM ((audio_sample_format_t)(1u << 0))
+#define AUDIO_SAMPLE_FORMAT_8BIT ((audio_sample_format_t)(1u << 1))
+#define AUDIO_SAMPLE_FORMAT_16BIT ((audio_sample_format_t)(1u << 2))
+#define AUDIO_SAMPLE_FORMAT_20BIT_PACKED ((audio_sample_format_t)(1u << 4))
+#define AUDIO_SAMPLE_FORMAT_24BIT_PACKED ((audio_sample_format_t)(1u << 5))
+#define AUDIO_SAMPLE_FORMAT_20BIT_IN32 ((audio_sample_format_t)(1u << 6))
+#define AUDIO_SAMPLE_FORMAT_24BIT_IN32 ((audio_sample_format_t)(1u << 7))
+#define AUDIO_SAMPLE_FORMAT_32BIT ((audio_sample_format_t)(1u << 8))
+#define AUDIO_SAMPLE_FORMAT_32BIT_FLOAT ((audio_sample_format_t)(1u << 9))
+#define AUDIO_SAMPLE_FORMAT_FLAG_UNSIGNED ((audio_sample_format_t)(1u << 30))
+#define AUDIO_SAMPLE_FORMAT_FLAG_INVERT_ENDIAN ((audio_sample_format_t)(1u << 31))
+#define AUDIO_SAMPLE_FORMAT_FLAG_MASK \
+ ((audio_sample_format_t)(AUDIO_SAMPLE_FORMAT_FLAG_UNSIGNED | \
+ AUDIO_SAMPLE_FORMAT_FLAG_INVERT_ENDIAN))
+
+// audio_stream_format_range_t
+//
+// A structure used along with the AUDIO_STREAM_CMD_GET_FORMATS command in order
+// to describe the formats supported by an audio stream.
+#define ASF_RANGE_FLAG_FPS_CONTINUOUS ((uint16_t)(1u << 0))
+#define ASF_RANGE_FLAG_FPS_48000_FAMILY ((uint16_t)(1u << 1))
+#define ASF_RANGE_FLAG_FPS_44100_FAMILY ((uint16_t)(1u << 2))
+typedef struct audio_stream_format_range {
+ audio_sample_format_t sample_formats;
+ uint32_t min_frames_per_second;
+ uint32_t max_frames_per_second;
+ uint8_t min_channels;
+ uint8_t max_channels;
+ uint16_t flags;
+} __PACKED audio_stream_format_range_t;
+
+static_assert(sizeof(audio_stream_format_range_t) == 16,
+ "audio_stream_format_range_t should be 16 bytes!");
+
+// audio_set_gain_flags_t
+//
+// Flags used by the AUDIO_STREAM_CMD_SET_GAIN message.
+//
+typedef uint32_t audio_set_gain_flags_t;
+#define AUDIO_SGF_MUTE_VALID \
+ ((audio_set_gain_flags_t)0x1) // Whether or not the mute flag is valid.
+#define AUDIO_SGF_AGC_VALID ((audio_set_gain_flags_t)0x2) // Whether or not the agc flag is valid.
+#define AUDIO_SGF_GAIN_VALID \
+ ((audio_set_gain_flags_t)0x4) // Whether or not the gain float is valid.
+#define AUDIO_SGF_MUTE ((audio_set_gain_flags_t)0x40000000) // Whether or not to mute the stream.
+#define AUDIO_SGF_AGC \
+ ((audio_set_gain_flags_t)0x80000000) // Whether or not enable AGC for the stream.
+
+// audio_pd_flags_t
+//
+// Flags used by AUDIO_STREAM_CMD_PLUG_DETECT commands to enable or disable
+// asynchronous plug detect notifications.
+//
+typedef uint32_t audio_pd_flags_t;
+#define AUDIO_PDF_NONE ((audio_pd_flags_t)0)
+#define AUDIO_PDF_ENABLE_NOTIFICATIONS ((audio_pd_flags_t)0x40000000)
+#define AUDIO_PDF_DISABLE_NOTIFICATIONS ((audio_pd_flags_t)0x80000000)
+
+// audio_pd_notify_flags_t
+//
+// Flags used by responses to the AUDIO_STREAM_CMD_PLUG_DETECT
+// message, and by AUDIO_STREAM_PLUG_DETECT_NOTIFY messages.
+//
+typedef uint32_t audio_pd_notify_flags_t;
+#define AUDIO_PDNF_HARDWIRED \
+ ((audio_pd_notify_flags_t)0x1) // Stream is hardwired (will always be plugged in)
+#define AUDIO_PDNF_CAN_NOTIFY \
+ ((audio_pd_notify_flags_t)0x2) // Stream is able to notify of plug state changes.
+#define AUDIO_PDNF_PLUGGED ((audio_pd_notify_flags_t)0x80000000) // Stream is currently plugged in.
+
+// AUDIO_STREAM_CMD_GET_FORMATS
+//
+// Must not be used with the NO_ACK flag.
+#define AUDIO_STREAM_CMD_GET_FORMATS_MAX_RANGES_PER_RESPONSE (15u)
+typedef struct audio_stream_cmd_get_formats_req {
+ audio_cmd_hdr_t hdr;
+} audio_stream_cmd_get_formats_req_t;
+
+// TODO(johngro) : Figure out if zx_txid_t is ever going to go up to 8 bytes or
+// not. If it is, just remove the _pad field below. If not, either keep it as
+// a _pad field, or repurpose it for some flags of some form. Right now, we use
+// it to make sure that format_ranges is aligned to a 16 byte boundary.
+typedef struct audio_stream_cmd_get_formats_resp {
+ audio_cmd_hdr_t hdr;
+ uint32_t _pad;
+ uint16_t format_range_count;
+ uint16_t first_format_range_ndx;
+ audio_stream_format_range_t format_ranges[AUDIO_STREAM_CMD_GET_FORMATS_MAX_RANGES_PER_RESPONSE];
+} audio_stream_cmd_get_formats_resp_t;
+
+static_assert(sizeof(audio_stream_cmd_get_formats_resp_t) == 256,
+ "audio_stream_cmd_get_formats_resp_t must be 256 bytes");
+
+// AUDIO_STREAM_CMD_SET_FORMAT
+//
+// Must not be used with the NO_ACK flag.
+typedef struct audio_stream_cmd_set_format_req {
+ audio_cmd_hdr_t hdr;
+ uint32_t frames_per_second;
+ audio_sample_format_t sample_format;
+ uint16_t channels;
+} audio_stream_cmd_set_format_req_t;
+
+typedef struct audio_stream_cmd_set_format_resp {
+ audio_cmd_hdr_t hdr;
+ zx_status_t result;
+ uint64_t external_delay_nsec;
+
+ // Note: Upon success, a channel used to control the audio buffer will also
+ // be returned.
+} audio_stream_cmd_set_format_resp_t;
+
+// AUDIO_STREAM_CMD_GET_GAIN
+//
+// Request that a gain notification be sent with the current details of the
+// streams current gain settings as well as gain setting capabilities.
+//
+// Must not be used with the NO_ACK flag.
+typedef struct audio_stream_cmd_get_gain_req {
+ audio_cmd_hdr_t hdr;
+} audio_stream_cmd_get_gain_req_t;
+
+typedef struct audio_stream_cmd_get_gain_resp {
+ // TODO(johngro) : Is there value in exposing the gain step to the level
+ // above the lowest level stream interface, or should we have all drivers
+ // behave as if they have continuous control at all times?
+ audio_cmd_hdr_t hdr;
+
+ bool cur_mute; // True if the stream is currently muted.
+ bool cur_agc; // True if the stream has AGC currently enabled.
+ float cur_gain; // The current setting gain of the stream in dB
+
+ bool can_mute; // True if the stream is capable of muting
+ bool can_agc; // True if the stream has support for AGC
+ float min_gain; // The minimum valid gain setting, in dB
+ float max_gain; // The maximum valid gain setting, in dB
+ float gain_step; // The smallest valid gain increment, counted from the minimum gain.
+} audio_stream_cmd_get_gain_resp_t;
+
+// AUDIO_STREAM_CMD_SET_GAIN
+//
+// Request that a stream change its gain settings to most closely match those
+// requested. Gain values for Valid requests will be rounded to the nearest
+// gain step. For example, if a stream can control its gain on the range from
+// -60.0 to 0.0 dB, a request to set the gain to -33.3 dB will result in a gain
+// of -33.5 being applied.
+//
+// Gain change requests outside of the capabilities of the stream's
+// amplifier will be rejected with a result of ZX_ERR_INVALID_ARGS. Using the
+// previous example, requests for gains of -65.0 or +3dB would be rejected.
+// Similarly, If an amplifier is capable of gain control but cannot mute, a
+// request to mute will be rejected.
+//
+// TODO(johngro) : Is this the correct behavior? Should we just apply sensible
+// limits instead? IOW - If the user requests a gain of -1000 dB, should we
+// just set the gain to -60dB? Likewise, if they request mute but the amplifier
+// has no hard mute feature, should we just set the gain to the minimum
+// permitted gain?
+//
+// May be used with the NO_ACK flag.
+typedef struct audio_stream_cmd_set_gain_req {
+ audio_cmd_hdr_t hdr;
+ audio_set_gain_flags_t flags;
+ float gain;
+} audio_stream_cmd_set_gain_req_t;
+
+typedef struct audio_stream_cmd_set_gain_resp {
+ audio_cmd_hdr_t hdr;
+ zx_status_t result;
+ // The current gain settings observed immediately after processing the set
+ // gain request.
+ bool cur_mute;
+ bool cur_agc;
+ float cur_gain;
+} audio_stream_cmd_set_gain_resp_t;
+
+// AUDIO_STREAM_CMD_PLUG_DETECT
+//
+// Trigger a plug detect operation and/or enable/disable asynchronous plug
+// detect notifications.
+//
+// May be used with the NO_ACK flag.
+typedef struct audio_stream_cmd_plug_detect_req {
+ audio_cmd_hdr_t hdr;
+ audio_pd_flags_t flags; // Options used to enable or disable notifications
+} audio_stream_cmd_plug_detect_req_t;
+
+typedef struct audio_stream_cmd_plug_detect_resp {
+ audio_cmd_hdr_t hdr;
+ audio_pd_notify_flags_t flags; // The current plug state and capabilities
+ zx_time_t plug_state_time; // The time of the plug state last change.
+} audio_stream_cmd_plug_detect_resp_t;
+
+// AUDIO_STREAM_PLUG_DETECT_NOTIFY
+//
+// Message asynchronously in response to a plug state change to clients who have
+// registered for plug state notifications.
+//
+// Note: Solicited and unsolicited plug detect messages currently use the same
+// structure and contain the same information. The difference between the two
+// is that Solicited messages, use AUDIO_STREAM_CMD_PLUG_DETECT as the value of
+// the `cmd` field of their header and the transaction ID of the request sent by
+// the client. Unsolicited messages use AUDIO_STREAM_PLUG_DETECT_NOTIFY as the
+// value value of the `cmd` field of their header, and
+// AUDIO_INVALID_TRANSACTION_ID for their transaction ID.
+typedef audio_stream_cmd_plug_detect_resp_t audio_stream_plug_detect_notify_t;
+
+// AUDIO_STREAM_CMD_GET_UNIQUE_ID
+//
+// Fetch a globally unique, but persistent ID for the stream.
+//
+// Drivers should make every effort to return as unique an identifier as
+// possible for each stream that they publish. This ID must not change between
+// boots. When available, using a globally unique device serial number is
+// strongly encouraged. Other possible sources of unique-ness include a
+// driver's physical connection path, driver binding information, manufacturer
+// calibration data, and so on.
+//
+// Note: a small number of hardcoded unique ID has been provided for built-in
+// devices. Platform drivers for systems with hardwired audio devices may use
+// these unique IDs as appropriate to signal which audio streams represent the
+// built-in devices for the system. Drivers for hot-pluggable audio devices
+// should *never* use these identifiers.
+//
+// Even given this, higher level code should *not* depend on these identifiers
+// being perfectly unique, and should be prepared to take steps to de-dupe
+// identifiers when needed.
+typedef struct audio_stream_cmd_get_unique_id_req {
+ audio_cmd_hdr_t hdr;
+} audio_stream_cmd_get_unique_id_req_t;
+
+typedef struct audio_stream_unique_id {
+ uint8_t data[16];
+} audio_stream_unique_id_t;
+
+#define AUDIO_STREAM_UNIQUE_ID_BUILTIN_SPEAKERS \
+ { \
+ .data = { 0x01, 0x00 } \
+ }
+#define AUDIO_STREAM_UNIQUE_ID_BUILTIN_HEADPHONE_JACK \
+ { \
+ .data = { 0x02, 0x00 } \
+ }
+#define AUDIO_STREAM_UNIQUE_ID_BUILTIN_MICROPHONE \
+ { \
+ .data = { 0x03, 0x00 } \
+ }
+#define AUDIO_STREAM_UNIQUE_ID_BUILTIN_HEADSET_JACK \
+ { \
+ .data = { 0x04, 0x00 } \
+ }
+
+typedef struct audio_stream_cmd_get_unique_id_resp {
+ audio_cmd_hdr_t hdr;
+ audio_stream_unique_id_t unique_id;
+} audio_stream_cmd_get_unique_id_resp_t;
+
+// AUDIO_STREAM_CMD_GET_STRING
+//
+// Fetch the specified string from a device's static string table. Strings
+// returned by the device driver...
+//
+// ++ Must be encoded using UTF8
+// ++ May contain embedded NULLs
+// ++ May not be NULL terminated
+//
+// Drivers are encouraged to NULL terminate all of their strings whenever
+// possible, but are not required to do so if the response buffer is too small.
+//
+typedef uint32_t audio_stream_string_id_t;
+#define AUDIO_STREAM_STR_ID_MANUFACTURER ((audio_stream_string_id_t)0x80000000)
+#define AUDIO_STREAM_STR_ID_PRODUCT ((audio_stream_string_id_t)0x80000001)
+
+typedef struct audio_stream_cmd_get_string_req {
+ audio_cmd_hdr_t hdr;
+ audio_stream_string_id_t id;
+} audio_stream_cmd_get_string_req_t;
+
+typedef struct audio_stream_cmd_get_string_resp {
+ audio_cmd_hdr_t hdr;
+ zx_status_t result;
+ audio_stream_string_id_t id;
+ uint32_t strlen;
+ uint8_t str[256 - sizeof(audio_cmd_hdr_t) - (3 * sizeof(uint32_t))];
+} audio_stream_cmd_get_string_resp_t;
+
+static_assert(sizeof(audio_stream_cmd_get_string_resp_t) == 256,
+ "audio_stream_cmd_get_string_resp_t must be exactly 256 bytes");
+
+// AUDIO_STREAM_CMD_GET_CLOCK_DOMAIN
+//
+// Fetch the hardware clock domain for this device.
+// On products containing audio devices that are not locked to the local system clock, the board
+// driver will provide a clock tree entry to the audio driver at driver startup time. From that,
+// the audio driver can extract the clock domain and provide it to the sender, upon receiving this
+// command. This domain value is all that the sender needs, in order to locate controls for that
+// clock domain in the clock tree and trim that clock domain's rate.
+// On products containing audio devices that are locked to the local system monotonic clock, a clock
+// domain value of 0 should be returned.
+//
+// Must not be used with the NO_ACK flag.
+typedef struct audio_stream_cmd_get_clock_domain_req {
+ audio_cmd_hdr_t hdr;
+} audio_stream_cmd_get_clock_domain_req_t;
+
+typedef struct audio_stream_cmd_get_clock_domain_resp {
+ audio_cmd_hdr_t hdr;
+ int32_t clock_domain;
+} audio_stream_cmd_get_clock_domain_resp_t;
+
+//
+// Ring-buffer commands
+//
+
+// AUDIO_RB_CMD_GET_FIFO_DEPTH
+//
+// TODO(johngro) : Is calling this "FIFO" depth appropriate? Should it be some
+// direction neutral form of something like "max-read-ahead-amount" or something
+// instead?
+//
+// Must not be used with the NO_ACK flag.
+typedef struct audio_rb_cmd_get_fifo_depth_req {
+ audio_cmd_hdr_t hdr;
+} audio_rb_cmd_get_fifo_depth_req_t;
+
+typedef struct audio_rb_cmd_get_fifo_depth_resp {
+ audio_cmd_hdr_t hdr;
+ zx_status_t result;
+
+ // A representation (in bytes) of how far ahead audio hardware may read
+ // into the stream (in the case of output) or may hold onto audio before
+ // writing it to memory (in the case of input).
+ uint32_t fifo_depth;
+} audio_rb_cmd_get_fifo_depth_resp_t;
+
+// AUDIO_RB_CMD_GET_BUFFER
+typedef struct audio_rb_cmd_get_buffer_req {
+ audio_cmd_hdr_t hdr;
+
+ uint32_t min_ring_buffer_frames;
+ uint32_t notifications_per_ring;
+} audio_rb_cmd_get_buffer_req_t;
+
+typedef struct audio_rb_cmd_get_buffer_resp {
+ audio_cmd_hdr_t hdr;
+ zx_status_t result;
+ uint32_t num_ring_buffer_frames;
+
+ // NOTE: If result == ZX_OK, a VMO handle representing the ring buffer to
+ // be used will be returned as well. Clients may map this buffer with
+ // read-write permissions in the case of an output stream, or read-only
+ // permissions in the case of an input stream. The size of the VMO
+ // indicates where the wrap point of the ring (in bytes) is located in the
+ // VMO. This size *must* always be an integral number of audio frames.
+ //
+ // TODO(johngro) : Should we provide some indication of whether or not this
+ // memory is being used directly for HW DMA and may need explicit cache
+ // flushing/invalidation?
+} audio_rb_cmd_get_buffer_resp_t;
+
+// AUDIO_RB_CMD_START
+typedef struct audio_rb_cmd_start_req {
+ audio_cmd_hdr_t hdr;
+} audio_rb_cmd_start_req_t;
+
+typedef struct audio_rb_cmd_start_resp {
+ audio_cmd_hdr_t hdr;
+ zx_status_t result;
+ uint64_t start_time;
+} audio_rb_cmd_start_resp_t;
+
+// AUDIO_RB_CMD_STOP
+typedef struct audio_rb_cmd_stop_req {
+ audio_cmd_hdr_t hdr;
+} audio_rb_cmd_stop_req_t;
+
+typedef struct audio_rb_cmd_stop_resp {
+ audio_cmd_hdr_t hdr;
+ zx_status_t result;
+} audio_rb_cmd_stop_resp_t;
+
+// AUDIO_RB_POSITION_NOTIFY
+typedef struct audio_rb_position_notify {
+ audio_cmd_hdr_t hdr;
+
+ // The time, per system monotonic clock, of the below byte position.
+ zx_time_t monotonic_time;
+
+ // The current position (in bytes) of the driver/hardware's read (output) or
+ // write (input) pointer in the ring buffer.
+ uint32_t ring_buffer_pos;
+} audio_rb_position_notify_t;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_DEVICE_AUDIO_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/dlfcn.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/dlfcn.h
new file mode 100644
index 0000000..f37e9be
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/dlfcn.h
@@ -0,0 +1,35 @@
+// Copyright 2018 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.
+
+#ifndef SYSROOT_ZIRCON_DLFCN_H_
+#define SYSROOT_ZIRCON_DLFCN_H_
+
+#include <dlfcn.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// Loads a dynamic shared object stored in |vmo|.
+// Acts identically to dlopen, but acts on a vmo
+// instead of a file path.
+//
+// Does not take ownership of the input vmo.
+void* dlopen_vmo(zx_handle_t vmo, int mode);
+
+// Replace the handle to the "loader service" used to map names
+// to VM objects for dlopen et al. This takes ownership of the
+// given handle, and gives the caller ownership of the old handle
+// in the return value.
+zx_handle_t dl_set_loader_service(zx_handle_t new_svc);
+
+// Ask the active "loader service" (if there is one), to return
+// a new connection. Not all loader services need support this.
+// On success, a channel handle to the new connection is returned
+// via out.
+zx_status_t dl_clone_loader_service(zx_handle_t* out);
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_DLFCN_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/driver/binding.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/driver/binding.h
new file mode 100644
index 0000000..82f513e
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/driver/binding.h
@@ -0,0 +1,310 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_DRIVER_BINDING_H_
+#define SYSROOT_ZIRCON_DRIVER_BINDING_H_
+
+#include <assert.h>
+#include <stdalign.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <zircon/compiler.h>
+
+__BEGIN_CDECLS
+
+// COAABBBB VVVVVVVV Condition Opcode paramA paramB Value
+
+#define OP_ABORT 0x0 // if (cond) return no-match
+#define OP_MATCH 0x1 // if (cond) return match
+#define OP_GOTO 0x2 // if (cond) advance to next LABEL(paramA)
+#define OP_LABEL 0x5 // no-op, labels line with paramA
+
+#define COND_AL 0x0 // true
+#define COND_EQ 0x1 // bind(paramB) == Value
+#define COND_NE 0x2 // bind(paramB) != Value
+#define COND_GT 0x3 // bind(paramB) > Value
+#define COND_LT 0x4 // bind(paramB) < Value
+#define COND_GE 0x5 // bind(paramB) >= Value
+#define COND_LE 0x6 // bind(paramB) <= Value
+
+// branches are forward-only
+// branches always go to the first matching LABEL
+// branches that cannot find a matching LABEL are treated as ABORTs
+// there is an implied unconditional ABORT after the last instruction
+// flags are initially zero, may be set/cleared with SET/CLEAR
+// flags may be tested by comparison against BIND_FLAGS
+
+#define BINDINST(c, o, a, b, v) \
+ { (((c)&0xF) << 28) | (((o)&0xF) << 24) | (((a)&0xFF) << 16) | ((b)&0xFFFF), (v), 0 /* debug */ }
+
+#define BINDINST_CC(n) ((n) >> 28)
+#define BINDINST_OP(n) (((n) >> 24) & 0xF)
+#define BINDINST_PA(n) (((n) >> 16) & 0xFF)
+#define BINDINST_PB(n) ((n)&0xFFFF)
+
+#define BI_ABORT() BINDINST(COND_AL, OP_ABORT, 0, 0, 0)
+#define BI_MATCH() BINDINST(COND_AL, OP_MATCH, 0, 0, 0)
+#define BI_GOTO(n) BINDINST(COND_AL, OP_GOTO, n, 0, 0)
+#define BI_LABEL(n) BINDINST(COND_AL, OP_LABEL, n, 0, 0)
+
+#define BI_ABORT_IF(c, b, v) BINDINST(COND_##c, OP_ABORT, 0, b, v)
+#define BI_MATCH_IF(c, b, v) BINDINST(COND_##c, OP_MATCH, 0, b, v)
+#define BI_GOTO_IF(c, b, v, n) BINDINST(COND_##c, OP_GOTO, n, b, v)
+
+// for drivers that only want to be bound on user request
+#define BI_ABORT_IF_AUTOBIND BI_ABORT_IF(NE, BIND_AUTOBIND, 0)
+
+// global binding variables at 0x00XX
+#define BIND_FLAGS 0x0000 // value of the flags register
+#define BIND_PROTOCOL 0x0001 // primary protocol of the device
+#define BIND_AUTOBIND 0x0002 // if this is an automated bind/load
+
+// pci binding variables at 0x01XX
+#define BIND_PCI_VID 0x0100
+#define BIND_PCI_DID 0x0101
+#define BIND_PCI_CLASS 0x0102
+#define BIND_PCI_SUBCLASS 0x0103
+#define BIND_PCI_INTERFACE 0x0104
+#define BIND_PCI_REVISION 0x0105
+
+// usb binding variables at 0x02XX
+// these are used for both ZX_PROTOCOL_USB and ZX_PROTOCOL_USB_FUNCTION
+#define BIND_USB_VID 0x0200
+#define BIND_USB_PID 0x0201
+#define BIND_USB_CLASS 0x0202
+#define BIND_USB_SUBCLASS 0x0203
+#define BIND_USB_PROTOCOL 0x0204
+
+// Platform bus binding variables at 0x03XX
+#define BIND_PLATFORM_DEV_VID 0x0300
+#define BIND_PLATFORM_DEV_PID 0x0301
+#define BIND_PLATFORM_DEV_DID 0x0302
+#define BIND_PLATFORM_PROTO 0x0303
+
+// ACPI binding variables at 0x04XX
+// The _HID is a 7- or 8-byte string. Because a bind property is 32-bit, use 2
+// properties to bind using the _HID. They are encoded in big endian order for
+// human readability. In the case of 7-byte _HID's, the 8th-byte shall be 0.
+#define BIND_ACPI_HID_0_3 0x0400 // char 0-3
+#define BIND_ACPI_HID_4_7 0x0401 // char 4-7
+// The _CID may be a valid HID value or a bus-specific string. The ACPI bus
+// driver only publishes those that are valid HID values.
+#define BIND_ACPI_CID_0_3 0x0402 // char 0-3
+#define BIND_ACPI_CID_4_7 0x0403 // char 4-7
+
+// Intel HDA Codec binding variables at 0x05XX
+#define BIND_IHDA_CODEC_VID 0x0500
+#define BIND_IHDA_CODEC_DID 0x0501
+#define BIND_IHDA_CODEC_MAJOR_REV 0x0502
+#define BIND_IHDA_CODEC_MINOR_REV 0x0503
+#define BIND_IHDA_CODEC_VENDOR_REV 0x0504
+#define BIND_IHDA_CODEC_VENDOR_STEP 0x0505
+
+// Serial binding variables at 0x06XX
+#define BIND_SERIAL_CLASS 0x0600
+#define BIND_SERIAL_VID 0x0601
+#define BIND_SERIAL_PID 0x0602
+
+// NAND binding variables at 0x07XX
+#define BIND_NAND_CLASS 0x0700
+
+// Bluetooth binding variables at 0x08XX
+#define BIND_BT_GATT_SVC_UUID16 0x0800
+// 128-bit UUID is split across 4 32-bit unsigned ints
+#define BIND_BT_GATT_SVC_UUID128_1 0x0801
+#define BIND_BT_GATT_SVC_UUID128_2 0x0802
+#define BIND_BT_GATT_SVC_UUID128_3 0x0803
+#define BIND_BT_GATT_SVC_UUID128_4 0x0804
+
+// SDIO binding variables at 0x09XX
+#define BIND_SDIO_VID 0x0900
+#define BIND_SDIO_PID 0x0901
+#define BIND_SDIO_FUNCTION 0x0902
+
+// I2C binding variables at 0x0A0X
+#define BIND_I2C_CLASS 0x0A00
+#define BIND_I2C_BUS_ID 0x0A01
+#define BIND_I2C_ADDRESS 0x0A02
+
+// GPIO binding variables at 0x0A1X
+#define BIND_GPIO_PIN 0x0A10
+
+// POWER binding variables at 0x0A2X
+#define BIND_POWER_DOMAIN 0x0A20
+#define BIND_POWER_DOMAIN_COMPOSITE 0x0A21
+
+// POWER binding variables at 0x0A3X
+#define BIND_CLOCK_ID 0x0A30
+
+// SPI binding variables at 0x0A4X
+#define BIND_SPI_CLASS 0x0A40
+#define BIND_SPI_BUS_ID 0x0A41
+#define BIND_SPI_CHIP_SELECT 0x0A42
+
+// PWM binding variables at 0x0A5X
+#define BIND_PWM_ID 0x0A50
+
+// Init Step binding variables at 0x0A6X
+#define BIND_INIT_STEP 0x0A60
+
+// Fuchsia-defined topological path properties are at 0x0B00 through 0x0B7F.
+// Vendor-defined topological path properties are at 0x0B80 to 0x0BFF.
+// For vendor properties, it is recommended that a vendor ID be included
+// and checked via some other property.
+#define BIND_TOPO_START 0x0B00
+#define BIND_TOPO_PCI 0x0B00
+#define BIND_TOPO_I2C 0x0B01
+#define BIND_TOPO_SPI 0x0B02
+#define BIND_TOPO_VENDOR_START 0x0B80
+#define BIND_TOPO_VENDOR_END 0x0BFF
+#define BIND_TOPO_END 0x0BFF
+
+#define BIND_TOPO_PCI_PACK(bus, dev, func) (((bus) << 8) | (dev << 3) | (func))
+#define BIND_TOPO_PCI_UNPACK_BUS(topo) (((topo) >> 8) & 0xff)
+#define BIND_TOPO_PCI_UNPACK_DEVICE(topo) (((topo) >> 3) & 0x1f)
+#define BIND_TOPO_PCI_UNPACK_FUNCTION(topo) ((topo)&0x7)
+
+#define BIND_TOPO_I2C_PACK(addr) ((addr))
+#define BIND_TOPO_I2C_UNPACK(topo) ((topo))
+
+#define BIND_TOPO_SPI_PACK(bus, chip_select) (((bus) << 8) | (chip_select))
+#define BIND_TOPO_SPI_UNPACK_BUS_ID(topo) (((topo) >> 8) && 0xff)
+#define BIND_TOPO_SPI_UNPACK_CHIP_SELECT(topo) ((topo)&0xff)
+
+typedef struct zx_bind_inst {
+ uint32_t op;
+ uint32_t arg;
+ uint32_t debug;
+} zx_bind_inst_t;
+
+typedef struct zx_device_prop {
+ uint16_t id;
+ uint16_t reserved;
+ uint32_t value;
+} zx_device_prop_t;
+
+// simple example
+#if 0
+zx_bind_inst_t i915_binding[] = {
+ BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_PCI),
+ BI_ABORT_IF(NE, BIND_PCI_VID, 0x8086),
+ BI_MATCH_IF(EQ, BIND_PCI_DID, 0x1616), // broadwell
+ BI_MATCH_IF(EQ, BIND_PCI_DID, 0x1916), // skylake
+ BI_ABORT(),
+};
+#endif
+
+#define ZIRCON_NOTE_NAME "Zircon"
+#define ZIRCON_NOTE_DRIVER 0x31565244 // DRV1
+
+typedef struct {
+ // Elf64_Nhdr fields:
+ uint32_t namesz;
+ uint32_t descsz;
+ uint32_t type;
+ // ELF note name. namesz is the exact size of the name (including '\0'),
+ // but the storage size is always rounded up to a multiple of 4 bytes.
+ char name[(sizeof(ZIRCON_NOTE_NAME) + 3) & -4];
+} zircon_driver_note_header_t;
+
+#define ZIRCON_DRIVER_NOTE_HEADER_INIT(object) \
+ { \
+ /* .namesz = */ sizeof(ZIRCON_NOTE_NAME), \
+ /* .descsz = */ (sizeof(object) - sizeof(zircon_driver_note_header_t)), \
+ /* .type = */ ZIRCON_NOTE_DRIVER, /* .name = */ ZIRCON_NOTE_NAME, \
+ }
+
+typedef struct {
+ // See flag bits below.
+ uint32_t flags;
+
+ // Driver Metadata
+ uint32_t bindcount;
+ uint32_t reserved0;
+ char name[32];
+ char vendor[16];
+ char version[16];
+
+ // Driver Bind Program follows
+} zircon_driver_note_payload_t;
+
+// Flag bits in the driver note:
+
+// Driver is built with `-fsanitize=address` and can only be loaded into a
+// devhost that supports the ASan runtime.
+#define ZIRCON_DRIVER_NOTE_FLAG_ASAN (1u << 0)
+
+#define ZIRCON_DRIVER_NOTE_PAYLOAD_INIT(Driver, VendorName, Version, BindCount) \
+ { \
+ /* .flags = */ ZIRCON_DRIVER_NOTE_FLAGS, /* .bindcount = */ (BindCount), /* .reserved0 = */ 0, \
+ /* .name = */ #Driver, /* .vendor = */ VendorName, /* .version = */ Version, \
+ }
+
+#define ZIRCON_DRIVER_NOTE_FLAGS \
+ (__has_feature(address_sanitizer) ? ZIRCON_DRIVER_NOTE_FLAG_ASAN : 0)
+
+typedef struct {
+ zircon_driver_note_header_t header;
+ zircon_driver_note_payload_t payload;
+} zircon_driver_note_t;
+
+static_assert(offsetof(zircon_driver_note_t, payload) == sizeof(zircon_driver_note_header_t),
+ "alignment snafu?");
+
+// Without this, ASan will add redzone padding after the object, which
+// would make it invalid ELF note format.
+#if __has_feature(address_sanitizer)
+#define ZIRCON_DRIVER_NOTE_ASAN __attribute__((no_sanitize("address")))
+#else
+#define ZIRCON_DRIVER_NOTE_ASAN
+#endif
+
+// GCC has a quirk about how '__attribute__((visibility("default")))'
+// (__EXPORT here) works for const variables in C++. The attribute has no
+// effect when used on the definition of a const variable, and GCC gives a
+// warning/error about that. The attribute must appear on the "extern"
+// declaration of the variable instead.
+
+// We explicitly align the note to 4 bytes. That's its natural alignment
+// anyway, but the compilers sometimes like to over-align as an
+// optimization while other tools sometimes like to complain if SHT_NOTE
+// sections are over-aligned (since this could result in padding being
+// inserted that makes it violate the ELF note format). Standard C11
+// doesn't permit alignas(...) on a type but we could use __ALIGNED(4) on
+// all the types (i.e. GNU __attribute__ syntax instead of C11 syntax).
+// But the alignment of the types is not actually the issue: it's the
+// compiler deciding to over-align the individual object regardless of its
+// type's alignment, so we have to explicitly set the alignment of the
+// object to defeat any compiler default over-alignment.
+
+#define ZIRCON_DRIVER_BEGIN(Driver, Ops, VendorName, Version, BindCount) \
+ const zx_driver_ops_t* __zircon_driver_ops__ __EXPORT = &(Ops); \
+ zx_driver_rec_t __zircon_driver_rec__ __EXPORT = { \
+ /* .ops = */ &(Ops), /* .driver = */ NULL, \
+ /* .log_flags = */ 7, /* DDK_LOG_ERROR | DDK_LOG_WARN | DDK_LOG_INFO */ \
+ }; \
+ extern const struct zircon_driver_note __zircon_driver_note__ __EXPORT; \
+ alignas(4) __SECTION(".note.zircon.driver." #Driver) \
+ ZIRCON_DRIVER_NOTE_ASAN const struct zircon_driver_note { \
+ zircon_driver_note_t note; \
+ zx_bind_inst_t binding[BindCount]; \
+ } __zircon_driver_note__ = { \
+ /* .note = */ { \
+ ZIRCON_DRIVER_NOTE_HEADER_INIT(__zircon_driver_note__), \
+ ZIRCON_DRIVER_NOTE_PAYLOAD_INIT(Driver, VendorName, Version, BindCount), \
+ }, \
+ /* .binding = */ {
+#define ZIRCON_DRIVER_END(Driver) \
+ } \
+ } \
+ ;
+
+// TODO: if we moved the Ops from the BEGIN() to END() macro we
+// could add a zircon_driver_note_t* to the zx_driver_rec_t,
+// define it in END(), and have only one symbol to dlsym()
+// when loading drivers
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_DRIVER_BINDING_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/errors.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/errors.h
new file mode 100644
index 0000000..4e0da7d
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/errors.h
@@ -0,0 +1,233 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_ERRORS_H_
+#define SYSROOT_ZIRCON_ERRORS_H_
+
+// Zircon statuses are signed 32 bit integers. The space of values is
+// divided as follows:
+// - The zero value is for the OK status.
+// - Negative values are defined by the system, in this file.
+// - Positive values are reserved for protocol-specific error values,
+// and will never be defined by the system.
+
+#define ZX_OK (0)
+
+// ======= Internal failures =======
+// ZX_ERR_INTERNAL: The system encountered an otherwise unspecified error
+// while performing the operation.
+#define ZX_ERR_INTERNAL (-1)
+
+// ZX_ERR_NOT_SUPPORTED: The operation is not implemented, supported,
+// or enabled.
+#define ZX_ERR_NOT_SUPPORTED (-2)
+
+// ZX_ERR_NO_RESOURCES: The system was not able to allocate some resource
+// needed for the operation.
+#define ZX_ERR_NO_RESOURCES (-3)
+
+// ZX_ERR_NO_MEMORY: The system was not able to allocate memory needed
+// for the operation.
+#define ZX_ERR_NO_MEMORY (-4)
+
+// -5 used to be ZX_ERR_CALL_FAILED.
+
+// ZX_ERR_INTERNAL_INTR_RETRY: The system call was interrupted, but should be
+// retried. This should not be seen outside of the VDSO.
+#define ZX_ERR_INTERNAL_INTR_RETRY (-6)
+
+// ======= Parameter errors =======
+// ZX_ERR_INVALID_ARGS: an argument is invalid, ex. null pointer
+#define ZX_ERR_INVALID_ARGS (-10)
+
+// ZX_ERR_BAD_HANDLE: A specified handle value does not refer to a handle.
+#define ZX_ERR_BAD_HANDLE (-11)
+
+// ZX_ERR_WRONG_TYPE: The subject of the operation is the wrong type to
+// perform the operation.
+// Example: Attempting a message_read on a thread handle.
+#define ZX_ERR_WRONG_TYPE (-12)
+
+// ZX_ERR_BAD_SYSCALL: The specified syscall number is invalid.
+#define ZX_ERR_BAD_SYSCALL (-13)
+
+// ZX_ERR_OUT_OF_RANGE: An argument is outside the valid range for this
+// operation.
+#define ZX_ERR_OUT_OF_RANGE (-14)
+
+// ZX_ERR_BUFFER_TOO_SMALL: A caller provided buffer is too small for
+// this operation.
+#define ZX_ERR_BUFFER_TOO_SMALL (-15)
+
+// ======= Precondition or state errors =======
+// ZX_ERR_BAD_STATE: operation failed because the current state of the
+// object does not allow it, or a precondition of the operation is
+// not satisfied
+#define ZX_ERR_BAD_STATE (-20)
+
+// ZX_ERR_TIMED_OUT: The time limit for the operation elapsed before
+// the operation completed.
+#define ZX_ERR_TIMED_OUT (-21)
+
+// ZX_ERR_SHOULD_WAIT: The operation cannot be performed currently but
+// potentially could succeed if the caller waits for a prerequisite
+// to be satisfied, for example waiting for a handle to be readable
+// or writable.
+// Example: Attempting to read from a channel that has no
+// messages waiting but has an open remote will return ZX_ERR_SHOULD_WAIT.
+// Attempting to read from a channel that has no messages waiting
+// and has a closed remote end will return ZX_ERR_PEER_CLOSED.
+#define ZX_ERR_SHOULD_WAIT (-22)
+
+// ZX_ERR_CANCELED: The in-progress operation (e.g. a wait) has been
+// canceled.
+#define ZX_ERR_CANCELED (-23)
+
+// ZX_ERR_PEER_CLOSED: The operation failed because the remote end of the
+// subject of the operation was closed.
+#define ZX_ERR_PEER_CLOSED (-24)
+
+// ZX_ERR_NOT_FOUND: The requested entity is not found.
+#define ZX_ERR_NOT_FOUND (-25)
+
+// ZX_ERR_ALREADY_EXISTS: An object with the specified identifier
+// already exists.
+// Example: Attempting to create a file when a file already exists
+// with that name.
+#define ZX_ERR_ALREADY_EXISTS (-26)
+
+// ZX_ERR_ALREADY_BOUND: The operation failed because the named entity
+// is already owned or controlled by another entity. The operation
+// could succeed later if the current owner releases the entity.
+#define ZX_ERR_ALREADY_BOUND (-27)
+
+// ZX_ERR_UNAVAILABLE: The subject of the operation is currently unable
+// to perform the operation.
+// Note: This is used when there's no direct way for the caller to
+// observe when the subject will be able to perform the operation
+// and should thus retry.
+#define ZX_ERR_UNAVAILABLE (-28)
+
+// ======= Permission check errors =======
+// ZX_ERR_ACCESS_DENIED: The caller did not have permission to perform
+// the specified operation.
+#define ZX_ERR_ACCESS_DENIED (-30)
+
+// ======= Input-output errors =======
+// ZX_ERR_IO: Otherwise unspecified error occurred during I/O.
+#define ZX_ERR_IO (-40)
+
+// ZX_ERR_REFUSED: The entity the I/O operation is being performed on
+// rejected the operation.
+// Example: an I2C device NAK'ing a transaction or a disk controller
+// rejecting an invalid command, or a stalled USB endpoint.
+#define ZX_ERR_IO_REFUSED (-41)
+
+// ZX_ERR_IO_DATA_INTEGRITY: The data in the operation failed an integrity
+// check and is possibly corrupted.
+// Example: CRC or Parity error.
+#define ZX_ERR_IO_DATA_INTEGRITY (-42)
+
+// ZX_ERR_IO_DATA_LOSS: The data in the operation is currently unavailable
+// and may be permanently lost.
+// Example: A disk block is irrecoverably damaged.
+#define ZX_ERR_IO_DATA_LOSS (-43)
+
+// ZX_ERR_IO_NOT_PRESENT: The device is no longer available (has been
+// unplugged from the system, powered down, or the driver has been
+// unloaded)
+#define ZX_ERR_IO_NOT_PRESENT (-44)
+
+// ZX_ERR_IO_OVERRUN: More data was received from the device than expected.
+// Example: a USB "babble" error due to a device sending more data than
+// the host queued to receive.
+#define ZX_ERR_IO_OVERRUN (-45)
+
+// ZX_ERR_IO_MISSED_DEADLINE: An operation did not complete within the required timeframe.
+// Example: A USB isochronous transfer that failed to complete due to an overrun or underrun.
+#define ZX_ERR_IO_MISSED_DEADLINE (-46)
+
+// ZX_ERR_IO_INVALID: The data in the operation is invalid parameter or is out of range.
+// Example: A USB transfer that failed to complete with TRB Error
+#define ZX_ERR_IO_INVALID (-47)
+
+// ======== Filesystem Errors ========
+// ZX_ERR_BAD_PATH: Path name is too long.
+#define ZX_ERR_BAD_PATH (-50)
+
+// ZX_ERR_NOT_DIR: Object is not a directory or does not support
+// directory operations.
+// Example: Attempted to open a file as a directory or
+// attempted to do directory operations on a file.
+#define ZX_ERR_NOT_DIR (-51)
+
+// ZX_ERR_NOT_FILE: Object is not a regular file.
+#define ZX_ERR_NOT_FILE (-52)
+
+// ZX_ERR_FILE_BIG: This operation would cause a file to exceed a
+// filesystem-specific size limit
+#define ZX_ERR_FILE_BIG (-53)
+
+// ZX_ERR_NO_SPACE: Filesystem or device space is exhausted.
+#define ZX_ERR_NO_SPACE (-54)
+
+// ZX_ERR_NOT_EMPTY: Directory is not empty.
+#define ZX_ERR_NOT_EMPTY (-55)
+
+// ======== Flow Control ========
+// These are not errors, as such, and will never be returned
+// by a syscall or public API. They exist to allow callbacks
+// to request changes in operation.
+//
+// ZX_ERR_STOP: Do not call again.
+// Example: A notification callback will be called on every
+// event until it returns something other than ZX_OK.
+// This status allows differentiation between "stop due to
+// an error" and "stop because the work is done."
+#define ZX_ERR_STOP (-60)
+
+// ZX_ERR_NEXT: Advance to the next item.
+// Example: A notification callback will use this response
+// to indicate it did not "consume" an item passed to it,
+// but by choice, not due to an error condition.
+#define ZX_ERR_NEXT (-61)
+
+// ZX_ERR_ASYNC: Ownership of the item has moved to an asynchronous worker.
+//
+// Unlike ZX_ERR_STOP, which implies that iteration on an object
+// should stop, and ZX_ERR_NEXT, which implies that iteration
+// should continue to the next item, ZX_ERR_ASYNC implies
+// that an asynchronous worker is responsible for continuing iteration.
+//
+// Example: A notification callback will be called on every
+// event, but one event needs to handle some work asynchronously
+// before it can continue. ZX_ERR_ASYNC implies the worker is
+// responsible for resuming iteration once its work has completed.
+#define ZX_ERR_ASYNC (-62)
+
+// ======== Network-related errors ========
+
+// ZX_ERR_PROTOCOL_NOT_SUPPORTED: Specified protocol is not
+// supported.
+#define ZX_ERR_PROTOCOL_NOT_SUPPORTED (-70)
+
+// ZX_ERR_ADDRESS_UNREACHABLE: Host is unreachable.
+#define ZX_ERR_ADDRESS_UNREACHABLE (-71)
+
+// ZX_ERR_ADDRESS_IN_USE: Address is being used by someone else.
+#define ZX_ERR_ADDRESS_IN_USE (-72)
+
+// ZX_ERR_NOT_CONNECTED: Socket is not connected.
+#define ZX_ERR_NOT_CONNECTED (-73)
+
+// ZX_ERR_CONNECTION_REFUSED: Remote peer rejected the connection.
+#define ZX_ERR_CONNECTION_REFUSED (-74)
+
+// ZX_ERR_CONNECTION_RESET: Connection was reset.
+#define ZX_ERR_CONNECTION_RESET (-75)
+
+// ZX_ERR_CONNECTION_ABORTED: Connection was aborted.
+#define ZX_ERR_CONNECTION_ABORTED (-76)
+
+#endif // SYSROOT_ZIRCON_ERRORS_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/exception.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/exception.h
new file mode 100644
index 0000000..bf3843b
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/exception.h
@@ -0,0 +1,19 @@
+// 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.
+
+#pragma once
+
+#include <zircon/syscalls/exception.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+__EXPORT const char* _zx_exception_get_string(zx_excp_type_t exception);
+__EXPORT const char* zx_exception_get_string(zx_excp_type_t exception);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/features.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/features.h
new file mode 100644
index 0000000..d60e724
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/features.h
@@ -0,0 +1,47 @@
+// Copyright 2018 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.
+
+#ifndef SYSROOT_ZIRCON_FEATURES_H_
+#define SYSROOT_ZIRCON_FEATURES_H_
+
+// clang-format off
+
+// types of features that can be retrieved via |zx_system_get_features|
+#define ZX_FEATURE_KIND_CPU ((uint32_t)0)
+#define ZX_FEATURE_KIND_HW_BREAKPOINT_COUNT ((uint32_t)1)
+#define ZX_FEATURE_KIND_HW_WATCHPOINT_COUNT ((uint32_t)2)
+
+// arch-independent CPU features
+#define ZX_HAS_CPU_FEATURES ((uint32_t)(1u << 0))
+
+#if defined(__x86_64__)
+
+// x86-64 CPU features
+// None; use cpuid instead
+
+#elif defined(__aarch64__)
+
+// arm64 CPU features
+#define ZX_ARM64_FEATURE_ISA_FP ((uint32_t)(1u << 1))
+#define ZX_ARM64_FEATURE_ISA_ASIMD ((uint32_t)(1u << 2))
+#define ZX_ARM64_FEATURE_ISA_AES ((uint32_t)(1u << 3))
+#define ZX_ARM64_FEATURE_ISA_PMULL ((uint32_t)(1u << 4))
+#define ZX_ARM64_FEATURE_ISA_SHA1 ((uint32_t)(1u << 5))
+#define ZX_ARM64_FEATURE_ISA_SHA2 ((uint32_t)(1u << 6))
+#define ZX_ARM64_FEATURE_ISA_CRC32 ((uint32_t)(1u << 7))
+#define ZX_ARM64_FEATURE_ISA_ATOMICS ((uint32_t)(1u << 8))
+#define ZX_ARM64_FEATURE_ISA_RDM ((uint32_t)(1u << 9))
+#define ZX_ARM64_FEATURE_ISA_SHA3 ((uint32_t)(1u << 10))
+#define ZX_ARM64_FEATURE_ISA_SM3 ((uint32_t)(1u << 11))
+#define ZX_ARM64_FEATURE_ISA_SM4 ((uint32_t)(1u << 12))
+#define ZX_ARM64_FEATURE_ISA_DP ((uint32_t)(1u << 13))
+#define ZX_ARM64_FEATURE_ISA_DPB ((uint32_t)(1u << 14))
+
+#else
+
+#error what architecture?
+
+#endif
+
+#endif // SYSROOT_ZIRCON_FEATURES_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/fidl.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/fidl.h
new file mode 100644
index 0000000..152843a
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/fidl.h
@@ -0,0 +1,452 @@
+// Copyright 2017 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.
+
+#ifndef SYSROOT_ZIRCON_FIDL_H_
+#define SYSROOT_ZIRCON_FIDL_H_
+
+#include <assert.h> // NOLINT(modernize-deprecated-headers, foobar)
+#include <stdalign.h> // NOLINT(modernize-deprecated-headers)
+#include <stdint.h> // NOLINT(modernize-*)
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// Fidl data types have a representation in a wire format. This wire
+// format is shared by all language bindings, including C11 and C++.
+//
+// The C bindings also define a representation of fidl data types. For
+// a given type, the size and alignment of all parts of the type agree
+// with the wire format's representation. The C representation differs
+// in the representation of pointers to out-of-line allocations. On
+// the wire, allocations are encoded as either present or not. In C,
+// they are actual pointers. The C representation also places any
+// transferred handle types (including requests) inline. The wire
+// format tracks handles separately, just like the underlying channel
+// transport does.
+//
+// Turning the wire format into the C format is called decoding.
+//
+// Turning the C format into the wire format is called encoding.
+//
+// The formats are designed to allow for in-place coding, assuming all
+// out-of-line allocations placed are in traversal order (defined
+// below) with natural alignment.
+
+// Bounds.
+
+// Various fidl types, such as strings and vectors, may be bounded. If
+// no explicit bound is given, then FIDL_MAX_SIZE is implied.
+
+#define FIDL_MAX_SIZE UINT32_MAX
+
+// Out of line allocations.
+
+// The fidl wire format represents potential out-of-line allocations
+// (corresponding to actual pointer types in the C format) as
+// uintptr_t. For allocations that are actually present and that will
+// be patched up with pointers during decoding, the FIDL_ALLOC_PRESENT
+// value is used. For non-present nullable allocations, the
+// FIDL_ALLOC_ABSENT value is used.
+
+#define FIDL_ALLOC_PRESENT ((uintptr_t)UINTPTR_MAX)
+#define FIDL_ALLOC_ABSENT ((uintptr_t)0)
+
+// Out of line allocations are all 8 byte aligned.
+// TODO(fxb/42792): Remove either this FIDL_ALIGN macro or the FidlAlign function in
+// fidl/internal.h.
+#define FIDL_ALIGNMENT ((size_t)8)
+#define FIDL_ALIGN(a) (((a) + 7u) & ~7u)
+#define FIDL_ALIGNDECL alignas(FIDL_ALIGNMENT)
+
+// An opaque struct representing the encoding of a particular fidl
+// type.
+typedef struct fidl_type fidl_type_t;
+
+// Primitive types.
+
+// Both on the wire and once deserialized, primitive fidl types
+// correspond directly to C types. There is no intermediate layer of
+// typedefs. For instance, fidl's float64 is generated as double.
+
+// All primitive types are non-nullable.
+
+// All primitive types are naturally sized and aligned on the wire.
+
+// fidl C Meaning.
+// ---------------------------------------------
+// bool bool A boolean.
+// int8 int8_t An 8 bit signed integer.
+// int16 int16_t A 16 bit signed integer.
+// int32 int32_t A 32 bit signed integer.
+// int64 int64_t A 64 bit signed integer.
+// uint8 uint8_t An 8 bit unsigned integer.
+// uint16 uint16_t A 16 bit unsigned integer.
+// uint32 uint32_t A 32 bit unsigned integer.
+// uint64 uint64_t A 64 bit unsigned integer.
+// float32 float A 32 bit IEEE-754 float.
+// float64 double A 64 bit IEEE-754 float.
+
+// Enums.
+
+// Fidl enums have an undering integer type (one of int8, int16,
+// int32, int64, uint8, uint16, uint32, or uint64). The wire format of
+// an enum and the C format of an enum are the same as the
+// corresponding primitive type.
+
+// String types.
+
+// Fidl strings are variable-length UTF-8 strings. Strings can be
+// nullable (string?) or nonnullable (string); if nullable, the null
+// string is distinct from the empty string. Strings can be bounded to
+// a fixed byte length (e.g. string:40? is a nullable string of at
+// most 40 bytes).
+
+// Strings are not guaranteed to be nul terminated. Strings can
+// contain embedded nuls throughout their length.
+
+// The fidl wire format dictates that strings are valid UTF-8. It is
+// up to clients to provide well-formed UTF-8 and servers to check for
+// it. Message encoding and decoding can, but does not by default,
+// perform this check.
+
+// All deserialized string types are represented by the fidl_string_t
+// structure. This structure consists of a size (in bytes) and a
+// pointer to an out-of-line allocation of uint8_t, guaranteed to be
+// at least as long as the length.
+
+// The bound on a string type is not present in the serialized format,
+// but is checked as part of validation.
+
+typedef struct fidl_string {
+ // Number of UTF-8 code units (bytes), must be 0 if |data| is null.
+ uint64_t size;
+
+ // Pointer to UTF-8 code units (bytes) or null
+ char* data;
+} fidl_string_t;
+
+// When encoded, an absent nullable string is represented as a
+// fidl_string_t with size 0 and FIDL_ALLOC_ABSENT data, with no
+// out-of-line allocation associated with it. A present string
+// (nullable or not) is represented as a fidl_string_t with some size
+// and with data equal to FIDL_ALLOC_PRESENT, which the decoding
+// process replaces with an actual pointer to the next out-of-line
+// allocation.
+
+// All string types:
+
+// fidl C Meaning
+// -----------------------------------------------------------------
+// string fidl_string_t A string of arbitrary length.
+// string? fidl_string_t An optional string of arbitrary length.
+// string:N fidl_string_t A string up to N bytes long.
+// string:N? fidl_string_t An optional string up to N bytes long.
+
+// Arrays.
+
+// On the wire, an array of N objects of type T (array<T, N>) is
+// represented the same as N contiguous Ts. Equivalently, it is
+// represented the same as a nonnullable struct containing N fields
+// all of type T.
+
+// In C, this is just represented as a C array of the corresponding C
+// type.
+
+// Vector types.
+
+// Fidl vectors are variable-length arrays of a given type T. Vectors
+// can be nullable (vector<T>?) or nonnullable (vector<T>); if
+// nullable, the null vector is distinct from the empty
+// vector. Vectors can be bounded to a fixed element length
+// (e.g. vector<T>:40? is a nullable vector of at most 40 Ts).
+
+// All deserialized vector types are represented by the fidl_vector_t
+// structure. This structure consists of a count and a pointer to the
+// bytes.
+
+// The bound on a vector type is not present in the serialized format,
+// but is checked as part of validation.
+
+typedef struct fidl_vector {
+ // Number of elements, must be 0 if |data| is null.
+ uint64_t count;
+
+ // Pointer to element data or null.
+ void* data;
+} fidl_vector_t;
+
+// When encoded, an absent nullable vector is represented as a
+// fidl_vector_t with size 0 and FIDL_ALLOC_ABSENT data, with no
+// out-of-line allocation associated with it. A present vector
+// (nullable or not) is represented as a fidl_vector_t with some size
+// and with data equal to FIDL_ALLOC_PRESENT, which the decoding
+// process replaces with an actual pointer to the next out-of-line
+// allocation.
+
+// All vector types:
+
+// fidl C Meaning
+// --------------------------------------------------------------------------
+// vector<T> fidl_vector_t A vector of T, of arbitrary length.
+// vector<T>? fidl_vector_t An optional vector of T, of arbitrary length.
+// vector<T>:N fidl_vector_t A vector of T, up to N elements.
+// vector<T>:N? fidl_vector_t An optional vector of T, up to N elements.
+
+// Envelope.
+
+// An efficient way to encapsulate uninterpreted FIDL messages.
+// - Stores a variable size uninterpreted payload out-of-line.
+// - Payload may contain an arbitrary number of bytes and handles.
+// - Allows for encapsulation of one FIDL message inside of another.
+// - Building block for extensible structures such as tables & extensible
+// unions.
+
+// When encoded for transfer, |data| indicates presence of content:
+// - FIDL_ALLOC_ABSENT : envelope is null
+// - FIDL_ALLOC_PRESENT : envelope is non-null, |data| is the next out-of-line object
+// When decoded for consumption, |data| is a pointer to content.
+// - nullptr : envelope is null
+// - <valid pointer> : envelope is non-null, |data| is at indicated memory address
+
+typedef struct {
+ // The size of the entire envelope contents, including any additional
+ // out-of-line objects that the envelope may contain. For example, a
+ // vector<string>'s num_bytes for ["hello", "world"] would include the
+ // string contents in the size, not just the outer vector. Always a multiple
+ // of 8; must be zero if envelope is null.
+ uint32_t num_bytes;
+
+ // The number of handles in the envelope, including any additional
+ // out-of-line objects that the envelope contains. Must be zero if envelope is null.
+ uint32_t num_handles;
+
+ // A pointer to the out-of-line envelope data in decoded form, or
+ // FIDL_ALLOC_(ABSENT|PRESENT) in encoded form.
+ union {
+ void* data;
+ uintptr_t presence;
+ };
+} fidl_envelope_t;
+
+// Handle types.
+
+// Handle types are encoded directly. Just like primitive types, there
+// is no fidl-specific handle type. Generated fidl structures simply
+// mention zx_handle_t.
+
+// Handle types are either nullable (handle?), or not (handle); and
+// either explicitly typed (e.g. handle<Channel> or handle<Job>), or
+// not.
+
+// All fidl handle types, regardless of subtype, are represented as
+// zx_handle_t. The encoding tables do know the handle subtypes,
+// however, for clients which wish to perform explicit checking.
+
+// The following are the possible handle subtypes.
+
+// process
+// thread
+// vmo
+// channel
+// event
+// port
+// interrupt
+// iomap
+// pci
+// log
+// socket
+// resource
+// eventpair
+// job
+// vmar
+// fifo
+// hypervisor
+// guest
+// timer
+
+// All handle types are 4 byte sized and aligned on the wire.
+
+// When encoded, absent nullable handles are represented as
+// FIDL_HANDLE_ABSENT. Present handles, whether nullable or not, are
+// represented as FIDL_HANDLE_PRESENT, which the decoding process will
+// overwrite with the next handle value in the channel message.
+
+#define FIDL_HANDLE_ABSENT ((zx_handle_t)ZX_HANDLE_INVALID)
+#define FIDL_HANDLE_PRESENT ((zx_handle_t)UINT32_MAX)
+
+// fidl C Meaning
+// ------------------------------------------------------------------
+// handle zx_handle_t Any valid handle.
+// handle? zx_handle_t Any valid handle, or ZX_HANDLE_INVALID.
+// handle<T> zx_handle_t Any valid T handle.
+// handle<T>? zx_handle_t Any valid T handle, or ZX_HANDLE_INVALID.
+
+// Unions.
+
+// Fidl unions are a tagged sum type. The tag is a 4 bytes. For every
+// union type, the fidl compiler generates an enum representing the
+// different variants of the enum. This is followed, in C and on the
+// wire, by large enough and aligned enough storage for all members of
+// the union.
+
+// Unions may be nullable. Nullable unions are represented as a
+// pointer to an out of line allocation of tag-and-member. As with
+// other out-of-line allocations, ones present on the wire take the
+// value FIDL_ALLOC_PRESENT and those that are not are represented by
+// FIDL_ALLOC_NULL. Nonnullable unions are represented inline as a
+// tag-and-member.
+
+// For each fidl union type, a corresponding C type is generated. They
+// are all structs consisting of a fidl_union_tag_t discriminant,
+// followed by an anonymous union of all the union members.
+
+typedef uint32_t fidl_union_tag_t;
+
+// fidl C Meaning
+// --------------------------------------------------------------------
+// union foo {...} struct union_foo { An inline union.
+// fidl_union_tag_t tag;
+// union {...};
+// }
+//
+// union foo {...}? struct union_foo* A pointer to a
+// union_foo, or else
+// FIDL_ALLOC_ABSENT.
+
+// Tables.
+
+// Tables are 'flexible structs', where all members are optional, and new
+// members can be added, or old members removed while preserving ABI
+// compatibility. Each table member is referenced by ordinal, sequentially
+// assigned from 1 onward, with no gaps. Each member content is stored
+// out-of-line in an envelope, and a table is simply a vector of these envelopes
+// with the requirement that the last envelope must be present in order
+// to guarantee a canonical representation.
+
+typedef struct {
+ fidl_vector_t envelopes;
+} fidl_table_t;
+
+// Extensible unions.
+
+// Extensible unions, or "xunions" (colloquially pronounced "zoo-nions") are
+// similar to unions, except that storage for union members are out-of-line
+// rather than inline. This enables union members to be added and removed while
+// preserving ABI compatibility with the existing xunion definition.
+
+typedef uint64_t fidl_xunion_tag_t;
+
+enum {
+ kFidlXUnionEmptyTag = 0, // The tag representing an empty xunion.
+};
+
+typedef struct {
+ fidl_xunion_tag_t tag;
+ fidl_envelope_t envelope;
+} fidl_xunion_t;
+
+// Messages.
+
+// All fidl messages share a common 16 byte header.
+
+enum {
+ kFidlWireFormatMagicNumberInitial = 1,
+};
+
+typedef struct fidl_message_header {
+ zx_txid_t txid;
+ uint8_t flags[3];
+ // This value indicates the message's wire format. Two sides with different
+ // wire formats are incompatible with each other
+ uint8_t magic_number;
+ uint64_t ordinal;
+} fidl_message_header_t;
+
+// Messages which do not have a response use zero as a special
+// transaction id.
+
+#define FIDL_TXID_NO_RESPONSE 0ul
+
+// A FIDL message.
+typedef struct fidl_msg {
+ // The bytes of the message.
+ //
+ // The bytes of the message might be in the encoded or decoded form.
+ // Functions that take a |fidl_msg_t| as an argument should document whether
+ // the expect encoded or decoded messages.
+ //
+ // See |num_bytes| for the number of bytes in the message.
+ void* bytes;
+
+ // The handles of the message.
+ //
+ // See |num_bytes| for the number of bytes in the message.
+ zx_handle_t* handles;
+
+ // The number of bytes in |bytes|.
+ uint32_t num_bytes;
+
+ // The number of handles in |handles|.
+ uint32_t num_handles;
+} fidl_msg_t;
+
+// An outstanding FIDL transaction.
+typedef struct fidl_txn fidl_txn_t;
+struct fidl_txn {
+ // Replies to the outstanding request and complete the FIDL transaction.
+ //
+ // Pass the |fidl_txn_t| object itself as the first parameter. The |msg|
+ // should already be encoded. This function always consumes any handles
+ // present in |msg|.
+ //
+ // Call |reply| only once for each |txn| object. After |reply| returns, the
+ // |txn| object is considered invalid and might have been freed or reused
+ // for another purpose.
+ zx_status_t (*reply)(fidl_txn_t* txn, const fidl_msg_t* msg);
+};
+
+// An epitaph is a message that a server sends just prior to closing the
+// connection. It provides an indication of why the connection is being closed.
+// Epitaphs are defined in the FIDL wire format specification. Once sent down
+// the wire, the channel should be closed.
+typedef struct fidl_epitaph {
+ FIDL_ALIGNDECL
+
+ // The method ordinal for all epitaphs must be kFidlOrdinalEpitaph
+ fidl_message_header_t hdr;
+
+ // The error associated with this epitaph is stored as a struct{int32} in
+ // the message payload. System errors must be constants of type zx_status_t,
+ // which are all negative. Positive numbers should be used for application
+ // errors. A value of ZX_OK indicates no error.
+ zx_status_t error;
+} fidl_epitaph_t;
+
+// This ordinal value is reserved for Epitaphs.
+enum {
+ kFidlOrdinalEpitaph = 0xFFFFFFFFFFFFFFFF,
+};
+
+// Assumptions.
+
+// Ensure that FIDL_ALIGNMENT is sufficient.
+static_assert(alignof(bool) <= FIDL_ALIGNMENT, "");
+static_assert(alignof(int8_t) <= FIDL_ALIGNMENT, "");
+static_assert(alignof(int16_t) <= FIDL_ALIGNMENT, "");
+static_assert(alignof(int32_t) <= FIDL_ALIGNMENT, "");
+static_assert(alignof(int64_t) <= FIDL_ALIGNMENT, "");
+static_assert(alignof(uint8_t) <= FIDL_ALIGNMENT, "");
+static_assert(alignof(uint16_t) <= FIDL_ALIGNMENT, "");
+static_assert(alignof(uint32_t) <= FIDL_ALIGNMENT, "");
+static_assert(alignof(uint64_t) <= FIDL_ALIGNMENT, "");
+static_assert(alignof(float) <= FIDL_ALIGNMENT, "");
+static_assert(alignof(double) <= FIDL_ALIGNMENT, "");
+static_assert(alignof(void*) <= FIDL_ALIGNMENT, "");
+static_assert(alignof(fidl_union_tag_t) <= FIDL_ALIGNMENT, "");
+static_assert(alignof(fidl_message_header_t) <= FIDL_ALIGNMENT, "");
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_FIDL_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/gpt.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/gpt.h
new file mode 100644
index 0000000..005415c
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/gpt.h
@@ -0,0 +1,300 @@
+// Copyright 2017 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.
+
+#ifndef SYSROOT_ZIRCON_HW_GPT_H_
+#define SYSROOT_ZIRCON_HW_GPT_H_
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <zircon/compiler.h>
+
+#define GPT_MAGIC (0x5452415020494645ull) // 'EFI PART'
+#define GPT_HEADER_SIZE 0x5c
+#define GPT_ENTRY_SIZE 0x80
+#define GPT_GUID_LEN 16
+#define GPT_GUID_STRLEN 37
+#define GPT_NAME_LEN 72
+
+typedef struct gpt_header {
+ uint64_t magic; // Magic number.
+ uint32_t revision; // Revision.
+ uint32_t size; // Size of the header.
+ uint32_t crc32; // Checksum of this header.
+ uint32_t reserved0; // Reserved field.
+ uint64_t current; // Block where this table is stored.
+ uint64_t backup; // Block where other copy of partition table is stored.
+ uint64_t first; // First usable block. Block after primary partition table ends.
+ uint64_t last; // Last usable block. Block before backup partition table starts.
+ uint8_t guid[GPT_GUID_LEN]; // Disk GUID.
+ uint64_t entries; // Starting block where entries for this partition tables are found.
+ // Value equals 2 for primary copy.
+ uint32_t entries_count; // Total number of entries.
+ uint32_t entries_size; // Size of each entry.
+ uint32_t entries_crc; // Checksum of the entire entries array.
+} __PACKED gpt_header_t;
+
+static_assert(GPT_HEADER_SIZE == sizeof(gpt_header_t), "Gpt header size invalid");
+
+typedef struct gpt_entry {
+ uint8_t type[GPT_GUID_LEN];
+ uint8_t guid[GPT_GUID_LEN];
+ uint64_t first;
+ uint64_t last;
+ uint64_t flags;
+ uint8_t name[GPT_NAME_LEN]; // UTF-16 on disk
+} gpt_entry_t;
+
+static_assert(GPT_ENTRY_SIZE == sizeof(gpt_entry_t), "Gpt entry size invalid");
+
+// clang-format off
+#define GUID_EMPTY_STRING "00000000-0000-0000-0000-000000000000"
+#define GUID_EMPTY_VALUE { \
+ 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, \
+ 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 \
+}
+#define GUID_EMPTY_NAME "empty"
+
+#define GUID_EFI_STRING "C12A7328-F81F-11D2-BA4B-00A0C93EC93B"
+#define GUID_EFI_VALUE { \
+ 0x28, 0x73, 0x2a, 0xc1, \
+ 0x1f, 0xf8, \
+ 0xd2, 0x11, \
+ 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b \
+}
+#define GUID_EFI_NAME "efi-system"
+
+// GUID for a system partition
+#define GUID_SYSTEM_STRING "606B000B-B7C7-4653-A7D5-B737332C899D"
+#define GUID_SYSTEM_VALUE { \
+ 0x0b, 0x00, 0x6b, 0x60, \
+ 0xc7, 0xb7, \
+ 0x53, 0x46, \
+ 0xa7, 0xd5, 0xb7, 0x37, 0x33, 0x2c, 0x89, 0x9d \
+}
+#define GUID_SYSTEM_NAME "fuchsia-system"
+
+// GUID for a data partition
+#define GUID_DATA_STRING "08185F0C-892D-428A-A789-DBEEC8F55E6A"
+#define GUID_DATA_VALUE { \
+ 0x0c, 0x5f, 0x18, 0x08, \
+ 0x2d, 0x89, \
+ 0x8a, 0x42, \
+ 0xa7, 0x89, 0xdb, 0xee, 0xc8, 0xf5, 0x5e, 0x6a \
+}
+#define GUID_DATA_NAME "fuchsia-data"
+
+// GUID for a installer partition
+#define GUID_INSTALL_STRING "48435546-4953-2041-494E-5354414C4C52"
+#define GUID_INSTALL_VALUE { \
+ 0x46, 0x55, 0x43, 0x48, \
+ 0x53, 0x49, \
+ 0x41, 0x20, \
+ 0x49, 0x4E, 0x53, 0x54, 0x41, 0x4C, 0x4C, 0x52 \
+}
+#define GUID_INSTALL_NAME "fuchsia-install"
+
+#define GUID_BLOB_STRING "2967380E-134C-4CBB-B6DA-17E7CE1CA45D"
+#define GUID_BLOB_VALUE { \
+ 0x0e, 0x38, 0x67, 0x29, \
+ 0x4c, 0x13, \
+ 0xbb, 0x4c, \
+ 0xb6, 0xda, 0x17, 0xe7, 0xce, 0x1c, 0xa4, 0x5d \
+}
+#define GUID_BLOB_NAME "fuchsia-blob"
+
+#define GUID_FVM_STRING "41D0E340-57E3-954E-8C1E-17ECAC44CFF5"
+#define GUID_FVM_VALUE { \
+ 0x40, 0xe3, 0xd0, 0x41, \
+ 0xe3, 0x57, \
+ 0x4e, 0x95, \
+ 0x8c, 0x1e, 0x17, 0xec, 0xac, 0x44, 0xcf, 0xf5 \
+}
+#define GUID_FVM_NAME "fuchsia-fvm"
+
+#define GUID_ZIRCON_A_STRING "DE30CC86-1F4A-4A31-93C4-66F147D33E05"
+#define GUID_ZIRCON_A_VALUE { \
+ 0x86, 0xcc, 0x30, 0xde, \
+ 0x4a, 0x1f, \
+ 0x31, 0x4a, \
+ 0x93, 0xc4, 0x66, 0xf1, 0x47, 0xd3, 0x3e, 0x05, \
+}
+#define GUID_ZIRCON_A_NAME "zircon-a"
+
+#define GUID_ZIRCON_B_STRING "23CC04DF-C278-4CE7-8471-897D1A4BCDF7"
+#define GUID_ZIRCON_B_VALUE { \
+ 0xdf, 0x04, 0xcc, 0x23, \
+ 0x78, 0xc2, \
+ 0xe7, 0x4c, \
+ 0x84, 0x71, 0x89, 0x7d, 0x1a, 0x4b, 0xcd, 0xf7 \
+}
+#define GUID_ZIRCON_B_NAME "zircon-b"
+
+#define GUID_ZIRCON_R_STRING "A0E5CF57-2DEF-46BE-A80C-A2067C37CD49"
+#define GUID_ZIRCON_R_VALUE { \
+ 0x57, 0xcf, 0xe5, 0xa0, \
+ 0xef, 0x2d, \
+ 0xbe, 0x46, \
+ 0xa8, 0x0c, 0xa2, 0x06, 0x7c, 0x37, 0xcd, 0x49 \
+}
+#define GUID_ZIRCON_R_NAME "zircon-r"
+
+#define GUID_SYS_CONFIG_STRING "4E5E989E-4C86-11E8-A15B-480FCF35F8E6"
+#define GUID_SYS_CONFIG_VALUE { \
+ 0x9e, 0x98, 0x5e, 0x4e, \
+ 0x86, 0x4c, \
+ 0xe8, 0x11, \
+ 0xa1, 0x5b, 0x48, 0x0f, 0xcf, 0x35, 0xf8, 0xe6 \
+}
+#define GUID_SYS_CONFIG_NAME "sys-config"
+
+#define GUID_FACTORY_CONFIG_STRING "5A3A90BE-4C86-11E8-A15B-480FCF35F8E6"
+#define GUID_FACTORY_CONFIG_VALUE { \
+ 0xbe, 0x90, 0x3a, 0x5a, \
+ 0x86, 0x4c, \
+ 0xe8, 0x11, \
+ 0xa1, 0x5b, 0x48, 0x0f, 0xcf, 0x35, 0xf8, 0xe6 \
+}
+#define GUID_FACTORY_CONFIG_NAME "factory"
+
+#define GUID_BOOTLOADER_STRING "5ECE94FE-4C86-11E8-A15B-480FCF35F8E6"
+#define GUID_BOOTLOADER_VALUE { \
+ 0xfe, 0x94, 0xce, 0x5e, \
+ 0x86, 0x4c, \
+ 0xe8, 0x11, \
+ 0xa1, 0x5b, 0x48, 0x0f, 0xcf, 0x35, 0xf8, 0xe6 \
+}
+#define GUID_BOOTLOADER_NAME "bootloader"
+
+#define GUID_TEST_STRING "8B94D043-30BE-4871-9DFA-D69556E8C1F3"
+#define GUID_TEST_VALUE { \
+ 0x43, 0xD0, 0x94, 0x8b, \
+ 0xbe, 0x30, \
+ 0x71, 0x48, \
+ 0x9d, 0xfa, 0xd6, 0x95, 0x56, 0xe8, 0xc1, 0xf3 \
+}
+#define GUID_TEST_NAME "guid-test"
+
+#define GUID_VBMETA_A_STRING "A13B4D9A-EC5F-11E8-97D8-6C3BE52705BF"
+#define GUID_VBMETA_A_VALUE { \
+ 0x9a, 0x4d, 0x3b, 0xa1, \
+ 0x5f, 0xec, \
+ 0xe8, 0x11, \
+ 0x97, 0xd8, 0x6c, 0x3b, 0xe5, 0x27, 0x05, 0xbf \
+}
+#define GUID_VBMETA_A_NAME "vbmeta_a"
+
+#define GUID_VBMETA_B_STRING "A288ABF2-EC5F-11E8-97D8-6C3BE52705BF"
+#define GUID_VBMETA_B_VALUE { \
+ 0xf2, 0xab, 0x88, 0xa2, \
+ 0x5f, 0xec, \
+ 0xe8, 0x11, \
+ 0x97, 0xd8, 0x6c, 0x3b, 0xe5, 0x27, 0x05, 0xbf \
+}
+#define GUID_VBMETA_B_NAME "vbmeta_b"
+
+#define GUID_VBMETA_R_STRING "6A2460C3-CD11-4E8B-80A8-12CCE268ED0A"
+#define GUID_VBMETA_R_VALUE { \
+ 0xc3, 0x60, 0x24, 0x6a, \
+ 0x11, 0xcd, \
+ 0x8b, 0x4e, \
+ 0x80, 0xa8, 0x12, 0xcc, 0xe2, 0x68, 0xed, 0x0a \
+}
+#define GUID_VBMETA_R_NAME "vbmeta_r"
+
+#define GUID_ABR_META_STRING "1D75395D-F2C6-476B-A8B7-45CC1C97B476"
+#define GUID_ABR_META_VALUE { \
+ 0x5d, 0x39, 0x75, 0x1d, \
+ 0xc6, 0xf2, \
+ 0x6b, 0x47, \
+ 0xa8, 0xb7, 0x45, 0xcc, 0x1c, 0x97, 0xb4, 0x76 \
+}
+#define GUID_ABR_META_NAME "misc"
+
+#define GUID_CROS_KERNEL_STRING "FE3A2A5D-4F32-41A7-B725-ACCC3285A309"
+#define GUID_CROS_KERNEL_VALUE { \
+ 0x5d, 0x2a, 0x3a, 0xfe, \
+ 0x32, 0x4f, \
+ 0xa7, 0x41, \
+ 0xb7, 0x25, 0xac, 0xcc, 0x32, 0x85, 0xa3, 0x09 \
+}
+#define GUID_CROS_KERNEL_NAME "cros-kernel"
+
+#define GUID_CROS_ROOTFS_STRING "3CB8E202-3B7E-47DD-8A3C-7FF2A13CFCEC"
+#define GUID_CROS_ROOTFS_VALUE { \
+ 0x02, 0xe2, 0xb8, 0x3C, \
+ 0x7e, 0x3b, \
+ 0xdd, 0x47, \
+ 0x8a, 0x3c, 0x7f, 0xf2, 0xa1, 0x3c, 0xfc, 0xec \
+}
+#define GUID_CROS_ROOTFS_NAME "cros-rootfs"
+
+#define GUID_CROS_RESERVED_STRING "2E0A753D-9E48-43B0-8337-B15192CB1B5E"
+#define GUID_CROS_RESERVED_VALUE { \
+ 0x3d, 0x75, 0x0a, 0x2e, \
+ 0x48, 0x9e, \
+ 0xb0, 0x43, \
+ 0x83, 0x37, 0xb1, 0x51, 0x92, 0xcb, 0x1b, 0x5e \
+}
+#define GUID_CROS_RESERVED_NAME "cros-reserved"
+
+#define GUID_CROS_FIRMWARE_STRING "CAB6E88E-ABF3-4102-A07A-D4BB9BE3C1D3"
+#define GUID_CROS_FIRMWARE_VALUE { \
+ 0x8e, 0xe8, 0xb6, 0xca, \
+ 0xf3, 0xab, \
+ 0x02, 0x41, \
+ 0xa0, 0x7a, 0xd4, 0xbb, 0x9b, 0xe3, 0xc1, 0xd3 \
+}
+#define GUID_CROS_FIRMWARE_NAME "cros-firmware"
+
+#define GUID_CROS_DATA_STRING "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7"
+#define GUID_CROS_DATA_VALUE { \
+ 0xa2, 0xa0, 0xd0, 0xeb, \
+ 0xe5, 0xb9, \
+ 0x33, 0x44, \
+ 0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7 \
+}
+#define GUID_CROS_DATA_NAME "cros-data"
+
+#define GUID_BIOS_STRING "21686148-6449-6E6F-744E-656564454649"
+#define GUID_BIOS_VALUE { \
+ 0x48, 0x61, 0x68, 0x21, \
+ 0x49, 0x64, \
+ 0x6f, 0x6e, \
+ 0x74, 0x4e, 0x65, 0x65, 0x64, 0x45, 0x46, 0x49 \
+}
+#define GUID_BIOS_NAME "bios"
+
+#define GUID_EMMC_BOOT1_STRING "900B0FC5-90CD-4D4F-84F9-9F8ED579DB88"
+#define GUID_EMMC_BOOT1_VALUE { \
+ 0xc5, 0x0f, 0x0b, 0x90, \
+ 0xcd, 0x90, \
+ 0x4f, 0x4d, \
+ 0x84, 0xf9, 0x9f, 0x8e, 0xd5, 0x79, 0xdb, 0x88 \
+}
+#define GUID_EMMC_BOOT1_NAME "emmc-boot1"
+
+#define GUID_EMMC_BOOT2_STRING "B2B2E8D1-7C10-4EBC-A2D0-4614568260AD"
+#define GUID_EMMC_BOOT2_VALUE { \
+ 0xd1, 0xe8, 0xb2, 0xb2, \
+ 0x10, 0x7c, \
+ 0xbc, 0x4e, \
+ 0xa2, 0xd0, 0x46, 0x14, 0x56, 0x82, 0x60, 0xad \
+}
+#define GUID_EMMC_BOOT2_NAME "emmc-boot2"
+
+#define GUID_LINUX_FILESYSTEM_DATA_STRING "0FC63DAF-8483-4772-8E79-3D69D8477DE4"
+#define GUID_LINUX_FILESYSTEM_DATA_VALUE { \
+ 0xaf, 0x3d, 0xc6, 0x0f, \
+ 0x83, 0x84, \
+ 0x72, 0x47, \
+ 0x8e, 0x79, 0x3d, 0x69, 0xd8, 0x47, 0x7d, 0xe4 \
+}
+#define GUID_LINUX_FILESYSTEM_DATA_NAME "linux-filesystem"
+
+// clang-format on
+
+#endif // SYSROOT_ZIRCON_HW_GPT_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/i2c.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/i2c.h
new file mode 100644
index 0000000..e35b6f1
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/i2c.h
@@ -0,0 +1,10 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_HW_I2C_H_
+#define SYSROOT_ZIRCON_HW_I2C_H_
+
+#define I2C_CLASS_HID 1
+
+#endif // SYSROOT_ZIRCON_HW_I2C_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/pci.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/pci.h
new file mode 100644
index 0000000..7de1bca
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/pci.h
@@ -0,0 +1,50 @@
+// Copyright 2018 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.
+
+#ifndef SYSROOT_ZIRCON_HW_PCI_H_
+#define SYSROOT_ZIRCON_HW_PCI_H_
+
+#include <stdint.h>
+#include <zircon/compiler.h>
+
+__BEGIN_CDECLS
+
+// Structure for passing around PCI address information
+typedef struct pci_bdf {
+ uint8_t bus_id;
+ uint8_t device_id;
+ uint8_t function_id;
+} pci_bdf_t;
+
+// TODO(cja): This header is used for the transition of these defines from
+// kernel to userspace, but due to pci_bdf_t some of the kernel includes it.
+// Make sure defines here don't clash with those in pci_common.h by having this
+// guard, but remove it after the transition.
+#ifndef WITH_KERNEL_PCIE
+
+#define PCI_MAX_BUSES (256u)
+#define PCI_MAX_DEVICES_PER_BUS (32u)
+#define PCI_MAX_FUNCTIONS_PER_DEVICE (8u)
+#define PCI_MAX_FUNCTIONS_PER_BUS (PCI_MAX_DEVICES_PER_BUS * PCI_MAX_FUNCTIONS_PER_DEVICE)
+
+#define PCI_STANDARD_CONFIG_HDR_SIZE (64u)
+#define PCI_BASE_CONFIG_SIZE (256u)
+#define PCIE_EXTENDED_CONFIG_SIZE (4096u)
+#define PCIE_ECAM_BYTES_PER_BUS (PCIE_EXTENDED_CONFIG_SIZE * PCI_MAX_FUNCTIONS_PER_BUS)
+
+#define PCI_BAR_REGS_PER_BRIDGE (2u)
+#define PCI_BAR_REGS_PER_DEVICE (6u)
+#define PCI_MAX_BAR_REGS (6u)
+
+#define PCI_MAX_LEGACY_IRQ_PINS (4u)
+#define PCI_MAX_MSI_IRQS (32u)
+#define PCIE_MAX_MSIX_IRQS (2048u)
+
+#define PCI_INVALID_VENDOR_ID (0xFFFF)
+
+#endif // WITH_KERNEL_PCIE
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_HW_PCI_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/usb.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/usb.h
new file mode 100644
index 0000000..8256c2e
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/usb.h
@@ -0,0 +1,281 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_HW_USB_H_
+#define SYSROOT_ZIRCON_HW_USB_H_
+
+// clang-format off
+
+#include <endian.h>
+#include <stdint.h>
+#include <zircon/compiler.h>
+
+__BEGIN_CDECLS
+
+// maximum number of endpoints per device
+#define USB_MAX_EPS 32
+
+/* Request Types */
+#define USB_DIR_OUT (0 << 7)
+#define USB_DIR_IN (1 << 7)
+#define USB_DIR_MASK (1 << 7)
+#define USB_TYPE_STANDARD (0 << 5)
+#define USB_TYPE_CLASS (1 << 5)
+#define USB_TYPE_VENDOR (2 << 5)
+#define USB_TYPE_MASK (3 << 5)
+#define USB_RECIP_DEVICE (0 << 0)
+#define USB_RECIP_INTERFACE (1 << 0)
+#define USB_RECIP_ENDPOINT (2 << 0)
+#define USB_RECIP_OTHER (3 << 0)
+#define USB_RECIP_MASK (0x1f << 0)
+
+/* 1.0 Request Values */
+#define USB_REQ_GET_STATUS 0x00
+#define USB_REQ_CLEAR_FEATURE 0x01
+#define USB_REQ_SET_FEATURE 0x03
+#define USB_REQ_SET_ADDRESS 0x05
+#define USB_REQ_GET_DESCRIPTOR 0x06
+#define USB_REQ_SET_DESCRIPTOR 0x07
+#define USB_REQ_GET_CONFIGURATION 0x08
+#define USB_REQ_SET_CONFIGURATION 0x09
+#define USB_REQ_GET_INTERFACE 0x0A
+#define USB_REQ_SET_INTERFACE 0x0B
+#define USB_REQ_SYNCH_FRAME 0x0C
+
+/* USB device/interface classes */
+#define USB_CLASS_AUDIO 0x01
+#define USB_CLASS_COMM 0x02
+#define USB_CLASS_HID 0x03
+#define USB_CLASS_PHYSICAL 0x05
+#define USB_CLASS_IMAGING 0x06
+#define USB_CLASS_PRINTER 0x07
+#define USB_CLASS_MSC 0x08
+#define USB_CLASS_HUB 0x09
+#define USB_CLASS_CDC 0x0a
+#define USB_CLASS_CCID 0x0b
+#define USB_CLASS_SECURITY 0x0d
+#define USB_CLASS_VIDEO 0x0e
+#define USB_CLASS_HEALTHCARE 0x0f
+#define USB_CLASS_DIAGNOSTIC 0xdc
+#define USB_CLASS_WIRELESS 0xe0
+#define USB_CLASS_MISC 0xef
+#define USB_CLASS_APPLICATION_SPECIFIC 0xfe
+#define USB_CLASS_VENDOR 0xFf
+
+#define USB_SUBCLASS_MSC_SCSI 0x06
+#define USB_PROTOCOL_MSC_BULK_ONLY 0x50
+
+#define USB_SUBCLASS_DFU 0x01
+#define USB_PROTOCOL_DFU 0x02
+
+#define USB_SUBCLASS_VENDOR 0xFF
+#define USB_PROTOCOL_TEST_FTDI 0x01
+#define USB_PROTOCOL_TEST_HID_ONE_ENDPOINT 0x02
+#define USB_PROTOCOL_TEST_HID_TWO_ENDPOINT 0x03
+
+/* Descriptor Types */
+#define USB_DT_DEVICE 0x01
+#define USB_DT_CONFIG 0x02
+#define USB_DT_STRING 0x03
+#define USB_DT_INTERFACE 0x04
+#define USB_DT_ENDPOINT 0x05
+#define USB_DT_DEVICE_QUALIFIER 0x06
+#define USB_DT_OTHER_SPEED_CONFIG 0x07
+#define USB_DT_INTERFACE_POWER 0x08
+#define USB_DT_INTERFACE_ASSOCIATION 0x0b
+#define USB_DT_HID 0x21
+#define USB_DT_HIDREPORT 0x22
+#define USB_DT_HIDPHYSICAL 0x23
+#define USB_DT_CS_INTERFACE 0x24
+#define USB_DT_CS_ENDPOINT 0x25
+#define USB_DT_SS_EP_COMPANION 0x30
+#define USB_DT_SS_ISOCH_EP_COMPANION 0x31
+
+/* USB device feature selectors */
+#define USB_DEVICE_SELF_POWERED 0x00
+#define USB_DEVICE_REMOTE_WAKEUP 0x01
+#define USB_DEVICE_TEST_MODE 0x02
+
+/* Configuration attributes (bmAttributes) */
+#define USB_CONFIGURATION_REMOTE_WAKEUP 0x20
+#define USB_CONFIGURATION_SELF_POWERED 0x40
+#define USB_CONFIGURATION_RESERVED_7 0x80 // This bit must be set
+
+/* Endpoint direction (bEndpointAddress) */
+#define USB_ENDPOINT_IN 0x80
+#define USB_ENDPOINT_OUT 0x00
+#define USB_ENDPOINT_DIR_MASK 0x80
+#define USB_ENDPOINT_NUM_MASK 0x1F
+
+/* Endpoint types (bmAttributes) */
+#define USB_ENDPOINT_CONTROL 0x00
+#define USB_ENDPOINT_ISOCHRONOUS 0x01
+#define USB_ENDPOINT_BULK 0x02
+#define USB_ENDPOINT_INTERRUPT 0x03
+#define USB_ENDPOINT_TYPE_MASK 0x03
+
+/* Endpoint synchronization type (bmAttributes) */
+#define USB_ENDPOINT_NO_SYNCHRONIZATION 0x00
+#define USB_ENDPOINT_ASYNCHRONOUS 0x04
+#define USB_ENDPOINT_ADAPTIVE 0x08
+#define USB_ENDPOINT_SYNCHRONOUS 0x0C
+#define USB_ENDPOINT_SYNCHRONIZATION_MASK 0x0C
+
+/* Endpoint usage type (bmAttributes) */
+#define USB_ENDPOINT_DATA 0x00
+#define USB_ENDPOINT_FEEDBACK 0x10
+#define USB_ENDPOINT_IMPLICIT_FEEDBACK 0x20
+#define USB_ENDPOINT_USAGE_MASK 0x30
+
+#define USB_ENDPOINT_HALT 0x00
+
+// Values in this set match those used in XHCI and other parts of the USB specification
+#define USB_SPEED_UNDEFINED 0
+#define USB_SPEED_FULL 1
+#define USB_SPEED_LOW 2
+#define USB_SPEED_HIGH 3
+#define USB_SPEED_SUPER 4
+typedef uint32_t usb_speed_t;
+
+/* general USB defines */
+typedef struct {
+ uint8_t bmRequestType;
+ uint8_t bRequest;
+ uint16_t wValue;
+ uint16_t wIndex;
+ uint16_t wLength;
+} __attribute__ ((packed)) usb_setup_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+} __attribute__ ((packed)) usb_descriptor_header_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_DEVICE
+ uint16_t bcdUSB;
+ uint8_t bDeviceClass;
+ uint8_t bDeviceSubClass;
+ uint8_t bDeviceProtocol;
+ uint8_t bMaxPacketSize0;
+ uint16_t idVendor;
+ uint16_t idProduct;
+ uint16_t bcdDevice;
+ uint8_t iManufacturer;
+ uint8_t iProduct;
+ uint8_t iSerialNumber;
+ uint8_t bNumConfigurations;
+} __attribute__ ((packed)) usb_device_descriptor_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_CONFIG
+ uint16_t wTotalLength;
+ uint8_t bNumInterfaces;
+ uint8_t bConfigurationValue;
+ uint8_t iConfiguration;
+ uint8_t bmAttributes;
+ uint8_t bMaxPower;
+} __attribute__ ((packed)) usb_configuration_descriptor_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_STRING
+ uint8_t bString[];
+} __attribute__ ((packed)) usb_string_descriptor_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_INTERFACE
+ uint8_t bInterfaceNumber;
+ uint8_t bAlternateSetting;
+ uint8_t bNumEndpoints;
+ uint8_t bInterfaceClass;
+ uint8_t bInterfaceSubClass;
+ uint8_t bInterfaceProtocol;
+ uint8_t iInterface;
+} __attribute__ ((packed)) usb_interface_descriptor_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_ENDPOINT
+ uint8_t bEndpointAddress;
+ uint8_t bmAttributes;
+ uint16_t wMaxPacketSize;
+ uint8_t bInterval;
+} __attribute__ ((packed)) usb_endpoint_descriptor_t;
+#define usb_ep_num(ep) ((ep)->bEndpointAddress & USB_ENDPOINT_NUM_MASK)
+// usb_ep_num2() useful with you have bEndpointAddress outside of a descriptor.
+#define usb_ep_num2(addr) ((addr) & USB_ENDPOINT_NUM_MASK)
+#define usb_ep_direction(ep) ((ep)->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
+#define usb_ep_type(ep) ((ep)->bmAttributes & USB_ENDPOINT_TYPE_MASK)
+#define usb_ep_sync_type(ep) ((ep)->bmAttributes & USB_ENDPOINT_SYNCHRONIZATION_MASK)
+// max packet size is in bits 10..0
+#define usb_ep_max_packet(ep) (le16toh((ep)->wMaxPacketSize) & 0x07FF)
+// for high speed interrupt and isochronous endpoints, additional transactions per microframe
+// are in bits 12..11
+#define usb_ep_add_mf_transactions(ep) ((le16toh((ep)->wMaxPacketSize) >> 11) & 3)
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_DEVICE_QUALIFIER
+ uint16_t bcdUSB;
+ uint8_t bDeviceClass;
+ uint8_t bDeviceSubClass;
+ uint8_t bDeviceProtocol;
+ uint8_t bMaxPacketSize0;
+ uint8_t bNumConfigurations;
+ uint8_t bReserved;
+} __attribute__ ((packed)) usb_device_qualifier_descriptor_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_SS_EP_COMPANION
+ uint8_t bMaxBurst;
+ uint8_t bmAttributes;
+ uint16_t wBytesPerInterval;
+} __attribute__ ((packed)) usb_ss_ep_comp_descriptor_t;
+#define usb_ss_ep_comp_isoc_mult(ep) ((ep)->bmAttributes & 0x3)
+#define usb_ss_ep_comp_isoc_comp(ep) (!!((ep)->bmAttributes & 0x80))
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_SS_ISOCH_EP_COMPANION
+ uint16_t wReserved;
+ uint32_t dwBytesPerInterval;
+} __attribute__ ((packed)) usb_ss_isoch_ep_comp_descriptor_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_INTERFACE_ASSOCIATION
+ uint8_t bFirstInterface;
+ uint8_t bInterfaceCount;
+ uint8_t bFunctionClass;
+ uint8_t bFunctionSubClass;
+ uint8_t bFunctionProtocol;
+ uint8_t iFunction;
+} __attribute__ ((packed)) usb_interface_assoc_descriptor_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_CS_INTERFACE
+ uint8_t bDescriptorSubType;
+} __attribute__ ((packed)) usb_cs_interface_descriptor_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_STRING
+ uint16_t wLangIds[127];
+} __attribute__ ((packed)) usb_langid_desc_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_STRING
+ uint16_t code_points[127];
+} __attribute__ ((packed)) usb_string_desc_t;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_HW_USB_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/usb/audio.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/usb/audio.h
new file mode 100644
index 0000000..4e68f87
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/usb/audio.h
@@ -0,0 +1,527 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_HW_USB_AUDIO_H_
+#define SYSROOT_ZIRCON_HW_USB_AUDIO_H_
+
+// clang-format off
+
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+////////////////////////////////////////////////////
+//
+// General Audio interface constants
+//
+////////////////////////////////////////////////////
+
+// audio interface subclasses
+#define USB_SUBCLASS_AUDIO_CONTROL 0x01
+#define USB_SUBCLASS_AUDIO_STREAMING 0x02
+#define USB_SUBCLASS_MIDI_STREAMING 0x03
+
+// audio class specific descriptor types
+#define USB_AUDIO_CS_DEVICE 0x21
+#define USB_AUDIO_CS_CONFIGURATION 0x22
+#define USB_AUDIO_CS_STRING 0x23
+#define USB_AUDIO_CS_INTERFACE 0x24
+#define USB_AUDIO_CS_ENDPOINT 0x25
+
+////////////////////////////////////////////////////
+//
+// Audio Control interface constants
+//
+////////////////////////////////////////////////////
+
+// audio class specific AC interface descriptor subtypes
+#define USB_AUDIO_AC_HEADER 0x01
+#define USB_AUDIO_AC_INPUT_TERMINAL 0x02
+#define USB_AUDIO_AC_OUTPUT_TERMINAL 0x03
+#define USB_AUDIO_AC_MIXER_UNIT 0x04
+#define USB_AUDIO_AC_SELECTOR_UNIT 0x05
+#define USB_AUDIO_AC_FEATURE_UNIT 0x06
+#define USB_AUDIO_AC_PROCESSING_UNIT 0x07
+#define USB_AUDIO_AC_EXTENSION_UNIT 0x08
+
+// processing unit process types
+#define USB_AUDIO_UP_DOWN_MIX_PROCESS 0x01
+#define USB_AUDIO_DOLBY_PROLOGIC_PROCESS 0x02
+#define USB_AUDIO_3D_STEREO_EXTENDER_PROCESS 0x03
+#define USB_AUDIO_REVERBERATION_PROCESS 0x04
+#define USB_AUDIO_CHORUS_PROCESS 0x05
+#define USB_AUDIO_DYN_RANGE_COMP_PROCESS 0x06
+
+// audio class specific endpoint descriptor subtypes
+#define USB_AUDIO_EP_GENERAL 0x01
+
+// audio class specific request codes
+#define USB_AUDIO_SET_CUR 0x01
+#define USB_AUDIO_GET_CUR 0x81
+#define USB_AUDIO_SET_MIN 0x02
+#define USB_AUDIO_GET_MIN 0x82
+#define USB_AUDIO_SET_MAX 0x03
+#define USB_AUDIO_GET_MAX 0x83
+#define USB_AUDIO_SET_RES 0x04
+#define USB_AUDIO_GET_RES 0x84
+#define USB_AUDIO_SET_MEM 0x05
+#define USB_AUDIO_GET_MEM 0x85
+#define USB_AUDIO_GET_STAT 0xFF
+
+// terminal control selectors
+#define USB_AUDIO_COPY_PROTECT_CONTROL 0x01
+
+// feature unit control selectors
+#define USB_AUDIO_MUTE_CONTROL 0x01
+#define USB_AUDIO_VOLUME_CONTROL 0x02
+#define USB_AUDIO_BASS_CONTROL 0x03
+#define USB_AUDIO_MID_CONTROL 0x04
+#define USB_AUDIO_TREBLE_CONTROL 0x05
+#define USB_AUDIO_GRAPHIC_EQUALIZER_CONTROL 0x06
+#define USB_AUDIO_AUTOMATIC_GAIN_CONTROL 0x07
+#define USB_AUDIO_DELAY_CONTROL 0x08
+#define USB_AUDIO_BASS_BOOST_CONTROL 0x09
+#define USB_AUDIO_LOUDNESS_CONTROL 0x0A
+
+// feature unit control support bitmasks
+#define USB_AUDIO_FU_BMA_MUTE (1u << 0u)
+#define USB_AUDIO_FU_BMA_VOLUME (1u << 1u)
+#define USB_AUDIO_FU_BMA_BASS (1u << 2u)
+#define USB_AUDIO_FU_BMA_MID (1u << 3u)
+#define USB_AUDIO_FU_BMA_TREBLE (1u << 4u)
+#define USB_AUDIO_FU_BMA_GRAPHIC_EQUALIZER (1u << 5u)
+#define USB_AUDIO_FU_BMA_AUTOMATIC_GAIN (1u << 6u)
+#define USB_AUDIO_FU_BMA_DELAY (1u << 7u)
+#define USB_AUDIO_FU_BMA_BASS_BOOST (1u << 8u)
+#define USB_AUDIO_FU_BMA_LOUDNESS (1u << 9u)
+
+// up/down mix processing unit control selectors
+#define USB_AUDIO_UD_ENABLE_CONTROL 0x01
+#define USB_AUDIO_UD_MODE_SELECT_CONTROL 0x02
+#define USB_AUDIO_UD_MODE_SELECT_CONTROL 0x02
+
+// Dolby Prologic processing unit control selectors
+#define USB_AUDIO_DP_ENABLE_CONTROL 0x01
+#define USB_AUDIO_DP_MODE_SELECT_CONTROL 0x02
+
+// 3D stereo extender processing unit control selectors
+#define USB_AUDIO_3D_ENABLE_CONTROL 0x01
+#define USB_AUDIO_SPACIOUSNESS_CONTROL 0x03
+
+// reverberation processing unit control selectors
+#define USB_AUDIO_RV_ENABLE_CONTROL 0x01
+#define USB_AUDIO_REVERB_LEVEL_CONTROL 0x02
+#define USB_AUDIO_REVERB_TIME_CONTROL 0x03
+#define USB_AUDIO_REVERB_FEEDBACK_CONTROL 0x04
+
+// chorus processing unit control selectors
+#define USB_AUDIO_CH_ENABLE_CONTROL 0x01
+#define USB_AUDIO_CHORUS_LEVEL_CONTROL 0x02
+#define USB_AUDIO_CHORUS_RATE_CONTROL 0x03
+#define USB_AUDIO_CHORUS_DEPTH_CONTROL 0x04
+
+// dynamic range compressor processing unit control selectors
+#define USB_AUDIO_DR_ENABLE_CONTROL 0x01
+#define USB_AUDIO_COMPRESSION_RATE_CONTROL 0x02
+#define USB_AUDIO_MAXAMPL_CONTROL 0x03
+#define USB_AUDIO_THRESHOLD_CONTROL 0x04
+#define USB_AUDIO_ATTACK_TIME 0x05
+#define USB_AUDIO_RELEASE_TIME 0x06
+
+// extension unit control selectors
+#define USB_AUDIO_XU_ENABLE_CONTROL 0x01
+
+// endpoint control selectors
+#define USB_AUDIO_SAMPLING_FREQ_CONTROL 0x01
+#define USB_AUDIO_PITCH_CONTROL 0x02
+
+// USB audio terminal types
+#define USB_AUDIO_TERMINAL_USB_UNDEFINED 0x0100
+#define USB_AUDIO_TERMINAL_USB_STREAMING 0x0101
+#define USB_AUDIO_TERMINAL_USB_VENDOR 0x01FF
+#define USB_AUDIO_TERMINAL_INPUT_UNDEFINED 0x0200
+#define USB_AUDIO_TERMINAL_MICROPHONE 0x0201
+#define USB_AUDIO_TERMINAL_DESKTOP_MICROPHONE 0x0202
+#define USB_AUDIO_TERMINAL_PERSONAL_MICROPHONE 0x0203
+#define USB_AUDIO_TERMINAL_OMNI_DIRECTIONAL_MICROPHONE 0x0204
+#define USB_AUDIO_TERMINAL_MICROPHONE_ARRAY 0x0205
+#define USB_AUDIO_TERMINAL_PROCESSING_MICROPHONE_ARRAY 0x0206
+#define USB_AUDIO_TERMINAL_OUTPUT_UNDEFINED 0x0300
+#define USB_AUDIO_TERMINAL_SPEAKER 0x0301
+#define USB_AUDIO_TERMINAL_HEADPHONES 0x0302
+#define USB_AUDIO_TERMINAL_HEAD_MOUNTED_DISPLAY_AUDIO 0x0303
+#define USB_AUDIO_TERMINAL_DESKTOP_SPEAKER 0x0304
+#define USB_AUDIO_TERMINAL_ROOM_SPEAKER 0x0305
+#define USB_AUDIO_TERMINAL_COMMUNICATION_SPEAKER 0x0306
+#define USB_AUDIO_TERMINAL_LOW_FREQ_EFFECTS_SPEAKER 0x0307
+#define USB_AUDIO_TERMINAL_BIDIRECTIONAL_UNDEFINED 0x0400
+#define USB_AUDIO_TERMINAL_HANDSET 0x0401
+#define USB_AUDIO_TERMINAL_HEADSET 0x0402
+#define USB_AUDIO_TERMINAL_SPEAKERPHONE 0x0403
+#define USB_AUDIO_TERMINAL_ECHO_SUPPRESSING_SPEAKERPHONE 0x0404
+#define USB_AUDIO_TERMINAL_ECHO_CANCELING_SPEAKERPHONE 0x0405
+#define USB_AUDIO_TERMINAL_TELEPHONY_UNDEFINED 0x0500
+#define USB_AUDIO_TERMINAL_PHONE_LINE 0x0501
+#define USB_AUDIO_TERMINAL_TELEPHONE 0x0502
+#define USB_AUDIO_TERMINAL_DOWN_LINE_PHONE 0x0503
+#define USB_AUDIO_TERMINAL_EXTERNAL_UNDEFINED 0x0600
+#define USB_AUDIO_TERMINAL_ANALOG_CONNECTOR 0x0601
+#define USB_AUDIO_TERMINAL_DIGITAL_AUDIO_INTERFACE 0x0602
+#define USB_AUDIO_TERMINAL_LINE_CONNECTOR 0x0603
+#define USB_AUDIO_TERMINAL_LEGACY_AUDIO_CONNECTOR 0x0604
+#define USB_AUDIO_TERMINAL_SPDIF_INTERFACE 0x0605
+#define USB_AUDIO_TERMINAL_1394_DA_STREAM 0x0606
+#define USB_AUDIO_TERMINAL_1394_DV_STREAM_SOUNDTRACK 0x0607
+#define USB_AUDIO_TERMINAL_EMBEDDED_UNDEFINED 0x0700
+#define USB_AUDIO_TERMINAL_LEVEL_CALIBRATION_NOISE_SOURCE 0x0701
+#define USB_AUDIO_TERMINAL_EQUALIZATION_NOISE 0x0702
+#define USB_AUDIO_TERMINAL_CD_PLAYER 0x0703
+#define USB_AUDIO_TERMINAL_DAT 0x0704
+#define USB_AUDIO_TERMINAL_DCC 0x0705
+#define USB_AUDIO_TERMINAL_MINI_DISK 0x0706
+#define USB_AUDIO_TERMINAL_ANALOG_TAPE 0x0707
+#define USB_AUDIO_TERMINAL_PHONOGRAPH 0x0708
+#define USB_AUDIO_TERMINAL_VCR_AUDIO 0x0709
+#define USB_AUDIO_TERMINAL_VIDEO_DISK_AUDIO 0x070A
+#define USB_AUDIO_TERMINAL_DVD_AUDIO 0x070B
+#define USB_AUDIO_TERMINAL_TV_TUNER_AUDIO 0x070C
+#define USB_AUDIO_TERMINAL_SATELLITE_RECEIVER_AUDIO 0x070D
+#define USB_AUDIO_TERMINAL_CABLE_TUNER_AUDIO 0x070E
+#define USB_AUDIO_TERMINAL_DSS_AUDIO 0x070F
+#define USB_AUDIO_TERMINAL_RADIO_RECEIVER 0x0710
+#define USB_AUDIO_TERMINAL_RADIO_TRANSMITTER 0x0711
+#define USB_AUDIO_TERMINAL_MULTI_TRACK_RECORDER 0x0712
+#define USB_AUDIO_TERMINAL_SYNTHESIZER 0x0713
+
+////////////////////////////////////////////////////
+//
+// Audio streaming interface constants
+//
+////////////////////////////////////////////////////
+
+// Audio stream class-specific AS interface descriptor subtypes
+#define USB_AUDIO_AS_GENERAL 0x01
+#define USB_AUDIO_AS_FORMAT_TYPE 0x02
+#define USB_AUDIO_AS_FORMAT_SPECIFIC 0x03
+
+// wFormatTag values present in the class specific AS header
+// Defined in Section A.1 of USB Device Class Definition for Audio Data Formats
+#define USB_AUDIO_AS_FT_TYPE_I_UNDEFINED 0x0000
+#define USB_AUDIO_AS_FT_PCM 0x0001
+#define USB_AUDIO_AS_FT_PCM8 0x0002
+#define USB_AUDIO_AS_FT_IEEE_FLOAT 0x0003
+#define USB_AUDIO_AS_FT_ALAW 0x0004
+#define USB_AUDIO_AS_FT_MULAW 0x0005
+#define USB_AUDIO_AS_FT_TYPE_II_UNDEFINED 0x1000
+#define USB_AUDIO_AS_FT_MPEG 0x1001
+#define USB_AUDIO_AS_FT_AC3 0x1002
+#define USB_AUDIO_AS_FT_TYPE_III_UNDEFINED 0x2000
+#define USB_AUDIO_AS_FT_IEC1937_AC3 0x2001
+#define USB_AUDIO_AS_FT_IEC1937_MPEG1_L1 0x2002
+#define USB_AUDIO_AS_FT_IEC1937_MPEG1_L23 0x2003
+#define USB_AUDIO_AS_FT_IEC1937_MPEG2_EXT 0x2004
+#define USB_AUDIO_AS_FT_IEC1937_MPEG2_L1_LS 0x2005
+#define USB_AUDIO_AS_FT_IEC1937_MPEG2_L23_LS 0x2006
+
+// Audio stream class-specific format-specific types
+#define USB_AUDIO_FORMAT_TYPE_UNDEFINED 0x00
+#define USB_AUDIO_FORMAT_TYPE_I 0x01
+#define USB_AUDIO_FORMAT_TYPE_II 0x02
+#define USB_AUDIO_FORMAT_TYPE_III 0x03
+
+////////////////////////////////////////////////////
+//
+// MIDI streaming interface constants
+//
+////////////////////////////////////////////////////
+
+// MIDI class specific MS interface descriptor subtypes
+#define USB_MIDI_MS_HEADER 0x01
+#define USB_MIDI_IN_JACK 0x02
+#define USB_MIDI_OUT_JACK 0x03
+#define USB_MIDI_ELEMENT 0x04
+
+// MIDI class specific MS endpoint descriptor subtypes
+#define USB_MIDI_MS_GENERAL 0x01
+
+// MIDI IN and OUT jack types
+#define USB_MIDI_JACK_EMBEDDED 0x01
+#define USB_MIDI_JACK_INTERNAL 0x02
+
+// MIDI endpoint control selectors
+#define USB_MIDI_ASSOCIATION_CONTROL 0x01
+
+
+// Top level header structure shared by all USB audio descriptors.
+//
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype;
+} __PACKED usb_audio_desc_header;
+
+// Audio Control Interface descriptor definitions
+//
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_AUDIO_AC_HEADER
+ uint16_t bcdADC;
+ uint16_t wTotalLength;
+ uint8_t bInCollection;
+ uint8_t baInterfaceNr[];
+} __PACKED usb_audio_ac_header_desc;
+
+// Common header structure shared by all unit and terminal descriptors found in
+// an Audio Control interface descriptor.
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_AUDIO_AC_.*_(TERMINAL|UNIT)
+ uint8_t bID;
+} __PACKED usb_audio_ac_ut_desc;
+
+// Common header structure shared by all terminal descriptors found in an Audio
+// Control interface descriptor.
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_AUDIO_AC_(INPUT|OUTPUT)_TERMINAL
+ uint8_t bTerminalID;
+ uint16_t wTerminalType;
+ uint8_t bAssocTerminal;
+} __PACKED usb_audio_ac_terminal_desc;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_AUDIO_AC_INPUT_TERMINAL
+ uint8_t bTerminalID;
+ uint16_t wTerminalType;
+ uint8_t bAssocTerminal;
+ uint8_t bNrChannels;
+ uint16_t wChannelConfig;
+ uint8_t iChannelNames;
+ uint8_t iTerminal;
+} __PACKED usb_audio_ac_input_terminal_desc;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_AUDIO_AC_OUTPUT_TERMINAL
+ uint8_t bTerminalID;
+ uint16_t wTerminalType;
+ uint8_t bAssocTerminal;
+ uint8_t bSourceID;
+ uint8_t iTerminal;
+} __PACKED usb_audio_ac_output_terminal_desc;
+
+// Note: Mixer unit descriptors contain two inlined variable length arrays, each
+// with descriptor data following them. They are therefor described using 3
+// structure definitions which are logically concatenated, but separated by the
+// inline arrays.
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_AUDIO_AC_MIXER_UNIT
+ uint8_t bUnitID;
+ uint8_t bNrInPins;
+ uint8_t baSourceID[];
+} __PACKED usb_audio_ac_mixer_unit_desc_0;
+
+typedef struct {
+ uint8_t bNrChannels;
+ uint16_t wChannelConfig;
+ uint8_t iChannelNames;
+ uint8_t bmControls[];
+} __PACKED usb_audio_ac_mixer_unit_desc_1;
+
+typedef struct {
+ uint8_t iMixer;
+} __PACKED usb_audio_ac_mixer_unit_desc_2;
+
+// Note: Selector unit descriptors contain an inlined variable length array with
+// descriptor data following it. They are therefor described using 2 structure
+// definitions which are logically concatenated, but separated by the inline
+// array.
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_AUDIO_AC_SELECTOR_UNIT
+ uint8_t bUnitID;
+ uint8_t bNrInPins;
+ uint8_t baSourceID[];
+} __PACKED usb_audio_ac_selector_unit_desc_0;
+
+typedef struct {
+ uint8_t iSelector;
+} __PACKED usb_audio_ac_selector_unit_desc_1;
+
+// Note: Feature unit descriptors contain an inlined variable length array with
+// descriptor data following it. They are therefor described using 2 structure
+// definitions which are logically concatenated, but separated by the inline
+// array.
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_AUDIO_AC_FEATURE_UNIT
+ uint8_t bUnitID;
+ uint8_t bSourceID;
+ uint8_t bControlSize;
+ uint8_t bmaControls[];
+} __PACKED usb_audio_ac_feature_unit_desc_0;
+
+typedef struct {
+ uint8_t iFeature;
+} __PACKED usb_audio_ac_feature_unit_desc_1;
+
+// Note: Processing unit descriptors contain two inlined variable length arrays,
+// each with descriptor data following them. They are therefor described using
+// 3 structure definitions which are logically concatenated, but separated by
+// the inline arrays.
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_AUDIO_AC_PROCESSING_UNIT
+ uint8_t bUnitID;
+ uint16_t wProcessType;
+ uint8_t bNrInPins;
+ uint8_t baSourceID[];
+} __PACKED usb_audio_ac_processing_unit_desc_0;
+
+typedef struct {
+ uint8_t bNrChannels;
+ uint16_t wChannelConfig;
+ uint8_t iChannelNames;
+ uint8_t bControlSize;
+ uint8_t bmControls[];
+} __PACKED usb_audio_ac_processing_unit_desc_1;
+
+typedef struct {
+ uint8_t iProcessing;
+ // Note: The Process-specific control structure follows this with the
+ // structure type determined by wProcessType
+ // TODO(johngro) : Define the process specific control structures. As of
+ // the 1.0 revision of the USB audio spec, the types to be defined are...
+ //
+ // ** Up/Down-mix
+ // ** Dolby Prologic
+ // ** 3D-Stereo Extender
+ // ** Reverberation
+ // ** Chorus
+ // ** Dynamic Range Compressor
+} __PACKED usb_audio_ac_processing_unit_desc_2;
+
+// Note: Extension unit descriptors contain two inlined variable length arrays,
+// each with descriptor data following them. They are therefor described using
+// 3 structure definitions which are logically concatenated, but separated by
+// the inline arrays.
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_AUDIO_AC_EXTENSION_UNIT
+ uint8_t bUnitID;
+ uint16_t wExtensionCode;
+ uint8_t bNrInPins;
+ uint8_t baSourceID[];
+} __PACKED usb_audio_ac_extension_unit_desc_0;
+
+typedef struct {
+ uint8_t bNrChannels;
+ uint16_t wChannelConfig;
+ uint8_t iChannelNames;
+ uint8_t bControlSize;
+ uint8_t bmControls[];
+} __PACKED usb_audio_ac_extension_unit_desc_1;
+
+typedef struct {
+ uint8_t iExtension;
+} __PACKED usb_audio_ac_extension_unit_desc_2;
+
+// Audio Streaming Interface descriptor definitions
+//
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_AUDIO_AS_GENERAL
+ uint8_t bTerminalLink;
+ uint8_t bDelay;
+ uint16_t wFormatTag;
+} __PACKED usb_audio_as_header_desc;
+
+typedef struct {
+ uint8_t freq[3]; // 24 bit unsigned integer, little-endian
+} __PACKED usb_audio_as_samp_freq;
+
+// Common header used by all format type descriptors
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_AUDIO_AS_FORMAT_TYPE
+ uint8_t bFormatType;
+} __PACKED usb_audio_as_format_type_hdr;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_AUDIO_AS_FORMAT_TYPE
+ uint8_t bFormatType; // USB_AUDIO_FORMAT_TYPE_I
+ uint8_t bNrChannels;
+ uint8_t bSubFrameSize;
+ uint8_t bBitResolution;
+ uint8_t bSamFreqType; // number of sampling frequencies
+ usb_audio_as_samp_freq tSamFreq[]; // list of sampling frequencies (3 bytes each)
+} __PACKED usb_audio_as_format_type_i_desc;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_ENDPOINT
+ uint8_t bDescriptorSubtype; // USB_AUDIO_EP_GENERAL
+ uint8_t bmAttributes;
+ uint8_t bLockDelayUnits;
+ uint16_t wLockDelay;
+} __PACKED usb_audio_as_isoch_ep_desc;
+
+// MIDI Streaming Interface descriptor definitions
+//
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_MIDI_MS_HEADER
+ uint16_t bcdMSC;
+ uint16_t wTotalLength;
+} __PACKED usb_midi_ms_header_desc;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_MIDI_IN_JACK
+ uint8_t bJackType;
+ uint8_t bJackID;
+ uint8_t iJack;
+} __PACKED usb_midi_ms_in_jack_desc;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_MIDI_OUT_JACK
+ uint8_t bJackType;
+ uint8_t bJackID;
+ uint8_t bNrInputPins;
+ uint8_t baSourceID;
+ uint8_t baSourcePin;
+} __PACKED usb_midi_ms_out_jack_desc;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_ENDPOINT
+ uint8_t bDescriptorSubtype; // USB_MIDI_MS_GENERAL
+ uint8_t bNumEmbMIDIJack;
+ uint8_t baAssocJackID[];
+} __PACKED usb_midi_ms_endpoint_desc;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_HW_USB_AUDIO_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/usb/cdc.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/usb/cdc.h
new file mode 100644
index 0000000..67ac8c7
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/usb/cdc.h
@@ -0,0 +1,150 @@
+// Copyright 2017 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.
+
+#ifndef SYSROOT_ZIRCON_HW_USB_CDC_H_
+#define SYSROOT_ZIRCON_HW_USB_CDC_H_
+
+#include <stdint.h>
+
+// clang-format off
+
+#include <zircon/compiler.h>
+
+/* CDC Subclasses for the Communications Interface Class */
+#define USB_CDC_SUBCLASS_DIRECT_LINE 0x01
+#define USB_CDC_SUBCLASS_ABSTRACT 0x02
+#define USB_CDC_SUBCLASS_TELEPHONE 0x03
+#define USB_CDC_SUBCLASS_MULTI_CHANNEL 0x04
+#define USB_CDC_SUBCLASS_CAPI 0x05
+#define USB_CDC_SUBCLASS_ETHERNET 0x06
+#define USB_CDC_SUBCLASS_ATM 0x07
+#define USB_CDC_SUBCLASS_WIRELESS_HANDSET 0x08
+#define USB_CDC_SUBCLASS_DEVICE_MGMT 0x09
+#define USB_CDC_SUBCLASS_MOBILE_DIRECT 0x0A
+#define USB_CDC_SUBCLASS_OBEX 0x0B
+#define USB_CDC_SUBCLASS_ETHERNET_EMU 0x0C
+#define USB_CDC_SUBCLASS_NETWORK_CTRL 0x0D
+
+/* CDC Descriptor SubTypes */
+#define USB_CDC_DST_HEADER 0x00
+#define USB_CDC_DST_CALL_MGMT 0x01
+#define USB_CDC_DST_ABSTRACT_CTRL_MGMT 0x02
+#define USB_CDC_DST_DIRECT_LINE_MGMT 0x03
+#define USB_CDC_DST_TELEPHONE_RINGER 0x04
+#define USB_CDC_DST_TELEPHONE_CALL_REPORTING 0x05
+#define USB_CDC_DST_UNION 0x06
+#define USB_CDC_DST_COUNTRY_SELECTION 0x07
+#define USB_CDC_DST_TELEPHONE_OP_MODES 0x08
+#define USB_CDC_DST_USB_TERMINAL 0x09
+#define USB_CDC_DST_NETWORK_CHANNEL 0x0A
+#define USB_CDC_DST_PROTOCOL_UNIT 0x0B
+#define USB_CDC_DST_EXTENSION_UNIT 0x0C
+#define USB_CDC_DST_MULTI_CHANNEL_MGMT 0x0D
+#define USB_CDC_DST_CAPI_CTRL_MGMT 0x0E
+#define USB_CDC_DST_ETHERNET 0x0F
+#define USB_CDC_DST_ATM_NETWORKING 0x10
+#define USB_CDC_DST_WIRELESS_HANDSET_CTRL 0x11
+#define USB_CDC_DST_MOBILE_DIRECT_LINE 0x12
+#define USB_CDC_DST_MDLM_DETAIL 0x13
+#define USB_CDC_DST_DEVICE_MGMT 0x14
+#define USB_CDC_DST_OBEX 0x15
+#define USB_CDC_DST_COMMAND_SET 0x16
+#define USB_CDC_DST_COMMAND_SET_DETAIL 0x17
+#define USB_CDC_DST_TELEPHONE_CTRL 0x18
+#define USB_CDC_DST_OBEX_SERVICE_ID 0x19
+#define USB_CDC_DST_NCM 0x1A
+
+/* CDC Class-Specific Notification Codes */
+#define USB_CDC_NC_NETWORK_CONNECTION 0x00
+#define USB_CDC_NC_RESPONSE_AVAILABLE 0x01
+#define USB_CDC_NC_SERIAL_STATE 0x20
+#define USB_CDC_NC_CONNECTION_SPEED_CHANGE 0x2A
+
+/* CDC Ethernet Class-Specific Request Codes */
+#define USB_CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40
+#define USB_CDC_SET_ETHERNET_PM_PATTERN_FILTER 0x41
+#define USB_CDC_GET_ETHERNET_PM_PATTERN_FILTER 0x42
+#define USB_CDC_SET_ETHERNET_PACKET_FILTER 0x43
+#define USB_CDC_GET_ETHERNET_STATISTIC 0x44
+
+/* CDC Ethernet Packet Filter Modes Bits */
+#define USB_CDC_PACKET_TYPE_PROMISCUOUS (1 << 0)
+#define USB_CDC_PACKET_TYPE_ALL_MULTICAST (1 << 1)
+#define USB_CDC_PACKET_TYPE_DIRECTED (1 << 2)
+#define USB_CDC_PACKET_TYPE_BROADCAST (1 << 3)
+#define USB_CDC_PACKET_TYPE_MULTICAST (1 << 4)
+
+/* CDC Class-Specific Requests */
+#define USB_CDC_SEND_ENCAPSULATED_COMMAND 0x00
+#define USB_CDC_GET_ENCAPSULATED_RESPONSE 0x01
+
+__BEGIN_CDECLS
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_CS_INTERFACE
+ uint8_t bDescriptorSubType; // USB_CDC_DST_HEADER
+ uint16_t bcdCDC;
+} __attribute__ ((packed)) usb_cs_header_interface_descriptor_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_CS_INTERFACE
+ uint8_t bDescriptorSubType; // USB_CDC_DST_CALL_MGMT
+ uint8_t bmCapabilities;
+ uint8_t bDataInterface;
+} __attribute__ ((packed)) usb_cs_call_mgmt_interface_descriptor_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_CS_INTERFACE
+ uint8_t bDescriptorSubType; // USB_CDC_DST_ABSTRACT_CTRL_MGMT
+ uint8_t bmCapabilities;
+} __attribute__ ((packed)) usb_cs_abstract_ctrl_mgmt_interface_descriptor_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_CS_INTERFACE
+ uint8_t bDescriptorSubType; // USB_CDC_DST_UNION
+ uint8_t bControlInterface;
+ uint8_t bSubordinateInterface[];
+} __attribute__ ((packed)) usb_cs_union_interface_descriptor_t;
+
+// fixed size version of usb_cs_union_interface_descriptor_t
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_CS_INTERFACE
+ uint8_t bDescriptorSubType; // USB_CDC_DST_UNION
+ uint8_t bControlInterface;
+ uint8_t bSubordinateInterface;
+} __attribute__ ((packed)) usb_cs_union_interface_descriptor_1_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_CS_INTERFACE
+ uint8_t bDescriptorSubType; // USB_CDC_DST_ETHERNET
+ uint8_t iMACAddress;
+ uint32_t bmEthernetStatistics;
+ uint16_t wMaxSegmentSize;
+ uint16_t wNumberMCFilters;
+ uint8_t bNumberPowerFilters;
+} __attribute__ ((packed)) usb_cs_ethernet_interface_descriptor_t;
+
+typedef struct {
+ uint8_t bmRequestType;
+ uint8_t bNotification;
+ uint16_t wValue;
+ uint16_t wIndex;
+ uint16_t wLength;
+} __attribute__ ((packed)) usb_cdc_notification_t;
+
+typedef struct {
+ usb_cdc_notification_t notification;
+ uint32_t downlink_br;
+ uint32_t uplink_br;
+ } __attribute__ ((packed)) usb_cdc_speed_change_notification_t;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_HW_USB_CDC_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/usb/dfu.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/usb/dfu.h
new file mode 100644
index 0000000..7ca40f0
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/usb/dfu.h
@@ -0,0 +1,82 @@
+// Copyright 2018 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.
+
+#ifndef SYSROOT_ZIRCON_HW_USB_DFU_H_
+#define SYSROOT_ZIRCON_HW_USB_DFU_H_
+
+// clang-format off
+
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// USB DFU Spec, Rev 1.1
+
+// DFU Class-Specific Request Values
+// Table 3.2
+#define USB_DFU_DETACH 0x00
+#define USB_DFU_DNLOAD 0x01
+#define USB_DFU_UPLOAD 0x02
+#define USB_DFU_GET_STATUS 0x03
+#define USB_DFU_CLR_STATUS 0x04
+#define USB_DFU_GET_STATE 0x05
+#define USB_DFU_ABORT 0x06
+
+// DFU Class-Specific Descriptor Types
+// Table 4.1.3
+#define USB_DFU_CS_FUNCTIONAL 0x21
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DFU_CS_FUNCTIONAL
+ uint8_t bmAttributes;
+ uint16_t wDetachTimeOut;
+ uint16_t wTransferSize;
+ uint16_t bcdDFUVersion;
+} __PACKED usb_dfu_func_desc_t;
+
+// DFU_GET_STATUS Response
+// Section 6.1.2
+typedef struct {
+ uint8_t bStatus;
+ uint8_t bwPollTimeout[3]; // 24 bit unsigned integer
+ uint8_t bState;
+ uint8_t bString;
+} __PACKED usb_dfu_get_status_data_t;
+
+// DFU Device Status Values
+#define USB_DFU_STATUS_OK 0x00
+#define USB_DFU_STATUS_ERR_TARGET 0x01
+#define USB_DFU_STATUS_ERR_FILE 0x02
+#define USB_DFU_STATUS_ERR_WRITE 0x03
+#define USB_DFU_STATUS_ERR_ERASE 0x04
+#define USB_DFU_STATUS_ERR_CHECK_ERASED 0x05
+#define USB_DFU_STATUS_ERR_PROG 0x06
+#define USB_DFU_STATUS_ERR_VERIFY 0x07
+#define USB_DFU_STATUS_ERR_ADDRESS 0x08
+#define USB_DFU_STATUS_ERR_NOT_DONE 0x09
+#define USB_DFU_STATUS_ERR_FIRMWARE 0x0A
+#define USB_DFU_STATUS_ERR_VENDOR 0x0B
+#define USB_DFU_STATUS_ERR_USER 0x0C
+#define USB_DFU_STATUS_ERR_POR 0x0D
+#define USB_DFU_STATUS_ERR_UNKNOWN 0x0E
+#define USB_DFU_STATUS_ERR_STALLED_PKT 0x0F
+
+// DFU Device State Values
+#define USB_DFU_STATE_APP_IDLE 0x00
+#define USB_DFU_STATE_APP_DETACH 0x01
+#define USB_DFU_STATE_DFU_IDLE 0x02
+#define USB_DFU_STATE_DFU_DNLOAD_SYNC 0x03
+#define USB_DFU_STATE_DFU_DNBUSY 0x04
+#define USB_DFU_STATE_DFU_DNLOAD_IDLE 0x05
+#define USB_DFU_STATE_DFU_MANIFEST_SYNC 0x06
+#define USB_DFU_STATE_DFU_MANIFEST 0x07
+#define USB_DFU_STATE_DFU_MANIFEST_WAIT_RESET 0x08
+#define USB_DFU_STATE_DFU_UPLOAD_IDLE 0x09
+#define USB_DFU_STATE_DFU_ERROR 0x0A
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_HW_USB_DFU_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/usb/hid.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/usb/hid.h
new file mode 100644
index 0000000..97dea4e
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/usb/hid.h
@@ -0,0 +1,46 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_HW_USB_HID_H_
+#define SYSROOT_ZIRCON_HW_USB_HID_H_
+
+#include <stdint.h>
+#include <zircon/compiler.h>
+
+__BEGIN_CDECLS
+
+// clang-format off
+
+// HID Request Values.
+#define USB_HID_GET_REPORT 0x01
+#define USB_HID_GET_IDLE 0x02
+#define USB_HID_GET_PROTOCOL 0x03
+#define USB_HID_SET_REPORT 0x09
+#define USB_HID_SET_IDLE 0x0A
+#define USB_HID_SET_PROTOCOL 0x0B
+
+// HID USB protocols
+#define USB_HID_PROTOCOL_KBD 0x01
+#define USB_HID_PROTOCOL_MOUSE 0x02
+#define USB_HID_SUBCLASS_BOOT 0x01
+
+// clang-format on
+
+typedef struct {
+ uint8_t bDescriptorType;
+ uint16_t wDescriptorLength;
+} __attribute__((packed)) usb_hid_descriptor_entry_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t bcdHID;
+ uint8_t bCountryCode;
+ uint8_t bNumDescriptors;
+ usb_hid_descriptor_entry_t descriptors[];
+} __attribute__((packed)) usb_hid_descriptor_t;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_HW_USB_HID_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/usb/hub.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/usb/hub.h
new file mode 100644
index 0000000..10ed110
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/usb/hub.h
@@ -0,0 +1,120 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_HW_USB_HUB_H_
+#define SYSROOT_ZIRCON_HW_USB_HUB_H_
+
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+// clang-format off
+
+__BEGIN_CDECLS
+
+// Hub request types
+#define USB_RECIP_HUB (USB_TYPE_CLASS | USB_RECIP_DEVICE)
+#define USB_RECIP_PORT (USB_TYPE_CLASS | USB_RECIP_OTHER)
+
+// Hub requests
+#define USB_HUB_SET_DEPTH 12
+
+// Hub descriptor types
+#define USB_HUB_DESC_TYPE 0x29
+#define USB_HUB_DESC_TYPE_SS 0x2A // for superspeed hubs
+
+// Hub Class Feature Selectors (USB 2.0 spec Table 11.17)
+#define USB_FEATURE_C_HUB_LOCAL_POWER 0
+#define USB_FEATURE_C_HUB_OVER_CURRENT 1
+#define USB_FEATURE_PORT_CONNECTION 0
+#define USB_FEATURE_PORT_ENABLE 1
+#define USB_FEATURE_PORT_SUSPEND 2
+#define USB_FEATURE_PORT_OVER_CURRENT 3
+#define USB_FEATURE_PORT_RESET 4
+#define USB_FEATURE_PORT_LINK_STATE 5
+#define USB_FEATURE_PORT_POWER 8
+#define USB_FEATURE_PORT_LOW_SPEED 9
+#define USB_FEATURE_C_PORT_CONNECTION 16
+#define USB_FEATURE_C_PORT_ENABLE 17
+#define USB_FEATURE_C_PORT_SUSPEND 18
+#define USB_FEATURE_C_PORT_OVER_CURRENT 19
+#define USB_FEATURE_C_PORT_RESET 20
+#define USB_FEATURE_PORT_TEST 21
+#define USB_FEATURE_PORT_INDICATOR 22
+#define USB_FEATURE_PORT_INDICATOR 22
+#define USB_FEATURE_PORT_U1_TIMEOUT 23
+#define USB_FEATURE_PORT_U2_TIMEOUT 24
+#define USB_FEATURE_C_PORT_LINK_STATE 25
+#define USB_FEATURE_C_PORT_CONFIG_ERROR 26
+#define USB_FEATURE_PORT_REMOTE_WAKE_MASK 27
+#define USB_FEATURE_BH_PORT_RESET 28
+#define USB_FEATURE_C_BH_PORT_RESET 29
+#define USB_FEATURE_FORCE_LINKPM_ACCEPT 30
+
+typedef struct {
+ uint8_t bDescLength;
+ uint8_t bDescriptorType;
+ uint8_t bNbrPorts;
+ uint16_t wHubCharacteristics;
+ uint8_t bPowerOn2PwrGood;
+ uint8_t bHubContrCurrent;
+ union {
+ // USB 2.0
+ struct {
+ // variable length depending on number of ports
+ uint8_t DeviceRemovable[4];
+ uint8_t PortPwrCtrlMask[4];
+ } __attribute__ ((packed)) hs;
+ // USB 3.0
+ struct {
+ uint8_t bHubHdrDecLat;
+ uint16_t wHubDelay;
+ uint16_t DeviceRemovable;
+ } __attribute__ ((packed)) ss;
+ } __attribute__ ((packed));
+} __attribute__ ((packed)) usb_hub_descriptor_t;
+
+typedef struct {
+ uint16_t wHubStatus;
+ uint16_t wHubChange;
+} __attribute__ ((packed)) usb_hub_status_t;
+
+// wHubStatus bits
+#define USB_HUB_LOCAL_POWER (1 << 0)
+#define USB_HUB_OVER_CURRENT (1 << 1)
+
+typedef struct {
+ uint16_t wPortStatus;
+ uint16_t wPortChange;
+} __attribute__ ((packed)) usb_port_status_t;
+
+// Port Status bits
+#define USB_PORT_CONNECTION (1 << 0)
+#define USB_PORT_ENABLE (1 << 1)
+#define USB_PORT_SUSPEND (1 << 2) // USB 2.0 only
+#define USB_PORT_OVER_CURRENT (1 << 3)
+#define USB_PORT_RESET (1 << 4)
+#define USB_PORT_POWER (1 << 8) // USB 2.0 only
+#define USB_PORT_LOW_SPEED (1 << 9) // USB 2.0 only
+#define USB_PORT_HIGH_SPEED (1 << 10) // USB 2.0 only
+#define USB_PORT_TEST_MODE (1 << 11) // USB 2.0 only
+#define USB_PORT_INDICATOR_CONTROL (1 << 12) // USB 2.0 only
+
+// Port Status Changed bits
+#define USB_C_PORT_CONNECTION (1 << 0)
+#define USB_C_PORT_ENABLE (1 << 1) // USB 2.0 only
+#define USB_C_PORT_SUSPEND (1 << 2) // USB 2.0 only
+#define USB_C_PORT_OVER_CURRENT (1 << 3)
+#define USB_C_PORT_RESET (1 << 4)
+#define USB_C_BH_PORT_RESET (1 << 5) // USB 3.0 only
+#define USB_C_PORT_LINK_STATE (1 << 6) // USB 3.0 only
+#define USB_C_PORT_CONFIG_ERROR (1 << 7) // USB 3.0 only
+#define USB_C_PORT_POWER (1 << 8) // USB 2.0 only
+#define USB_C_PORT_LOW_SPEED (1 << 9) // USB 2.0 only
+#define USB_C_PORT_HIGH_SPEED (1 << 10) // USB 2.0 only
+#define USB_C_PORT_TEST_MODE (1 << 11) // USB 2.0 only
+#define USB_C_PORT_INDICATOR_CONTROL (1 << 12) // USB 2.0 only
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_HW_USB_HUB_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/usb/ums.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/usb/ums.h
new file mode 100644
index 0000000..6640803
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/usb/ums.h
@@ -0,0 +1,159 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_HW_USB_UMS_H_
+#define SYSROOT_ZIRCON_HW_USB_UMS_H_
+
+// clang-format off
+
+// SCSI commands
+#define UMS_TEST_UNIT_READY 0x00
+#define UMS_REQUEST_SENSE 0x03
+#define UMS_INQUIRY 0x12
+#define UMS_MODE_SELECT6 0x15
+#define UMS_MODE_SENSE6 0x1A
+#define UMS_START_STOP_UNIT 0x1B
+#define UMS_TOGGLE_REMOVABLE 0x1E
+#define UMS_READ_FORMAT_CAPACITIES 0x23
+#define UMS_READ_CAPACITY10 0x25
+#define UMS_READ10 0x28
+#define UMS_WRITE10 0x2A
+#define UMS_SYNCHRONIZE_CACHE 0x35
+#define UMS_MODE_SELECT10 0x55
+#define UMS_MODE_SENSE10 0x5A
+#define UMS_READ16 0x88
+#define UMS_WRITE16 0x8A
+#define UMS_READ_CAPACITY16 0x9E
+#define UMS_READ12 0xA8
+#define UMS_WRITE12 0xAA
+
+// control request values
+#define USB_REQ_RESET 0xFF
+#define USB_REQ_GET_MAX_LUN 0xFE
+
+// error codes for CSW processing
+typedef uint32_t csw_status_t;
+#define CSW_SUCCESS ((csw_status_t)0)
+#define CSW_FAILED ((csw_status_t)1)
+#define CSW_PHASE_ERROR ((csw_status_t)2)
+#define CSW_INVALID ((csw_status_t)3)
+#define CSW_TAG_MISMATCH ((csw_status_t)4)
+
+// signatures in header and status
+#define CBW_SIGNATURE 0x43425355
+#define CSW_SIGNATURE 0x53425355
+
+// transfer lengths
+#define UMS_INQUIRY_TRANSFER_LENGTH 0x24
+#define UMS_REQUEST_SENSE_TRANSFER_LENGTH 0x12
+#define UMS_READ_FORMAT_CAPACITIES_TRANSFER_LENGTH 0xFC
+
+// 6 Byte SCSI command
+// This is big endian
+typedef struct {
+ uint8_t opcode;
+ uint8_t misc;
+ uint16_t lba; // logical block address
+ uint8_t length;
+ uint8_t control;
+} __PACKED scsi_command6_t;
+static_assert(sizeof(scsi_command6_t) == 6, "");
+
+// 10 Byte SCSI command
+// This is big endian
+typedef struct {
+ uint8_t opcode;
+ uint8_t misc;
+ uint32_t lba; // logical block address
+ uint8_t misc2;
+ uint8_t length_hi; // break length into two pieces to avoid odd alignment
+ uint8_t length_lo;
+ uint8_t control;
+} __PACKED scsi_command10_t;
+static_assert(sizeof(scsi_command10_t) == 10, "");
+
+// 12 Byte SCSI command
+// This is big endian
+typedef struct {
+ uint8_t opcode;
+ uint8_t misc;
+ uint32_t lba; // logical block address
+ uint32_t length;
+ uint8_t misc2;
+ uint8_t control;
+} __PACKED scsi_command12_t;
+static_assert(sizeof(scsi_command12_t) == 12, "");
+
+// 16 Byte SCSI command
+// This is big endian
+typedef struct {
+ uint8_t opcode;
+ uint8_t misc;
+ uint64_t lba; // logical block address
+ uint32_t length;
+ uint8_t misc2;
+ uint8_t control;
+} __PACKED scsi_command16_t;
+static_assert(sizeof(scsi_command16_t) == 16, "");
+
+// SCSI Read Capacity 10 payload
+// This is big endian
+typedef struct {
+ uint32_t lba;
+ uint32_t block_length;
+} __PACKED scsi_read_capacity_10_t;
+static_assert(sizeof(scsi_read_capacity_10_t) == 8, "");
+
+// SCSI Read Capacity 16 payload
+// This is big endian
+typedef struct {
+ uint64_t lba;
+ uint32_t block_length;
+ uint8_t ptype_prot_en; // bit 0: PROT_EN, bits 1-3: P_TYPE
+ uint8_t resesrved[19];
+} __PACKED scsi_read_capacity_16_t;
+static_assert(sizeof(scsi_read_capacity_16_t) == 32, "");
+
+// SCSI Mode Sense 6 command
+typedef struct {
+ uint8_t opcode; // UMS_MODE_SENSE6
+ uint8_t disable_block_desc;
+ uint8_t page;
+ uint8_t subpage;
+ uint8_t allocation_length;
+ uint8_t control;
+} __PACKED scsi_mode_sense_6_command_t;
+static_assert(sizeof(scsi_mode_sense_6_command_t) == 6, "");
+
+// SCSI Mode Sense 6 data response
+typedef struct {
+ uint8_t mode_data_length;
+ uint8_t medium_type;
+ uint8_t device_specific_param;
+ uint8_t block_desc_length;
+} __PACKED scsi_mode_sense_6_data_t;
+#define MODE_SENSE_DSP_RO 0x80 // bit 7 of device_specific_param: read-only
+
+// Command Block Wrapper
+typedef struct {
+ uint32_t dCBWSignature; // CBW_SIGNATURE
+ uint32_t dCBWTag;
+ uint32_t dCBWDataTransferLength;
+ uint8_t bmCBWFlags;
+ uint8_t bCBWLUN;
+ uint8_t bCBWCBLength;
+ uint8_t CBWCB[16];
+} __PACKED ums_cbw_t;
+static_assert(sizeof(ums_cbw_t) == 31, "");
+
+// Command Status Wrapper
+typedef struct {
+ uint32_t dCSWSignature; // CSW_SIGNATURE
+ uint32_t dCSWTag;
+ uint32_t dCSWDataResidue;
+ uint8_t bmCSWStatus;
+} __PACKED ums_csw_t;
+static_assert(sizeof(ums_csw_t) == 13, "");
+
+#endif // SYSROOT_ZIRCON_HW_USB_UMS_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/usb/video.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/usb/video.h
new file mode 100644
index 0000000..925b5b6
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/hw/usb/video.h
@@ -0,0 +1,308 @@
+// Copyright 2017 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.
+
+#ifndef SYSROOT_ZIRCON_HW_USB_VIDEO_H_
+#define SYSROOT_ZIRCON_HW_USB_VIDEO_H_
+
+// clang-format off
+
+#include <zircon/compiler.h>
+#include <stdint.h>
+
+__BEGIN_CDECLS;
+
+// video interface subclasses
+#define USB_SUBCLASS_VIDEO_CONTROL 0x01
+#define USB_SUBCLASS_VIDEO_STREAMING 0x02
+#define USB_SUBCLASS_VIDEO_INTERFACE_COLLECTION 0x03
+
+// video class specific descriptor types
+#define USB_VIDEO_CS_DEVICE 0x21
+#define USB_VIDEO_CS_CONFIGURATION 0x22
+#define USB_VIDEO_CS_STRING 0x23
+#define USB_VIDEO_CS_INTERFACE 0x24
+#define USB_VIDEO_CS_ENDPOINT 0x25
+
+// video class specific VC interface descriptor subtypes
+#define USB_VIDEO_VC_HEADER 0x01
+#define USB_VIDEO_VC_INPUT_TERMINAL 0x02
+#define USB_VIDEO_VC_OUTPUT_TERMINAL 0x03
+#define USB_VIDEO_VC_SELECTOR_UNIT 0x04
+#define USB_VIDEO_VC_PROCESSING_UNIT 0x05
+#define USB_VIDEO_VC_EXTENSION_UNIT 0x06
+#define USB_VIDEO_VC_ENCODING_UNIT 0x07
+
+// video class specific VS interface descriptor subtypes
+#define USB_VIDEO_VS_INPUT_HEADER 0x01
+#define USB_VIDEO_VS_OUTPUT_HEADER 0x02
+#define USB_VIDEO_VS_STILL_IMAGE_FRAME 0x03
+#define USB_VIDEO_VS_FORMAT_UNCOMPRESSED 0x04
+#define USB_VIDEO_VS_FRAME_UNCOMPRESSED 0x05
+#define USB_VIDEO_VS_FORMAT_MJPEG 0x06
+#define USB_VIDEO_VS_FRAME_MJPEG 0x07
+#define USB_VIDEO_VS_FORMAT_MPEG2TS 0x0A
+#define USB_VIDEO_VS_FORMAT_DV 0x0C
+#define USB_VIDEO_VS_COLORFORMAT 0x0D
+#define USB_VIDEO_VS_FORMAT_FRAME_BASED 0x10
+#define USB_VIDEO_VS_FRAME_FRAME_BASED 0x11
+#define USB_VIDEO_VS_FORMAT_STREAM_BASED 0x12
+#define USB_VIDEO_VS_FORMAT_H264 0x13
+#define USB_VIDEO_VS_FRAME_H264 0x14
+#define USB_VIDEO_VS_FORMAT_H264_SIMULCAST 0x15
+#define USB_VIDEO_VS_FORMAT_VP8 0x16
+#define USB_VIDEO_VS_FRAME_VP8 0x17
+#define USB_VIDEO_VS_FORMAT_VP8_SIMULCAST 0x18
+
+// video class specific endpoint descriptor subtypes
+#define USB_VIDEO_EP_GENERAL 0x01
+#define USB_VIDEO_EP_ENDPOINT 0x02
+#define USB_VIDEO_EP_INTERRUPT 0x03
+
+// video class specific request codes
+#define USB_VIDEO_SET_CUR 0x01
+#define USB_VIDEO_SET_CUR_ALL 0x11
+#define USB_VIDEO_GET_CUR 0x81
+#define USB_VIDEO_GET_MIN 0x82
+#define USB_VIDEO_GET_MAX 0x83
+#define USB_VIDEO_GET_RES 0x84
+#define USB_VIDEO_GET_LEN 0x85
+#define USB_VIDEO_GET_INFO 0x86
+#define USB_VIDEO_GET_DEF 0x87
+#define USB_VIDEO_GET_CUR_ALL 0x91
+#define USB_VIDEO_GET_MIN_ALL 0x92
+#define USB_VIDEO_GET_MAX_ALL 0x93
+#define USB_VIDEO_GET_RES_ALL 0x94
+#define USB_VIDEO_GET_DEF_ALL 0x97
+
+// video streaming interface control selectors
+#define USB_VIDEO_VS_PROBE_CONTROL 0x01
+#define USB_VIDEO_VS_COMMIT_CONTROL 0x02
+#define USB_VIDEO_VS_STILL_PROBE_CONTROL 0x03
+#define USB_VIDEO_VS_STILL_COMMIT_CONTROL 0x04
+#define USB_VIDEO_VS_STILL_IMAGE_TRIGGER_CONTROL 0x05
+#define USB_VIDEO_VS_STREAM_ERROR_CODE_CONTROL 0x06
+#define USB_VIDEO_VS_GENERATE_KEY_FRAME_CONTROL 0x07
+#define USB_VIDEO_VS_UPDATE_FRAME_SEGMENT_CONTROL 0x08
+#define USB_VIDEO_VS_SYNCH_DELAY_CONTROL 0x09
+
+// header for usb_video_vc_* below
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_VIDEO_CS_INTERFACE
+ uint8_t bDescriptorSubtype;
+} __PACKED usb_video_vc_desc_header;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_VIDEO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_VIDEO_VC_HEADER
+ uint16_t bcdUVC;
+ uint16_t wTotalLength;
+ uint32_t dwClockFrequency;
+ uint8_t bInCollection;
+ uint8_t baInterfaceNr[];
+} __PACKED usb_video_vc_header_desc;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_VIDEO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_VIDEO_VC_INPUT_TERMINAL
+ uint8_t bTerminalID;
+ uint16_t wTerminalType;
+ uint8_t bAssocTerminal;
+ uint8_t iTerminal;
+} __PACKED usb_video_vc_input_terminal_desc;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_VIDEO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_VIDEO_VC_OUTPUT_TERMINAL
+ uint8_t bTerminalID;
+ uint16_t wTerminalType;
+ uint8_t bAssocTerminal;
+ uint8_t bSourceID;
+ uint8_t iTerminal;
+} __PACKED usb_video_vc_output_terminal_desc;
+
+// class specific VC interrupt endpoint descriptor
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_VIDEO_CS_ENDPOINT
+ uint8_t bDescriptorSubtype; // USB_ENDPOINT_INTERRUPT
+ uint16_t wMaxTransferSize;
+} __PACKED usb_video_vc_interrupt_endpoint_desc;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_VIDEO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_VIDEO_VS_HEADER
+ uint8_t bNumFormats;
+ uint16_t wTotalLength;
+ uint8_t bEndpointAddress;
+ uint8_t bmInfo;
+ uint8_t bTerminalLink;
+ uint8_t bStillCaptureMethod;
+ uint8_t bTriggerSupport;
+ uint8_t bTriggerUsage;
+ uint8_t bControlSize;
+ uint8_t bmaControls[];
+} __PACKED usb_video_vs_input_header_desc;
+
+#define GUID_LENGTH 16
+
+// A GUID consists of a:
+// - four-byte integer
+// - two-byte integer
+// - two-byte integer
+// - eight-byte array
+//
+// The string representation uses big endian format, so to convert it
+// to a byte array we need to reverse the byte order of the three integers.
+//
+// See USB Video Class revision 1.5, FAQ section 2.9
+// for GUID Data Structure Layout.
+
+#define USB_VIDEO_GUID_YUY2_STRING "32595559-0000-0010-8000-00AA00389B71"
+#define USB_VIDEO_GUID_YUY2_VALUE { \
+ 0x59, 0x55, 0x59, 0x32, \
+ 0x00, 0x00, \
+ 0x10, 0x00, \
+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 \
+}
+
+#define USB_VIDEO_GUID_NV12_STRING "3231564E-0000-0010-8000-00AA00389B71"
+#define USB_VIDEO_GUID_NV12_VALUE { \
+ 0x4e, 0x56, 0x31, 0x32, \
+ 0x00, 0x00, \
+ 0x10, 0x00, \
+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 \
+}
+
+#define USB_VIDEO_GUID_M420_STRING "3032344D-0000-0010-8000-00AA00389B71"
+#define USB_VIDEO_GUID_M420_VALUE { \
+ 0x4d, 0x34, 0x32, 0x30, \
+ 0x00, 0x00, \
+ 0x10, 0x00, \
+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 \
+}
+
+#define USB_VIDEO_GUID_I420_STRING "30323449-0000-0010-8000-00AA00389B71"
+#define USB_VIDEO_GUID_I420_VALUE { \
+ 0x49, 0x34, 0x32, 0x30, \
+ 0x00, 0x00, \
+ 0x10, 0x00, \
+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 \
+}
+
+// USB Video Payload Uncompressed
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_VIDEO_CS_INTERFACE
+ uint8_t bDescriptorSubType; // USB_VIDEO_VS_FORMAT_UNCOMPRESSED
+ uint8_t bFormatIndex;
+ uint8_t bNumFrameDescriptors;
+ uint8_t guidFormat[GUID_LENGTH];
+ uint8_t bBitsPerPixel;
+ uint8_t bDefaultFrameIndex;
+ uint8_t bAspectRatioX;
+ uint8_t bAspectRatioY;
+ uint8_t bmInterfaceFlags;
+ uint8_t bCopyProtect;
+} __PACKED usb_video_vs_uncompressed_format_desc;
+
+// USB Video Payload MJPEG
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_VIDEO_CS_INTERFACE
+ uint8_t bDescriptorSubType; // USB_VIDEO_VS_FORMAT_MJPEG
+ uint8_t bFormatIndex;
+ uint8_t bNumFrameDescriptors;
+ uint8_t bmFlags;
+ uint8_t bDefaultFrameIndex;
+ uint8_t bAspectRatioX;
+ uint8_t bAspectRatioY;
+ uint8_t bmInterfaceFlags;
+ uint8_t bCopyProtect;
+} __PACKED usb_video_vs_mjpeg_format_desc;
+
+// Uncompressed and MJPEG formats have the same frame descriptor structure.
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_VIDEO_CS_INTERFACE
+ uint8_t bDescriptorSubType; // USB_VIDEO_VS_FRAME_UNCOMPRESSED / USB_VIDEO_VS_FRAME_MJPEG
+ uint8_t bFrameIndex;
+ uint8_t bmCapabilities;
+ uint16_t wWidth;
+ uint16_t wHeight;
+ uint32_t dwMinBitRate;
+ uint32_t dwMaxBitRate;
+ uint32_t dwMaxVideoFrameBufferSize;
+ uint32_t dwDefaultFrameInterval;
+ uint8_t bFrameIntervalType;
+ uint32_t dwFrameInterval[];
+} __PACKED usb_video_vs_frame_desc;
+
+// Stream negotiation
+#define USB_VIDEO_BM_HINT_FRAME_INTERVAL (1 << 0)
+#define USB_VIDEO_BM_HINT_KEY_FRAME_RATE (1 << 1)
+#define USB_VIDEO_BM_HINT_P_FRAME_RATE (1 << 2)
+#define USB_VIDEO_BM_HINT_COMP_QUALITY (1 << 3)
+#define USB_VIDEO_BM_HINT_COMP_WINDOW_SIZE (1 << 4)
+
+typedef struct {
+ uint16_t bmHint;
+ uint8_t bFormatIndex;
+ uint8_t bFrameIndex;
+ uint32_t dwFrameInterval;
+ uint16_t wKeyFrameRate;
+ uint16_t wPFrameRate;
+ uint16_t wCompQuality;
+ uint16_t wCompWindowSize;
+ uint16_t wDelay;
+ uint32_t dwMaxVideoFrameSize;
+ uint32_t dwMaxPayloadTransferSize;
+ // The following fields are optional.
+ uint32_t dwClockFrequency;
+ uint8_t bmFramingInfo;
+ uint8_t bPreferedVersion;
+ uint8_t bMinVersion;
+ uint8_t bMaxVersion;
+ uint8_t bUsage;
+ uint8_t bBitDepthLuma;
+ uint8_t bmSettings;
+ uint8_t bMaxNumberOfRefFramesPlus1;
+ uint16_t bmRateControlModes;
+ uint32_t bmLayoutPerStream;
+} __PACKED usb_video_vc_probe_and_commit_controls;
+
+// For accessing payload bmHeaderInfo bitmap
+#define USB_VIDEO_VS_PAYLOAD_HEADER_FID (1 << 0)
+#define USB_VIDEO_VS_PAYLOAD_HEADER_EOF (1 << 1)
+#define USB_VIDEO_VS_PAYLOAD_HEADER_PTS (1 << 2)
+#define USB_VIDEO_VS_PAYLOAD_HEADER_SCR (1 << 3)
+#define USB_VIDEO_VS_PAYLOAD_HEADER_RES (1 << 4)
+#define USB_VIDEO_VS_PAYLOAD_HEADER_STI (1 << 5)
+#define USB_VIDEO_VS_PAYLOAD_HEADER_ERR (1 << 6)
+#define USB_VIDEO_VS_PAYLOAD_HEADER_EOH (1 << 7)
+
+// Common header for all payloads.
+typedef struct {
+ uint8_t bHeaderLength;
+ uint8_t bmHeaderInfo;
+
+} __PACKED usb_video_vs_payload_header;
+
+typedef struct {
+ uint8_t bHeaderLength;
+ uint8_t bmHeaderInfo;
+ uint32_t dwPresentationTime;
+ uint32_t scrSourceTimeClock;
+ // Frame number when the source clock was sampled.
+ uint16_t scrSourceClockSOFCounter;
+} __PACKED usb_video_vs_uncompressed_payload_header;
+
+__END_CDECLS;
+
+
+#endif // SYSROOT_ZIRCON_HW_USB_VIDEO_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/limits.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/limits.h
new file mode 100644
index 0000000..f062d5e
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/limits.h
@@ -0,0 +1,14 @@
+// Copyright 2018 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.
+
+#ifndef SYSROOT_ZIRCON_LIMITS_H_
+#define SYSROOT_ZIRCON_LIMITS_H_
+
+#include <stdint.h>
+
+#define ZX_PAGE_SHIFT ((uint32_t)12u)
+#define ZX_PAGE_SIZE ((uintptr_t)(1u << ZX_PAGE_SHIFT))
+#define ZX_PAGE_MASK (ZX_PAGE_SIZE - 1u)
+
+#endif // SYSROOT_ZIRCON_LIMITS_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/listnode.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/listnode.h
new file mode 100644
index 0000000..fb64acf
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/listnode.h
@@ -0,0 +1,300 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_LISTNODE_H_
+#define SYSROOT_ZIRCON_LISTNODE_H_
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <zircon/compiler.h>
+
+__BEGIN_CDECLS
+
+#define containerof(ptr, type, member) ((type*)((uintptr_t)(ptr)-offsetof(type, member)))
+
+typedef struct list_node list_node_t;
+
+struct list_node {
+ list_node_t* prev;
+ list_node_t* next;
+};
+
+#define LIST_INITIAL_VALUE(list) \
+ { &(list), &(list) }
+#define LIST_INITIAL_CLEARED_VALUE \
+ { NULL, NULL }
+
+static inline void list_initialize(list_node_t* list) { list->prev = list->next = list; }
+
+static inline void list_clear_node(list_node_t* item) { item->prev = item->next = 0; }
+
+static inline bool list_in_list(const list_node_t* item) {
+ if (item->prev == 0 && item->next == 0)
+ return false;
+ else
+ return true;
+}
+
+static inline void list_add_head(list_node_t* list, list_node_t* item) {
+ item->next = list->next;
+ item->prev = list;
+ list->next->prev = item;
+ list->next = item;
+}
+
+#define list_add_after(entry, new_entry) list_add_head(entry, new_entry)
+
+static inline void list_add_tail(list_node_t* list, list_node_t* item) {
+ item->prev = list->prev;
+ item->next = list;
+ list->prev->next = item;
+ list->prev = item;
+}
+
+#define list_add_before(entry, new_entry) list_add_tail(entry, new_entry)
+
+static inline void list_delete(list_node_t* item) {
+ item->next->prev = item->prev;
+ item->prev->next = item->next;
+ item->prev = item->next = 0;
+}
+
+static inline void list_replace_node(list_node_t* old_node, list_node_t* new_node) {
+ // replace a spot in a list with a new node
+ // assumes old_node is part of a list and new_node is not
+ new_node->next = old_node->next;
+ new_node->prev = old_node->prev;
+ old_node->prev = old_node->next = 0;
+
+ new_node->next->prev = new_node;
+ new_node->prev->next = new_node;
+}
+
+static inline list_node_t* list_remove_head(list_node_t* list) {
+ if (list->next != list) {
+ list_node_t* item = list->next;
+ list_delete(item);
+ return item;
+ } else {
+ return NULL;
+ }
+}
+
+#define list_remove_head_type(list, type, element) \
+ ({ \
+ list_node_t* __nod = list_remove_head(list); \
+ type* __t; \
+ if (__nod) \
+ __t = containerof(__nod, type, element); \
+ else \
+ __t = (type*)0; \
+ __t; \
+ })
+
+static inline list_node_t* list_remove_tail(list_node_t* list) {
+ if (list->prev != list) {
+ list_node_t* item = list->prev;
+ list_delete(item);
+ return item;
+ } else {
+ return NULL;
+ }
+}
+
+#define list_remove_tail_type(list, type, element) \
+ ({ \
+ list_node_t* __nod = list_remove_tail(list); \
+ type* __t; \
+ if (__nod) \
+ __t = containerof(__nod, type, element); \
+ else \
+ __t = (type*)0; \
+ __t; \
+ })
+
+static inline list_node_t* list_peek_head(const list_node_t* list) {
+ if (list->next != list) {
+ return list->next;
+ } else {
+ return NULL;
+ }
+}
+
+#define list_peek_head_type(list, type, element) \
+ ({ \
+ list_node_t* __nod = list_peek_head(list); \
+ type* __t; \
+ if (__nod) \
+ __t = containerof(__nod, type, element); \
+ else \
+ __t = (type*)0; \
+ __t; \
+ })
+
+static inline list_node_t* list_peek_tail(const list_node_t* list) {
+ if (list->prev != list) {
+ return list->prev;
+ } else {
+ return NULL;
+ }
+}
+
+#define list_peek_tail_type(list, type, element) \
+ ({ \
+ list_node_t* __nod = list_peek_tail(list); \
+ type* __t; \
+ if (__nod) \
+ __t = containerof(__nod, type, element); \
+ else \
+ __t = (type*)0; \
+ __t; \
+ })
+
+static inline list_node_t* list_prev(list_node_t* list, list_node_t* item) {
+ if (item->prev != list)
+ return item->prev;
+ else
+ return NULL;
+}
+
+#define list_prev_type(list, item, type, element) \
+ ({ \
+ list_node_t* __nod = list_prev(list, item); \
+ type* __t; \
+ if (__nod) \
+ __t = containerof(__nod, type, element); \
+ else \
+ __t = (type*)0; \
+ __t; \
+ })
+
+static inline list_node_t* list_prev_wrap(list_node_t* list, list_node_t* item) {
+ if (item->prev != list)
+ return item->prev;
+ else if (item->prev->prev != list)
+ return item->prev->prev;
+ else
+ return NULL;
+}
+
+#define list_prev_wrap_type(list, item, type, element) \
+ ({ \
+ list_node_t* __nod = list_prev_wrap(list, item); \
+ type* __t; \
+ if (__nod) \
+ __t = containerof(__nod, type, element); \
+ else \
+ __t = (type*)0; \
+ __t; \
+ })
+
+static inline list_node_t* list_next(list_node_t* list, list_node_t* item) {
+ if (item->next != list)
+ return item->next;
+ else
+ return NULL;
+}
+
+#define list_next_type(list, item, type, element) \
+ ({ \
+ list_node_t* __nod = list_next(list, item); \
+ type* __t; \
+ if (__nod) \
+ __t = containerof(__nod, type, element); \
+ else \
+ __t = (type*)0; \
+ __t; \
+ })
+
+static inline list_node_t* list_next_wrap(list_node_t* list, list_node_t* item) {
+ if (item->next != list)
+ return item->next;
+ else if (item->next->next != list)
+ return item->next->next;
+ else
+ return NULL;
+}
+
+#define list_next_wrap_type(list, item, type, element) \
+ ({ \
+ list_node_t* __nod = list_next_wrap(list, item); \
+ type* __t; \
+ if (__nod) \
+ __t = containerof(__nod, type, element); \
+ else \
+ __t = (type*)0; \
+ __t; \
+ })
+
+// iterates over the list, node should be list_node_t*
+#define list_for_every(list, node) for (node = (list)->next; node != (list); node = node->next)
+
+// iterates over the list in a safe way for deletion of current node
+// node and temp_node should be list_node_t*
+#define list_for_every_safe(list, node, temp_node) \
+ for (node = (list)->next, temp_node = (node)->next; node != (list); \
+ node = temp_node, temp_node = (node)->next)
+
+// iterates over the list, entry should be the container structure type *
+#define list_for_every_entry(list, entry, type, member) \
+ for ((entry) = containerof((list)->next, type, member); &(entry)->member != (list); \
+ (entry) = containerof((entry)->member.next, type, member))
+
+// iterates over the list in a safe way for deletion of current node
+// entry and temp_entry should be the container structure type *
+#define list_for_every_entry_safe(list, entry, temp_entry, type, member) \
+ for (entry = containerof((list)->next, type, member), \
+ temp_entry = containerof((entry)->member.next, type, member); \
+ &(entry)->member != (list); \
+ entry = temp_entry, temp_entry = containerof((temp_entry)->member.next, type, member))
+
+static inline bool list_is_empty(const list_node_t* list) {
+ return (list->next == list) ? true : false;
+}
+
+static inline size_t list_length(const list_node_t* list) {
+ size_t cnt = 0;
+ const list_node_t* node = list;
+ list_for_every(list, node) { cnt++; }
+
+ return cnt;
+}
+
+// Splice the contents of splice_from into the list immediately following pos.
+static inline void list_splice_after(list_node_t* splice_from, list_node_t* pos) {
+ if (list_is_empty(splice_from)) {
+ return;
+ }
+ splice_from->next->prev = pos;
+ splice_from->prev->next = pos->next;
+ pos->next->prev = splice_from->prev;
+ pos->next = splice_from->next;
+ list_initialize(splice_from);
+}
+
+// Split the contents of list after (but not including) pos, into split_to
+// (which should be empty).
+static inline void list_split_after(list_node_t* list, list_node_t* pos, list_node_t* split_to) {
+ if (pos->next == list) {
+ list_initialize(split_to);
+ return;
+ }
+ split_to->prev = list->prev;
+ split_to->prev->next = split_to;
+ split_to->next = pos->next;
+ split_to->next->prev = split_to;
+ pos->next = list;
+ list->prev = pos;
+}
+
+// Moves all the contents of old_list (which may or may not be empty)
+// to new_list (which should be empty).
+static inline void list_move(list_node_t* old_list, list_node_t* new_list) {
+ list_initialize(new_list);
+ list_splice_after(old_list, new_list);
+}
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_LISTNODE_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/pixelformat.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/pixelformat.h
new file mode 100644
index 0000000..f28f35f
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/pixelformat.h
@@ -0,0 +1,28 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_PIXELFORMAT_H_
+#define SYSROOT_ZIRCON_PIXELFORMAT_H_
+
+#include <stdint.h>
+
+typedef uint32_t zx_pixel_format_t;
+// clang-format off
+
+#define ZX_PIXEL_FORMAT_NONE ((zx_pixel_format_t)0x00000000)
+
+#define ZX_PIXEL_FORMAT_RGB_565 ((zx_pixel_format_t)0x00020001)
+#define ZX_PIXEL_FORMAT_RGB_332 ((zx_pixel_format_t)0x00010002)
+#define ZX_PIXEL_FORMAT_RGB_2220 ((zx_pixel_format_t)0x00010003)
+#define ZX_PIXEL_FORMAT_ARGB_8888 ((zx_pixel_format_t)0x00040004)
+#define ZX_PIXEL_FORMAT_RGB_x888 ((zx_pixel_format_t)0x00040005)
+#define ZX_PIXEL_FORMAT_MONO_8 ((zx_pixel_format_t)0x00010007)
+#define ZX_PIXEL_FORMAT_GRAY_8 ((zx_pixel_format_t)0x00010007)
+#define ZX_PIXEL_FORMAT_NV12 ((zx_pixel_format_t)0x00010008)
+#define ZX_PIXEL_FORMAT_RGB_888 ((zx_pixel_format_t)0x00030009)
+#define ZX_PIXEL_FORMAT_ABGR_8888 ((zx_pixel_format_t)0x0004000a)
+#define ZX_PIXEL_FORMAT_BGR_888x ((zx_pixel_format_t)0x0004000b)
+#define ZX_PIXEL_FORMAT_BYTES(pf) (((pf) >> 16) & 7)
+
+#endif // SYSROOT_ZIRCON_PIXELFORMAT_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/process.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/process.h
new file mode 100644
index 0000000..ef2bcb1
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/process.h
@@ -0,0 +1,35 @@
+// Copyright 2017 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.
+
+#ifndef SYSROOT_ZIRCON_PROCESS_H_
+#define SYSROOT_ZIRCON_PROCESS_H_
+
+#include <stdint.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// Accessors for Zircon-specific state maintained by the language runtime
+
+// Examines the set of handles received at process startup for one matching
+// |hnd_info|. If one is found, atomically returns it and removes it from the
+// set available to future calls.
+// |hnd_info| is a value returned by PA_HND().
+zx_handle_t zx_take_startup_handle(uint32_t hnd_info);
+
+zx_handle_t _zx_thread_self(void);
+zx_handle_t zx_thread_self(void);
+
+zx_handle_t _zx_process_self(void);
+zx_handle_t zx_process_self(void);
+
+zx_handle_t _zx_vmar_root_self(void);
+zx_handle_t zx_vmar_root_self(void);
+
+zx_handle_t _zx_job_default(void);
+zx_handle_t zx_job_default(void);
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_PROCESS_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/processargs.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/processargs.h
new file mode 100644
index 0000000..fbad376
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/processargs.h
@@ -0,0 +1,170 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_PROCESSARGS_H_
+#define SYSROOT_ZIRCON_PROCESSARGS_H_
+
+#include <stdint.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// This is a protocol for passing state to a new process
+// via a message in a channel.
+
+#define ZX_PROCARGS_PROTOCOL ((uint32_t)0x4150585du) // MXPA
+#define ZX_PROCARGS_VERSION ((uint32_t)0x0001000u)
+
+typedef struct zx_proc_args zx_proc_args_t;
+
+struct zx_proc_args {
+ // Protocol and version identifiers to allow for
+ // different process start message protocols and
+ // versioning of the same.
+ uint32_t protocol;
+ uint32_t version;
+
+ // Offset from start of message to handle info
+ // array, which contains one uint32_t per handle
+ // passed along with the message.
+ uint32_t handle_info_off;
+
+ // Offset from start of message to arguments and
+ // count of arguments. Arguments are provided as
+ // a set of null-terminated utf-8 strings, one
+ // after the other.
+ uint32_t args_off;
+ uint32_t args_num;
+
+ // Offset from start of message to environment strings and count of
+ // them. Environment entries are provided as a set of null-terminated
+ // UTF-8 strings, one after the other. Canonically each string has
+ // the form "NAME=VALUE", but nothing enforces this.
+ uint32_t environ_off;
+ uint32_t environ_num;
+
+ // Offset from start of message to name strings and count of them.
+ // These strings are packed similar to the argument strings,
+ // but are referenced by PA_NS_* handle table entries and used
+ // to set up namespaces.
+ //
+ // Specifically: In a handle table entry with PA_HND_TYPE(info)
+ // of PA_NS_*, PA_HND_ARG(info) is an index into this name table.
+ uint32_t names_off;
+ uint32_t names_num;
+};
+
+// Handle Info entries associate a type and optional
+// argument with each handle included in the process
+// arguments message.
+#define PA_HND(type, arg) (((type)&0xFF) | (((arg)&0xFFFF) << 16))
+#define PA_HND_TYPE(n) ((n)&0xFF)
+#define PA_HND_ARG(n) (((n) >> 16) & 0xFFFF)
+
+// --- Core Runtime Handles ---
+// Used by libc init (or equivalent) and dynamic loader
+
+// Handle to our own process.
+#define PA_PROC_SELF 0x01u
+
+// Handle to the initial thread of our own process.
+#define PA_THREAD_SELF 0x02u
+
+// Handle to a job object which can be used to make child processes.
+//
+// The job can be the same as the one used to create this process or it can
+// be different.
+#define PA_JOB_DEFAULT 0x03u
+
+// Handle to the root of our address space
+#define PA_VMAR_ROOT 0x04u
+
+// Handle to the VMAR used to load the initial program image.
+#define PA_VMAR_LOADED 0x05u
+
+// --- Loader Service and VMO Handles ---
+// Used by libc init (or equivalent) and dynamic loader
+
+// Service for loading shared libraries.
+//
+// See |fuchsia.ldsvc.Loader| for the interface definition.
+#define PA_LDSVC_LOADER 0x10u
+
+// Handle to the VMO containing the ELF image of the system vDSO. This
+// handle is duplicable, transferable, readable, and executable, but not
+// writable. The contents of the VM object should be treated like any
+// other general-purpose ELF file image of type ET_DYN. A process only
+// needs this handle so that it can map the vDSO into new processes it
+// might create or propagate it on to its children so they can do so.
+// Each process's own vDSO was mapped in by its creator before the
+// process started, its address passed as an argument to entry point.
+#define PA_VMO_VDSO 0x11u
+
+// Handle to the VMO used to map the initial thread's stack. This
+// handle usually has all rights. The protocol between process creator
+// and new process is that this entire VM object has been mapped in
+// before the process starts. The initial value for the SP register in
+// the new process is the high edge of the mapping (assuming stacks grow
+// downwards), adjusted down as required by the particular machine's C
+// calling convention for function entry. Thus the new process can
+// compute its exact stack bounds by subtracting the size reported by
+// this VMO from the (adjusted back up) initial SP value.
+#define PA_VMO_STACK 0x13u
+
+// VM object handle for the main executable file
+#define PA_VMO_EXECUTABLE 0x14u
+
+// Used by kernel and userboot during startup
+#define PA_VMO_BOOTDATA 0x1Au
+
+// Used by kernel and userboot during startup
+#define PA_VMO_BOOTFS 0x1Bu
+
+// Used by the kernel to export debug information as a file in bootfs. When
+// devmgr starts, it looks for handles of this type, and adds them as files in
+// /boot/kernel/<vmo-name>.
+#define PA_VMO_KERNEL_FILE 0x1Cu
+
+// --- Namespace Handles ---
+
+// A handle which will handle OPEN requests relative
+// to a particular path which is specified by the
+// nametable entry referred to by the "arg" field
+#define PA_NS_DIR 0x20u
+
+// --- File Descriptor Handles ---
+
+// A handle which will be used as a file descriptor.
+#define PA_FD 0x30u
+
+// -- Lifecyle handle --
+//
+// A Handle to a channel on which the process may receive lifecycle events from
+// the ELF runner by serving the |fuchsia.process.Lifecycle| protocol.
+#define PA_LIFECYCLE 0x3Au
+
+// Server endpoint for handling connection to appmgr services.
+#define PA_DIRECTORY_REQUEST 0x3Bu
+
+// Used by devmgr and devhosts
+#define PA_RESOURCE 0x3Fu
+
+// --- Clock handles ---
+//
+// A clock which provides access to UTC. Used by runtimes which are expected to
+// provide access to UTC via their standard libraries.
+//
+#define PA_CLOCK_UTC 0x40u
+
+// --- Various ---
+
+// Handle types for one-off use and prototyping
+#define PA_USER0 0xF0u
+#define PA_USER1 0xF1u
+#define PA_USER2 0xF2u
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_PROCESSARGS_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/rights.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/rights.h
new file mode 100644
index 0000000..2ab61b9
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/rights.h
@@ -0,0 +1,123 @@
+// Copyright 2017 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.
+
+#ifndef SYSROOT_ZIRCON_RIGHTS_H_
+#define SYSROOT_ZIRCON_RIGHTS_H_
+
+#include <stdint.h>
+
+typedef uint32_t zx_rights_t;
+#define ZX_RIGHT_NONE ((zx_rights_t)0u)
+#define ZX_RIGHT_DUPLICATE ((zx_rights_t)1u << 0)
+#define ZX_RIGHT_TRANSFER ((zx_rights_t)1u << 1)
+#define ZX_RIGHT_READ ((zx_rights_t)1u << 2)
+#define ZX_RIGHT_WRITE ((zx_rights_t)1u << 3)
+#define ZX_RIGHT_EXECUTE ((zx_rights_t)1u << 4)
+#define ZX_RIGHT_MAP ((zx_rights_t)1u << 5)
+#define ZX_RIGHT_GET_PROPERTY ((zx_rights_t)1u << 6)
+#define ZX_RIGHT_SET_PROPERTY ((zx_rights_t)1u << 7)
+#define ZX_RIGHT_ENUMERATE ((zx_rights_t)1u << 8)
+#define ZX_RIGHT_DESTROY ((zx_rights_t)1u << 9)
+#define ZX_RIGHT_SET_POLICY ((zx_rights_t)1u << 10)
+#define ZX_RIGHT_GET_POLICY ((zx_rights_t)1u << 11)
+#define ZX_RIGHT_SIGNAL ((zx_rights_t)1u << 12)
+#define ZX_RIGHT_SIGNAL_PEER ((zx_rights_t)1u << 13)
+#define ZX_RIGHT_WAIT ((zx_rights_t)1u << 14)
+#define ZX_RIGHT_INSPECT ((zx_rights_t)1u << 15)
+#define ZX_RIGHT_MANAGE_JOB ((zx_rights_t)1u << 16)
+#define ZX_RIGHT_MANAGE_PROCESS ((zx_rights_t)1u << 17)
+#define ZX_RIGHT_MANAGE_THREAD ((zx_rights_t)1u << 18)
+#define ZX_RIGHT_APPLY_PROFILE ((zx_rights_t)1u << 19)
+#define ZX_RIGHT_SAME_RIGHTS ((zx_rights_t)1u << 31)
+
+// Convenient names for commonly grouped rights.
+#define ZX_RIGHTS_BASIC (ZX_RIGHT_TRANSFER | ZX_RIGHT_DUPLICATE | ZX_RIGHT_WAIT | ZX_RIGHT_INSPECT)
+
+#define ZX_RIGHTS_IO (ZX_RIGHT_READ | ZX_RIGHT_WRITE)
+
+#define ZX_RIGHTS_PROPERTY (ZX_RIGHT_GET_PROPERTY | ZX_RIGHT_SET_PROPERTY)
+
+#define ZX_RIGHTS_POLICY (ZX_RIGHT_GET_POLICY | ZX_RIGHT_SET_POLICY)
+
+#define ZX_DEFAULT_CHANNEL_RIGHTS \
+ ((ZX_RIGHTS_BASIC & (~ZX_RIGHT_DUPLICATE)) | ZX_RIGHTS_IO | ZX_RIGHT_SIGNAL | \
+ ZX_RIGHT_SIGNAL_PEER)
+
+#define ZX_DEFAULT_EVENT_RIGHTS (ZX_RIGHTS_BASIC | ZX_RIGHT_SIGNAL)
+
+#define ZX_DEFAULT_SYSTEM_EVENT_LOW_MEMORY_RIGHTS \
+ (ZX_RIGHT_WAIT | ZX_RIGHT_DUPLICATE | ZX_RIGHT_TRANSFER)
+
+#define ZX_DEFAULT_EVENTPAIR_RIGHTS (ZX_RIGHTS_BASIC | ZX_RIGHT_SIGNAL | ZX_RIGHT_SIGNAL_PEER)
+
+#define ZX_DEFAULT_FIFO_RIGHTS \
+ (ZX_RIGHTS_BASIC | ZX_RIGHTS_IO | ZX_RIGHT_SIGNAL | ZX_RIGHT_SIGNAL_PEER)
+
+#define ZX_DEFAULT_GUEST_RIGHTS \
+ (ZX_RIGHT_TRANSFER | ZX_RIGHT_DUPLICATE | ZX_RIGHT_WRITE | ZX_RIGHT_INSPECT | \
+ ZX_RIGHT_MANAGE_PROCESS)
+
+#define ZX_DEFAULT_INTERRUPT_RIGHTS (ZX_RIGHTS_BASIC | ZX_RIGHTS_IO | ZX_RIGHT_SIGNAL)
+
+#define ZX_DEFAULT_IO_MAPPING_RIGHTS (ZX_RIGHT_READ | ZX_RIGHT_INSPECT)
+
+#define ZX_DEFAULT_JOB_RIGHTS \
+ (ZX_RIGHTS_BASIC | ZX_RIGHTS_IO | ZX_RIGHTS_PROPERTY | ZX_RIGHTS_POLICY | ZX_RIGHT_ENUMERATE | \
+ ZX_RIGHT_DESTROY | ZX_RIGHT_SIGNAL | ZX_RIGHT_MANAGE_JOB | ZX_RIGHT_MANAGE_PROCESS | \
+ ZX_RIGHT_MANAGE_THREAD)
+
+#define ZX_DEFAULT_LOG_RIGHTS (ZX_RIGHTS_BASIC | ZX_RIGHT_WRITE | ZX_RIGHT_SIGNAL)
+
+#define ZX_DEFAULT_MSI_RIGHTS (ZX_RIGHTS_BASIC | ZX_RIGHT_INSPECT)
+
+#define ZX_DEFAULT_PCI_DEVICE_RIGHTS (ZX_RIGHTS_BASIC | ZX_RIGHTS_IO)
+
+#define ZX_DEFAULT_PCI_INTERRUPT_RIGHTS (ZX_RIGHTS_BASIC | ZX_RIGHTS_IO | ZX_RIGHT_SIGNAL)
+
+#define ZX_DEFAULT_PORT_RIGHTS ((ZX_RIGHTS_BASIC & (~ZX_RIGHT_WAIT)) | ZX_RIGHTS_IO)
+
+#define ZX_DEFAULT_PROCESS_RIGHTS \
+ (ZX_RIGHTS_BASIC | ZX_RIGHTS_IO | ZX_RIGHTS_PROPERTY | ZX_RIGHT_ENUMERATE | ZX_RIGHT_DESTROY | \
+ ZX_RIGHT_SIGNAL | ZX_RIGHT_MANAGE_PROCESS | ZX_RIGHT_MANAGE_THREAD)
+
+#define ZX_DEFAULT_RESOURCE_RIGHTS \
+ (ZX_RIGHT_TRANSFER | ZX_RIGHT_DUPLICATE | ZX_RIGHT_WRITE | ZX_RIGHT_INSPECT)
+
+#define ZX_DEFAULT_SOCKET_RIGHTS \
+ (ZX_RIGHTS_BASIC | ZX_RIGHTS_IO | ZX_RIGHT_GET_PROPERTY | ZX_RIGHT_SET_PROPERTY | \
+ ZX_RIGHT_SIGNAL | ZX_RIGHT_SIGNAL_PEER)
+
+#define ZX_DEFAULT_STREAM_RIGHTS (ZX_RIGHTS_BASIC | ZX_RIGHTS_PROPERTY | ZX_RIGHT_SIGNAL)
+
+#define ZX_DEFAULT_THREAD_RIGHTS \
+ (ZX_RIGHTS_BASIC | ZX_RIGHTS_IO | ZX_RIGHTS_PROPERTY | ZX_RIGHT_DESTROY | ZX_RIGHT_SIGNAL | \
+ ZX_RIGHT_MANAGE_THREAD)
+
+#define ZX_DEFAULT_TIMER_RIGHTS (ZX_RIGHTS_BASIC | ZX_RIGHT_WRITE | ZX_RIGHT_SIGNAL)
+
+#define ZX_DEFAULT_VCPU_RIGHTS (ZX_RIGHTS_BASIC | ZX_RIGHTS_IO | ZX_RIGHT_EXECUTE | ZX_RIGHT_SIGNAL)
+
+#define ZX_DEFAULT_VMAR_RIGHTS (ZX_RIGHTS_BASIC & (~ZX_RIGHT_WAIT))
+
+#define ZX_DEFAULT_VMO_RIGHTS \
+ (ZX_RIGHTS_BASIC | ZX_RIGHTS_IO | ZX_RIGHTS_PROPERTY | ZX_RIGHT_MAP | ZX_RIGHT_SIGNAL)
+
+#define ZX_DEFAULT_IOMMU_RIGHTS (ZX_RIGHTS_BASIC & (~ZX_RIGHT_WAIT))
+
+#define ZX_DEFAULT_BTI_RIGHTS ((ZX_RIGHTS_BASIC & (~ZX_RIGHT_WAIT)) | ZX_RIGHTS_IO | ZX_RIGHT_MAP)
+
+#define ZX_DEFAULT_PROFILE_RIGHTS ((ZX_RIGHTS_BASIC & (~ZX_RIGHT_WAIT)) | ZX_RIGHT_APPLY_PROFILE)
+
+#define ZX_DEFAULT_PMT_RIGHTS (ZX_RIGHT_INSPECT)
+
+#define ZX_DEFAULT_SUSPEND_TOKEN_RIGHTS (ZX_RIGHT_TRANSFER | ZX_RIGHT_INSPECT)
+
+#define ZX_DEFAULT_PAGER_RIGHTS \
+ (ZX_RIGHT_INSPECT | ZX_RIGHT_GET_PROPERTY | ZX_RIGHT_SET_PROPERTY | ZX_RIGHT_TRANSFER)
+
+#define ZX_DEFAULT_EXCEPTION_RIGHTS (ZX_RIGHT_TRANSFER | ZX_RIGHTS_PROPERTY | ZX_RIGHT_INSPECT)
+
+#define ZX_DEFAULT_CLOCK_RIGHTS (ZX_RIGHTS_BASIC | ZX_RIGHTS_IO)
+
+#endif // SYSROOT_ZIRCON_RIGHTS_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/sanitizer.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/sanitizer.h
new file mode 100644
index 0000000..c2f2e8e
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/sanitizer.h
@@ -0,0 +1,171 @@
+// Copyright 2017 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.
+
+#ifndef SYSROOT_ZIRCON_SANITIZER_H_
+#define SYSROOT_ZIRCON_SANITIZER_H_
+
+// Interfaces declared in this file are intended for the use of sanitizer
+// runtime library implementation code. Each sanitizer runtime works only
+// with the appropriately sanitized build of libc. These functions should
+// never be called when using the unsanitized libc. But these names are
+// always exported so that the libc ABI is uniform across sanitized and
+// unsanitized builds (only unsanitized shared library binaries are used at
+// link time, including linking the sanitizer runtime shared libraries).
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include <threads.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// These are aliases for the functions defined in libc, which are always
+// the unsanitized versions. The sanitizer runtimes can call them by these
+// aliases when they are overriding libc's definitions of the unadorned
+// symbols.
+__typeof(memcpy) __unsanitized_memcpy;
+__typeof(memmove) __unsanitized_memmove;
+__typeof(memset) __unsanitized_memset;
+
+// The sanitized libc allocates the shadow memory in the appropriate ratio for
+// the particular sanitizer (shadow_base == shadow_limit >> SHADOW_SCALE)
+// early during startup, before any other address space allocations can occur.
+// Shadow memory always starts at address zero:
+// [memory_limit, UINTPTR_MAX) Address space reserved by the system.
+// [shadow_limit, memory_limit) Address space available to the user.
+// [shadow_base, shadow_limit) Shadow memory, preallocated.
+// [0, shadow_base) Shadow gap, cannot be allocated.
+typedef struct saniziter_shadow_bounds {
+ uintptr_t shadow_base;
+ uintptr_t shadow_limit;
+ uintptr_t memory_limit;
+} sanitizer_shadow_bounds_t;
+
+// Returns the shadow bounds for the current process.
+sanitizer_shadow_bounds_t __sanitizer_shadow_bounds(void);
+
+// Fill the shadow memory corresponding to [base, base+size) with |value|. The
+// threshold is used as a hint to determine when to switch to a more efficient
+// mechanism when zero-filling large shadow regions. This assumes that both
+// |base| and |size| are aligned to the shadow multiple.
+void __sanitizer_fill_shadow(uintptr_t base, size_t size, uint8_t value, size_t threshold);
+
+// Write logging information from the sanitizer runtime. The buffer
+// is expected to be printable text with '\n' ending each line.
+// Timestamps and globally unique identifiers of the calling process
+// and thread (zx_koid_t) are attached to all messages, so there is no
+// need to include those details in the text. The log of messages
+// written with this call automatically includes address and ELF build
+// ID details of the program and all shared libraries sufficient to
+// translate raw address values into program symbols or source
+// locations via a post-processor that has access to the original ELF
+// files and their debugging information. The text can contain markup
+// around address values that should be resolved symbolically; see
+// TODO(mcgrathr) for the format and details of the post-processor.
+void __sanitizer_log_write(const char* buffer, size_t len);
+
+// Runtimes that have binary data to publish (e.g. coverage) use this
+// interface. The name describes the data sink that will receive this
+// blob of data; the string is not used after this call returns. The
+// caller creates a VMO (e.g. zx_vmo_create) and passes it in; the VMO
+// handle is consumed by this call. Each particular data sink has its
+// own conventions about both the format of the data in the VMO and the
+// protocol for when data must be written there. For some sinks, the
+// VMO's data is used immediately. For other sinks, the caller is
+// expected to have the VMO mapped in and be writing more data there
+// throughout the life of the process, to be analyzed only after the
+// process terminates. Yet others might use an asynchronous shared
+// memory protocol between producer and consumer.
+void __sanitizer_publish_data(const char* sink_name, zx_handle_t vmo);
+
+// Runtimes that want to read configuration files use this interface.
+// The name is a string from the user (something akin to a file name
+// but not necessarily actually a file name); the string is not used
+// after this call returns. On success, this yields a read-only VMO
+// handle from which the contents associated with that name can be
+// read; the caller is responsible for closing this handle.
+zx_status_t __sanitizer_get_configuration(const char* config_name, zx_handle_t* out_vmo);
+
+// Changes protection of the code in the range of len bytes starting
+// from addr. The writable argument specifies whether the code should
+// be made writable or not. This function is only valid on ranges within
+// the caller's own code segment.
+// TODO(phosek) removes this when the proper debugging interface exists.
+zx_status_t __sanitizer_change_code_protection(uintptr_t addr, size_t len, bool writable);
+
+// This stops all other threads in the process so memory should be quiescent.
+// Then it makes callbacks for memory regions containing non-const global
+// variables, thread stacks, thread registers, and thread-local storage
+// regions (this includes thread_local variables as well as tss_set or
+// pthread_setspecific values). Each callback is optional; no such callbacks
+// are made if a null function pointer is given. The memory region passed to
+// each callback can be accessed only during that single callback and might no
+// longer be valid once the callback returns. Then it makes a final callback
+// before allowing other threads to resume running normally. If there are
+// problems stopping threads, no memory callbacks will be made and the
+// argument to the final callback will get an error code rather than ZX_OK.
+typedef void sanitizer_memory_snapshot_callback_t(void* mem, size_t len, void* arg);
+void __sanitizer_memory_snapshot(sanitizer_memory_snapshot_callback_t* globals,
+ sanitizer_memory_snapshot_callback_t* stacks,
+ sanitizer_memory_snapshot_callback_t* regs,
+ sanitizer_memory_snapshot_callback_t* tls,
+ void (*done)(zx_status_t, void*), void* arg);
+
+// The "hook" interfaces are functions that the sanitizer runtime library
+// can define and libc will call. There are default definitions in libc
+// which do nothing, but any other definitions will override those. These
+// declarations use __EXPORT (i.e. explicit STV_DEFAULT) to ensure any user
+// definitions are seen by libc even if the user code is being compiled
+// with -fvisibility=hidden or equivalent.
+
+// This is called at program startup, with the arguments that will be
+// passed to main. This is called before any other application code,
+// including both static constructors and initialization of things like
+// fdio and zx_take_startup_handle. It's basically the first thing called
+// after libc's most basic internal global initialization is complete and
+// the initial thread has switched to its real thread stack. Since not
+// even all of libc's own constructors have run yet, this should not call
+// into libc or other library code.
+__EXPORT void __sanitizer_startup_hook(int argc, char** argv, char** envp, void* stack_base,
+ size_t stack_size);
+
+// This is called when a new thread has been created but is not yet
+// running. Its C11 thrd_t value has been determined and its stack has
+// been allocated. All that remains is to actually start the thread
+// running (which can fail only in catastrophic bug situations). Its
+// return value will be passed to __sanitizer_thread_create_hook, below.
+__EXPORT void* __sanitizer_before_thread_create_hook(thrd_t thread, bool detached, const char* name,
+ void* stack_base, size_t stack_size);
+
+// This is called after a new thread has been created or creation has
+// failed at the final stage; __sanitizer_before_thread_create_hook has
+// been called first, and its return value is the first argument here.
+// The second argument is what the return value of C11 thrd_create would
+// be for this creation attempt (which might have been instigated by
+// either thrd_create or pthread_create). If it's thrd_success, then
+// the new thread has now started running. Otherwise (it's a different
+// <threads.h> thrd_* value), thread creation has failed and the thread
+// details reported to __sanitizer_before_thread_create_hook will be
+// freed without the thread ever starting.
+__EXPORT void __sanitizer_thread_create_hook(void* hook, thrd_t thread, int error);
+
+// This is called in each new thread as it starts up. The argument is
+// the same one returned by __sanitizer_before_thread_create_hook and
+// previously passed to __sanitizer_thread_create_hook.
+__EXPORT void __sanitizer_thread_start_hook(void* hook, thrd_t self);
+
+// This is called in each thread just before it dies.
+// All thread-specific destructors have been run.
+// The argument is the same one passed to __sanitizer_thread_start_hook.
+__EXPORT void __sanitizer_thread_exit_hook(void* hook, thrd_t self);
+
+// This is called with the argument to _exit and its return value
+// is the actual exit status for the process.
+__EXPORT int __sanitizer_process_exit_hook(int status);
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SANITIZER_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/status.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/status.h
new file mode 100644
index 0000000..798d2b0
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/status.h
@@ -0,0 +1,23 @@
+// Copyright 2016 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.
+
+#pragma once
+
+#include <zircon/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Given one of the status codes defined in <zircon/errors.h> (ZX_ERR_* or
+// ZX_OK), this function returns an identifier string for the status code.
+//
+// For example, zx_status_get_string(ZX_ERR_TIMED_OUT) returns the string
+// "ZX_ERR_TIMED_OUT".
+__EXPORT const char* _zx_status_get_string(zx_status_t status);
+__EXPORT const char* zx_status_get_string(zx_status_t status);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/string_view.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/string_view.h
new file mode 100644
index 0000000..f54ff2a
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/string_view.h
@@ -0,0 +1,67 @@
+// Copyright 2020 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.
+
+#pragma once
+
+#include <stddef.h>
+#if __cplusplus >= 201103L && __has_include(<type_traits>)
+#include <type_traits>
+#endif
+
+// This represents a UTF-8 string constant provided by the vDSO itself.
+// This pointer remains valid and the string doesn't change for the
+// life of the process (if not the system).
+//
+// This type exists to be the return value type for vDSO functions.
+// In current machine ABIs, it's returned "for free" in two registers.
+// To a C caller, these functions have ABIs indistinguishable from if
+// they simply returned `const char*` so there is no overhead to
+// supporting the explicit-length API as well as the traditional C
+// string API, though it does require writing out `.c_str` in the
+// source. C++ 17 callers can take advantage of direct coercion to
+// the standard std::string_view and std::u8string_view types, which
+// also allows e.g. direct construction of std::string.
+typedef struct {
+ const char* c_str; // UTF-8, guaranteed to be '\0'-terminated.
+ size_t length; // Length, not including the '\0' terminator.
+
+#ifdef __cplusplus
+ // This is ABI-identical to the usual implementation of std::string_view,
+ // when applied to NUL-terminated C strings. But this API doesn't presume
+ // that std::string_view has a particular implementation or exists at all.
+ // For convenience of use without directly using the C++ standard library
+ // API, a templatized implicit coercion is defined to types that have the
+ // API of std::string_view or std::u8string_view. With the most common
+ // implementations, this coercion will be compiled away to nothing.
+ template <
+ typename _T
+#if __cplusplus >= 201103L && __has_include(<type_traits>)
+ ,
+ typename = typename std::enable_if<sizeof(typename _T::value_type) == sizeof(char)>::type
+#endif
+ >
+ operator _T() {
+ // It's preferable to exclude incompatible types via SFINAE so that
+ // the user's diagnostic experience is exactly as if no coercion
+ // operator existed. SFINAE should exclude this definition when a
+ // C++11 <type_traits> is available to define std::enable_if. If
+ // no standard C++ library header is available, this will provide
+ // a specific diagnostic.
+ static_assert(sizeof(typename _T::value_type) == sizeof(char),
+ "zx_string_view_t can be coerced to C++ 17 std::string_view"
+ " or std::u8string_view or types with equivalent API");
+ return {reinterpret_cast<typename _T::const_pointer>(c_str), length};
+ }
+
+ // Preferably zx_string_view_t values should just be coerced to
+ // std::string_view. But it provides the most minimal aspects of
+ // the equivalent API in case a return value expression is used
+ // directly as `zx_foo_string().data()`, for example.
+ using value_type = char;
+ using const_pointer = const char*;
+ using size_type = size_t;
+ const_pointer data() const { return c_str; }
+ size_type size() const { return length; }
+#endif
+} zx_string_view_t;
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls.h
new file mode 100644
index 0000000..9e79e55
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls.h
@@ -0,0 +1,41 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_H_
+#define SYSROOT_ZIRCON_SYSCALLS_H_
+
+#include <zircon/string_view.h>
+#include <zircon/syscalls/object.h>
+#include <zircon/syscalls/pci.h>
+#include <zircon/syscalls/profile.h>
+#include <zircon/syscalls/types.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+#define _ZX_SYSCALL_DECL(name, type, attrs, nargs, arglist, prototype) \
+ extern attrs type zx_##name prototype; \
+ extern attrs type _zx_##name prototype;
+
+#ifdef __clang__
+#define _ZX_SYSCALL_ANNO(attr) __attribute__((attr))
+#else
+#define _ZX_SYSCALL_ANNO(attr) // Nothing for compilers without the support.
+#endif
+
+#include <zircon/syscalls/internal/cdecls.inc>
+
+#undef _ZX_SYSCALL_ANNO
+#undef _ZX_SYSCALL_DECL
+
+// Compatibility wrappers for deprecated syscalls also go here, when
+// there are any.
+
+// This DEPRECATED interface is replaced by zx_system_get_version_string.
+zx_status_t zx_system_get_version(char* version, size_t version_size) __LEAF_FN;
+zx_status_t _zx_system_get_version(char* version, size_t version_size) __LEAF_FN;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/clock.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/clock.h
new file mode 100644
index 0000000..eab1cd1
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/clock.h
@@ -0,0 +1,90 @@
+// 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_CLOCK_H_
+#define SYSROOT_ZIRCON_SYSCALLS_CLOCK_H_
+
+#include <zircon/time.h>
+
+// clang-format off
+
+// Argument version identifiers.
+//
+// All zx_clock_* syscalls which fetch or receive a structure's worth of
+// arguments encode a version number in the options field of the syscall. This
+// version field is in the same location and is the same size for each syscall,
+// so a common set of macros may be used for encoding and decoding.
+#define ZX_CLOCK_ARGS_VERSION_SHIFT ((uint64_t)58u)
+#define ZX_CLOCK_ARGS_VERSION_BITS ((uint64_t)6u)
+#define ZX_CLOCK_ARGS_VERSION_MASK \
+ (((((uint64_t)1) << ZX_CLOCK_ARGS_VERSION_BITS) - 1) << ZX_CLOCK_ARGS_VERSION_SHIFT)
+#define ZX_CLOCK_ARGS_VERSION(_N) \
+ (((uint64_t)(_N) << ZX_CLOCK_ARGS_VERSION_SHIFT) & ZX_CLOCK_ARGS_VERSION_MASK)
+
+// Clock creation options.
+#define ZX_CLOCK_OPT_MONOTONIC ((uint64_t)1u << 0)
+#define ZX_CLOCK_OPT_CONTINUOUS ((uint64_t)1u << 1)
+#define ZX_CLOCK_OPT_AUTO_START ((uint64_t)1u << 2)
+
+#define ZX_CLOCK_OPTS_ALL ( \
+ ZX_CLOCK_OPT_MONOTONIC | \
+ ZX_CLOCK_OPT_CONTINUOUS | \
+ ZX_CLOCK_OPT_AUTO_START)
+
+// Clock update flags
+#define ZX_CLOCK_UPDATE_OPTION_VALUE_VALID ((uint64_t)1u << 0)
+#define ZX_CLOCK_UPDATE_OPTION_RATE_ADJUST_VALID ((uint64_t)1u << 1)
+#define ZX_CLOCK_UPDATE_OPTION_ERROR_BOUND_VALID ((uint64_t)1u << 2)
+
+#define ZX_CLOCK_UPDATE_OPTIONS_ALL ( \
+ ZX_CLOCK_UPDATE_OPTION_VALUE_VALID | \
+ ZX_CLOCK_UPDATE_OPTION_RATE_ADJUST_VALID | \
+ ZX_CLOCK_UPDATE_OPTION_ERROR_BOUND_VALID)
+
+// Clock rate adjustment limits
+#define ZX_CLOCK_UPDATE_MIN_RATE_ADJUST ((int32_t)-1000)
+#define ZX_CLOCK_UPDATE_MAX_RATE_ADJUST ((int32_t)1000)
+
+// Special clock error values
+#define ZX_CLOCK_UNKNOWN_ERROR ((uint64_t)0xFFFFFFFFFFFFFFFF)
+
+// clang-format on
+
+typedef struct zx_clock_create_args_v1 {
+ zx_time_t backstop_time;
+} zx_clock_create_args_v1_t;
+
+typedef struct zx_clock_rate {
+ uint32_t synthetic_ticks;
+ uint32_t reference_ticks;
+} zx_clock_rate_t;
+
+typedef struct zx_clock_transformation {
+ int64_t reference_offset;
+ int64_t synthetic_offset;
+ zx_clock_rate_t rate;
+} zx_clock_transformation_t;
+
+typedef struct zx_clock_details_v1 {
+ uint64_t options;
+ zx_time_t backstop_time;
+ zx_clock_transformation_t ticks_to_synthetic;
+ zx_clock_transformation_t mono_to_synthetic;
+ uint64_t error_bound;
+ zx_ticks_t query_ticks;
+ zx_ticks_t last_value_update_ticks;
+ zx_ticks_t last_rate_adjust_update_ticks;
+ zx_ticks_t last_error_bounds_update_ticks;
+ uint32_t generation_counter;
+ uint8_t padding1[4];
+} zx_clock_details_v1_t;
+
+typedef struct zx_clock_update_args_v1 {
+ int32_t rate_adjust;
+ uint8_t padding1[4];
+ int64_t value;
+ uint64_t error_bound;
+} zx_clock_update_args_v1_t;
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_CLOCK_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/debug.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/debug.h
new file mode 100644
index 0000000..373381f
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/debug.h
@@ -0,0 +1,179 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_DEBUG_
+#define SYSROOT_ZIRCON_SYSCALLS_DEBUG_
+
+#include <stdint.h>
+#include <zircon/compiler.h>
+
+__BEGIN_CDECLS
+
+#if defined(__x86_64__)
+
+// Value for ZX_THREAD_STATE_GENERAL_REGS on x86-64 platforms.
+typedef struct zx_thread_state_general_regs {
+ uint64_t rax;
+ uint64_t rbx;
+ uint64_t rcx;
+ uint64_t rdx;
+ uint64_t rsi;
+ uint64_t rdi;
+ uint64_t rbp;
+ uint64_t rsp;
+ uint64_t r8;
+ uint64_t r9;
+ uint64_t r10;
+ uint64_t r11;
+ uint64_t r12;
+ uint64_t r13;
+ uint64_t r14;
+ uint64_t r15;
+ uint64_t rip;
+ uint64_t rflags;
+ uint64_t fs_base;
+ uint64_t gs_base;
+} zx_thread_state_general_regs_t;
+
+// Value for ZX_THREAD_STATE_FP_REGS on x64. Holds x87 and MMX state.
+typedef struct zx_thread_state_fp_regs {
+ uint16_t fcw; // Control word.
+ uint16_t fsw; // Status word.
+ uint8_t ftw; // Tag word.
+ uint8_t reserved;
+ uint16_t fop; // Opcode.
+ uint64_t fip; // Instruction pointer.
+ uint64_t fdp; // Data pointer.
+
+ uint8_t padding1[8];
+
+ // The x87/MMX state. For x87 the each "st" entry has the low 80 bits used for the register
+ // contents. For MMX, the low 64 bits are used. The higher bits are unused.
+ __ALIGNED(16)
+ struct {
+ uint64_t low;
+ uint64_t high;
+ } st[8];
+} zx_thread_state_fp_regs_t;
+
+// Value for ZX_THREAD_STATE_VECTOR_REGS on x64. Holds SSE and AVX registers.
+//
+// Setting vector registers will only work for threads that have previously executed an
+// instruction using the corresponding register class.
+typedef struct zx_thread_state_vector_regs {
+ // When only 16 registers are supported (pre-AVX-512), zmm[16-31] will be 0.
+ // YMM registers (256 bits) are v[0-4], XMM registers (128 bits) are v[0-2].
+ struct {
+ uint64_t v[8];
+ } zmm[32];
+
+ // AVX-512 opmask registers. Will be 0 unless AVX-512 is supported.
+ uint64_t opmask[8];
+
+ // SIMD control and status register.
+ uint32_t mxcsr;
+
+ uint8_t padding1[4];
+} zx_thread_state_vector_regs_t;
+
+// Value for ZX_THREAD_STATE_DEBUG_REGS on x64 platforms.
+typedef struct zx_thread_state_debug_regs {
+ uint64_t dr[4];
+ // DR4 and D5 are not used.
+ uint64_t dr6; // Status register.
+ uint64_t dr7; // Control register.
+} zx_thread_state_debug_regs_t;
+
+#elif defined(__aarch64__)
+
+// Value for ZX_THREAD_STATE_GENERAL_REGS on ARM64 platforms.
+typedef struct zx_thread_state_general_regs {
+ uint64_t r[30];
+ uint64_t lr;
+ uint64_t sp;
+ uint64_t pc;
+ uint64_t cpsr;
+ uint64_t tpidr;
+} zx_thread_state_general_regs_t;
+
+// Value for ZX_THREAD_STATE_FP_REGS on ARM64 platforms.
+// This is unused because vector state is used for all floating point on ARM64.
+typedef struct zx_thread_state_fp_regs {
+ // Avoids sizing differences for empty structs between C and C++.
+ uint32_t unused;
+} zx_thread_state_fp_regs_t;
+
+// Value for ZX_THREAD_STATE_VECTOR_REGS on ARM64 platforms.
+typedef struct zx_thread_state_vector_regs {
+ uint32_t fpcr;
+ uint32_t fpsr;
+ struct {
+ uint64_t low;
+ uint64_t high;
+ } v[32];
+} zx_thread_state_vector_regs_t;
+
+// ARMv8-A provides 2 to 16 hardware breakpoint registers.
+// The number is obtained by the BRPs field in the EDDFR register.
+#define AARCH64_MAX_HW_BREAKPOINTS 16
+// ARMv8-A provides 2 to 16 watchpoint breakpoint registers.
+// The number is obtained by the WRPs field in the EDDFR register.
+#define AARCH64_MAX_HW_WATCHPOINTS 16
+
+// Value for XZ_THREAD_STATE_DEBUG_REGS for ARM64 platforms.
+typedef struct zx_thread_state_debug_regs {
+ struct {
+ uint32_t dbgbcr; // HW Breakpoint Control register.
+ uint8_t padding1[4];
+ uint64_t dbgbvr; // HW Breakpoint Value register.
+ } hw_bps[AARCH64_MAX_HW_BREAKPOINTS];
+ // Number of HW Breakpoints in the platform.
+ // Will be set on read and ignored on write.
+
+ struct {
+ uint32_t dbgwcr; // HW Watchpoint Control register.
+ uint8_t padding1[4];
+ uint64_t dbgwvr; // HW Watchpoint Value register.
+ } hw_wps[AARCH64_MAX_HW_WATCHPOINTS];
+
+ // Faulting Virtual Address for watchpoint exceptions.
+ // Read-only, values are ignored on write.
+ uint64_t far;
+
+ // The esr value since the last exception.
+ // Read-only, values are ignored on write.
+ uint32_t esr;
+
+ // Number of HW Breakpoints/Watchpoints in the platform.
+ // Will be set on read and ignored on write.
+ uint8_t hw_bps_count;
+ uint8_t hw_wps_count;
+
+ uint8_t padding1[2];
+
+} zx_thread_state_debug_regs_t;
+
+#endif
+
+// Value for ZX_THREAD_STATE_SINGLE_STEP. The value can be 0 (not single-stepping), or 1
+// (single-stepping). Other values will give ZX_ERR_INVALID_ARGS.
+typedef uint32_t zx_thread_state_single_step_t;
+
+// Values for ZX_THREAD_X86_REGISTER_FS and ZX_THREAD_X86_REGISTER_GS;
+typedef uint64_t zx_thread_x86_register_fs_t;
+typedef uint64_t zx_thread_x86_register_gs_t;
+
+// Possible values for "kind" in zx_thread_read_state and zx_thread_write_state.
+typedef uint32_t zx_thread_state_topic_t;
+#define ZX_THREAD_STATE_GENERAL_REGS ((uint32_t)0) // zx_thread_state_general_regs_t value.
+#define ZX_THREAD_STATE_FP_REGS ((uint32_t)1) // zx_thread_state_fp_regs_t value.
+#define ZX_THREAD_STATE_VECTOR_REGS ((uint32_t)2) // zx_thread_state_vector_regs_t value.
+#define ZX_THREAD_STATE_DEBUG_REGS ((uint32_t)4) // zx_thread_state_debug_regs_t value.
+#define ZX_THREAD_STATE_SINGLE_STEP ((uint32_t)5) // zx_thread_state_single_step_t value.
+#define ZX_THREAD_X86_REGISTER_FS ((uint32_t)6) // zx_thread_x86_register_fs_t value.
+#define ZX_THREAD_X86_REGISTER_GS ((uint32_t)7) // zx_thread_x86_register_gs_t value.
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_DEBUG_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/exception.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/exception.h
new file mode 100644
index 0000000..6191e0f
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/exception.h
@@ -0,0 +1,136 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_EXCEPTION_H_
+#define SYSROOT_ZIRCON_SYSCALLS_EXCEPTION_H_
+
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// ask clang format not to mess up the indentation:
+// clang-format off
+
+// The following exception values were chosen for historical reasons.
+
+// Architectural exceptions.
+//
+// Depending on the exception, further information can be found in
+// |report.context.arch|.
+
+#define ZX_EXCP_GENERAL ((uint32_t) 0x008u)
+#define ZX_EXCP_FATAL_PAGE_FAULT ((uint32_t) 0x108u)
+#define ZX_EXCP_UNDEFINED_INSTRUCTION ((uint32_t) 0x208u)
+#define ZX_EXCP_SW_BREAKPOINT ((uint32_t) 0x308u)
+#define ZX_EXCP_HW_BREAKPOINT ((uint32_t) 0x408u)
+#define ZX_EXCP_UNALIGNED_ACCESS ((uint32_t) 0x508u)
+
+// Synthetic exceptions.
+
+// These bits are set for synthetic exceptions to distinguish them from
+// architectural exceptions.
+#define ZX_EXCP_SYNTH ((uint32_t) 0x8000u)
+
+// A thread is starting.
+// This exception is sent to debuggers only (ZX_EXCEPTION_CHANNEL_TYPE_DEBUGGER).
+// The thread that generates this exception is paused until it the debugger
+// handles the exception.
+#define ZX_EXCP_THREAD_STARTING ((uint32_t) 0x008u | ZX_EXCP_SYNTH)
+
+// A thread is exiting.
+// This exception is sent to debuggers only (ZX_EXCEPTION_CHANNEL_TYPE_DEBUGGER).
+// This exception is different from ZX_EXCP_GONE in that a debugger can
+// still examine thread state.
+// The thread that generates this exception is paused until it the debugger
+// handles the exception.
+#define ZX_EXCP_THREAD_EXITING ((uint32_t) 0x108u | ZX_EXCP_SYNTH)
+
+// This exception is generated when a syscall fails with a job policy
+// error (for example, an invalid handle argument is passed to the
+// syscall when the ZX_POL_BAD_HANDLE policy is enabled) and
+// ZX_POL_ACTION_EXCEPTION is set for the policy.
+// The thread that generates this exception is paused until it the debugger
+// handles the exception.
+#define ZX_EXCP_POLICY_ERROR ((uint32_t) 0x208u | ZX_EXCP_SYNTH)
+
+// A process is starting.
+// This exception is sent to job debuggers only
+// (ZX_EXCEPTION_CHANNEL_TYPE_JOB_DEBUGGER).
+// The thread that generates this exception is paused until it the debugger
+// handles the exception.
+#define ZX_EXCP_PROCESS_STARTING ((uint32_t) 0x308u | ZX_EXCP_SYNTH)
+
+typedef uint32_t zx_excp_type_t;
+
+// Assuming |excp| is an exception type, the following returns true if the
+// type is architectural.
+#define ZX_EXCP_IS_ARCH(excp) (((excp) & ZX_EXCP_SYNTH) == 0)
+
+typedef struct zx_x86_64_exc_data {
+ uint64_t vector;
+ uint64_t err_code;
+ uint64_t cr2;
+} zx_x86_64_exc_data_t;
+
+typedef struct zx_arm64_exc_data {
+ uint32_t esr;
+ uint8_t padding1[4];
+ uint64_t far;
+} zx_arm64_exc_data_t;
+
+// data associated with an exception (siginfo in linux parlance)
+// Things available from regsets (e.g., pc) are not included here.
+// For an example list of things one might add, see linux siginfo.
+typedef struct zx_exception_context {
+ struct {
+ union {
+ zx_x86_64_exc_data_t x86_64;
+ struct {
+ zx_arm64_exc_data_t arm_64;
+ uint8_t padding1[8];
+ };
+ } u;
+ } arch;
+} zx_exception_context_t;
+
+// The common header of all exception reports.
+typedef struct zx_exception_header {
+ // The actual size, in bytes, of the report (including this field).
+ uint32_t size;
+
+ zx_excp_type_t type;
+} zx_exception_header_t;
+
+// Data reported to an exception handler for most exceptions.
+typedef struct zx_exception_report {
+ zx_exception_header_t header;
+ // The remainder of the report is exception-specific.
+ zx_exception_context_t context;
+} zx_exception_report_t;
+
+// Basic info sent along with the handle over an exception channel.
+typedef struct zx_exception_info {
+ zx_koid_t pid;
+ zx_koid_t tid;
+ zx_excp_type_t type;
+ uint8_t padding1[4];
+} zx_exception_info_t;
+
+// Options for zx_create_exception_channel.
+// When creating an exception channel, use the task's debug channel.
+#define ZX_EXCEPTION_CHANNEL_DEBUGGER ((uint32_t)1)
+
+// The type of exception handler a thread may be waiting for a response from.
+// These values are reported in zx_info_thread_t.wait_exception_channel_type.
+#define ZX_EXCEPTION_CHANNEL_TYPE_NONE ((uint32_t)0u)
+#define ZX_EXCEPTION_CHANNEL_TYPE_DEBUGGER ((uint32_t)1u)
+#define ZX_EXCEPTION_CHANNEL_TYPE_THREAD ((uint32_t)2u)
+#define ZX_EXCEPTION_CHANNEL_TYPE_PROCESS ((uint32_t)3u)
+#define ZX_EXCEPTION_CHANNEL_TYPE_JOB ((uint32_t)4u)
+#define ZX_EXCEPTION_CHANNEL_TYPE_JOB_DEBUGGER ((uint32_t)5u)
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_EXCEPTION_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/hypervisor.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/hypervisor.h
new file mode 100644
index 0000000..f574d4e
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/hypervisor.h
@@ -0,0 +1,78 @@
+// Copyright 2017 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_HYPERVISOR_H_
+#define SYSROOT_ZIRCON_SYSCALLS_HYPERVISOR_H_
+
+#include <assert.h>
+
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// clang-format off
+typedef uint32_t zx_guest_trap_t;
+
+#define ZX_GUEST_TRAP_BELL ((zx_guest_trap_t) 0u)
+#define ZX_GUEST_TRAP_MEM ((zx_guest_trap_t) 1u)
+#define ZX_GUEST_TRAP_IO ((zx_guest_trap_t) 2u)
+
+typedef uint32_t zx_vcpu_t;
+
+#define ZX_VCPU_STATE ((zx_vcpu_t) 0u)
+#define ZX_VCPU_IO ((zx_vcpu_t) 1u)
+// clang-format on
+
+// Structure to read and write VCPU state.
+typedef struct zx_vcpu_state {
+#if __aarch64__
+ uint64_t x[31];
+ uint64_t sp;
+ // Contains only the user-controllable upper 4-bits (NZCV).
+ uint32_t cpsr;
+ uint8_t padding1[4];
+#elif __x86_64__
+ uint64_t rax;
+ uint64_t rcx;
+ uint64_t rdx;
+ uint64_t rbx;
+ uint64_t rsp;
+ uint64_t rbp;
+ uint64_t rsi;
+ uint64_t rdi;
+ uint64_t r8;
+ uint64_t r9;
+ uint64_t r10;
+ uint64_t r11;
+ uint64_t r12;
+ uint64_t r13;
+ uint64_t r14;
+ uint64_t r15;
+ // Contains only the user-controllable lower 32-bits.
+ uint64_t rflags;
+#endif
+} zx_vcpu_state_t;
+
+// Structure to read and write VCPU state for IO ports.
+typedef struct zx_vcpu_io {
+ uint8_t access_size;
+ uint8_t padding1[3];
+ union {
+ struct {
+ uint8_t u8;
+ uint8_t padding2[3];
+ };
+ struct {
+ uint16_t u16;
+ uint8_t padding3[2];
+ };
+ uint32_t u32;
+ uint8_t data[4];
+ };
+} zx_vcpu_io_t;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_HYPERVISOR_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/internal/cdecls.inc b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/internal/cdecls.inc
new file mode 100644
index 0000000..1a14308
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/internal/cdecls.inc
@@ -0,0 +1,1057 @@
+// 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.
+
+// WARNING: THIS FILE IS MACHINE GENERATED BY //tools/kazoo. DO NOT EDIT.
+
+#ifndef _ZX_SYSCALL_DECL
+#error "<zircon/syscalls.h> is the public API header"
+#endif
+
+_ZX_SYSCALL_DECL(bti_create, zx_status_t, /* no attributes */, 4,
+ (iommu, options, bti_id, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t iommu,
+ uint32_t options,
+ uint64_t bti_id,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(bti_pin, zx_status_t, /* no attributes */, 8,
+ (handle, options, vmo, offset, size, addrs, num_addrs, pmt), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t vmo,
+ uint64_t offset,
+ uint64_t size,
+ zx_paddr_t* addrs,
+ size_t num_addrs,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* pmt))
+
+_ZX_SYSCALL_DECL(bti_release_quarantine, zx_status_t, /* no attributes */, 1,
+ (handle), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle))
+
+_ZX_SYSCALL_DECL(cache_flush, zx_status_t, /* no attributes */, 3,
+ (addr, size, options), (
+ const void* addr,
+ size_t size,
+ uint32_t options))
+
+_ZX_SYSCALL_DECL(channel_create, zx_status_t, /* no attributes */, 3,
+ (options, out0, out1), (
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out0,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out1))
+
+_ZX_SYSCALL_DECL(channel_read, zx_status_t, /* no attributes */, 8,
+ (handle, options, bytes, handles, num_bytes, num_handles, actual_bytes, actual_handles), (
+ _ZX_SYSCALL_ANNO(use_handle("FuchsiaUnchecked")) zx_handle_t handle,
+ uint32_t options,
+ void* bytes,
+ _ZX_SYSCALL_ANNO(acquire_handle("FuchsiaUnchecked")) zx_handle_t* handles,
+ uint32_t num_bytes,
+ uint32_t num_handles,
+ uint32_t* actual_bytes,
+ uint32_t* actual_handles))
+
+_ZX_SYSCALL_DECL(channel_read_etc, zx_status_t, /* no attributes */, 8,
+ (handle, options, bytes, handles, num_bytes, num_handles, actual_bytes, actual_handles), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ void* bytes,
+ zx_handle_info_t* handles,
+ uint32_t num_bytes,
+ uint32_t num_handles,
+ uint32_t* actual_bytes,
+ uint32_t* actual_handles))
+
+_ZX_SYSCALL_DECL(channel_write, zx_status_t, /* no attributes */, 6,
+ (handle, options, bytes, num_bytes, handles, num_handles), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ const void* bytes,
+ uint32_t num_bytes,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) const zx_handle_t* handles,
+ uint32_t num_handles))
+
+_ZX_SYSCALL_DECL(channel_write_etc, zx_status_t, /* no attributes */, 6,
+ (handle, options, bytes, num_bytes, handles, num_handles), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ const void* bytes,
+ uint32_t num_bytes,
+ zx_handle_disposition_t* handles,
+ uint32_t num_handles))
+
+_ZX_SYSCALL_DECL(channel_call, zx_status_t, /* no attributes */, 6,
+ (handle, options, deadline, args, actual_bytes, actual_handles), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ zx_time_t deadline,
+ const zx_channel_call_args_t* args,
+ uint32_t* actual_bytes,
+ uint32_t* actual_handles))
+
+_ZX_SYSCALL_DECL(clock_get, zx_status_t, /* no attributes */, 2,
+ (clock_id, out), (
+ zx_clock_t clock_id,
+ zx_time_t* out))
+
+_ZX_SYSCALL_DECL(clock_get_monotonic, zx_time_t, /* no attributes */, 0,
+ (), (void))
+
+_ZX_SYSCALL_DECL(clock_adjust, zx_status_t, /* no attributes */, 3,
+ (handle, clock_id, offset), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_clock_t clock_id,
+ int64_t offset))
+
+_ZX_SYSCALL_DECL(clock_create, zx_status_t, /* no attributes */, 3,
+ (options, args, out), (
+ uint64_t options,
+ const void* args,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(clock_read, zx_status_t, /* no attributes */, 2,
+ (handle, now), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_time_t* now))
+
+_ZX_SYSCALL_DECL(clock_get_details, zx_status_t, /* no attributes */, 3,
+ (handle, options, details), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint64_t options,
+ void* details))
+
+_ZX_SYSCALL_DECL(clock_update, zx_status_t, /* no attributes */, 3,
+ (handle, options, args), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint64_t options,
+ const void* args))
+
+_ZX_SYSCALL_DECL(cprng_draw, void, /* no attributes */, 2,
+ (buffer, buffer_size), (
+ void* buffer,
+ size_t buffer_size))
+
+_ZX_SYSCALL_DECL(cprng_add_entropy, zx_status_t, /* no attributes */, 2,
+ (buffer, buffer_size), (
+ const void* buffer,
+ size_t buffer_size))
+
+_ZX_SYSCALL_DECL(debug_read, zx_status_t, /* no attributes */, 4,
+ (handle, buffer, buffer_size, actual), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ char* buffer,
+ size_t buffer_size,
+ size_t* actual))
+
+_ZX_SYSCALL_DECL(debug_write, zx_status_t, /* no attributes */, 2,
+ (buffer, buffer_size), (
+ const char* buffer,
+ size_t buffer_size))
+
+_ZX_SYSCALL_DECL(debug_send_command, zx_status_t, /* no attributes */, 3,
+ (resource, buffer, buffer_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t resource,
+ const char* buffer,
+ size_t buffer_size))
+
+_ZX_SYSCALL_DECL(debuglog_create, zx_status_t, /* no attributes */, 3,
+ (resource, options, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t resource,
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(debuglog_write, zx_status_t, /* no attributes */, 4,
+ (handle, options, buffer, buffer_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ const void* buffer,
+ size_t buffer_size))
+
+_ZX_SYSCALL_DECL(debuglog_read, zx_status_t, /* no attributes */, 4,
+ (handle, options, buffer, buffer_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ void* buffer,
+ size_t buffer_size))
+
+_ZX_SYSCALL_DECL(event_create, zx_status_t, /* no attributes */, 2,
+ (options, out), (
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(eventpair_create, zx_status_t, /* no attributes */, 3,
+ (options, out0, out1), (
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out0,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out1))
+
+_ZX_SYSCALL_DECL(exception_get_thread, zx_status_t, /* no attributes */, 2,
+ (handle, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(exception_get_process, zx_status_t, /* no attributes */, 2,
+ (handle, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(fifo_create, zx_status_t, /* no attributes */, 5,
+ (elem_count, elem_size, options, out0, out1), (
+ size_t elem_count,
+ size_t elem_size,
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out0,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out1))
+
+_ZX_SYSCALL_DECL(fifo_read, zx_status_t, /* no attributes */, 5,
+ (handle, elem_size, data, data_size, actual_count), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ size_t elem_size,
+ void* data,
+ size_t data_size,
+ size_t* actual_count))
+
+_ZX_SYSCALL_DECL(fifo_write, zx_status_t, /* no attributes */, 5,
+ (handle, elem_size, data, count, actual_count), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ size_t elem_size,
+ const void* data,
+ size_t count,
+ size_t* actual_count))
+
+_ZX_SYSCALL_DECL(framebuffer_get_info, zx_status_t, /* no attributes */, 5,
+ (resource, format, width, height, stride), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t resource,
+ uint32_t* format,
+ uint32_t* width,
+ uint32_t* height,
+ uint32_t* stride))
+
+_ZX_SYSCALL_DECL(framebuffer_set_range, zx_status_t, /* no attributes */, 7,
+ (resource, vmo, len, format, width, height, stride), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t resource,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t vmo,
+ uint32_t len,
+ uint32_t format,
+ uint32_t width,
+ uint32_t height,
+ uint32_t stride))
+
+_ZX_SYSCALL_DECL(futex_wait, zx_status_t, /* no attributes */, 4,
+ (value_ptr, current_value, new_futex_owner, deadline), (
+ const zx_futex_t* value_ptr,
+ zx_futex_t current_value,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t new_futex_owner,
+ zx_time_t deadline))
+
+_ZX_SYSCALL_DECL(futex_wake, zx_status_t, /* no attributes */, 2,
+ (value_ptr, wake_count), (
+ const zx_futex_t* value_ptr,
+ uint32_t wake_count))
+
+_ZX_SYSCALL_DECL(futex_requeue, zx_status_t, /* no attributes */, 6,
+ (value_ptr, wake_count, current_value, requeue_ptr, requeue_count, new_requeue_owner), (
+ const zx_futex_t* value_ptr,
+ uint32_t wake_count,
+ zx_futex_t current_value,
+ const zx_futex_t* requeue_ptr,
+ uint32_t requeue_count,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t new_requeue_owner))
+
+_ZX_SYSCALL_DECL(futex_wake_single_owner, zx_status_t, /* no attributes */, 1,
+ (value_ptr), (
+ const zx_futex_t* value_ptr))
+
+_ZX_SYSCALL_DECL(futex_requeue_single_owner, zx_status_t, /* no attributes */, 5,
+ (value_ptr, current_value, requeue_ptr, requeue_count, new_requeue_owner), (
+ const zx_futex_t* value_ptr,
+ zx_futex_t current_value,
+ const zx_futex_t* requeue_ptr,
+ uint32_t requeue_count,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t new_requeue_owner))
+
+_ZX_SYSCALL_DECL(futex_get_owner, zx_status_t, /* no attributes */, 2,
+ (value_ptr, koid), (
+ const zx_futex_t* value_ptr,
+ zx_koid_t* koid))
+
+_ZX_SYSCALL_DECL(guest_create, zx_status_t, /* no attributes */, 4,
+ (resource, options, guest_handle, vmar_handle), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t resource,
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* guest_handle,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* vmar_handle))
+
+_ZX_SYSCALL_DECL(guest_set_trap, zx_status_t, /* no attributes */, 6,
+ (handle, kind, addr, size, port_handle, key), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t kind,
+ zx_vaddr_t addr,
+ size_t size,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t port_handle,
+ uint64_t key))
+
+_ZX_SYSCALL_DECL(handle_close, zx_status_t, /* no attributes */, 1,
+ (handle), (
+ _ZX_SYSCALL_ANNO(release_handle("Fuchsia")) zx_handle_t handle))
+
+_ZX_SYSCALL_DECL(handle_close_many, zx_status_t, /* no attributes */, 2,
+ (handles, num_handles), (
+ _ZX_SYSCALL_ANNO(release_handle("Fuchsia")) const zx_handle_t* handles,
+ size_t num_handles))
+
+_ZX_SYSCALL_DECL(handle_duplicate, zx_status_t, /* no attributes */, 3,
+ (handle, rights, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_rights_t rights,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(handle_replace, zx_status_t, /* no attributes */, 3,
+ (handle, rights, out), (
+ _ZX_SYSCALL_ANNO(release_handle("Fuchsia")) zx_handle_t handle,
+ zx_rights_t rights,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(interrupt_create, zx_status_t, /* no attributes */, 4,
+ (src_obj, src_num, options, out_handle), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t src_obj,
+ uint32_t src_num,
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out_handle))
+
+_ZX_SYSCALL_DECL(interrupt_bind, zx_status_t, /* no attributes */, 4,
+ (handle, port_handle, key, options), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t port_handle,
+ uint64_t key,
+ uint32_t options))
+
+_ZX_SYSCALL_DECL(interrupt_wait, zx_status_t, /* no attributes */, 2,
+ (handle, out_timestamp), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_time_t* out_timestamp))
+
+_ZX_SYSCALL_DECL(interrupt_destroy, zx_status_t, /* no attributes */, 1,
+ (handle), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle))
+
+_ZX_SYSCALL_DECL(interrupt_ack, zx_status_t, /* no attributes */, 1,
+ (handle), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle))
+
+_ZX_SYSCALL_DECL(interrupt_trigger, zx_status_t, /* no attributes */, 3,
+ (handle, options, timestamp), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ zx_time_t timestamp))
+
+_ZX_SYSCALL_DECL(interrupt_bind_vcpu, zx_status_t, /* no attributes */, 3,
+ (handle, vcpu, options), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t vcpu,
+ uint32_t options))
+
+_ZX_SYSCALL_DECL(iommu_create, zx_status_t, /* no attributes */, 5,
+ (resource, type, desc, desc_size, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t resource,
+ uint32_t type,
+ const void* desc,
+ size_t desc_size,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(ioports_request, zx_status_t, /* no attributes */, 3,
+ (resource, io_addr, len), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t resource,
+ uint16_t io_addr,
+ uint32_t len))
+
+_ZX_SYSCALL_DECL(ioports_release, zx_status_t, /* no attributes */, 3,
+ (resource, io_addr, len), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t resource,
+ uint16_t io_addr,
+ uint32_t len))
+
+_ZX_SYSCALL_DECL(job_create, zx_status_t, /* no attributes */, 3,
+ (parent_job, options, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t parent_job,
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(job_set_policy, zx_status_t, /* no attributes */, 5,
+ (handle, options, topic, policy, policy_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ uint32_t topic,
+ const void* policy,
+ uint32_t policy_size))
+
+_ZX_SYSCALL_DECL(job_set_critical, zx_status_t, /* no attributes */, 3,
+ (job, options, process), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t job,
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t process))
+
+_ZX_SYSCALL_DECL(ktrace_read, zx_status_t, /* no attributes */, 5,
+ (handle, data, offset, data_size, actual), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ void* data,
+ uint32_t offset,
+ size_t data_size,
+ size_t* actual))
+
+_ZX_SYSCALL_DECL(ktrace_control, zx_status_t, /* no attributes */, 4,
+ (handle, action, options, ptr), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t action,
+ uint32_t options,
+ void* ptr))
+
+_ZX_SYSCALL_DECL(ktrace_write, zx_status_t, /* no attributes */, 4,
+ (handle, id, arg0, arg1), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t id,
+ uint32_t arg0,
+ uint32_t arg1))
+
+_ZX_SYSCALL_DECL(nanosleep, zx_status_t, /* no attributes */, 1,
+ (deadline), (
+ zx_time_t deadline))
+
+_ZX_SYSCALL_DECL(ticks_get, zx_ticks_t, /* no attributes */, 0,
+ (), (void))
+
+_ZX_SYSCALL_DECL(ticks_per_second, zx_ticks_t, __CONST, 0,
+ (), (void))
+
+_ZX_SYSCALL_DECL(deadline_after, zx_time_t, /* no attributes */, 1,
+ (nanoseconds), (
+ zx_duration_t nanoseconds))
+
+_ZX_SYSCALL_DECL(vmar_unmap_handle_close_thread_exit, zx_status_t, /* no attributes */, 4,
+ (vmar_handle, addr, size, close_handle), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t vmar_handle,
+ zx_vaddr_t addr,
+ size_t size,
+ _ZX_SYSCALL_ANNO(release_handle("Fuchsia")) zx_handle_t close_handle))
+
+_ZX_SYSCALL_DECL(futex_wake_handle_close_thread_exit, void, __NO_RETURN, 4,
+ (value_ptr, wake_count, new_value, close_handle), (
+ const zx_futex_t* value_ptr,
+ uint32_t wake_count,
+ int32_t new_value,
+ _ZX_SYSCALL_ANNO(release_handle("Fuchsia")) zx_handle_t close_handle))
+
+_ZX_SYSCALL_DECL(mtrace_control, zx_status_t, /* no attributes */, 6,
+ (handle, kind, action, options, ptr, ptr_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t kind,
+ uint32_t action,
+ uint32_t options,
+ void* ptr,
+ size_t ptr_size))
+
+_ZX_SYSCALL_DECL(object_wait_one, zx_status_t, /* no attributes */, 4,
+ (handle, signals, deadline, observed), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_signals_t signals,
+ zx_time_t deadline,
+ zx_signals_t* observed))
+
+_ZX_SYSCALL_DECL(object_wait_many, zx_status_t, /* no attributes */, 3,
+ (items, num_items, deadline), (
+ zx_wait_item_t* items,
+ size_t num_items,
+ zx_time_t deadline))
+
+_ZX_SYSCALL_DECL(object_wait_async, zx_status_t, /* no attributes */, 5,
+ (handle, port, key, signals, options), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t port,
+ uint64_t key,
+ zx_signals_t signals,
+ uint32_t options))
+
+_ZX_SYSCALL_DECL(object_signal, zx_status_t, /* no attributes */, 3,
+ (handle, clear_mask, set_mask), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t clear_mask,
+ uint32_t set_mask))
+
+_ZX_SYSCALL_DECL(object_signal_peer, zx_status_t, /* no attributes */, 3,
+ (handle, clear_mask, set_mask), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t clear_mask,
+ uint32_t set_mask))
+
+_ZX_SYSCALL_DECL(object_get_property, zx_status_t, /* no attributes */, 4,
+ (handle, property, value, value_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t property,
+ void* value,
+ size_t value_size))
+
+_ZX_SYSCALL_DECL(object_set_property, zx_status_t, /* no attributes */, 4,
+ (handle, property, value, value_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t property,
+ const void* value,
+ size_t value_size))
+
+_ZX_SYSCALL_DECL(object_get_info, zx_status_t, /* no attributes */, 6,
+ (handle, topic, buffer, buffer_size, actual, avail), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t topic,
+ void* buffer,
+ size_t buffer_size,
+ size_t* actual,
+ size_t* avail))
+
+_ZX_SYSCALL_DECL(object_get_child, zx_status_t, /* no attributes */, 4,
+ (handle, koid, rights, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint64_t koid,
+ zx_rights_t rights,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(object_set_profile, zx_status_t, /* no attributes */, 3,
+ (handle, profile, options), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t profile,
+ uint32_t options))
+
+_ZX_SYSCALL_DECL(pager_create, zx_status_t, /* no attributes */, 2,
+ (options, out), (
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(pager_create_vmo, zx_status_t, /* no attributes */, 6,
+ (pager, options, port, key, size, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t pager,
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t port,
+ uint64_t key,
+ uint64_t size,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(pager_detach_vmo, zx_status_t, /* no attributes */, 2,
+ (pager, vmo), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t pager,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t vmo))
+
+_ZX_SYSCALL_DECL(pager_supply_pages, zx_status_t, /* no attributes */, 6,
+ (pager, pager_vmo, offset, length, aux_vmo, aux_offset), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t pager,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t pager_vmo,
+ uint64_t offset,
+ uint64_t length,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t aux_vmo,
+ uint64_t aux_offset))
+
+_ZX_SYSCALL_DECL(pc_firmware_tables, zx_status_t, /* no attributes */, 3,
+ (handle, acpi_rsdp, smbios), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_paddr_t* acpi_rsdp,
+ zx_paddr_t* smbios))
+
+_ZX_SYSCALL_DECL(pci_get_nth_device, zx_status_t, /* no attributes */, 4,
+ (handle, index, out_info, out_handle), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t index,
+ zx_pcie_device_info_t* out_info,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out_handle))
+
+_ZX_SYSCALL_DECL(pci_enable_bus_master, zx_status_t, /* no attributes */, 2,
+ (handle, enable), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ bool enable))
+
+_ZX_SYSCALL_DECL(pci_reset_device, zx_status_t, /* no attributes */, 1,
+ (handle), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle))
+
+_ZX_SYSCALL_DECL(pci_config_read, zx_status_t, /* no attributes */, 4,
+ (handle, offset, width, out_val), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint16_t offset,
+ size_t width,
+ uint32_t* out_val))
+
+_ZX_SYSCALL_DECL(pci_config_write, zx_status_t, /* no attributes */, 4,
+ (handle, offset, width, val), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint16_t offset,
+ size_t width,
+ uint32_t val))
+
+_ZX_SYSCALL_DECL(pci_cfg_pio_rw, zx_status_t, /* no attributes */, 8,
+ (handle, bus, dev, func, offset, val, width, write), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint8_t bus,
+ uint8_t dev,
+ uint8_t func,
+ uint8_t offset,
+ uint32_t* val,
+ size_t width,
+ bool write))
+
+_ZX_SYSCALL_DECL(pci_get_bar, zx_status_t, /* no attributes */, 4,
+ (handle, bar_num, out_bar, out_handle), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t bar_num,
+ zx_pci_bar_t* out_bar,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out_handle))
+
+_ZX_SYSCALL_DECL(pci_map_interrupt, zx_status_t, /* no attributes */, 3,
+ (handle, which_irq, out_handle), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ int32_t which_irq,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out_handle))
+
+_ZX_SYSCALL_DECL(pci_query_irq_mode, zx_status_t, /* no attributes */, 3,
+ (handle, mode, out_max_irqs), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t mode,
+ uint32_t* out_max_irqs))
+
+_ZX_SYSCALL_DECL(pci_set_irq_mode, zx_status_t, /* no attributes */, 3,
+ (handle, mode, requested_irq_count), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t mode,
+ uint32_t requested_irq_count))
+
+_ZX_SYSCALL_DECL(pci_init, zx_status_t, /* no attributes */, 3,
+ (handle, init_buf, len), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ const zx_pci_init_arg_t* init_buf,
+ uint32_t len))
+
+_ZX_SYSCALL_DECL(pci_add_subtract_io_range, zx_status_t, /* no attributes */, 5,
+ (handle, mmio, base, len, add), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ bool mmio,
+ uint64_t base,
+ uint64_t len,
+ bool add))
+
+_ZX_SYSCALL_DECL(pmt_unpin, zx_status_t, /* no attributes */, 1,
+ (handle), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle))
+
+_ZX_SYSCALL_DECL(port_create, zx_status_t, /* no attributes */, 2,
+ (options, out), (
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(port_queue, zx_status_t, /* no attributes */, 2,
+ (handle, packet), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ const zx_port_packet_t* packet))
+
+_ZX_SYSCALL_DECL(port_wait, zx_status_t, /* no attributes */, 3,
+ (handle, deadline, packet), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_time_t deadline,
+ zx_port_packet_t* packet))
+
+_ZX_SYSCALL_DECL(port_cancel, zx_status_t, /* no attributes */, 3,
+ (handle, source, key), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t source,
+ uint64_t key))
+
+_ZX_SYSCALL_DECL(process_exit, void, __NO_RETURN, 1,
+ (retcode), (
+ int64_t retcode))
+
+_ZX_SYSCALL_DECL(process_create, zx_status_t, /* no attributes */, 6,
+ (job, name, name_size, options, proc_handle, vmar_handle), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t job,
+ const char* name,
+ size_t name_size,
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* proc_handle,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* vmar_handle))
+
+_ZX_SYSCALL_DECL(process_start, zx_status_t, /* no attributes */, 6,
+ (handle, thread, entry, stack, arg1, arg2), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t thread,
+ zx_vaddr_t entry,
+ zx_vaddr_t stack,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t arg1,
+ uintptr_t arg2))
+
+_ZX_SYSCALL_DECL(process_read_memory, zx_status_t, /* no attributes */, 5,
+ (handle, vaddr, buffer, buffer_size, actual), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_vaddr_t vaddr,
+ void* buffer,
+ size_t buffer_size,
+ size_t* actual))
+
+_ZX_SYSCALL_DECL(process_write_memory, zx_status_t, /* no attributes */, 5,
+ (handle, vaddr, buffer, buffer_size, actual), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_vaddr_t vaddr,
+ const void* buffer,
+ size_t buffer_size,
+ size_t* actual))
+
+_ZX_SYSCALL_DECL(profile_create, zx_status_t, /* no attributes */, 4,
+ (root_job, options, profile, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t root_job,
+ uint32_t options,
+ const zx_profile_info_t* profile,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(resource_create, zx_status_t, /* no attributes */, 7,
+ (parent_rsrc, options, base, size, name, name_size, resource_out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t parent_rsrc,
+ uint32_t options,
+ uint64_t base,
+ size_t size,
+ const char* name,
+ size_t name_size,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* resource_out))
+
+_ZX_SYSCALL_DECL(smc_call, zx_status_t, /* no attributes */, 3,
+ (handle, parameters, out_smc_result), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ const zx_smc_parameters_t* parameters,
+ zx_smc_result_t* out_smc_result))
+
+_ZX_SYSCALL_DECL(socket_create, zx_status_t, /* no attributes */, 3,
+ (options, out0, out1), (
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out0,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out1))
+
+_ZX_SYSCALL_DECL(socket_write, zx_status_t, /* no attributes */, 5,
+ (handle, options, buffer, buffer_size, actual), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ const void* buffer,
+ size_t buffer_size,
+ size_t* actual))
+
+_ZX_SYSCALL_DECL(socket_read, zx_status_t, /* no attributes */, 5,
+ (handle, options, buffer, buffer_size, actual), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ void* buffer,
+ size_t buffer_size,
+ size_t* actual))
+
+_ZX_SYSCALL_DECL(socket_shutdown, zx_status_t, /* no attributes */, 2,
+ (handle, options), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options))
+
+_ZX_SYSCALL_DECL(stream_create, zx_status_t, /* no attributes */, 4,
+ (options, vmo, seek, out_stream), (
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t vmo,
+ zx_off_t seek,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out_stream))
+
+_ZX_SYSCALL_DECL(stream_writev, zx_status_t, /* no attributes */, 5,
+ (handle, options, vector, num_vector, actual), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ const zx_iovec_t* vector,
+ size_t num_vector,
+ size_t* actual))
+
+_ZX_SYSCALL_DECL(stream_writev_at, zx_status_t, /* no attributes */, 6,
+ (handle, options, offset, vector, num_vector, actual), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ zx_off_t offset,
+ const zx_iovec_t* vector,
+ size_t num_vector,
+ size_t* actual))
+
+_ZX_SYSCALL_DECL(stream_readv, zx_status_t, /* no attributes */, 5,
+ (handle, options, vector, num_vector, actual), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ zx_iovec_t* vector,
+ size_t num_vector,
+ size_t* actual))
+
+_ZX_SYSCALL_DECL(stream_readv_at, zx_status_t, /* no attributes */, 6,
+ (handle, options, offset, vector, num_vector, actual), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ zx_off_t offset,
+ zx_iovec_t* vector,
+ size_t num_vector,
+ size_t* actual))
+
+_ZX_SYSCALL_DECL(stream_seek, zx_status_t, /* no attributes */, 4,
+ (handle, whence, offset, out_seek), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_stream_seek_origin_t whence,
+ int64_t offset,
+ zx_off_t* out_seek))
+
+_ZX_SYSCALL_DECL(system_get_dcache_line_size, uint32_t, __CONST, 0,
+ (), (void))
+
+_ZX_SYSCALL_DECL(system_get_num_cpus, uint32_t, __CONST, 0,
+ (), (void))
+
+_ZX_SYSCALL_DECL(system_get_version_string, zx_string_view_t, __CONST, 0,
+ (), (void))
+
+_ZX_SYSCALL_DECL(system_get_physmem, uint64_t, /* no attributes */, 0,
+ (), (void))
+
+_ZX_SYSCALL_DECL(system_get_features, zx_status_t, /* no attributes */, 2,
+ (kind, features), (
+ uint32_t kind,
+ uint32_t* features))
+
+_ZX_SYSCALL_DECL(system_get_event, zx_status_t, /* no attributes */, 3,
+ (root_job, kind, event), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t root_job,
+ uint32_t kind,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* event))
+
+_ZX_SYSCALL_DECL(system_mexec, zx_status_t, /* no attributes */, 3,
+ (resource, kernel_vmo, bootimage_vmo), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t resource,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t kernel_vmo,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t bootimage_vmo))
+
+_ZX_SYSCALL_DECL(system_mexec_payload_get, zx_status_t, /* no attributes */, 3,
+ (resource, buffer, buffer_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t resource,
+ void* buffer,
+ size_t buffer_size))
+
+_ZX_SYSCALL_DECL(system_powerctl, zx_status_t, /* no attributes */, 3,
+ (resource, cmd, arg), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t resource,
+ uint32_t cmd,
+ const zx_system_powerctl_arg_t* arg))
+
+_ZX_SYSCALL_DECL(task_suspend, zx_status_t, /* no attributes */, 2,
+ (handle, token), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* token))
+
+_ZX_SYSCALL_DECL(task_suspend_token, zx_status_t, /* no attributes */, 2,
+ (handle, token), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* token))
+
+_ZX_SYSCALL_DECL(task_create_exception_channel, zx_status_t, /* no attributes */, 3,
+ (handle, options, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(task_kill, zx_status_t, /* no attributes */, 1,
+ (handle), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle))
+
+_ZX_SYSCALL_DECL(thread_exit, void, __NO_RETURN, 0,
+ (), (void))
+
+_ZX_SYSCALL_DECL(thread_create, zx_status_t, /* no attributes */, 5,
+ (process, name, name_size, options, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t process,
+ const char* name,
+ size_t name_size,
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(thread_start, zx_status_t, /* no attributes */, 5,
+ (handle, thread_entry, stack, arg1, arg2), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_vaddr_t thread_entry,
+ zx_vaddr_t stack,
+ uintptr_t arg1,
+ uintptr_t arg2))
+
+_ZX_SYSCALL_DECL(thread_read_state, zx_status_t, /* no attributes */, 4,
+ (handle, kind, buffer, buffer_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t kind,
+ void* buffer,
+ size_t buffer_size))
+
+_ZX_SYSCALL_DECL(thread_write_state, zx_status_t, /* no attributes */, 4,
+ (handle, kind, buffer, buffer_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t kind,
+ const void* buffer,
+ size_t buffer_size))
+
+_ZX_SYSCALL_DECL(timer_create, zx_status_t, /* no attributes */, 3,
+ (options, clock_id, out), (
+ uint32_t options,
+ zx_clock_t clock_id,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(timer_set, zx_status_t, /* no attributes */, 3,
+ (handle, deadline, slack), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_time_t deadline,
+ zx_duration_t slack))
+
+_ZX_SYSCALL_DECL(timer_cancel, zx_status_t, /* no attributes */, 1,
+ (handle), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle))
+
+_ZX_SYSCALL_DECL(vcpu_create, zx_status_t, /* no attributes */, 4,
+ (guest, options, entry, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t guest,
+ uint32_t options,
+ zx_vaddr_t entry,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(vcpu_resume, zx_status_t, /* no attributes */, 2,
+ (handle, packet), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_port_packet_t* packet))
+
+_ZX_SYSCALL_DECL(vcpu_interrupt, zx_status_t, /* no attributes */, 2,
+ (handle, vector), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t vector))
+
+_ZX_SYSCALL_DECL(vcpu_read_state, zx_status_t, /* no attributes */, 4,
+ (handle, kind, buffer, buffer_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t kind,
+ void* buffer,
+ size_t buffer_size))
+
+_ZX_SYSCALL_DECL(vcpu_write_state, zx_status_t, /* no attributes */, 4,
+ (handle, kind, buffer, buffer_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t kind,
+ const void* buffer,
+ size_t buffer_size))
+
+_ZX_SYSCALL_DECL(vmar_allocate, zx_status_t, /* no attributes */, 6,
+ (parent_vmar, options, offset, size, child_vmar, child_addr), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t parent_vmar,
+ zx_vm_option_t options,
+ size_t offset,
+ size_t size,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* child_vmar,
+ zx_vaddr_t* child_addr))
+
+_ZX_SYSCALL_DECL(vmar_destroy, zx_status_t, /* no attributes */, 1,
+ (handle), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle))
+
+_ZX_SYSCALL_DECL(vmar_map, zx_status_t, /* no attributes */, 7,
+ (handle, options, vmar_offset, vmo, vmo_offset, len, mapped_addr), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_vm_option_t options,
+ size_t vmar_offset,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t vmo,
+ uint64_t vmo_offset,
+ size_t len,
+ zx_vaddr_t* mapped_addr))
+
+_ZX_SYSCALL_DECL(vmar_unmap, zx_status_t, /* no attributes */, 3,
+ (handle, addr, len), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_vaddr_t addr,
+ size_t len))
+
+_ZX_SYSCALL_DECL(vmar_protect, zx_status_t, /* no attributes */, 4,
+ (handle, options, addr, len), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_vm_option_t options,
+ zx_vaddr_t addr,
+ size_t len))
+
+_ZX_SYSCALL_DECL(vmar_op_range, zx_status_t, /* no attributes */, 6,
+ (handle, op, address, size, buffer, buffer_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t op,
+ zx_vaddr_t address,
+ size_t size,
+ void* buffer,
+ size_t buffer_size))
+
+_ZX_SYSCALL_DECL(vmo_create, zx_status_t, /* no attributes */, 3,
+ (size, options, out), (
+ uint64_t size,
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(vmo_read, zx_status_t, /* no attributes */, 4,
+ (handle, buffer, offset, buffer_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ void* buffer,
+ uint64_t offset,
+ size_t buffer_size))
+
+_ZX_SYSCALL_DECL(vmo_write, zx_status_t, /* no attributes */, 4,
+ (handle, buffer, offset, buffer_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ const void* buffer,
+ uint64_t offset,
+ size_t buffer_size))
+
+_ZX_SYSCALL_DECL(vmo_get_size, zx_status_t, /* no attributes */, 2,
+ (handle, size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint64_t* size))
+
+_ZX_SYSCALL_DECL(vmo_set_size, zx_status_t, /* no attributes */, 2,
+ (handle, size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint64_t size))
+
+_ZX_SYSCALL_DECL(vmo_op_range, zx_status_t, /* no attributes */, 6,
+ (handle, op, offset, size, buffer, buffer_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t op,
+ uint64_t offset,
+ uint64_t size,
+ void* buffer,
+ size_t buffer_size))
+
+_ZX_SYSCALL_DECL(vmo_create_child, zx_status_t, /* no attributes */, 5,
+ (handle, options, offset, size, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ uint64_t offset,
+ uint64_t size,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(vmo_set_cache_policy, zx_status_t, /* no attributes */, 2,
+ (handle, cache_policy), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t cache_policy))
+
+_ZX_SYSCALL_DECL(vmo_replace_as_executable, zx_status_t, /* no attributes */, 3,
+ (handle, vmex, out), (
+ _ZX_SYSCALL_ANNO(release_handle("Fuchsia")) zx_handle_t handle,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t vmex,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(vmo_create_contiguous, zx_status_t, /* no attributes */, 4,
+ (bti, size, alignment_log2, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t bti,
+ size_t size,
+ uint32_t alignment_log2,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(vmo_create_physical, zx_status_t, /* no attributes */, 4,
+ (resource, paddr, size, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t resource,
+ zx_paddr_t paddr,
+ size_t size,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/iommu.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/iommu.h
new file mode 100644
index 0000000..708b606
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/iommu.h
@@ -0,0 +1,97 @@
+// Copyright 2017 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_IOMMU_H_
+#define SYSROOT_ZIRCON_SYSCALLS_IOMMU_H_
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <zircon/compiler.h>
+
+__BEGIN_CDECLS
+
+#define ZX_IOMMU_MAX_DESC_LEN 4096
+
+// Values for the |type| argument of the zx_iommu_create() syscall.
+#define ZX_IOMMU_TYPE_DUMMY 0
+#define ZX_IOMMU_TYPE_INTEL 1
+
+// Data structures for creating a dummy IOMMU instance
+typedef struct zx_iommu_desc_dummy {
+ uint8_t reserved;
+} zx_iommu_desc_dummy_t;
+
+// Data structures for creating an Intel IOMMU instance
+
+// This scope represents a single PCI endpoint device
+#define ZX_IOMMU_INTEL_SCOPE_ENDPOINT 0
+// This scope represents a PCI-PCI bridge. The bridge and all of its downstream
+// devices will be included in this scope.
+#define ZX_IOMMU_INTEL_SCOPE_BRIDGE 1
+
+// TODO(teisenbe): Investigate FIDL for this. Multiple embedded lists seems
+// right up its alley.
+typedef struct zx_iommu_desc_intel_scope {
+ uint8_t type;
+ // The bus number of the first bus decoded by the host bridge this scope is attached to.
+ uint8_t start_bus;
+ // Number of bridges (including the host bridge) between host bridge and the
+ // device.
+ uint8_t num_hops;
+ // The device number and function numbers of the bridges along the way,
+ // ending with the device itself.
+ // |dev_func[0]| is the address on |start_bus| of the first bridge in the
+ // path (excluding the host bridge). |dev_func[num_hops-1]| is the address
+ // of the device itself.
+ uint8_t dev_func[5];
+} zx_iommu_desc_intel_scope_t;
+
+typedef struct zx_iommu_desc_intel_reserved_memory {
+ uint64_t base_addr; // Physical address of the base of reserved memory.
+ uint64_t len; // Number of bytes of reserved memory.
+
+ // The number of bytes of zx_iommu_desc_intel_scope_t's that follow this descriptor.
+ uint8_t scope_bytes;
+
+ uint8_t _reserved[7]; // Padding
+
+ // This is a list of all devices that need access to this memory range.
+ //
+ // zx_iommu_desc_intel_scope_t scopes[num_scopes];
+} zx_iommu_desc_intel_reserved_memory_t;
+
+typedef struct zx_iommu_desc_intel {
+ uint64_t register_base; // Physical address of registers
+ uint16_t pci_segment; // The PCI segment associated with this IOMMU
+
+ // If true, this IOMMU has all PCI devices in its segment under its scope.
+ // In this case, the list of scopes acts as a blacklist.
+ bool whole_segment;
+
+ // The number of bytes of zx_iommu_desc_intel_scope_t's that follow this descriptor.
+ uint8_t scope_bytes;
+
+ // The number of bytes of zx_iommu_desc_intel_reserved_memory_t's that follow the scope
+ // list.
+ uint16_t reserved_memory_bytes;
+
+ uint8_t _reserved[2]; // Padding
+
+ // If |whole_segment| is false, this is a list of all devices managed by
+ // this IOMMU. If |whole_segment| is true, this is a list of all devices on
+ // this segment *not* managed by this IOMMU. It has a total length in bytes of
+ // |scope_bytes|.
+ //
+ // zx_iommu_desc_intel_scope_t scopes[];
+
+ // A list of all BIOS-reserved memory regions this IOMMU needs to translate.
+ // It has a total length in bytes of |reserved_memory_bytes|.
+ //
+ // zx_iommu_desc_intel_reserved_memory_t reserved_mem[];
+} zx_iommu_desc_intel_t;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_IOMMU_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/log.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/log.h
new file mode 100644
index 0000000..0ea4c04
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/log.h
@@ -0,0 +1,58 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_LOG_H_
+#define SYSROOT_ZIRCON_SYSCALLS_LOG_H_
+
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// Defines and structures for zx_log_*()
+typedef struct zx_log_record {
+ uint32_t reserved;
+ uint16_t datalen;
+ uint16_t flags;
+ zx_time_t timestamp;
+ uint64_t pid;
+ uint64_t tid;
+ char data[];
+} zx_log_record_t;
+
+// ask clang format not to mess up the indentation:
+// clang-format off
+
+#define ZX_LOG_RECORD_MAX 256
+
+// Common Log Levels
+#define ZX_LOG_ERROR (0x0001)
+#define ZX_LOG_WARN (0x0002)
+#define ZX_LOG_INFO (0x0004)
+
+// Verbose log levels
+#define ZX_LOG_TRACE (0x0010)
+#define ZX_LOG_SPEW (0x0020)
+
+// Custom Log Levels
+#define ZX_LOG_DEBUG1 (0x0100)
+#define ZX_LOG_DEBUG2 (0x0200)
+#define ZX_LOG_DEBUG3 (0x0400)
+#define ZX_LOG_DEBUG4 (0x0800)
+
+// Filter Flags
+
+// Do not forward this message via network
+// (for logging in network core and drivers)
+#define ZX_LOG_LOCAL (0x1000)
+
+#define ZX_LOG_LEVEL_MASK (0x0FFF)
+#define ZX_LOG_FLAGS_MASK (0xFFFF)
+
+// Options
+
+#define ZX_LOG_FLAG_READABLE 0x40000000
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_LOG_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/object.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/object.h
new file mode 100644
index 0000000..7139ffe
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/object.h
@@ -0,0 +1,685 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_OBJECT_H_
+#define SYSROOT_ZIRCON_SYSCALLS_OBJECT_H_
+
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// ask clang format not to mess up the indentation:
+// clang-format off
+
+// Valid topics for zx_object_get_info.
+typedef uint32_t zx_object_info_topic_t;
+#define ZX_INFO_NONE ((zx_object_info_topic_t) 0u)
+#define ZX_INFO_HANDLE_VALID ((zx_object_info_topic_t) 1u)
+#define ZX_INFO_HANDLE_BASIC ((zx_object_info_topic_t) 2u) // zx_info_handle_basic_t[1]
+#define ZX_INFO_PROCESS ((zx_object_info_topic_t) 3u) // zx_info_process_t[1]
+#define ZX_INFO_PROCESS_THREADS ((zx_object_info_topic_t) 4u) // zx_koid_t[n]
+#define ZX_INFO_VMAR ((zx_object_info_topic_t) 7u) // zx_info_vmar_t[1]
+#define ZX_INFO_JOB_CHILDREN ((zx_object_info_topic_t) 8u) // zx_koid_t[n]
+#define ZX_INFO_JOB_PROCESSES ((zx_object_info_topic_t) 9u) // zx_koid_t[n]
+#define ZX_INFO_THREAD ((zx_object_info_topic_t) 10u) // zx_info_thread_t[1]
+#define ZX_INFO_THREAD_EXCEPTION_REPORT ((zx_object_info_topic_t) 11u) // zx_exception_report_t[1]
+#define ZX_INFO_TASK_STATS ((zx_object_info_topic_t) 12u) // zx_info_task_stats_t[1]
+#define ZX_INFO_PROCESS_MAPS ((zx_object_info_topic_t) 13u) // zx_info_maps_t[n]
+#define ZX_INFO_PROCESS_VMOS ((zx_object_info_topic_t) 14u) // zx_info_vmo_t[n]
+#define ZX_INFO_THREAD_STATS ((zx_object_info_topic_t) 15u) // zx_info_thread_stats_t[1]
+#define ZX_INFO_CPU_STATS ((zx_object_info_topic_t) 16u) // zx_info_cpu_stats_t[n]
+#define ZX_INFO_KMEM_STATS ((zx_object_info_topic_t) 17u) // zx_info_kmem_stats_t[1]
+#define ZX_INFO_RESOURCE ((zx_object_info_topic_t) 18u) // zx_info_resource_t[1]
+#define ZX_INFO_HANDLE_COUNT ((zx_object_info_topic_t) 19u) // zx_info_handle_count_t[1]
+#define ZX_INFO_BTI ((zx_object_info_topic_t) 20u) // zx_info_bti_t[1]
+#define ZX_INFO_PROCESS_HANDLE_STATS ((zx_object_info_topic_t) 21u) // zx_info_process_handle_stats_t[1]
+#define ZX_INFO_SOCKET ((zx_object_info_topic_t) 22u) // zx_info_socket_t[1]
+#define ZX_INFO_VMO ((zx_object_info_topic_t) 23u) // zx_info_vmo_t[1]
+#define ZX_INFO_JOB ((zx_object_info_topic_t) 24u) // zx_info_job_t[1]
+#define ZX_INFO_TIMER ((zx_object_info_topic_t) 25u) // zx_info_timer_t[1]
+#define ZX_INFO_STREAM ((zx_object_info_topic_t) 26u) // zx_info_stream_t[1]
+#define ZX_INFO_HANDLE_TABLE ((zx_object_info_topic_t) 27u) // zx_info_handle_extended_t[n]
+#define ZX_INFO_MSI ((zx_object_info_topic_t) 28u) // zx_info_msi_t[1]
+#define ZX_INFO_GUEST_STATS ((zx_object_info_topic_t) 29u) // zx_info_guest_stats_t[1]
+
+typedef uint32_t zx_obj_props_t;
+#define ZX_OBJ_PROP_NONE ((zx_obj_props_t) 0u)
+#define ZX_OBJ_PROP_WAITABLE ((zx_obj_props_t) 1u)
+
+// Return codes set when a task is killed.
+#define ZX_TASK_RETCODE_SYSCALL_KILL ((int64_t) -1024) // via zx_task_kill().
+#define ZX_TASK_RETCODE_OOM_KILL ((int64_t) -1025) // by the OOM killer.
+#define ZX_TASK_RETCODE_POLICY_KILL ((int64_t) -1026) // by the Job policy.
+#define ZX_TASK_RETCODE_VDSO_KILL ((int64_t) -1027) // by the VDSO.
+#define ZX_TASK_RETCODE_EXCEPTION_KILL ((int64_t) -1028) // Exception not handled.
+#define ZX_TASK_RETCODE_CRITICAL_PROCESS_KILL ((int64_t) -1029) // by a critical process.
+
+// Sentinel indicating an invalid or missing CPU.
+#define ZX_INFO_INVALID_CPU ((uint32_t)0xFFFFFFFFu)
+
+
+typedef struct zx_info_handle_basic {
+ // The unique id assigned by kernel to the object referenced by the
+ // handle.
+ zx_koid_t koid;
+
+ // The immutable rights assigned to the handle. Two handles that
+ // have the same koid and the same rights are equivalent and
+ // interchangeable.
+ zx_rights_t rights;
+
+ // The object type: channel, event, socket, etc.
+ zx_obj_type_t type;
+
+ // If the object referenced by the handle is related to another (such
+ // as the other end of a channel, or the parent of a job) then
+ // |related_koid| is the koid of that object, otherwise it is zero.
+ // This relationship is immutable: an object's |related_koid| does
+ // not change even if the related object no longer exists.
+ zx_koid_t related_koid;
+
+ // Set to ZX_OBJ_PROP_WAITABLE if the object referenced by the
+ // handle can be waited on; zero otherwise.
+ zx_obj_props_t props;
+
+ uint8_t padding1[4];
+} zx_info_handle_basic_t;
+
+typedef struct zx_info_handle_extended {
+ // The object type: channel, event, socket, etc.
+ zx_obj_type_t type;
+
+ // The handle value which is only valid for the process which
+ // was passed to ZX_INFO_HANDLE_TABLE.
+ zx_handle_t handle_value;
+
+ // The immutable rights assigned to the handle. Two handles that
+ // have the same koid and the same rights are equivalent and
+ // interchangeable.
+ zx_rights_t rights;
+
+ // Set to ZX_OBJ_PROP_WAITABLE if the object referenced by the
+ // handle can be waited on; zero otherwise.
+ zx_obj_props_t props;
+
+ // The unique id assigned by kernel to the object referenced by the
+ // handle.
+ zx_koid_t koid;
+
+ // If the object referenced by the handle is related to another (such
+ // as the other end of a channel, or the parent of a job) then
+ // |related_koid| is the koid of that object, otherwise it is zero.
+ // This relationship is immutable: an object's |related_koid| does
+ // not change even if the related object no longer exists.
+ zx_koid_t related_koid;
+
+ // If the object referenced by the handle has a peer, like the
+ // other end of a channel, then this is the koid of the process
+ // which currently owns it. This value is not stable; the process
+ // can change the owner at any moment.
+ //
+ // This is currently unimplemented and contains 0.
+ zx_koid_t peer_owner_koid;
+} zx_info_handle_extended_t;
+
+typedef struct zx_info_handle_count {
+ // The number of outstanding handles to a kernel object.
+ uint32_t handle_count;
+} zx_info_handle_count_t;
+
+typedef struct zx_info_process_handle_stats {
+ // The number of outstanding handles to kernel objects of each type.
+ uint32_t handle_count[ZX_OBJ_TYPE_UPPER_BOUND];
+} zx_info_process_handle_stats_t;
+
+typedef struct zx_info_process {
+ // The process's return code; only valid if |exited| is true.
+ // If the process was killed, it will be one of the ZX_TASK_RETCODE values.
+ int64_t return_code;
+
+ // True if the process has ever left the initial creation state,
+ // even if it has exited as well.
+ bool started;
+
+ // If true, the process has exited and |return_code| is valid.
+ bool exited;
+
+ // True if a debugger is attached to the process.
+ bool debugger_attached;
+
+ uint8_t padding1[5];
+} zx_info_process_t;
+
+typedef struct zx_info_job {
+ // The job's return code; only valid if |exited| is true.
+ // If the process was killed, it will be one of the ZX_TASK_RETCODE values.
+ int64_t return_code;
+
+ // If true, the job has exited and |return_code| is valid.
+ bool exited;
+
+ // True if the ZX_PROP_JOB_KILL_ON_OOM was set.
+ bool kill_on_oom;
+
+ // True if a debugger is attached to the job.
+ bool debugger_attached;
+
+ uint8_t padding1[5];
+} zx_info_job_t;
+
+typedef struct zx_info_timer {
+ // The options passed to zx_timer_create().
+ uint32_t options;
+
+ uint8_t padding1[4];
+
+ // The deadline with respect to ZX_CLOCK_MONOTONIC at which the timer will
+ // fire next.
+ //
+ // This value will be zero if the timer is not set to fire.
+ zx_time_t deadline;
+
+ // Specifies a range from deadline - slack to deadline + slack during which
+ // the timer is allowed to fire. The system uses this parameter as a hint to
+ // coalesce nearby timers.
+ //
+ // The precise coalescing behavior is controlled by the options parameter
+ // specified when the timer was created.
+ //
+ // This value will be zero if the timer is not set to fire.
+ zx_duration_t slack;
+} zx_info_timer_t;
+
+typedef struct zx_info_stream {
+ // The options passed to zx_stream_create().
+ uint32_t options;
+
+ uint8_t padding1[4];
+
+ // The current seek offset.
+ //
+ // Used by zx_stream_readv and zx_stream_writev to determine where to read
+ // and write the stream.
+ zx_off_t seek;
+
+ // The current size of the stream.
+ //
+ // The number of bytes in the stream that store data. The stream itself
+ // might have a larger capacity to avoid reallocating the underlying storage
+ // as the stream grows or shrinks.
+ uint64_t content_size;
+} zx_info_stream_t;
+
+typedef uint32_t zx_thread_state_t;
+
+typedef struct zx_info_thread {
+ // One of ZX_THREAD_STATE_* values.
+ zx_thread_state_t state;
+
+ // If |state| is ZX_THREAD_STATE_BLOCKED_EXCEPTION, the thread has gotten
+ // an exception and is waiting for the exception response from the specified
+ // handler.
+
+ // The value is one of ZX_EXCEPTION_CHANNEL_TYPE_*.
+ uint32_t wait_exception_channel_type;
+
+ // CPUs this thread may be scheduled on, as specified by
+ // a profile object applied to this thread.
+ //
+ // The kernel may not internally store invalid CPUs in the mask, so
+ // this may not exactly match the mask applied to the thread for
+ // CPUs beyond what the system is able to use.
+ zx_cpu_set_t cpu_affinity_mask;
+} zx_info_thread_t;
+
+typedef struct zx_info_thread_stats {
+ // Total accumulated running time of the thread.
+ zx_duration_t total_runtime;
+
+ // CPU number that this thread was last scheduled on, or ZX_INFO_INVALID_CPU
+ // if the thread has never been scheduled on a CPU. By the time this call
+ // returns, the thread may have been scheduled elsewhere, so this
+ // information should only be used as a hint or for statistics.
+ uint32_t last_scheduled_cpu;
+
+ uint8_t padding1[4];
+} zx_info_thread_stats_t;
+
+// Statistics about resources (e.g., memory) used by a task. Can be relatively
+// expensive to gather.
+typedef struct zx_info_task_stats {
+ // The total size of mapped memory ranges in the task.
+ // Not all will be backed by physical memory.
+ size_t mem_mapped_bytes;
+
+ // For the fields below, a byte is considered committed if it's backed by
+ // physical memory. Some of the memory may be double-mapped, and thus
+ // double-counted.
+
+ // Committed memory that is only mapped into this task.
+ size_t mem_private_bytes;
+
+ // Committed memory that is mapped into this and at least one other task.
+ size_t mem_shared_bytes;
+
+ // A number that estimates the fraction of mem_shared_bytes that this
+ // task is responsible for keeping alive.
+ //
+ // An estimate of:
+ // For each shared, committed byte:
+ // mem_scaled_shared_bytes += 1 / (number of tasks mapping this byte)
+ //
+ // This number is strictly smaller than mem_shared_bytes.
+ size_t mem_scaled_shared_bytes;
+} zx_info_task_stats_t;
+
+typedef struct zx_info_vmar {
+ // Base address of the region.
+ uintptr_t base;
+
+ // Length of the region, in bytes.
+ size_t len;
+} zx_info_vmar_t;
+
+typedef struct zx_info_bti {
+ // zx_bti_pin will always be able to return addresses that are contiguous for at
+ // least this many bytes. E.g. if this returns 1MB, then a call to
+ // zx_bti_pin() with a size of 2MB will return at most two physically-contiguous runs.
+ // If the size were 2.5MB, it will return at most three physically-contiguous runs.
+ uint64_t minimum_contiguity;
+
+ // The number of bytes in the device's address space (UINT64_MAX if 2^64).
+ uint64_t aspace_size;
+
+ // The count of the pinned memory object tokens. Requesting this count is
+ // racy, so this should only be used for informative reasons.
+ uint64_t pmo_count;
+
+ // The count of the quarantined pinned memory object tokens. Requesting this count is
+ // racy, so this should only be used for informative reasons.
+ uint64_t quarantine_count;
+} zx_info_bti_t;
+
+typedef struct zx_info_socket {
+ // The options passed to zx_socket_create().
+ uint32_t options;
+
+ uint8_t padding1[4];
+
+ // The maximum size of the receive buffer of a socket, in bytes.
+ //
+ // The receive buffer may become full at a capacity less than the maximum
+ // due to overhead.
+ size_t rx_buf_max;
+
+ // The size of the receive buffer of a socket, in bytes.
+ size_t rx_buf_size;
+
+ // The amount of data, in bytes, that is available for reading in a single
+ // zx_socket_read call.
+ //
+ // For stream sockets, this value will match |rx_buf_size|. For datagram
+ // sockets, this value will be the size of the next datagram in the receive
+ // buffer.
+ size_t rx_buf_available;
+
+ // The maximum size of the transmit buffer of a socket, in bytes.
+ //
+ // The transmit buffer may become full at a capacity less than the maximum
+ // due to overhead.
+ //
+ // Will be zero if the peer endpoint is closed.
+ size_t tx_buf_max;
+
+ // The size of the transmit buffer of a socket, in bytes.
+ //
+ // Will be zero if the peer endpoint is closed.
+ size_t tx_buf_size;
+} zx_info_socket_t;
+
+// Types and values used by ZX_INFO_PROCESS_MAPS.
+
+// Describes a VM mapping.
+typedef struct zx_info_maps_mapping {
+ // MMU flags for the mapping.
+ // Bitwise OR of ZX_VM_PERM_{READ,WRITE,EXECUTE} values.
+ zx_vm_option_t mmu_flags;
+ uint8_t padding1[4];
+ // koid of the mapped VMO.
+ zx_koid_t vmo_koid;
+ // Offset into the above VMO.
+ uint64_t vmo_offset;
+ // The number of PAGE_SIZE pages in the mapped region of the VMO
+ // that are backed by physical memory.
+ size_t committed_pages;
+} zx_info_maps_mapping_t;
+
+// Types of entries represented by zx_info_maps_t.
+// Can't use zx_obj_type_t because not all of these are
+// user-visible kernel object types.
+typedef uint32_t zx_info_maps_type_t;
+#define ZX_INFO_MAPS_TYPE_NONE ((zx_info_maps_type_t) 0u)
+#define ZX_INFO_MAPS_TYPE_ASPACE ((zx_info_maps_type_t) 1u)
+#define ZX_INFO_MAPS_TYPE_VMAR ((zx_info_maps_type_t) 2u)
+#define ZX_INFO_MAPS_TYPE_MAPPING ((zx_info_maps_type_t) 3u)
+
+// Describes a node in the aspace/vmar/mapping hierarchy for a user process.
+typedef struct zx_info_maps {
+ // Name if available; empty string otherwise.
+ char name[ZX_MAX_NAME_LEN];
+ // Base address.
+ zx_vaddr_t base;
+ // Size in bytes.
+ size_t size;
+
+ // The depth of this node in the tree.
+ // Can be used for indentation, or to rebuild the tree from an array
+ // of zx_info_maps_t entries, which will be in depth-first pre-order.
+ size_t depth;
+ // The type of this entry; indicates which union entry is valid.
+ zx_info_maps_type_t type;
+ uint8_t padding1[4];
+ union {
+ zx_info_maps_mapping_t mapping;
+ // No additional fields for other types.
+ } u;
+} zx_info_maps_t;
+
+
+// Values and types used by ZX_INFO_PROCESS_VMOS.
+
+// The VMO is backed by RAM, consuming memory.
+// Mutually exclusive with ZX_INFO_VMO_TYPE_PHYSICAL.
+// See ZX_INFO_VMO_TYPE(flags)
+#define ZX_INFO_VMO_TYPE_PAGED (1u<<0)
+
+// The VMO points to a physical address range, and does not consume memory.
+// Typically used to access memory-mapped hardware.
+// Mutually exclusive with ZX_INFO_VMO_TYPE_PAGED.
+// See ZX_INFO_VMO_TYPE(flags)
+#define ZX_INFO_VMO_TYPE_PHYSICAL (0u<<0)
+
+// Returns a VMO's type based on its flags, allowing for checks like
+// if (ZX_INFO_VMO_TYPE(f) == ZX_INFO_VMO_TYPE_PAGED)
+#define ZX_INFO_VMO_TYPE(flags) ((flags) & (1u<<0))
+
+// The VMO is resizable.
+#define ZX_INFO_VMO_RESIZABLE (1u<<1)
+
+// The VMO is a child, and is a copy-on-write clone.
+#define ZX_INFO_VMO_IS_COW_CLONE (1u<<2)
+
+// When reading a list of VMOs pointed to by a process, indicates that the
+// process has a handle to the VMO, which isn't necessarily mapped.
+#define ZX_INFO_VMO_VIA_HANDLE (1u<<3)
+
+// When reading a list of VMOs pointed to by a process, indicates that the
+// process maps the VMO into a VMAR, but doesn't necessarily have a handle to
+// the VMO.
+#define ZX_INFO_VMO_VIA_MAPPING (1u<<4)
+
+// The VMO is a pager owned VMO created by zx_pager_create_vmo or is
+// a clone of a VMO with this flag set. Will only be set on VMOs with
+// the ZX_INFO_VMO_TYPE_PAGED flag set.
+#define ZX_INFO_VMO_PAGER_BACKED (1u<<5)
+
+// The VMO is contiguous
+#define ZX_INFO_VMO_CONTIGUOUS (1u<<6)
+
+// Describes a VMO. For mapping information, see |zx_info_maps_t|.
+typedef struct zx_info_vmo {
+ // The koid of this VMO.
+ zx_koid_t koid;
+
+ // The name of this VMO.
+ char name[ZX_MAX_NAME_LEN];
+
+ // The size of this VMO; i.e., the amount of virtual address space it
+ // would consume if mapped.
+ uint64_t size_bytes;
+
+ // If this VMO is a clone, the koid of its parent. Otherwise, zero.
+ // See |flags| for the type of clone.
+ zx_koid_t parent_koid;
+
+ // The number of clones of this VMO, if any.
+ size_t num_children;
+
+ // The number of times this VMO is currently mapped into VMARs.
+ // Note that the same process will often map the same VMO twice,
+ // and both mappings will be counted here. (I.e., this is not a count
+ // of the number of processes that map this VMO; see share_count.)
+ size_t num_mappings;
+
+ // An estimate of the number of unique address spaces that
+ // this VMO is mapped into. Every process has its own address space,
+ // and so does the kernel.
+ size_t share_count;
+
+ // Bitwise OR of ZX_INFO_VMO_* values.
+ uint32_t flags;
+
+ uint8_t padding1[4];
+
+ // If |ZX_INFO_VMO_TYPE(flags) == ZX_INFO_VMO_TYPE_PAGED|, the amount of
+ // memory currently allocated to this VMO; i.e., the amount of physical
+ // memory it consumes. Undefined otherwise.
+ uint64_t committed_bytes;
+
+ // If |flags & ZX_INFO_VMO_VIA_HANDLE|, the handle rights.
+ // Undefined otherwise.
+ zx_rights_t handle_rights;
+
+ // VMO mapping cache policy. One of ZX_CACHE_POLICY_*
+ uint32_t cache_policy;
+} zx_info_vmo_t;
+
+typedef struct zx_info_guest_stats {
+ uint32_t cpu_number;
+ uint32_t flags;
+
+ uint64_t vm_entries;
+ uint64_t vm_exits;
+#ifdef __aarch64__
+ uint64_t wfi_wfe_instructions;
+ uint64_t instruction_aborts;
+ uint64_t data_aborts;
+ uint64_t system_instructions;
+ uint64_t smc_instructions;
+ uint64_t interrupts;
+#else
+ uint64_t interrupts;
+ uint64_t interrupt_windows;
+ uint64_t cpuid_instructions;
+ uint64_t hlt_instructions;
+ uint64_t control_register_accesses;
+ uint64_t io_instructions;
+ uint64_t rdmsr_instructions;
+ uint64_t wrmsr_instructions;
+ uint64_t ept_violations;
+ uint64_t xsetbv_instructions;
+ uint64_t pause_instructions;
+ uint64_t vmcall_instructions;
+#endif
+} zx_info_guest_stats_t;
+
+// kernel statistics per cpu
+// TODO(cpu), expose the deprecated stats via a new syscall.
+typedef struct zx_info_cpu_stats {
+ uint32_t cpu_number;
+ uint32_t flags;
+
+ zx_duration_t idle_time;
+
+ // kernel scheduler counters
+ uint64_t reschedules;
+ uint64_t context_switches;
+ uint64_t irq_preempts;
+ uint64_t preempts;
+ uint64_t yields;
+
+ // cpu level interrupts and exceptions
+ uint64_t ints; // hardware interrupts, minus timer interrupts or inter-processor interrupts
+ uint64_t timer_ints; // timer interrupts
+ uint64_t timers; // timer callbacks
+ uint64_t page_faults; // (deprecated, returns 0) page faults
+ uint64_t exceptions; // (deprecated, returns 0) exceptions such as undefined opcode
+ uint64_t syscalls;
+
+ // inter-processor interrupts
+ uint64_t reschedule_ipis;
+ uint64_t generic_ipis;
+} zx_info_cpu_stats_t;
+
+// Information about kernel memory usage.
+// Can be expensive to gather.
+typedef struct zx_info_kmem_stats {
+ // The total amount of physical memory available to the system.
+ uint64_t total_bytes;
+
+ // The amount of unallocated memory.
+ uint64_t free_bytes;
+
+ // The amount of memory reserved by and mapped into the kernel for reasons
+ // not covered by other fields in this struct. Typically for readonly data
+ // like the ram disk and kernel image, and for early-boot dynamic memory.
+ uint64_t wired_bytes;
+
+ // The amount of memory allocated to the kernel heap.
+ uint64_t total_heap_bytes;
+
+ // The portion of |total_heap_bytes| that is not in use.
+ uint64_t free_heap_bytes;
+
+ // The amount of memory committed to VMOs, both kernel and user.
+ // A superset of all userspace memory.
+ // Does not include certain VMOs that fall under |wired_bytes|.
+ //
+ // TODO(dbort): Break this into at least two pieces: userspace VMOs that
+ // have koids, and kernel VMOs that don't. Or maybe look at VMOs
+ // mapped into the kernel aspace vs. everything else.
+ uint64_t vmo_bytes;
+
+ // The amount of memory used for architecture-specific MMU metadata
+ // like page tables.
+ uint64_t mmu_overhead_bytes;
+
+ // The amount of memory in use by IPC.
+ uint64_t ipc_bytes;
+
+ // Non-free memory that isn't accounted for in any other field.
+ uint64_t other_bytes;
+} zx_info_kmem_stats_t;
+
+typedef struct zx_info_resource {
+ // The resource kind; resource object kinds are detailed in the resource.md
+ uint32_t kind;
+ // Resource's creation flags
+ uint32_t flags;
+ // Resource's base value (inclusive)
+ uint64_t base;
+ // Resource's length value
+ size_t size;
+ char name[ZX_MAX_NAME_LEN];
+} zx_info_resource_t;
+
+typedef struct zx_info_msi {
+ // The target adress for write transactions.
+ uint64_t target_addr;
+ // The data that the device ill write when triggering an IRQ.
+ uint32_t target_data;
+ // The first IRQ in the allocated block.
+ uint32_t base_irq_id;
+ // The number of IRQs in the allocated block.
+ uint32_t num_irq;
+} zx_info_msi_t;
+
+
+#define ZX_INFO_CPU_STATS_FLAG_ONLINE (1u<<0)
+
+// Object properties.
+
+// Argument is a char[ZX_MAX_NAME_LEN].
+#define ZX_PROP_NAME ((uint32_t) 3u)
+
+#if __x86_64__
+// Argument is a uintptr_t.
+#define ZX_PROP_REGISTER_GS ((uint32_t) 2u)
+#define ZX_PROP_REGISTER_FS ((uint32_t) 4u)
+#endif
+
+// Argument is the value of ld.so's _dl_debug_addr, a uintptr_t. If the
+// property is set to the magic value of ZX_PROCESS_DEBUG_ADDR_BREAK_ON_SET
+// on process startup, ld.so will trigger a debug breakpoint immediately after
+// setting the property to the correct value.
+#define ZX_PROP_PROCESS_DEBUG_ADDR ((uint32_t) 5u)
+#define ZX_PROCESS_DEBUG_ADDR_BREAK_ON_SET ((uintptr_t) 1u)
+
+// Argument is the base address of the vDSO mapping (or zero), a uintptr_t.
+#define ZX_PROP_PROCESS_VDSO_BASE_ADDRESS ((uint32_t) 6u)
+
+// Whether the dynamic loader should issue a debug trap when loading a shared library,
+// either initially or when running (e.g. dlopen).
+//
+// See docs/reference/syscalls/object_get_property.md
+// See third_party/ulib/musl/ldso/dynlink.c.
+#define ZX_PROP_PROCESS_BREAK_ON_LOAD ((uint32_t) 7u)
+
+// The process's context id as recorded by h/w instruction tracing, a uintptr_t.
+// On X86 this is the cr3 value.
+// TODO(dje): Wasn't sure whether the gaps in property numbers are unusable
+// due to being old dleeted values. For now I just picked something.
+#define ZX_PROP_PROCESS_HW_TRACE_CONTEXT_ID ((uint32_t) 8u)
+
+// Argument is a size_t.
+#define ZX_PROP_SOCKET_RX_THRESHOLD 12u
+#define ZX_PROP_SOCKET_TX_THRESHOLD 13u
+
+// Terminate this job if the system is low on memory.
+#define ZX_PROP_JOB_KILL_ON_OOM 15u
+
+// Exception close behavior.
+#define ZX_PROP_EXCEPTION_STATE 16u
+
+// The size of the content in a VMO, in bytes.
+//
+// The content size of a VMO can be larger or smaller than the actual size of
+// the VMO.
+//
+// Argument is a uint64_t.
+#define ZX_PROP_VMO_CONTENT_SIZE 17u
+
+// Basic thread states, in zx_info_thread_t.state.
+#define ZX_THREAD_STATE_NEW ((zx_thread_state_t) 0x0000u)
+#define ZX_THREAD_STATE_RUNNING ((zx_thread_state_t) 0x0001u)
+#define ZX_THREAD_STATE_SUSPENDED ((zx_thread_state_t) 0x0002u)
+// ZX_THREAD_STATE_BLOCKED is never returned by itself.
+// It is always returned with a more precise reason.
+// See ZX_THREAD_STATE_BLOCKED_* below.
+#define ZX_THREAD_STATE_BLOCKED ((zx_thread_state_t) 0x0003u)
+#define ZX_THREAD_STATE_DYING ((zx_thread_state_t) 0x0004u)
+#define ZX_THREAD_STATE_DEAD ((zx_thread_state_t) 0x0005u)
+
+// More precise thread states.
+#define ZX_THREAD_STATE_BLOCKED_EXCEPTION ((zx_thread_state_t) 0x0103u)
+#define ZX_THREAD_STATE_BLOCKED_SLEEPING ((zx_thread_state_t) 0x0203u)
+#define ZX_THREAD_STATE_BLOCKED_FUTEX ((zx_thread_state_t) 0x0303u)
+#define ZX_THREAD_STATE_BLOCKED_PORT ((zx_thread_state_t) 0x0403u)
+#define ZX_THREAD_STATE_BLOCKED_CHANNEL ((zx_thread_state_t) 0x0503u)
+#define ZX_THREAD_STATE_BLOCKED_WAIT_ONE ((zx_thread_state_t) 0x0603u)
+#define ZX_THREAD_STATE_BLOCKED_WAIT_MANY ((zx_thread_state_t) 0x0703u)
+#define ZX_THREAD_STATE_BLOCKED_INTERRUPT ((zx_thread_state_t) 0x0803u)
+#define ZX_THREAD_STATE_BLOCKED_PAGER ((zx_thread_state_t) 0x0903u)
+
+// Reduce possibly-more-precise state to a basic state.
+// Useful if, for example, you want to check for BLOCKED on anything.
+#define ZX_THREAD_STATE_BASIC(n) ((n) & 0xff)
+
+// How a thread should behave when the current exception is closed.
+#define ZX_EXCEPTION_STATE_TRY_NEXT 0u
+#define ZX_EXCEPTION_STATE_HANDLED 1u
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_OBJECT_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/pci.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/pci.h
new file mode 100644
index 0000000..d1049c2
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/pci.h
@@ -0,0 +1,134 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_PCI_H_
+#define SYSROOT_ZIRCON_SYSCALLS_PCI_H_
+
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// ask clang format not to mess up the indentation:
+// clang-format off
+
+
+// Base Address Registers are accessed in userspace via the get_bar protocol method. The
+// Bar is represented via a pci_bar_t struct which contains a handle pointer to a VMO
+// in the case of an MMIO bar, as well as a PIO addr/size pair for the memory region
+// to access if a PIO bar. In the latter case, the protocol will acquire the appropriate
+// permissions for the process to write to that PIO region on that architecture.
+typedef uint32_t zx_pci_bar_types_t;
+#define ZX_PCI_BAR_TYPE_UNUSED ((zx_pci_bar_types_t) 0u)
+#define ZX_PCI_BAR_TYPE_MMIO ((zx_pci_bar_types_t) 1u)
+#define ZX_PCI_BAR_TYPE_PIO ((zx_pci_bar_types_t) 2u)
+
+// TODO(cja): This makes some assumptions that anything in an arch's PIO region
+// is going to be defined as a base address and size. This will need to be
+// updated to a per-platform structure in the event that doesn't pan out
+// in the future.
+typedef struct zx_pci_bar {
+ uint32_t id;
+ uint32_t type;
+ size_t size;
+ union {
+ uintptr_t addr;
+ struct {
+ zx_handle_t handle;
+ uint8_t padding1[4];
+ };
+ };
+} zx_pci_bar_t;
+
+// Defines and structures related to zx_pci_*()
+// Info returned to dev manager for PCIe devices when probing.
+typedef struct zx_pcie_device_info {
+ uint16_t vendor_id;
+ uint16_t device_id;
+
+ uint8_t base_class;
+ uint8_t sub_class;
+ uint8_t program_interface;
+ uint8_t revision_id;
+
+ uint8_t bus_id;
+ uint8_t dev_id;
+ uint8_t func_id;
+
+ uint8_t padding1;
+} zx_pcie_device_info_t;
+
+#define ZX_PCI_MAX_BUSSES (256u)
+#define ZX_PCI_MAX_DEVICES_PER_BUS (32u)
+#define ZX_PCI_MAX_FUNCTIONS_PER_DEVICE (8u)
+#define ZX_PCI_MAX_FUNCTIONS_PER_BUS (ZX_PCI_MAX_DEVICES_PER_BUS * ZX_PCI_MAX_FUNCTIONS_PER_DEVICE)
+
+#define ZX_PCI_MAX_LEGACY_IRQ_PINS (4u)
+#define ZX_PCI_MAX_MSI_IRQS (32u)
+#define ZX_PCI_MAX_MSIX_IRQS (2048u)
+
+#define ZX_PCI_STANDARD_CONFIG_HDR_SIZE (64u)
+#define ZX_PCI_BASE_CONFIG_SIZE (256u)
+#define ZX_PCI_EXTENDED_CONFIG_SIZE (4096u)
+#define ZX_PCI_ECAM_BYTE_PER_BUS (ZX_PCI_EXTENDED_CONFIG_SIZE * ZX_PCI_MAX_FUNCTIONS_PER_BUS)
+
+#define ZX_PCI_BAR_REGS_PER_BRIDGE (2u)
+#define ZX_PCI_BAR_REGS_PER_DEVICE (6u)
+#define ZX_PCI_MAX_BAR_REGS (6u)
+
+#define ZX_PCI_NO_IRQ_MAPPING UINT32_MAX
+
+// Used for zx_pci_init_arg_t::addr_windows::cfg_space_type
+#define PCI_CFG_SPACE_TYPE_PIO (0u)
+#define PCI_CFG_SPACE_TYPE_MMIO (1u)
+#define PCI_CFG_SPACE_TYPE_DW_ROOT (2u) // Designware Root Bridge ECAM
+#define PCI_CFG_SPACE_TYPE_DW_DS (3u) // Designware Downstream ECAM
+
+// Dimensions: device id, function id, legacy pin number
+// ZX_PCI_NO_IRQ_MAPPING if no mapping specified.
+typedef uint32_t zx_pci_irq_swizzle_lut_t[ZX_PCI_MAX_DEVICES_PER_BUS]
+ [ZX_PCI_MAX_FUNCTIONS_PER_DEVICE]
+ [ZX_PCI_MAX_LEGACY_IRQ_PINS];
+
+// We support up to 224 IRQs on a system, this is the maximum supported by
+// LAPICs (today) so this should be a safe number.
+#define ZX_PCI_MAX_IRQS 224
+
+typedef struct zx_pci_init_arg {
+ zx_pci_irq_swizzle_lut_t dev_pin_to_global_irq;
+
+ uint32_t num_irqs;
+ struct {
+ uint32_t global_irq;
+ bool level_triggered;
+ bool active_high;
+ uint8_t padding1[2];
+ } irqs[ZX_PCI_MAX_IRQS];
+
+ uint32_t addr_window_count;
+ struct {
+ uint64_t base;
+ size_t size;
+ uint8_t bus_start;
+ uint8_t bus_end;
+ uint8_t cfg_space_type;
+ bool has_ecam;
+ uint8_t padding1[4];
+ } addr_windows[];
+} zx_pci_init_arg_t;
+
+#define ZX_PCI_INIT_ARG_MAX_ECAM_WINDOWS 2
+#define ZX_PCI_INIT_ARG_MAX_SIZE (sizeof(((zx_pci_init_arg_t*)NULL)->addr_windows[0]) * \
+ ZX_PCI_INIT_ARG_MAX_ECAM_WINDOWS + \
+ sizeof(zx_pci_init_arg_t))
+
+// Enum used to select PCIe IRQ modes
+typedef uint32_t zx_pci_irq_mode_t;
+#define ZX_PCIE_IRQ_MODE_DISABLED ((zx_pci_irq_mode_t) 0u)
+#define ZX_PCIE_IRQ_MODE_LEGACY ((zx_pci_irq_mode_t) 1u)
+#define ZX_PCIE_IRQ_MODE_MSI ((zx_pci_irq_mode_t) 2u)
+#define ZX_PCIE_IRQ_MODE_MSI_X ((zx_pci_irq_mode_t) 3u)
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_PCI_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/policy.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/policy.h
new file mode 100644
index 0000000..158c604
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/policy.h
@@ -0,0 +1,89 @@
+// Copyright 2017 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_POLICY_H_
+#define SYSROOT_ZIRCON_SYSCALLS_POLICY_H_
+
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// ask clang format not to mess up the indentation:
+// clang-format off
+
+// Policy is applied for the conditions that are not
+// specified by the parent job policy.
+#define ZX_JOB_POL_RELATIVE 0u
+// Policy is either applied as-is or the syscall fails.
+#define ZX_JOB_POL_ABSOLUTE 1u
+
+// Basic policy topic.
+#define ZX_JOB_POL_BASIC_V1 0u
+#define ZX_JOB_POL_BASIC_V2 0x01000000u
+
+// Timer slack policy topic.
+#define ZX_JOB_POL_TIMER_SLACK 1u
+
+// Input structure to use with ZX_JOB_POL_BASIC_V1.
+typedef struct zx_policy_basic_v1 {
+ uint32_t condition;
+ uint32_t policy;
+} zx_policy_basic_v1_t;
+
+// Input structure to use with ZX_JOB_POL_BASIC_V2.
+typedef struct zx_policy_basic_v2 {
+ uint32_t condition;
+ uint32_t action;
+ uint32_t flags;
+} zx_policy_basic_v2_t;
+
+#define ZX_JOB_POL_BASIC ZX_JOB_POL_BASIC_V1
+typedef struct zx_policy_basic_v1 zx_policy_basic;
+typedef struct zx_policy_basic_v1 zx_policy_basic_t;
+
+// Conditions handled by job policy.
+#define ZX_POL_BAD_HANDLE 0u
+#define ZX_POL_WRONG_OBJECT 1u
+#define ZX_POL_VMAR_WX 2u
+#define ZX_POL_NEW_ANY 3u
+#define ZX_POL_NEW_VMO 4u
+#define ZX_POL_NEW_CHANNEL 5u
+#define ZX_POL_NEW_EVENT 6u
+#define ZX_POL_NEW_EVENTPAIR 7u
+#define ZX_POL_NEW_PORT 8u
+#define ZX_POL_NEW_SOCKET 9u
+#define ZX_POL_NEW_FIFO 10u
+#define ZX_POL_NEW_TIMER 11u
+#define ZX_POL_NEW_PROCESS 12u
+#define ZX_POL_NEW_PROFILE 13u
+#define ZX_POL_AMBIENT_MARK_VMO_EXEC 14u
+#ifdef _KERNEL
+#define ZX_POL_MAX 15u
+#endif
+
+// Policy actions.
+#define ZX_POL_ACTION_ALLOW 0u
+#define ZX_POL_ACTION_DENY 1u
+#define ZX_POL_ACTION_ALLOW_EXCEPTION 2u
+#define ZX_POL_ACTION_DENY_EXCEPTION 3u
+#define ZX_POL_ACTION_KILL 4u
+#ifdef _KERNEL
+#define ZX_POL_ACTION_MAX 5u
+#endif
+
+// Policy override.
+#define ZX_POL_OVERRIDE_ALLOW 0u
+#define ZX_POL_OVERRIDE_DENY 1u
+
+
+// Input structure to use with ZX_JOB_POL_TIMER_SLACK.
+typedef struct zx_policy_timer_slack {
+ zx_duration_t min_slack;
+ uint32_t default_mode;
+ uint8_t padding1[4];
+} zx_policy_timer_slack_t;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_POLICY_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/port.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/port.h
new file mode 100644
index 0000000..9feb4dc
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/port.h
@@ -0,0 +1,173 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_PORT_H_
+#define SYSROOT_ZIRCON_SYSCALLS_PORT_H_
+
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// clang-format off
+
+// zx_object_wait_async() options
+#define ZX_WAIT_ASYNC_ONCE ((uint32_t)0u)
+#define ZX_WAIT_ASYNC_TIMESTAMP ((uint32_t)1u)
+
+// packet types. zx_port_packet_t::type
+#define ZX_PKT_TYPE_USER ((uint8_t)0x00u)
+#define ZX_PKT_TYPE_SIGNAL_ONE ((uint8_t)0x01u)
+// 0x02 was previously used for "ZX_PKT_TYPE_SIGNAL_REP".
+#define ZX_PKT_TYPE_GUEST_BELL ((uint8_t)0x03u)
+#define ZX_PKT_TYPE_GUEST_MEM ((uint8_t)0x04u)
+#define ZX_PKT_TYPE_GUEST_IO ((uint8_t)0x05u)
+#define ZX_PKT_TYPE_GUEST_VCPU ((uint8_t)0x06u)
+#define ZX_PKT_TYPE_INTERRUPT ((uint8_t)0x07u)
+#define ZX_PKT_TYPE_PAGE_REQUEST ((uint8_t)0x09u)
+
+// For options passed to port_create
+#define ZX_PORT_BIND_TO_INTERRUPT ((uint32_t)(0x1u << 0))
+
+#define ZX_PKT_TYPE_MASK ((uint32_t)0x000000FFu)
+
+#define ZX_PKT_IS_USER(type) ((type) == ZX_PKT_TYPE_USER)
+#define ZX_PKT_IS_SIGNAL_ONE(type) ((type) == ZX_PKT_TYPE_SIGNAL_ONE)
+#define ZX_PKT_IS_GUEST_BELL(type) ((type) == ZX_PKT_TYPE_GUEST_BELL)
+#define ZX_PKT_IS_GUEST_MEM(type) ((type) == ZX_PKT_TYPE_GUEST_MEM)
+#define ZX_PKT_IS_GUEST_IO(type) ((type) == ZX_PKT_TYPE_GUEST_IO)
+#define ZX_PKT_IS_GUEST_VCPU(type) ((type) == ZX_PKT_TYPE_GUEST_VCPU)
+#define ZX_PKT_IS_INTERRUPT(type) ((type) == ZX_PKT_TYPE_INTERRUPT)
+#define ZX_PKT_IS_PAGE_REQUEST(type) ((type) == ZX_PKT_TYPE_PAGE_REQUEST)
+
+// zx_packet_guest_vcpu_t::type
+#define ZX_PKT_GUEST_VCPU_INTERRUPT ((uint8_t)0)
+#define ZX_PKT_GUEST_VCPU_STARTUP ((uint8_t)1)
+
+// zx_packet_page_request_t::command
+#define ZX_PAGER_VMO_READ ((uint16_t) 0)
+#define ZX_PAGER_VMO_COMPLETE ((uint16_t) 1)
+// clang-format on
+
+// port_packet_t::type ZX_PKT_TYPE_USER.
+typedef union zx_packet_user {
+ uint64_t u64[4];
+ uint32_t u32[8];
+ uint16_t u16[16];
+ uint8_t c8[32];
+} zx_packet_user_t;
+
+// port_packet_t::type ZX_PKT_TYPE_SIGNAL_ONE.
+typedef struct zx_packet_signal {
+ zx_signals_t trigger;
+ zx_signals_t observed;
+ uint64_t count;
+ uint64_t timestamp;
+ uint64_t reserved1;
+} zx_packet_signal_t;
+
+typedef struct zx_packet_guest_bell {
+ zx_gpaddr_t addr;
+ uint64_t reserved0;
+ uint64_t reserved1;
+ uint64_t reserved2;
+} zx_packet_guest_bell_t;
+
+typedef struct zx_packet_guest_mem {
+ zx_gpaddr_t addr;
+#if __aarch64__
+ uint8_t access_size;
+ bool sign_extend;
+ uint8_t xt;
+ bool read;
+ uint8_t padding1[4];
+ uint64_t data;
+ uint64_t reserved;
+#elif __x86_64__
+// NOTE: x86 instructions are guaranteed to be 15 bytes or fewer.
+#define X86_MAX_INST_LEN 15u
+ uint8_t inst_len;
+ uint8_t inst_buf[X86_MAX_INST_LEN];
+ // This is the default operand size as determined by the CS and EFER register (Volume 3,
+ // Section 5.2.1). If operating in 64-bit mode then near branches and all instructions, except
+ // far branches, that implicitly reference the RSP will actually have a default operand size of
+ // 64-bits (Volume 2, Section 2.2.1.7), and not the 32-bits that will be given here.
+ uint8_t default_operand_size;
+ uint8_t reserved[7];
+#endif
+} zx_packet_guest_mem_t;
+
+typedef struct zx_packet_guest_io {
+ uint16_t port;
+ uint8_t access_size;
+ bool input;
+ union {
+ struct {
+ uint8_t u8;
+ uint8_t padding1[3];
+ };
+ struct {
+ uint16_t u16;
+ uint8_t padding2[2];
+ };
+ uint32_t u32;
+ uint8_t data[4];
+ };
+ uint64_t reserved0;
+ uint64_t reserved1;
+ uint64_t reserved2;
+} zx_packet_guest_io_t;
+
+typedef struct zx_packet_guest_vcpu {
+ union {
+ struct {
+ uint64_t mask;
+ uint8_t vector;
+ uint8_t padding1[7];
+ } interrupt;
+ struct {
+ uint64_t id;
+ zx_gpaddr_t entry;
+ } startup;
+ };
+ uint8_t type;
+ uint8_t padding1[7];
+ uint64_t reserved;
+} zx_packet_guest_vcpu_t;
+
+typedef struct zx_packet_interrupt {
+ zx_time_t timestamp;
+ uint64_t reserved0;
+ uint64_t reserved1;
+ uint64_t reserved2;
+} zx_packet_interrupt_t;
+
+typedef struct zx_packet_page_request {
+ uint16_t command;
+ uint16_t flags;
+ uint32_t reserved0;
+ uint64_t offset;
+ uint64_t length;
+ uint64_t reserved1;
+} zx_packet_page_request_t;
+
+typedef struct zx_port_packet {
+ uint64_t key;
+ uint32_t type;
+ zx_status_t status;
+ union {
+ zx_packet_user_t user;
+ zx_packet_signal_t signal;
+ zx_packet_guest_bell_t guest_bell;
+ zx_packet_guest_mem_t guest_mem;
+ zx_packet_guest_io_t guest_io;
+ zx_packet_guest_vcpu_t guest_vcpu;
+ zx_packet_interrupt_t interrupt;
+ zx_packet_page_request_t page_request;
+ };
+} zx_port_packet_t;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_PORT_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/profile.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/profile.h
new file mode 100644
index 0000000..5abf561
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/profile.h
@@ -0,0 +1,49 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_PROFILE_H_
+#define SYSROOT_ZIRCON_SYSCALLS_PROFILE_H_
+
+#include <zircon/syscalls/scheduler.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+#define ZX_PRIORITY_LOWEST 0
+#define ZX_PRIORITY_LOW 8
+#define ZX_PRIORITY_DEFAULT 16
+#define ZX_PRIORITY_HIGH 24
+#define ZX_PRIORITY_HIGHEST 31
+
+#define ZX_PROFILE_INFO_FLAG_PRIORITY (1 << 0)
+#define ZX_PROFILE_INFO_FLAG_CPU_MASK (1 << 1)
+#define ZX_PROFILE_INFO_FLAG_DEADLINE (1 << 2)
+
+typedef struct zx_profile_info {
+ // A bitmask of ZX_PROFILE_INFO_FLAG_* values. Specifies which fields
+ // below have been specified. Other fields are considered unset.
+ uint32_t flags;
+
+ uint8_t padding1[4];
+
+ union {
+ struct {
+ // Scheduling priority. |flags| must have ZX_PROFILE_INFO_FLAG_PRIORITY set.
+ int32_t priority;
+
+ uint8_t padding2[20];
+ };
+
+ // Scheduling deadline. |flags| must have ZX_PROFILE_INFO_FLAG_DEADLINE set.
+ zx_sched_deadline_params_t deadline_params;
+ };
+
+ // CPUs that threads may be scheduled on. |flags| must have
+ // ZX_PROFILE_INFO_FLAG_CPU_MASK set.
+ zx_cpu_set_t cpu_affinity_mask;
+} zx_profile_info_t;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_PROFILE_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/resource.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/resource.h
new file mode 100644
index 0000000..84b12a1
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/resource.h
@@ -0,0 +1,37 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_RESOURCE_H_
+#define SYSROOT_ZIRCON_SYSCALLS_RESOURCE_H_
+
+#include <stdint.h>
+
+#include <zircon/compiler.h>
+
+// Resources that require a region allocator to handle exclusive reservations
+// are defined in a contiguous block starting at 0 up to ZX_RSRC_KIND_COUNT-1.
+// After that point, all resource 'kinds' are abstract and need no underlying
+// bookkeeping. It's important that ZX_RSRC_KIND_COUNT is defined for each
+// architecture to properly allocate only the bookkeeping necessary.
+//
+// TODO(ZX-2419): Don't expose ZX_RSRC_KIND_COUNT to userspace
+
+typedef uint32_t zx_rsrc_kind_t;
+#define ZX_RSRC_KIND_MMIO ((zx_rsrc_kind_t)0u)
+#define ZX_RSRC_KIND_IRQ ((zx_rsrc_kind_t)1u)
+#define ZX_RSRC_KIND_IOPORT ((zx_rsrc_kind_t)2u)
+#define ZX_RSRC_KIND_HYPERVISOR ((zx_rsrc_kind_t)3u)
+#define ZX_RSRC_KIND_ROOT ((zx_rsrc_kind_t)4u)
+#define ZX_RSRC_KIND_VMEX ((zx_rsrc_kind_t)5u)
+#define ZX_RSRC_KIND_SMC ((zx_rsrc_kind_t)6u)
+#define ZX_RSRC_KIND_COUNT ((zx_rsrc_kind_t)7u)
+
+typedef uint32_t zx_rsrc_flags_t;
+#define ZX_RSRC_FLAG_EXCLUSIVE ((zx_rsrc_flags_t)0x00010000u)
+#define ZX_RSRC_FLAGS_MASK ((zx_rsrc_flags_t)ZX_RSRC_FLAG_EXCLUSIVE)
+
+#define ZX_RSRC_EXTRACT_KIND(x) ((x)&0x0000FFFF)
+#define ZX_RSRC_EXTRACT_FLAGS(x) ((x)&0xFFFF0000)
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_RESOURCE_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/scheduler.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/scheduler.h
new file mode 100644
index 0000000..c119562
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/scheduler.h
@@ -0,0 +1,36 @@
+// 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_SCHEDULER_H_
+#define SYSROOT_ZIRCON_SYSCALLS_SCHEDULER_H_
+
+#include <zircon/compiler.h>
+#include <zircon/time.h>
+
+__BEGIN_CDECLS
+
+// Parameters for deadline scheduler profiles.
+//
+// At minimum, the following relation must hold:
+//
+// 0 < capacity <= relative_deadline <= period
+//
+// Additional restrictions on the range and granularity of the parameters may be
+// enforced, which can vary from system to system.
+//
+typedef struct zx_sched_deadline_params {
+ // The worst case execution time of the deadline work per interarrival period.
+ zx_duration_t capacity;
+
+ // The worst case finish time of the deadline work, relative to the beginning
+ // of the current interarrival period.
+ zx_duration_t relative_deadline;
+
+ // The worst case interarrival period of the deadline work.
+ zx_duration_t period;
+} zx_sched_deadline_params_t;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_SCHEDULER_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/smc.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/smc.h
new file mode 100644
index 0000000..93f1761
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/smc.h
@@ -0,0 +1,47 @@
+// Copyright 2018 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_SMC_H_
+#define SYSROOT_ZIRCON_SYSCALLS_SMC_H_
+
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// Silicon Partner.
+#define ARM_SMC_SERVICE_CALL_NUM_SIP_SERVICE_BASE 0x02
+#define ARM_SMC_SERVICE_CALL_NUM_SIP_SERVICE_LENGTH 0x01
+#define ARM_SMC_SERVICE_CALL_NUM_TRUSTED_OS_BASE 0x32
+#define ARM_SMC_SERVICE_CALL_NUM_TRUSTED_OS_LENGTH 0xE
+#define ARM_SMC_SERVICE_CALL_NUM_MAX 0x3F
+#define ARM_SMC_SERVICE_CALL_NUM_MASK 0x3F
+#define ARM_SMC_SERVICE_CALL_NUM_SHIFT 24
+#define ARM_SMC_GET_SERVICE_CALL_NUM_FROM_FUNC_ID(func_id) \
+ (((func_id) >> ARM_SMC_SERVICE_CALL_NUM_SHIFT) & ARM_SMC_SERVICE_CALL_NUM_MASK)
+
+typedef struct zx_smc_parameters {
+ uint32_t func_id;
+ uint8_t padding1[4];
+ uint64_t arg1;
+ uint64_t arg2;
+ uint64_t arg3;
+ uint64_t arg4;
+ uint64_t arg5;
+ uint64_t arg6;
+ uint16_t client_id;
+ uint16_t secure_os_id;
+ uint8_t padding2[4];
+} zx_smc_parameters_t;
+
+typedef struct zx_smc_result {
+ uint64_t arg0;
+ uint64_t arg1;
+ uint64_t arg2;
+ uint64_t arg3;
+ uint64_t arg6; // at least one implementation uses it as a way to return session_id.
+} zx_smc_result_t;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_SMC_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/system.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/system.h
new file mode 100644
index 0000000..b54d443
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/system.h
@@ -0,0 +1,44 @@
+// Copyright 2017 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_SYSTEM_H_
+#define SYSROOT_ZIRCON_SYSCALLS_SYSTEM_H_
+
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// Commands used by zx_system_powerctl()
+#define ZX_SYSTEM_POWERCTL_ENABLE_ALL_CPUS 1u
+#define ZX_SYSTEM_POWERCTL_DISABLE_ALL_CPUS_BUT_PRIMARY 2u
+#define ZX_SYSTEM_POWERCTL_ACPI_TRANSITION_S_STATE 3u
+#define ZX_SYSTEM_POWERCTL_X86_SET_PKG_PL1 4u
+#define ZX_SYSTEM_POWERCTL_REBOOT 5u
+#define ZX_SYSTEM_POWERCTL_REBOOT_BOOTLOADER 6u
+#define ZX_SYSTEM_POWERCTL_REBOOT_RECOVERY 7u
+#define ZX_SYSTEM_POWERCTL_SHUTDOWN 8u
+
+typedef struct zx_system_powerctl_arg {
+ union {
+ struct {
+ struct {
+ uint8_t target_s_state; // Value between 1 and 5 indicating which S-state
+ uint8_t sleep_type_a; // Value from ACPI VM (SLP_TYPa)
+ uint8_t sleep_type_b; // Value from ACPI VM (SLP_TYPb)
+ } acpi_transition_s_state;
+ uint8_t padding1[9];
+ };
+ struct {
+ uint32_t power_limit; // PL1 value in milliwatts
+ uint32_t time_window; // PL1 time window in microseconds
+ uint8_t clamp; // PL1 clamping enable
+ uint8_t enable; // PL1 enable
+ uint8_t padding2[2];
+ } x86_power_limit;
+ };
+} zx_system_powerctl_arg_t;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_SYSTEM_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/types.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/types.h
new file mode 100644
index 0000000..b7910f2
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/syscalls/types.h
@@ -0,0 +1,25 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_TYPES_H_
+#define SYSROOT_ZIRCON_SYSCALLS_TYPES_H_
+
+#include <zircon/compiler.h>
+
+__BEGIN_CDECLS
+
+// forward declarations needed by syscalls.h
+typedef struct zx_port_packet zx_port_packet_t;
+typedef struct zx_pci_bar zx_pci_bar_t;
+typedef struct zx_pcie_device_info zx_pcie_device_info_t;
+typedef struct zx_pci_init_arg zx_pci_init_arg_t;
+typedef union zx_rrec zx_rrec_t;
+typedef struct zx_system_powerctl_arg zx_system_powerctl_arg_t;
+typedef struct zx_profile_info zx_profile_info_t;
+typedef struct zx_smc_parameters zx_smc_parameters_t;
+typedef struct zx_smc_result zx_smc_result_t;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_TYPES_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/testonly-syscalls.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/testonly-syscalls.h
new file mode 100644
index 0000000..d994d86
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/testonly-syscalls.h
@@ -0,0 +1,30 @@
+// Copyright 2020 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.
+
+#ifndef SYSROOT_ZIRCON_TESTONLY_SYSCALLS_H_
+#define SYSROOT_ZIRCON_TESTONLY_SYSCALLS_H_
+
+#include <zircon/syscalls.h>
+
+__BEGIN_CDECLS
+
+// Make sure this matches <zircon/syscalls.h>.
+#define _ZX_SYSCALL_DECL(name, type, attrs, nargs, arglist, prototype) \
+ extern attrs type zx_##name prototype; \
+ extern attrs type _zx_##name prototype;
+
+#ifdef __clang__
+#define _ZX_SYSCALL_ANNO(attr) __attribute__((attr))
+#else
+#define _ZX_SYSCALL_ANNO(attr) // Nothing for compilers without the support.
+#endif
+
+#include <zircon/syscalls/internal/testonly-cdecls.inc>
+
+#undef _ZX_SYSCALL_ANNO
+#undef _ZX_SYSCALL_DECL
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_ONLY_SYSCALLS_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/threads.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/threads.h
new file mode 100644
index 0000000..5bfc4b0
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/threads.h
@@ -0,0 +1,40 @@
+// Copyright 2018 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.
+
+#ifndef SYSROOT_ZIRCON_THREADS_H_
+#define SYSROOT_ZIRCON_THREADS_H_
+
+#include <threads.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// Get the zx_handle_t corresponding to the thrd_t. This handle is
+// still owned by the C11 thread, and will not persist after the
+// thread exits and is joined or detached. Callers must duplicate the
+// handle, therefore, if they wish the thread handle to outlive the
+// execution of the C11 thread.
+zx_handle_t thrd_get_zx_handle(thrd_t t);
+
+// Converts a threads.h-style status value to an |zx_status_t|.
+static inline zx_status_t __PURE thrd_status_to_zx_status(int thrd_status) {
+ switch (thrd_status) {
+ case thrd_success:
+ return ZX_OK;
+ case thrd_nomem:
+ return ZX_ERR_NO_MEMORY;
+ case thrd_timedout:
+ return ZX_ERR_TIMED_OUT;
+ case thrd_busy:
+ return ZX_ERR_SHOULD_WAIT;
+ default:
+ case thrd_error:
+ return ZX_ERR_INTERNAL;
+ }
+}
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_THREADS_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/time.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/time.h
new file mode 100644
index 0000000..e6bd862
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/time.h
@@ -0,0 +1,153 @@
+// Copyright 2018 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.
+
+#ifndef SYSROOT_ZIRCON_TIME_H_
+#define SYSROOT_ZIRCON_TIME_H_
+
+#include <stdint.h>
+#include <zircon/compiler.h>
+
+__BEGIN_CDECLS
+
+// absolute time in nanoseconds (generally with respect to the monotonic clock)
+typedef int64_t zx_time_t;
+// a duration in nanoseconds
+typedef int64_t zx_duration_t;
+// a duration in hardware ticks
+typedef int64_t zx_ticks_t;
+
+#define ZX_TIME_INFINITE INT64_MAX
+#define ZX_TIME_INFINITE_PAST INT64_MIN
+
+// These functions perform overflow-safe time arithmetic and unit conversion, clamping to
+// ZX_TIME_INFINITE in case of overflow and ZX_TIME_INFINITE_PAST in case of underflow.
+//
+// C++ code should use zx::time and zx::duration instead.
+//
+// For arithmetic the naming scheme is:
+// zx_<first argument>_<operation>_<second argument>
+//
+// For unit conversion the naming scheme is:
+// zx_duration_from_<unit of argument>
+//
+// TODO(maniscalco): Consider expanding the set of operations to include division, modulo, and
+// floating point math.
+
+__CONSTEXPR static inline zx_time_t zx_time_add_duration(zx_time_t time, zx_duration_t duration) {
+ zx_time_t x = 0;
+ if (unlikely(add_overflow(time, duration, &x))) {
+ if (x >= 0) {
+ return ZX_TIME_INFINITE_PAST;
+ } else {
+ return ZX_TIME_INFINITE;
+ }
+ }
+ return x;
+}
+
+__CONSTEXPR static inline zx_time_t zx_time_sub_duration(zx_time_t time, zx_duration_t duration) {
+ zx_time_t x = 0;
+ if (unlikely(sub_overflow(time, duration, &x))) {
+ if (x >= 0) {
+ return ZX_TIME_INFINITE_PAST;
+ } else {
+ return ZX_TIME_INFINITE;
+ }
+ }
+ return x;
+}
+
+__CONSTEXPR static inline zx_duration_t zx_time_sub_time(zx_time_t time1, zx_time_t time2) {
+ zx_duration_t x = 0;
+ if (unlikely(sub_overflow(time1, time2, &x))) {
+ if (x >= 0) {
+ return ZX_TIME_INFINITE_PAST;
+ } else {
+ return ZX_TIME_INFINITE;
+ }
+ }
+ return x;
+}
+
+__CONSTEXPR static inline zx_duration_t zx_duration_add_duration(zx_duration_t dur1,
+ zx_duration_t dur2) {
+ zx_duration_t x = 0;
+ if (unlikely(add_overflow(dur1, dur2, &x))) {
+ if (x >= 0) {
+ return ZX_TIME_INFINITE_PAST;
+ } else {
+ return ZX_TIME_INFINITE;
+ }
+ }
+ return x;
+}
+
+__CONSTEXPR static inline zx_duration_t zx_duration_sub_duration(zx_duration_t dur1,
+ zx_duration_t dur2) {
+ zx_duration_t x = 0;
+ if (unlikely(sub_overflow(dur1, dur2, &x))) {
+ if (x >= 0) {
+ return ZX_TIME_INFINITE_PAST;
+ } else {
+ return ZX_TIME_INFINITE;
+ }
+ }
+ return x;
+}
+
+__CONSTEXPR static inline zx_duration_t zx_duration_mul_int64(zx_duration_t duration,
+ int64_t multiplier) {
+ zx_duration_t x = 0;
+ if (unlikely(mul_overflow(duration, multiplier, &x))) {
+ if ((duration > 0 && multiplier > 0) || (duration < 0 && multiplier < 0)) {
+ return ZX_TIME_INFINITE;
+ } else {
+ return ZX_TIME_INFINITE_PAST;
+ }
+ }
+ return x;
+}
+
+__CONSTEXPR static inline int64_t zx_nsec_from_duration(zx_duration_t n) { return n; }
+
+__CONSTEXPR static inline zx_duration_t zx_duration_from_nsec(int64_t n) {
+ return zx_duration_mul_int64(1, n);
+}
+
+__CONSTEXPR static inline zx_duration_t zx_duration_from_usec(int64_t n) {
+ return zx_duration_mul_int64(1000, n);
+}
+
+__CONSTEXPR static inline zx_duration_t zx_duration_from_msec(int64_t n) {
+ return zx_duration_mul_int64(1000000, n);
+}
+
+__CONSTEXPR static inline zx_duration_t zx_duration_from_sec(int64_t n) {
+ return zx_duration_mul_int64(1000000000, n);
+}
+
+__CONSTEXPR static inline zx_duration_t zx_duration_from_min(int64_t n) {
+ return zx_duration_mul_int64(60000000000, n);
+}
+
+__CONSTEXPR static inline zx_duration_t zx_duration_from_hour(int64_t n) {
+ return zx_duration_mul_int64(3600000000000, n);
+}
+
+// Similar to the functions above, these macros perform overflow-safe unit conversion. Prefer to use
+// the functions above instead of these macros.
+#define ZX_NSEC(n) (__ISCONSTANT(n) ? ((zx_duration_t)(1LL * (n))) : (zx_duration_from_nsec(n)))
+#define ZX_USEC(n) (__ISCONSTANT(n) ? ((zx_duration_t)(1000LL * (n))) : (zx_duration_from_usec(n)))
+#define ZX_MSEC(n) \
+ (__ISCONSTANT(n) ? ((zx_duration_t)(1000000LL * (n))) : (zx_duration_from_msec(n)))
+#define ZX_SEC(n) \
+ (__ISCONSTANT(n) ? ((zx_duration_t)(1000000000LL * (n))) : (zx_duration_from_sec(n)))
+#define ZX_MIN(n) \
+ (__ISCONSTANT(n) ? ((zx_duration_t)(60LL * 1000000000LL * (n))) : (zx_duration_from_min(n)))
+#define ZX_HOUR(n) \
+ (__ISCONSTANT(n) ? ((zx_duration_t)(3600LL * 1000000000LL * (n))) : (zx_duration_from_hour(n)))
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_TIME_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/tls.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/tls.h
new file mode 100644
index 0000000..dae9694
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/tls.h
@@ -0,0 +1,29 @@
+// Copyright 2017 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.
+
+#ifndef SYSROOT_ZIRCON_TLS_
+#define SYSROOT_ZIRCON_TLS_
+
+// These constants are part of the C/C++ ABI known to compilers for
+// *-fuchsia targets. These are offsets from the thread pointer.
+
+// This file must be includable in assembly files.
+
+#if defined(__x86_64__)
+
+#define ZX_TLS_STACK_GUARD_OFFSET 0x10
+#define ZX_TLS_UNSAFE_SP_OFFSET 0x18
+
+#elif defined(__aarch64__)
+
+#define ZX_TLS_STACK_GUARD_OFFSET (-0x10)
+#define ZX_TLS_UNSAFE_SP_OFFSET (-0x8)
+
+#else
+
+#error what architecture?
+
+#endif
+
+#endif // SYSROOT_ZIRCON_TLS_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/types.h b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/types.h
new file mode 100644
index 0000000..10faebb
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/include/zircon/types.h
@@ -0,0 +1,489 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_TYPES_H_
+#define SYSROOT_ZIRCON_TYPES_H_
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <zircon/compiler.h>
+#include <zircon/errors.h>
+#include <zircon/limits.h>
+#include <zircon/rights.h>
+#include <zircon/time.h>
+
+#ifndef __cplusplus
+#ifndef _KERNEL
+// We don't want to include <stdatomic.h> from the kernel code because the
+// kernel definitions of atomic operations are incompatible with those defined
+// in <stdatomic.h>.
+//
+// A better solution would be to use <stdatomic.h> and C11 atomic operation
+// even in the kernel, but that would require modifying all the code that uses
+// the existing homegrown atomics.
+#include <stdatomic.h>
+#endif
+#endif
+
+__BEGIN_CDECLS
+
+// ask clang format not to mess up the indentation:
+// clang-format off
+
+typedef uint32_t zx_handle_t;
+
+#define ZX_HANDLE_INVALID ((zx_handle_t)0)
+#define ZX_HANDLE_FIXED_BITS_MASK ((zx_handle_t)0x3)
+
+// See errors.h for the values zx_status_t can take.
+typedef int32_t zx_status_t;
+
+// clock ids
+typedef uint32_t zx_clock_t;
+#define ZX_CLOCK_MONOTONIC ((zx_clock_t)0)
+#define ZX_CLOCK_UTC ((zx_clock_t)1)
+#define ZX_CLOCK_THREAD ((zx_clock_t)2)
+
+typedef uint32_t zx_signals_t;
+
+#define ZX_SIGNAL_NONE ((zx_signals_t)0u)
+#define ZX_USER_SIGNAL_ALL ((zx_signals_t)0xff000000u)
+
+// Implementation details (__ZX_* not intended for public consumption)
+//
+// Signals that have a common meaning where used are named with that
+// meaning. Signals that do not, or are not yet in use, are named
+// generically.
+#define __ZX_OBJECT_SIGNAL_ALL ((zx_signals_t)0x00ffffffu)
+#define __ZX_OBJECT_READABLE ((zx_signals_t)1u << 0)
+#define __ZX_OBJECT_WRITABLE ((zx_signals_t)1u << 1)
+#define __ZX_OBJECT_PEER_CLOSED ((zx_signals_t)1u << 2)
+#define __ZX_OBJECT_SIGNALED ((zx_signals_t)1u << 3)
+#define __ZX_OBJECT_SIGNAL_4 ((zx_signals_t)1u << 4)
+#define __ZX_OBJECT_SIGNAL_5 ((zx_signals_t)1u << 5)
+#define __ZX_OBJECT_SIGNAL_6 ((zx_signals_t)1u << 6)
+#define __ZX_OBJECT_SIGNAL_7 ((zx_signals_t)1u << 7)
+#define __ZX_OBJECT_SIGNAL_8 ((zx_signals_t)1u << 8)
+#define __ZX_OBJECT_SIGNAL_9 ((zx_signals_t)1u << 9)
+#define __ZX_OBJECT_SIGNAL_10 ((zx_signals_t)1u << 10)
+#define __ZX_OBJECT_SIGNAL_11 ((zx_signals_t)1u << 11)
+#define __ZX_OBJECT_SIGNAL_12 ((zx_signals_t)1u << 12)
+#define __ZX_OBJECT_SIGNAL_13 ((zx_signals_t)1u << 13)
+#define __ZX_OBJECT_SIGNAL_14 ((zx_signals_t)1u << 14)
+#define __ZX_OBJECT_SIGNAL_15 ((zx_signals_t)1u << 15)
+#define __ZX_OBJECT_SIGNAL_16 ((zx_signals_t)1u << 16)
+#define __ZX_OBJECT_SIGNAL_17 ((zx_signals_t)1u << 17)
+#define __ZX_OBJECT_SIGNAL_18 ((zx_signals_t)1u << 18)
+#define __ZX_OBJECT_SIGNAL_19 ((zx_signals_t)1u << 19)
+#define __ZX_OBJECT_SIGNAL_20 ((zx_signals_t)1u << 20)
+#define __ZX_OBJECT_SIGNAL_21 ((zx_signals_t)1u << 21)
+#define __ZX_OBJECT_SIGNAL_22 ((zx_signals_t)1u << 22)
+#define __ZX_OBJECT_HANDLE_CLOSED ((zx_signals_t)1u << 23)
+
+
+
+// User Signals (for zx_object_signal() and zx_object_signal_peer())
+#define ZX_USER_SIGNAL_0 ((zx_signals_t)1u << 24)
+#define ZX_USER_SIGNAL_1 ((zx_signals_t)1u << 25)
+#define ZX_USER_SIGNAL_2 ((zx_signals_t)1u << 26)
+#define ZX_USER_SIGNAL_3 ((zx_signals_t)1u << 27)
+#define ZX_USER_SIGNAL_4 ((zx_signals_t)1u << 28)
+#define ZX_USER_SIGNAL_5 ((zx_signals_t)1u << 29)
+#define ZX_USER_SIGNAL_6 ((zx_signals_t)1u << 30)
+#define ZX_USER_SIGNAL_7 ((zx_signals_t)1u << 31)
+
+// Cancellation (handle was closed while waiting with it)
+#define ZX_SIGNAL_HANDLE_CLOSED __ZX_OBJECT_HANDLE_CLOSED
+
+// Event
+#define ZX_EVENT_SIGNALED __ZX_OBJECT_SIGNALED
+#define ZX_EVENT_SIGNAL_MASK (ZX_USER_SIGNAL_ALL | __ZX_OBJECT_SIGNALED)
+
+// EventPair
+#define ZX_EVENTPAIR_SIGNALED __ZX_OBJECT_SIGNALED
+#define ZX_EVENTPAIR_PEER_CLOSED __ZX_OBJECT_PEER_CLOSED
+#define ZX_EVENTPAIR_SIGNAL_MASK (ZX_USER_SIGNAL_ALL | __ZX_OBJECT_SIGNALED | __ZX_OBJECT_PEER_CLOSED)
+
+// Channel
+#define ZX_CHANNEL_READABLE __ZX_OBJECT_READABLE
+#define ZX_CHANNEL_WRITABLE __ZX_OBJECT_WRITABLE
+#define ZX_CHANNEL_PEER_CLOSED __ZX_OBJECT_PEER_CLOSED
+
+// Clock
+#define ZX_CLOCK_STARTED __ZX_OBJECT_SIGNAL_4
+
+// Socket
+#define ZX_SOCKET_READABLE __ZX_OBJECT_READABLE
+#define ZX_SOCKET_WRITABLE __ZX_OBJECT_WRITABLE
+#define ZX_SOCKET_PEER_CLOSED __ZX_OBJECT_PEER_CLOSED
+#define ZX_SOCKET_PEER_WRITE_DISABLED __ZX_OBJECT_SIGNAL_4
+#define ZX_SOCKET_WRITE_DISABLED __ZX_OBJECT_SIGNAL_5
+#define ZX_SOCKET_READ_THRESHOLD __ZX_OBJECT_SIGNAL_10
+#define ZX_SOCKET_WRITE_THRESHOLD __ZX_OBJECT_SIGNAL_11
+
+// Fifo
+#define ZX_FIFO_READABLE __ZX_OBJECT_READABLE
+#define ZX_FIFO_WRITABLE __ZX_OBJECT_WRITABLE
+#define ZX_FIFO_PEER_CLOSED __ZX_OBJECT_PEER_CLOSED
+
+// Task signals (process, thread, job)
+#define ZX_TASK_TERMINATED __ZX_OBJECT_SIGNALED
+
+// Job
+#define ZX_JOB_TERMINATED __ZX_OBJECT_SIGNALED
+#define ZX_JOB_NO_JOBS __ZX_OBJECT_SIGNAL_4
+#define ZX_JOB_NO_PROCESSES __ZX_OBJECT_SIGNAL_5
+
+// Process
+#define ZX_PROCESS_TERMINATED __ZX_OBJECT_SIGNALED
+
+// Thread
+#define ZX_THREAD_TERMINATED __ZX_OBJECT_SIGNALED
+#define ZX_THREAD_RUNNING __ZX_OBJECT_SIGNAL_4
+#define ZX_THREAD_SUSPENDED __ZX_OBJECT_SIGNAL_5
+
+// Log
+#define ZX_LOG_READABLE __ZX_OBJECT_READABLE
+#define ZX_LOG_WRITABLE __ZX_OBJECT_WRITABLE
+
+// Timer
+#define ZX_TIMER_SIGNALED __ZX_OBJECT_SIGNALED
+
+// VMO
+#define ZX_VMO_ZERO_CHILDREN __ZX_OBJECT_SIGNALED
+
+// global kernel object id.
+// Note: kernel object ids use 63 bits, with the most significant bit being zero.
+// The remaining values (msb==1) are for use by programs and tools that wish to
+// create koids for artificial objects.
+typedef uint64_t zx_koid_t;
+#define ZX_KOID_INVALID ((uint64_t) 0)
+#define ZX_KOID_KERNEL ((uint64_t) 1)
+// The first non-reserved koid. The first 1024 are reserved.
+#define ZX_KOID_FIRST ((uint64_t) 1024)
+
+// Maximum number of wait items allowed for zx_object_wait_many()
+#define ZX_WAIT_MANY_MAX_ITEMS ((size_t)64)
+
+// Structure for zx_object_wait_many():
+typedef struct zx_wait_item {
+ zx_handle_t handle;
+ zx_signals_t waitfor;
+ zx_signals_t pending;
+} zx_wait_item_t;
+
+// VM Object creation options
+#define ZX_VMO_RESIZABLE ((uint32_t)1u << 1)
+
+// VM Object opcodes
+#define ZX_VMO_OP_COMMIT ((uint32_t)1u)
+#define ZX_VMO_OP_DECOMMIT ((uint32_t)2u)
+#define ZX_VMO_OP_LOCK ((uint32_t)3u)
+#define ZX_VMO_OP_UNLOCK ((uint32_t)4u)
+// opcode 5 was ZX_VMO_OP_LOOKUP, but is now unused.
+#define ZX_VMO_OP_CACHE_SYNC ((uint32_t)6u)
+#define ZX_VMO_OP_CACHE_INVALIDATE ((uint32_t)7u)
+#define ZX_VMO_OP_CACHE_CLEAN ((uint32_t)8u)
+#define ZX_VMO_OP_CACHE_CLEAN_INVALIDATE ((uint32_t)9u)
+#define ZX_VMO_OP_ZERO ((uint32_t)10u)
+
+// VM Object clone flags
+#define ZX_VMO_CHILD_SNAPSHOT ((uint32_t)1u << 0)
+#define ZX_VMO_CHILD_SNAPSHOT_AT_LEAST_ON_WRITE ((uint32_t)1u << 4)
+#define ZX_VMO_CHILD_RESIZABLE ((uint32_t)1u << 2)
+#define ZX_VMO_CHILD_SLICE ((uint32_t)1u << 3)
+#define ZX_VMO_CHILD_NO_WRITE ((uint32_t)1u << 5)
+// Old clone flags that are on the path to deprecation.
+#define ZX_VMO_CLONE_COPY_ON_WRITE ((uint32_t)1u << 4)
+#define ZX_VMO_CHILD_COPY_ON_WRITE ((uint32_t)1u << 4)
+#define ZX_VMO_CHILD_PRIVATE_PAGER_COPY ((uint32_t)1u << 4)
+
+typedef uint32_t zx_vm_option_t;
+// Mapping flags to vmar routines
+#define ZX_VM_PERM_READ ((zx_vm_option_t)(1u << 0))
+#define ZX_VM_PERM_WRITE ((zx_vm_option_t)(1u << 1))
+#define ZX_VM_PERM_EXECUTE ((zx_vm_option_t)(1u << 2))
+#define ZX_VM_COMPACT ((zx_vm_option_t)(1u << 3))
+#define ZX_VM_SPECIFIC ((zx_vm_option_t)(1u << 4))
+#define ZX_VM_SPECIFIC_OVERWRITE ((zx_vm_option_t)(1u << 5))
+#define ZX_VM_CAN_MAP_SPECIFIC ((zx_vm_option_t)(1u << 6))
+#define ZX_VM_CAN_MAP_READ ((zx_vm_option_t)(1u << 7))
+#define ZX_VM_CAN_MAP_WRITE ((zx_vm_option_t)(1u << 8))
+#define ZX_VM_CAN_MAP_EXECUTE ((zx_vm_option_t)(1u << 9))
+#define ZX_VM_MAP_RANGE ((zx_vm_option_t)(1u << 10))
+#define ZX_VM_REQUIRE_NON_RESIZABLE ((zx_vm_option_t)(1u << 11))
+#define ZX_VM_ALLOW_FAULTS ((zx_vm_option_t)(1u << 12))
+
+#define ZX_VM_ALIGN_BASE 24
+#define ZX_VM_ALIGN_1KB ((zx_vm_option_t)(10u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_2KB ((zx_vm_option_t)(11u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_4KB ((zx_vm_option_t)(12u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_8KB ((zx_vm_option_t)(13u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_16KB ((zx_vm_option_t)(14u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_32KB ((zx_vm_option_t)(15u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_64KB ((zx_vm_option_t)(16u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_128KB ((zx_vm_option_t)(17u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_256KB ((zx_vm_option_t)(18u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_512KB ((zx_vm_option_t)(19u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_1MB ((zx_vm_option_t)(20u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_2MB ((zx_vm_option_t)(21u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_4MB ((zx_vm_option_t)(22u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_8MB ((zx_vm_option_t)(23u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_16MB ((zx_vm_option_t)(24u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_32MB ((zx_vm_option_t)(25u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_64MB ((zx_vm_option_t)(26u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_128MB ((zx_vm_option_t)(27u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_256MB ((zx_vm_option_t)(28u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_512MB ((zx_vm_option_t)(29u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_1GB ((zx_vm_option_t)(30u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_2GB ((zx_vm_option_t)(31u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_4GB ((zx_vm_option_t)(32u << ZX_VM_ALIGN_BASE))
+
+// virtual address
+typedef uintptr_t zx_vaddr_t;
+
+// physical address
+typedef uintptr_t zx_paddr_t;
+// low mem physical address
+typedef uint32_t zx_paddr32_t;
+// Hypervisor guest physical addresses.
+typedef uintptr_t zx_gpaddr_t;
+
+// offset
+typedef uint64_t zx_off_t;
+
+// vectorized I/O
+typedef struct zx_iovec {
+ void* buffer;
+ size_t capacity;
+} zx_iovec_t;
+
+// Maximum string length for kernel names (process name, thread name, etc)
+#define ZX_MAX_NAME_LEN ((size_t)32u)
+
+// Buffer size limits on the cprng syscalls
+#define ZX_CPRNG_DRAW_MAX_LEN ((size_t)256u)
+#define ZX_CPRNG_ADD_ENTROPY_MAX_LEN ((size_t)256u)
+
+// interrupt_create flags
+#define ZX_INTERRUPT_REMAP_IRQ ((uint32_t)0x1u)
+#define ZX_INTERRUPT_MODE_DEFAULT ((uint32_t)0u << 1)
+#define ZX_INTERRUPT_MODE_EDGE_LOW ((uint32_t)1u << 1)
+#define ZX_INTERRUPT_MODE_EDGE_HIGH ((uint32_t)2u << 1)
+#define ZX_INTERRUPT_MODE_LEVEL_LOW ((uint32_t)3u << 1)
+#define ZX_INTERRUPT_MODE_LEVEL_HIGH ((uint32_t)4u << 1)
+#define ZX_INTERRUPT_MODE_EDGE_BOTH ((uint32_t)5u << 1)
+#define ZX_INTERRUPT_MODE_MASK ((uint32_t)0xe)
+#define ZX_INTERRUPT_VIRTUAL ((uint32_t)0x10)
+
+// interrupt_bind flags
+#define ZX_INTERRUPT_BIND ((uint32_t)0x0u)
+#define ZX_INTERRUPT_UNBIND ((uint32_t)0x1u)
+
+// Preallocated virtual interrupt slot, typically used for signaling interrupt threads to exit.
+#define ZX_INTERRUPT_SLOT_USER ((uint32_t)62u)
+// interrupt wait slots must be in the range 0 - 62 inclusive
+#define ZX_INTERRUPT_MAX_SLOTS ((uint32_t)62u)
+
+// PCI interrupt handles use interrupt slot 0 for the PCI hardware interrupt
+#define ZX_PCI_INTERRUPT_SLOT ((uint32_t)0u)
+
+// Channel options and limits.
+#define ZX_CHANNEL_READ_MAY_DISCARD ((uint32_t)1u)
+
+#define ZX_CHANNEL_MAX_MSG_BYTES ((uint32_t)65536u)
+#define ZX_CHANNEL_MAX_MSG_HANDLES ((uint32_t)64u)
+
+// Fifo limits.
+#define ZX_FIFO_MAX_SIZE_BYTES ZX_PAGE_SIZE
+
+// Socket options and limits.
+// These options can be passed to zx_socket_shutdown().
+#define ZX_SOCKET_SHUTDOWN_WRITE ((uint32_t)1u << 0)
+#define ZX_SOCKET_SHUTDOWN_READ ((uint32_t)1u << 1)
+#define ZX_SOCKET_SHUTDOWN_MASK (ZX_SOCKET_SHUTDOWN_WRITE | ZX_SOCKET_SHUTDOWN_READ)
+
+// These can be passed to zx_socket_create().
+#define ZX_SOCKET_STREAM ((uint32_t)0u)
+#define ZX_SOCKET_DATAGRAM ((uint32_t)1u << 0)
+#define ZX_SOCKET_CREATE_MASK (ZX_SOCKET_DATAGRAM)
+
+// These can be passed to zx_socket_read().
+#define ZX_SOCKET_PEEK ((uint32_t)1u << 3)
+
+// These can be passed to zx_stream_create().
+#define ZX_STREAM_MODE_READ ((uint32_t)1u << 0)
+#define ZX_STREAM_MODE_WRITE ((uint32_t)1u << 1)
+#define ZX_STREAM_CREATE_MASK (ZX_STREAM_MODE_READ | ZX_STREAM_MODE_WRITE)
+
+// These can be passed to zx_stream_writev().
+#define ZX_STREAM_APPEND ((uint32_t)1u << 0)
+
+typedef uint32_t zx_stream_seek_origin_t;
+#define ZX_STREAM_SEEK_ORIGIN_START ((zx_stream_seek_origin_t)0u)
+#define ZX_STREAM_SEEK_ORIGIN_CURRENT ((zx_stream_seek_origin_t)1u)
+#define ZX_STREAM_SEEK_ORIGIN_END ((zx_stream_seek_origin_t)2u)
+
+// Flags which can be used to to control cache policy for APIs which map memory.
+#define ZX_CACHE_POLICY_CACHED ((uint32_t)0u)
+#define ZX_CACHE_POLICY_UNCACHED ((uint32_t)1u)
+#define ZX_CACHE_POLICY_UNCACHED_DEVICE ((uint32_t)2u)
+#define ZX_CACHE_POLICY_WRITE_COMBINING ((uint32_t)3u)
+#define ZX_CACHE_POLICY_MASK ((uint32_t)3u)
+
+// Flag bits for zx_cache_flush.
+#define ZX_CACHE_FLUSH_INSN ((uint32_t)1u << 0)
+#define ZX_CACHE_FLUSH_DATA ((uint32_t)1u << 1)
+#define ZX_CACHE_FLUSH_INVALIDATE ((uint32_t)1u << 2)
+
+// Timer options.
+#define ZX_TIMER_SLACK_CENTER ((uint32_t)0u)
+#define ZX_TIMER_SLACK_EARLY ((uint32_t)1u)
+#define ZX_TIMER_SLACK_LATE ((uint32_t)2u)
+
+// Bus Transaction Initiator options.
+#define ZX_BTI_PERM_READ ((uint32_t)1u << 0)
+#define ZX_BTI_PERM_WRITE ((uint32_t)1u << 1)
+#define ZX_BTI_PERM_EXECUTE ((uint32_t)1u << 2)
+#define ZX_BTI_COMPRESS ((uint32_t)1u << 3)
+#define ZX_BTI_CONTIGUOUS ((uint32_t)1u << 4)
+
+// Job options.
+// These options can be passed to zx_job_set_critical().
+#define ZX_JOB_CRITICAL_PROCESS_RETCODE_NONZERO ((uint32_t)1u << 0)
+
+typedef uint32_t zx_obj_type_t;
+
+#define ZX_OBJ_TYPE_NONE ((zx_obj_type_t)0u)
+#define ZX_OBJ_TYPE_PROCESS ((zx_obj_type_t)1u)
+#define ZX_OBJ_TYPE_THREAD ((zx_obj_type_t)2u)
+#define ZX_OBJ_TYPE_VMO ((zx_obj_type_t)3u)
+#define ZX_OBJ_TYPE_CHANNEL ((zx_obj_type_t)4u)
+#define ZX_OBJ_TYPE_EVENT ((zx_obj_type_t)5u)
+#define ZX_OBJ_TYPE_PORT ((zx_obj_type_t)6u)
+#define ZX_OBJ_TYPE_INTERRUPT ((zx_obj_type_t)9u)
+#define ZX_OBJ_TYPE_PCI_DEVICE ((zx_obj_type_t)11u)
+#define ZX_OBJ_TYPE_LOG ((zx_obj_type_t)12u)
+#define ZX_OBJ_TYPE_SOCKET ((zx_obj_type_t)14u)
+#define ZX_OBJ_TYPE_RESOURCE ((zx_obj_type_t)15u)
+#define ZX_OBJ_TYPE_EVENTPAIR ((zx_obj_type_t)16u)
+#define ZX_OBJ_TYPE_JOB ((zx_obj_type_t)17u)
+#define ZX_OBJ_TYPE_VMAR ((zx_obj_type_t)18u)
+#define ZX_OBJ_TYPE_FIFO ((zx_obj_type_t)19u)
+#define ZX_OBJ_TYPE_GUEST ((zx_obj_type_t)20u)
+#define ZX_OBJ_TYPE_VCPU ((zx_obj_type_t)21u)
+#define ZX_OBJ_TYPE_TIMER ((zx_obj_type_t)22u)
+#define ZX_OBJ_TYPE_IOMMU ((zx_obj_type_t)23u)
+#define ZX_OBJ_TYPE_BTI ((zx_obj_type_t)24u)
+#define ZX_OBJ_TYPE_PROFILE ((zx_obj_type_t)25u)
+#define ZX_OBJ_TYPE_PMT ((zx_obj_type_t)26u)
+#define ZX_OBJ_TYPE_SUSPEND_TOKEN ((zx_obj_type_t)27u)
+#define ZX_OBJ_TYPE_PAGER ((zx_obj_type_t)28u)
+#define ZX_OBJ_TYPE_EXCEPTION ((zx_obj_type_t)29u)
+#define ZX_OBJ_TYPE_CLOCK ((zx_obj_type_t)30u)
+#define ZX_OBJ_TYPE_STREAM ((zx_obj_type_t)31u)
+#define ZX_OBJ_TYPE_MSI_ALLOCATION ((zx_obj_type_t)32u)
+#define ZX_OBJ_TYPE_MSI_INTERRUPT ((zx_obj_type_t)33u)
+
+// System ABI commits to having no more than 64 object types.
+//
+// See zx_info_process_handle_stats_t for an example of a binary interface that
+// depends on having an upper bound for the number of object types.
+#define ZX_OBJ_TYPE_UPPER_BOUND ((zx_obj_type_t)64u)
+
+typedef uint32_t zx_system_event_type_t;
+#define ZX_SYSTEM_EVENT_OUT_OF_MEMORY ((zx_system_event_type_t)1u)
+#define ZX_SYSTEM_EVENT_MEMORY_PRESSURE_CRITICAL ((zx_system_event_type_t)2u)
+#define ZX_SYSTEM_EVENT_MEMORY_PRESSURE_WARNING ((zx_system_event_type_t)3u)
+#define ZX_SYSTEM_EVENT_MEMORY_PRESSURE_NORMAL ((zx_system_event_type_t)4u)
+
+// Used in channel_read_etc.
+typedef struct zx_handle_info {
+ zx_handle_t handle;
+ zx_obj_type_t type;
+ zx_rights_t rights;
+ uint32_t unused;
+} zx_handle_info_t;
+
+typedef uint32_t zx_handle_op_t;
+
+#define ZX_HANDLE_OP_MOVE ((zx_handle_op_t)0u)
+#define ZX_HANDLE_OP_DUPLICATE ((zx_handle_op_t)1u)
+
+// Used in channel_write_etc.
+typedef struct zx_handle_disposition {
+ zx_handle_op_t operation;
+ zx_handle_t handle;
+ zx_obj_type_t type;
+ zx_rights_t rights;
+ zx_status_t result;
+} zx_handle_disposition_t;
+
+// Transaction ID and argument types for zx_channel_call.
+typedef uint32_t zx_txid_t;
+
+typedef struct zx_channel_call_args {
+ const void* wr_bytes;
+ const zx_handle_t* wr_handles;
+ void *rd_bytes;
+ zx_handle_t* rd_handles;
+ uint32_t wr_num_bytes;
+ uint32_t wr_num_handles;
+ uint32_t rd_num_bytes;
+ uint32_t rd_num_handles;
+} zx_channel_call_args_t;
+
+// The ZX_VM_FLAG_* constants are to be deprecated in favor of the ZX_VM_*
+// versions.
+#define ZX_VM_FLAG_PERM_READ ((uint32_t)1u << 0)
+#define ZX_VM_FLAG_PERM_WRITE ((uint32_t)1u << 1)
+#define ZX_VM_FLAG_PERM_EXECUTE ((uint32_t)1u << 2)
+#define ZX_VM_FLAG_COMPACT ((uint32_t)1u << 3)
+#define ZX_VM_FLAG_SPECIFIC ((uint32_t)1u << 4)
+#define ZX_VM_FLAG_SPECIFIC_OVERWRITE ((uint32_t)1u << 5)
+#define ZX_VM_FLAG_CAN_MAP_SPECIFIC ((uint32_t)1u << 6)
+#define ZX_VM_FLAG_CAN_MAP_READ ((uint32_t)1u << 7)
+#define ZX_VM_FLAG_CAN_MAP_WRITE ((uint32_t)1u << 8)
+#define ZX_VM_FLAG_CAN_MAP_EXECUTE ((uint32_t)1u << 9)
+#define ZX_VM_FLAG_MAP_RANGE ((uint32_t)1u << 10)
+#define ZX_VM_FLAG_REQUIRE_NON_RESIZABLE ((uint32_t)1u << 11)
+
+// CPU masks specifying sets of CPUs.
+//
+// We currently are limited to systems with 512 CPUs or less.
+#define ZX_CPU_SET_MAX_CPUS 512
+#define ZX_CPU_SET_BITS_PER_WORD 64
+
+typedef struct zx_cpu_set {
+ // The |N|'th CPU is considered in the CPU set if the bit:
+ //
+ // cpu_mask[N / ZX_CPU_SET_BITS_PER_WORD]
+ // & (1 << (N % ZX_CPU_SET_BITS_PER_WORD))
+ //
+ // is set.
+ uint64_t mask[ZX_CPU_SET_MAX_CPUS / ZX_CPU_SET_BITS_PER_WORD];
+} zx_cpu_set_t;
+
+#ifdef __cplusplus
+// We cannot use <stdatomic.h> with C++ code as _Atomic qualifier defined by
+// C11 is not valid in C++11. There is not a single standard name that can
+// be used in both C and C++. C++ <atomic> defines names which are equivalent
+// to those in <stdatomic.h>, but these are contained in the std namespace.
+//
+// In kernel, the only operation done is a user_copy (of sizeof(int)) inside a
+// lock; otherwise the futex address is treated as a key.
+typedef int zx_futex_t;
+#else
+#ifdef _KERNEL
+typedef int zx_futex_t;
+#else
+typedef atomic_int zx_futex_t;
+#endif
+#endif
+typedef int zx_futex_storage_t;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_TYPES_H_
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/lib/Scrt1.o b/third_party/fuchsia-sdk/arch/arm64/sysroot/lib/Scrt1.o
new file mode 100644
index 0000000..330b0d5
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/lib/Scrt1.o
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/lib/libc.so b/third_party/fuchsia-sdk/arch/arm64/sysroot/lib/libc.so
new file mode 100755
index 0000000..fedc0d4
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/lib/libc.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/lib/libdl.so b/third_party/fuchsia-sdk/arch/arm64/sysroot/lib/libdl.so
new file mode 100644
index 0000000..f2072c3
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/lib/libdl.so
@@ -0,0 +1,5 @@
+/*
+ * The APIs traditionally found in -lm, -ldl, or -lpthread are all implemented
+ * in libc.so, so this file just redirects the linker to refer there instead.
+ */
+INPUT(AS_NEEDED(libc.so))
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/lib/libm.so b/third_party/fuchsia-sdk/arch/arm64/sysroot/lib/libm.so
new file mode 100644
index 0000000..f2072c3
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/lib/libm.so
@@ -0,0 +1,5 @@
+/*
+ * The APIs traditionally found in -lm, -ldl, or -lpthread are all implemented
+ * in libc.so, so this file just redirects the linker to refer there instead.
+ */
+INPUT(AS_NEEDED(libc.so))
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/lib/libpthread.so b/third_party/fuchsia-sdk/arch/arm64/sysroot/lib/libpthread.so
new file mode 100644
index 0000000..f2072c3
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/lib/libpthread.so
@@ -0,0 +1,5 @@
+/*
+ * The APIs traditionally found in -lm, -ldl, or -lpthread are all implemented
+ * in libc.so, so this file just redirects the linker to refer there instead.
+ */
+INPUT(AS_NEEDED(libc.so))
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/lib/librt.so b/third_party/fuchsia-sdk/arch/arm64/sysroot/lib/librt.so
new file mode 100644
index 0000000..f2072c3
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/lib/librt.so
@@ -0,0 +1,5 @@
+/*
+ * The APIs traditionally found in -lm, -ldl, or -lpthread are all implemented
+ * in libc.so, so this file just redirects the linker to refer there instead.
+ */
+INPUT(AS_NEEDED(libc.so))
diff --git a/third_party/fuchsia-sdk/arch/arm64/sysroot/lib/libzircon.so b/third_party/fuchsia-sdk/arch/arm64/sysroot/lib/libzircon.so
new file mode 100755
index 0000000..a40723d
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/sysroot/lib/libzircon.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/alias_workarounds.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/alias_workarounds.fidl
new file mode 100644
index 0000000..bdcfc5f
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/alias_workarounds.fidl
@@ -0,0 +1,100 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+// These are all aliases that will be subsumed by the future implementation of
+// templating, constraints, etc. in fidlc.
+//
+// The right hand side is completely ignored by kazoo, that is, only the name of
+// the alias is significant. Generally the right hand side is set so that if
+// there were no handling of the alias (and the alias was "expanded" as is the
+// default behaviour), it would result in something sensible.
+
+// TODO(fidlc): (mutable) char*
+using charptr = uint64;
+
+// TODO(fidl)
+using const_futexptr = int32;
+
+// TODO(fidlc): const void*
+using const_voidptr = uint64;
+
+// TODO(fidlc): mutable<string>
+using mutable_string = string;
+
+// TODO(fidlc): mutable<uint32>
+using mutable_uint32 = uint32;
+
+// TODO(fidlc): mutable<usize>
+using mutable_usize = usize;
+
+// TODO(fidlc): uint32 size
+// TODO(fidlc): mutable<vector<HandleDisposition>
+using mutable_vector_HandleDisposition_u32size = vector<HandleDisposition>;
+
+// TODO(fidlc): mutable<vector<WaitItem>>
+using mutable_vector_WaitItem = vector<WaitItem>;
+
+// TODO(fidlc): uint32 size
+// TODO(fidlc): mutable<vector<handle>
+using mutable_vector_handle_u32size = vector<handle>;
+
+// TODO(fidlc): mutable<vector<void>>
+using mutable_vector_void = vector<byte>;
+
+// TODO(fidlc): uint32 size
+// TODO(fidlc): mutable<vector<void>>
+using mutable_vector_void_u32size = vector<byte>;
+
+// TODO(fidlc): optional<PciBar>
+using optional_PciBar = PciBar;
+
+// TODO(fidlc): optional<PortPacket>
+using optional_PortPacket = PortPacket;
+
+// TODO(fidlc): optional<koid>
+using optional_koid = koid;
+
+// TODO(fidlc): optional<signals>
+using optional_signals = signals;
+
+// TODO(fidlc): optional<time>
+using optional_time = time;
+
+// TODO(fidlc): optional<uint32>
+using optional_uint32 = uint32;
+
+// TODO(fidlc): optional<usize>
+using optional_usize = usize;
+
+// TODO(fidlc): optional<usize>
+using optional_off = off;
+
+// TODO(fidlc): uint32 size
+// TODO(fidlc): vector<HandleInfo>
+using vector_HandleInfo_u32size = vector<HandleInfo>;
+
+// TODO(fidlc): vector<handle> uint32 size
+using vector_handle_u32size = vector<handle>;
+
+// TODO(fidlc): vector<paddr>>
+using vector_paddr = vector<paddr>;
+
+// TODO(fidlc): vector<void>
+using vector_void = vector<byte>;
+
+// TODO(fidlc): vector<iovec>
+using vector_iovec = vector<byte>;
+
+// TODO(fidlc): uint32 size
+// TODO(fidlc): vector<void>
+using vector_void_u32size = vector<byte>;
+
+// TODO(fidlc): (mutable) void*
+using voidptr = uint64;
+
+// This is <zircon/string_view.h>'s zx_string_view_t in C/C++.
+using string_view = uint64;
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/bti.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/bti.fidl
new file mode 100644
index 0000000..8ec1c08
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/bti.fidl
@@ -0,0 +1,32 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol bti {
+ /// Create a new bus transaction initiator.
+ /// Rights: iommu must be of type ZX_OBJ_TYPE_IOMMU and have ZX_RIGHT_NONE.
+ // TODO(ZX-2967): This is an unusual rights spec.
+ bti_create(handle<iommu> iommu, uint32 options, uint64 bti_id) -> (status status, handle<bti> out);
+
+ /// Pin pages and grant devices access to them.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_BTI and have ZX_RIGHT_MAP.
+ /// Rights: vmo must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_MAP.
+ /// Rights: If options & ZX_BTI_PERM_READ, vmo must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_READ.
+ /// Rights: If options & ZX_BTI_PERM_WRITE, vmo must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_WRITE.
+ /// Rights: If options & ZX_BTI_PERM_EXECUTE, vmo must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_READ.
+ // READ is intentional in the EXECUTE condition.
+ bti_pin(handle<bti> handle,
+ uint32 options,
+ handle<vmo> vmo,
+ uint64 offset,
+ uint64 size)
+ -> (status status, vector_paddr addrs, handle<pmt> pmt);
+
+ /// Releases all quarantined PMTs.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_BTI and have ZX_RIGHT_WRITE.
+ bti_release_quarantine(handle<bti> handle) -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/cache.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/cache.fidl
new file mode 100644
index 0000000..f1f8567
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/cache.fidl
@@ -0,0 +1,13 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol cache {
+ /// Flush CPU data and/or instruction caches.
+ [vdsocall]
+ cache_flush(const_voidptr addr, usize size, uint32 options) -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/channel.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/channel.fidl
new file mode 100644
index 0000000..25c8ca3
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/channel.fidl
@@ -0,0 +1,107 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+using ObjType = uint32;
+
+// TODO(scottmg): ZX_OBJ_TYPE_xyz here.
+
+using HandleOp = uint32;
+
+// TODO(scottmg): ZX_HANDLE_OP_xyz here.
+
+struct HandleInfo {
+ handle handle;
+ ObjType type;
+ rights rights;
+ uint32 unused;
+};
+
+struct ChannelCallArgs {
+ vector<byte> wr_bytes;
+ vector<handle> wr_handles;
+ // TODO(scottmg): mutable_vector_void
+ vector<byte> rd_bytes;
+ // TODO(scottmg): mutable_vector_handle
+ vector<handle> rd_handles;
+};
+
+struct HandleDisposition {
+ HandleOp operation;
+ handle handle;
+ ObjType type;
+ rights rights;
+ status result;
+};
+
+[Transport = "Syscall"]
+protocol channel {
+ /// Create a channel.
+ channel_create(uint32 options) -> (status status, handle out0, handle out1);
+
+ /// Read a message from a channel.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_CHANNEL and have ZX_RIGHT_READ.
+ [ArgReorder = "handle, options, bytes, handles, num_bytes, num_handles, actual_bytes, actual_handles",
+ HandleUnchecked]
+ channel_read(handle<channel> handle,
+ uint32 options)
+ -> (status status,
+ vector_void_u32size bytes,
+ vector_handle_u32size handles,
+ optional_uint32 actual_bytes,
+ optional_uint32 actual_handles);
+
+ /// Read a message from a channel.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_CHANNEL and have ZX_RIGHT_READ.
+ [ArgReorder = "handle, options, bytes, handles, num_bytes, num_handles, actual_bytes, actual_handles"]
+ channel_read_etc(handle<channel> handle,
+ uint32 options)
+ -> (status status,
+ vector_void_u32size bytes,
+ vector_HandleInfo_u32size handles,
+ optional_uint32 actual_bytes,
+ optional_uint32 actual_handles);
+
+ /// Write a message to a channel.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_CHANNEL and have ZX_RIGHT_WRITE.
+ /// Rights: Every entry of handles must have ZX_RIGHT_TRANSFER.
+ channel_write(handle<channel> handle,
+ uint32 options,
+ vector_void_u32size bytes,
+ vector_handle_u32size handles)
+ -> (status status);
+
+ /// Write a message to a channel.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_CHANNEL and have ZX_RIGHT_WRITE.
+ /// Rights: Every entry of handles must have ZX_RIGHT_TRANSFER.
+ channel_write_etc(handle<channel> handle,
+ uint32 options,
+ vector_void_u32size bytes,
+ mutable_vector_HandleDisposition_u32size handles)
+ -> (status status);
+
+ /// Rights: handle must be of type ZX_OBJ_TYPE_CHANNEL and have ZX_RIGHT_READ and have ZX_RIGHT_WRITE.
+ /// Rights: All wr_handles of args must have ZX_RIGHT_TRANSFER.
+ [internal]
+ channel_call_noretry(handle<channel> handle,
+ uint32 options,
+ time deadline,
+ ChannelCallArgs args)
+ -> (status status, uint32 actual_bytes, uint32 actual_handles);
+
+ [internal]
+ channel_call_finish(time deadline, ChannelCallArgs args)
+ -> (status status, uint32 actual_bytes, uint32 actual_handles);
+
+ /// Send a message to a channel and await a reply.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_CHANNEL and have ZX_RIGHT_READ and have ZX_RIGHT_WRITE.
+ /// Rights: All wr_handles of args must have ZX_RIGHT_TRANSFER.
+ [blocking,
+ vdsocall]
+ // TODO(scottmg): Express "All wr_handles of args must have ZX_RIGHT_TRANSFER."
+ channel_call(handle handle, uint32 options, time deadline, ChannelCallArgs args)
+ -> (status status, uint32 actual_bytes, uint32 actual_handles);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/clock.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/clock.fidl
new file mode 100644
index 0000000..5aecb3b
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/clock.fidl
@@ -0,0 +1,51 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+enum Clock : uint32 {
+ MONOTONIC = 0;
+ UTC = 1;
+ THREAD = 2;
+};
+
+[Transport = "Syscall"]
+protocol clock {
+ /// Acquire the current time.
+ clock_get(Clock clock_id) -> (status status, time out);
+
+ /// Acquire the current monotonic time.
+ [vdsocall]
+ clock_get_monotonic() -> (time time);
+
+ /// Rights: handle must have resource kind ZX_RSRC_KIND_ROOT.
+ clock_adjust(handle<resource> handle, Clock clock_id, int64 offset) -> (status status);
+
+ // Read clock monotonic, but demand that the read be performed using a
+ // syscall, instead of a vdso call.
+ //
+ // See the notes for ticks_get_via_kernel; this is not a syscall meant
+ // to be used by application code.
+ [internal]
+ clock_get_monotonic_via_kernel() -> (time time);
+
+ // TODO: handle<clock> for all of these.
+
+ /// Create a new clock object.
+ /// Rights: None.
+ clock_create(uint64 options, const_voidptr args) -> (status status, handle out);
+
+ /// Perform a basic read of the clock.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_CLOCK and have ZX_RIGHT_READ.
+ clock_read(handle handle) -> (status status, time now);
+
+ /// Fetch all of the low level details of the clock's current status.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_CLOCK and have ZX_RIGHT_READ.
+ clock_get_details(handle handle, uint64 options) -> (status status, voidptr details);
+
+ /// Make adjustments to a clock object.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_CLOCK and have ZX_RIGHT_WRITE.
+ clock_update(handle handle, uint64 options, const_voidptr args) -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/cprng.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/cprng.fidl
new file mode 100644
index 0000000..7431bde
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/cprng.fidl
@@ -0,0 +1,19 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol cprng {
+ [internal]
+ cprng_draw_once() -> (status status, vector_void buffer);
+
+ /// Draw from the kernel's CPRNG.
+ [vdsocall]
+ cprng_draw() -> (vector_void buffer);
+
+ /// Add entropy to the kernel CPRNG.
+ cprng_add_entropy(vector_void buffer) -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/debug.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/debug.fidl
new file mode 100644
index 0000000..e629799
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/debug.fidl
@@ -0,0 +1,17 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol debug {
+ /// Rights: handle must have resource kind ZX_RSRC_KIND_ROOT.
+ debug_read(handle<resource> handle) -> (status status, string buffer, usize actual);
+
+ debug_write(string buffer) -> (status status);
+
+ /// Rights: resource must have resource kind ZX_RSRC_KIND_ROOT.
+ debug_send_command(handle<resource> resource, string buffer) -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/debuglog.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/debuglog.fidl
new file mode 100644
index 0000000..23e1faf
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/debuglog.fidl
@@ -0,0 +1,20 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol debuglog {
+ // TODO(ZX-2967): handle == ZX_HANDLE_INVALID accepted.
+ /// Rights: resource must have resource kind ZX_RSRC_KIND_ROOT.
+ debuglog_create(handle<resource> resource, uint32 options)
+ -> (status status, handle<debuglog> out);
+
+ /// Rights: handle must be of type ZX_OBJ_TYPE_LOG and have ZX_RIGHT_WRITE.
+ debuglog_write(handle<debuglog> handle, uint32 options, vector_void buffer) -> (status status);
+
+ /// Rights: handle must be of type ZX_OBJ_TYPE_LOG and have ZX_RIGHT_READ.
+ debuglog_read(handle<debuglog> handle, uint32 options) -> (status status, vector_void buffer);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/event.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/event.fidl
new file mode 100644
index 0000000..4f12cd8
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/event.fidl
@@ -0,0 +1,12 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol event {
+ /// Create an event.
+ event_create(uint32 options) -> (status status, handle<event> out);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/eventpair.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/eventpair.fidl
new file mode 100644
index 0000000..a7a3e38
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/eventpair.fidl
@@ -0,0 +1,12 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol eventpair {
+ /// Create an event pair.
+ eventpair_create(uint32 options) -> (status status, handle<event> out0, handle<event> out1);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/exception.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/exception.fidl
new file mode 100644
index 0000000..db3e45a
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/exception.fidl
@@ -0,0 +1,17 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol exception {
+ /// Create a handle for the exception's thread.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_EXCEPTION.
+ exception_get_thread(handle<exception> handle) -> (status status, handle<thread> out);
+
+ /// Create a handle for the exception's process.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_EXCEPTION.
+ exception_get_process(handle<exception> handle) -> (status status, handle<process> out);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/fifo.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/fifo.fidl
new file mode 100644
index 0000000..0e9ee21
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/fifo.fidl
@@ -0,0 +1,23 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol fifo {
+ /// Create a fifo.
+ fifo_create(usize elem_count, usize elem_size, uint32 options)
+ -> (status status, handle<fifo> out0, handle<fifo> out1);
+
+ /// Read data from a fifo.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_FIFO and have ZX_RIGHT_READ.
+ fifo_read(handle<fifo> handle, usize elem_size)
+ -> (status status, vector_void data, optional_usize actual_count);
+
+ /// Write data to a fifo.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_FIFO and have ZX_RIGHT_WRITE.
+ fifo_write(handle<fifo> handle, usize elem_size, const_voidptr data, usize count)
+ -> (status status, optional_usize actual_count);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/framebuffer.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/framebuffer.fidl
new file mode 100644
index 0000000..2ab69c7
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/framebuffer.fidl
@@ -0,0 +1,24 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol framebuffer {
+ /// Rights: resource must have resource kind ZX_RSRC_KIND_ROOT.
+ framebuffer_get_info(handle<resource> resource)
+ -> (status status, uint32 format, uint32 width, uint32 height, uint32 stride);
+
+ // TODO(ZX-2967): vmo ZX_OBJ_TYPE_VMO; No rights required?
+ /// Rights: resource must have resource kind ZX_RSRC_KIND_ROOT.
+ framebuffer_set_range(handle<resource> resource,
+ handle<vmo> vmo,
+ uint32 len,
+ uint32 format,
+ uint32 width,
+ uint32 height,
+ uint32 stride)
+ -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/futex.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/futex.fidl
new file mode 100644
index 0000000..69ab6dc
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/futex.fidl
@@ -0,0 +1,58 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+// TODO(scottmg): This is approximately right, but will need to match the
+// current definition of zx_futex_t (atomic_int in some #if branches).
+using Futex = int32;
+
+// TODO(scottmg): The futex is unusual in that by virtue of being an int,
+// sometimes it's passed by pointer, and sometimes by value.
+
+[Transport = "Syscall"]
+protocol futex {
+ /// Wait on a futex.
+ /// Rights: None.
+ [blocking]
+ futex_wait(const_futexptr value_ptr, Futex current_value, handle new_futex_owner, time deadline)
+ -> (status status);
+
+ /// Wake some number of threads waiting on a futex, and set the ownership of the futex to nothing.
+ /// Rights: None.
+ futex_wake(const_futexptr value_ptr, uint32 wake_count) -> (status status);
+
+ /// Wake some number of threads waiting on a futex, and move more waiters to another wait queue.
+ /// Rights: None.
+ futex_requeue(const_futexptr value_ptr,
+ uint32 wake_count,
+ Futex current_value,
+ const_futexptr requeue_ptr,
+ uint32 requeue_count,
+ handle new_requeue_owner)
+ -> (status status);
+
+ /// Wake one thread waiting on a futex. If a thread is woken,
+ /// ownership of the futex is transferred to that thread. If no
+ /// thread is woken (because none are waiting), ownership of the
+ /// futex is set to none.
+ /// Rights: None.
+ futex_wake_single_owner(const_futexptr value_ptr) -> (status status);
+
+ /// Wake one thread waiting on a futex, and move more waiters to
+ /// another wait queue. Ownership is transferred to the woken thread,
+ /// or cancelled, as with |futex_wake_single_owner|.
+ /// Rights: None.
+ futex_requeue_single_owner(const_futexptr value_ptr,
+ Futex current_value,
+ const_futexptr requeue_ptr,
+ uint32 requeue_count,
+ handle new_requeue_owner)
+ -> (status status);
+
+ /// Fetch the koid current owner of a futex, if any.
+ /// Rights: None.
+ futex_get_owner(const_futexptr value_ptr) -> (status status, optional_koid koid);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/guest.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/guest.fidl
new file mode 100644
index 0000000..a75093e
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/guest.fidl
@@ -0,0 +1,25 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol guest {
+ /// Create a guest.
+ /// Rights: resource must have resource kind ZX_RSRC_KIND_HYPERVISOR.
+ guest_create(handle<resource> resource, uint32 options)
+ -> (status status, handle<guest> guest_handle, handle<vmar> vmar_handle);
+
+ /// Sets a trap within a guest.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_GUEST and have ZX_RIGHT_WRITE.
+ /// Rights: port_handle must be of type ZX_OBJ_TYPE_PORT and have ZX_RIGHT_WRITE.
+ guest_set_trap(handle<guest> handle,
+ uint32 kind,
+ vaddr addr,
+ usize size,
+ handle<port> port_handle,
+ uint64 key)
+ -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/handle.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/handle.fidl
new file mode 100644
index 0000000..b29842b
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/handle.fidl
@@ -0,0 +1,25 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol handle {
+ /// Close a handle.
+ /// Rights: None.
+ handle_close([Release] handle handle) -> (status status);
+
+ /// Close a number of handles.
+ /// Rights: None.
+ handle_close_many([Release] vector<handle> handles) -> (status status);
+
+ /// Duplicate a handle.
+ /// Rights: handle must have ZX_RIGHT_DUPLICATE.
+ handle_duplicate(handle handle, rights rights) -> (status status, handle out);
+
+ /// Replace a handle.
+ /// Rights: None.
+ handle_replace([Release] handle handle, rights rights) -> (status status, handle out);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/interrupt.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/interrupt.fidl
new file mode 100644
index 0000000..506df65
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/interrupt.fidl
@@ -0,0 +1,43 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol interrupt {
+ /// Create an interrupt object.
+ /// Rights: src_obj must have resource kind ZX_RSRC_KIND_IRQ.
+ interrupt_create(handle<resource> src_obj, uint32 src_num, uint32 options)
+ -> (status status, handle<interrupt> out_handle);
+
+ /// Bind an interrupt object to a port.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_INTERRUPT and have ZX_RIGHT_READ.
+ /// Rights: port_handle must be of type ZX_OBJ_TYPE_PORT and have ZX_RIGHT_WRITE.
+ interrupt_bind(handle<interrupt> handle, handle<port> port_handle, uint64 key, uint32 options)
+ -> (status status);
+
+ /// Wait for an interrupt.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_INTERRUPT and have ZX_RIGHT_WAIT.
+ [blocking]
+ interrupt_wait(handle<interrupt> handle) -> (status status, optional_time out_timestamp);
+
+ // TODO(ZX-2967): No DESTROY rights here.
+ /// Destroys an interrupt object.
+ interrupt_destroy(handle<interrupt> handle) -> (status status);
+
+ /// Acknowledge an interrupt and re-arm it.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_INTERRUPT and have ZX_RIGHT_WRITE.
+ interrupt_ack(handle<interrupt> handle) -> (status status);
+
+ /// Triggers a virtual interrupt object.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_INTERRUPT and have ZX_RIGHT_SIGNAL.
+ interrupt_trigger(handle<interrupt> handle, uint32 options, time timestamp) -> (status status);
+
+ /// Bind an interrupt object to a VCPU.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_INTERRUPT and have ZX_RIGHT_READ.
+ /// Rights: vcpu must be of type ZX_OBJ_TYPE_VCPU and have ZX_RIGHT_WRITE.
+ interrupt_bind_vcpu(handle<interrupt> handle, handle<vcpu> vcpu, uint32 options)
+ -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/iommu.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/iommu.fidl
new file mode 100644
index 0000000..84ac2a9
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/iommu.fidl
@@ -0,0 +1,14 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol iommu {
+ /// Create a new IOMMU object in the kernel.
+ /// Rights: resource must have resource kind ZX_RSRC_KIND_ROOT.
+ iommu_create(handle<resource> resource, uint32 type, vector_void desc)
+ -> (status status, handle<iommu> out);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/ioports.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/ioports.fidl
new file mode 100644
index 0000000..72353d3
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/ioports.fidl
@@ -0,0 +1,15 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol ioports {
+ /// Rights: resource must have resource kind ZX_RSRC_KIND_IOPORT.
+ ioports_request(handle<resource> resource, uint16 io_addr, uint32 len) -> (status status);
+
+ /// Rights: resource must have resource kind ZX_RSRC_KIND_IOPORT.
+ ioports_release(handle<resource> resource, uint16 io_addr, uint32 len) -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/job.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/job.fidl
new file mode 100644
index 0000000..edbdd2c
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/job.fidl
@@ -0,0 +1,24 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol job {
+ // TODO(ZX-2967): parent_job with ZX_RIGHT_WRITE is also accepted.
+ /// Create a new job.
+ /// Rights: parent_job must be of type ZX_OBJ_TYPE_JOB and have ZX_RIGHT_MANAGE_JOB.
+ job_create(handle<job> parent_job, uint32 options) -> (status status, handle<job> out);
+
+ /// Set job security and resource policies.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_JOB and have ZX_RIGHT_SET_POLICY.
+ job_set_policy(handle<job> handle, uint32 options, uint32 topic, vector_void_u32size policy)
+ -> (status status);
+
+ /// Set a process as critical to a job.
+ /// Rights: job must have ZX_RIGHT_DESTROY.
+ /// Rights: process must have ZX_RIGHT_WAIT.
+ job_set_critical(handle<job> job, uint32 options, handle<process> process) -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/ktrace.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/ktrace.fidl
new file mode 100644
index 0000000..d3234e6
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/ktrace.fidl
@@ -0,0 +1,26 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol ktrace {
+ // TODO(scottmg): This is another one where it's:
+ // (handle, data, offset, data_size)
+ // rather than:
+ // (handle, data, data_size, offset).
+ /// Rights: handle must have resource kind ZX_RSRC_KIND_ROOT.
+ [ArgReorder = "handle, data, offset, data_size, actual"]
+ ktrace_read(handle<resource> handle, uint32 offset)
+ -> (status status, vector_void data, usize actual);
+
+ // TODO(scottmg): syscalls.banjo had the length of |ptr| being |action|?
+ /// Rights: handle must have resource kind ZX_RSRC_KIND_ROOT.
+ ktrace_control(handle<resource> handle, uint32 action, uint32 options, voidptr ptr)
+ -> (status status);
+
+ /// Rights: handle must have resource kind ZX_RSRC_KIND_ROOT.
+ ktrace_write(handle<resource> handle, uint32 id, uint32 arg0, uint32 arg1) -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/misc.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/misc.fidl
new file mode 100644
index 0000000..6c0e4c4
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/misc.fidl
@@ -0,0 +1,57 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+// TODO(scottmg): These syscalls don't match the general naming convention of
+// zx_something_name(), they're just zx_name(), so NoProtocolPrefix tells the
+// generator to exclude putting "Misc" in the name.
+[Transport = "Syscall",
+NoProtocolPrefix]
+protocol misc {
+ /// High resolution sleep.
+ /// Rights: None.
+ [blocking]
+ nanosleep(time deadline) -> (status status);
+
+ /// Read the number of high-precision timer ticks since boot.
+ [vdsocall]
+ ticks_get() -> (ticks ticks);
+
+ /// Read the number of high-precision timer ticks in a second.
+ [const,
+ vdsocall]
+ ticks_per_second() -> (ticks ticks);
+
+ /// Convert a time relative to now to an absolute deadline.
+ [vdsocall]
+ deadline_after(duration nanoseconds) -> (time time);
+
+ /// Unmap memory, close handle, exit.
+ [vdsocall]
+ vmar_unmap_handle_close_thread_exit(handle<vmar> vmar_handle,
+ vaddr addr, usize size,
+ [Release] handle close_handle)
+ -> (status status);
+
+ /// Write to futex, wake futex, close handle, exit.
+ [noreturn,
+ vdsocall]
+ futex_wake_handle_close_thread_exit(const_futexptr value_ptr,
+ uint32 wake_count,
+ int32 new_value,
+ [Release] handle close_handle);
+
+ // Read the number of high-precision timer ticks since boot, but demand
+ // that the read be performed using a syscall, instead of a vdso call.
+ //
+ // Note that this is an internal syscall, not meant to be used by
+ // application code. By default, the vdso version of this syscall will do
+ // the proper thing, either directly reading from the hardware register
+ // backing the tick counter, or by making a syscall if the register is not
+ // accessible from user mode code (for whatever reason).
+ [internal]
+ ticks_get_via_kernel() -> (ticks ticks);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/mtrace.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/mtrace.fidl
new file mode 100644
index 0000000..f3c1f1c
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/mtrace.fidl
@@ -0,0 +1,17 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol mtrace {
+ /// Rights: handle must have resource kind ZX_RSRC_KIND_ROOT.
+ mtrace_control(handle<resource> handle,
+ uint32 kind,
+ uint32 action,
+ uint32 options,
+ mutable_vector_void ptr)
+ -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/object.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/object.fidl
new file mode 100644
index 0000000..f510fec
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/object.fidl
@@ -0,0 +1,95 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+// TODO(scottmg): Apply rights spec from WaitMany on |items| to |handle| here,
+// somehow.
+struct WaitItem {
+ handle handle;
+ signals waitfor;
+ signals pending;
+};
+
+[Transport = "Syscall"]
+protocol object {
+ /// Wait for signals on an object.
+ /// Rights: handle must have ZX_RIGHT_WAIT.
+ [blocking]
+ object_wait_one(handle handle, signals signals, time deadline)
+ -> (status status, optional_signals observed);
+
+ /// Wait for signals on multiple objects.
+ /// Rights: Every entry of items must have a handle field with ZX_RIGHT_WAIT.
+ [blocking]
+ object_wait_many(mutable_vector_WaitItem items, time deadline) -> (status status);
+
+ /// Subscribe for signals on an object.
+ /// Rights: handle must have ZX_RIGHT_WAIT.
+ /// Rights: port must be of type ZX_OBJ_TYPE_PORT and have ZX_RIGHT_WRITE.
+ object_wait_async(handle handle, handle<port> port, uint64 key, signals signals, uint32 options)
+ -> (status status);
+
+ /// Signal an object.
+ /// Rights: handle must have ZX_RIGHT_SIGNAL.
+ object_signal(handle handle, uint32 clear_mask, uint32 set_mask) -> (status status);
+
+ /// Signal an object's peer.
+ /// Rights: handle must have ZX_RIGHT_SIGNAL_PEER.
+ object_signal_peer(handle handle, uint32 clear_mask, uint32 set_mask) -> (status status);
+
+ /// Ask for various properties of various kernel objects.
+ /// Rights: handle must have ZX_RIGHT_GET_PROPERTY.
+ /// Rights: If property is ZX_PROP_PROCESS_DEBUG_ADDR, handle must be of type ZX_OBJ_TYPE_PROCESS.
+ /// Rights: If property is ZX_PROP_PROCESS_BREAK_ON_LOAD, handle must be of type ZX_OBJ_TYPE_PROCESS.
+ /// Rights: If property is ZX_PROP_PROCESS_VDSO_BASE_ADDRESS, handle must be of type ZX_OBJ_TYPE_PROCESS.
+ /// Rights: If property is ZX_PROP_SOCKET_RX_THRESHOLD, handle must be of type ZX_OBJ_TYPE_SOCKET.
+ /// Rights: If property is ZX_PROP_SOCKET_TX_THRESHOLD, handle must be of type ZX_OBJ_TYPE_SOCKET.
+ object_get_property(handle handle, uint32 property) -> (status status, vector_void value);
+
+ /// Set various properties of various kernel objects.
+ /// Rights: handle must have ZX_RIGHT_SET_PROPERTY.
+ /// Rights: If property is ZX_PROP_PROCESS_DEBUG_ADDR, handle must be of type ZX_OBJ_TYPE_PROCESS.
+ /// Rights: If property is ZX_PROP_PROCESS_BREAK_ON_LOAD, handle must be of type ZX_OBJ_TYPE_PROCESS.
+ /// Rights: If property is ZX_PROP_SOCKET_RX_THRESHOLD, handle must be of type ZX_OBJ_TYPE_SOCKET.
+ /// Rights: If property is ZX_PROP_SOCKET_TX_THRESHOLD, handle must be of type ZX_OBJ_TYPE_SOCKET.
+ /// Rights: If property is ZX_PROP_JOB_KILL_ON_OOM, handle must be of type ZX_OBJ_TYPE_JOB.
+ object_set_property(handle handle, uint32 property, vector_void value) -> (status status);
+
+ /// Query information about an object.
+ /// Rights: If topic is ZX_INFO_PROCESS, handle must be of type ZX_OBJ_TYPE_PROCESS and have ZX_RIGHT_INSPECT.
+ /// Rights: If topic is ZX_INFO_JOB, handle must be of type ZX_OBJ_TYPE_JOB and have ZX_RIGHT_INSPECT.
+ /// Rights: If topic is ZX_INFO_PROCESS_THREADS, handle must be of type ZX_OBJ_TYPE_PROCESS and have ZX_RIGHT_ENUMERATE.
+ /// Rights: If topic is ZX_INFO_JOB_CHILDREN, handle must be of type ZX_OBJ_TYPE_JOB and have ZX_RIGHT_ENUMERATE.
+ /// Rights: If topic is ZX_INFO_JOB_PROCESSES, handle must be of type ZX_OBJ_TYPE_JOB and have ZX_RIGHT_ENUMERATE.
+ /// Rights: If topic is ZX_INFO_THREAD, handle must be of type ZX_OBJ_TYPE_THREAD and have ZX_RIGHT_INSPECT.
+ /// Rights: If topic is ZX_INFO_THREAD_EXCEPTION_REPORT, handle must be of type ZX_OBJ_TYPE_THREAD and have ZX_RIGHT_INSPECT.
+ /// Rights: If topic is ZX_INFO_THREAD_STATS, handle must be of type ZX_OBJ_TYPE_THREAD and have ZX_RIGHT_INSPECT.
+ /// Rights: If topic is ZX_INFO_TASK_STATS, handle must be of type ZX_OBJ_TYPE_PROCESS and have ZX_RIGHT_INSPECT.
+ /// Rights: If topic is ZX_INFO_PROCESS_MAPS, handle must be of type ZX_OBJ_TYPE_PROCESS and have ZX_RIGHT_INSPECT.
+ /// Rights: If topic is ZX_INFO_PROCESS_VMOS, handle must be of type ZX_OBJ_TYPE_PROCESS and have ZX_RIGHT_INSPECT.
+ /// Rights: If topic is ZX_INFO_VMO, handle must be of type ZX_OBJ_TYPE_VMO.
+ /// TODO(ZX-2967), Should this require INSPECT?
+ /// Rights: If topic is ZX_INFO_VMAR, handle must be of type ZX_OBJ_TYPE_VMAR and have ZX_RIGHT_INSPECT.
+ /// Rights: If topic is ZX_INFO_CPU_STATS, handle must have resource kind ZX_RSRC_KIND_ROOT.
+ /// Rights: If topic is ZX_INFO_KMEM_STATS, handle must have resource kind ZX_RSRC_KIND_ROOT.
+ /// Rights: If topic is ZX_INFO_RESOURCE, handle must be of type ZX_OBJ_TYPE_RESOURCE and have ZX_RIGHT_INSPECT.
+ /// Rights: If topic is ZX_INFO_HANDLE_COUNT, handle must have ZX_RIGHT_INSPECT.
+ /// Rights: If topic is ZX_INFO_BTI, handle must be of type ZX_OBJ_TYPE_BTI and have ZX_RIGHT_INSPECT.
+ /// Rights: If topic is ZX_INFO_PROCESS_HANDLE_STATS, handle must be of type ZX_OBJ_TYPE_PROCESS and have ZX_RIGHT_INSPECT.
+ /// Rights: If topic is ZX_INFO_SOCKET, handle must be of type ZX_OBJ_TYPE_SOCKET and have ZX_RIGHT_INSPECT.
+ object_get_info(handle handle, uint32 topic)
+ -> (status status, vector_void buffer, optional_usize actual, optional_usize avail);
+
+ /// Given a kernel object with children objects, obtain a handle to the child specified by the provided kernel object id.
+ /// Rights: handle must have ZX_RIGHT_ENUMERATE.
+ object_get_child(handle handle, uint64 koid, rights rights) -> (status status, handle out);
+
+ /// Apply a scheduling profile to a thread.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_THREAD and have ZX_RIGHT_MANAGE_THREAD.
+ /// Rights: profile must be of type ZX_OBJ_TYPE_PROFILE and have ZX_RIGHT_APPLY_PROFILE.
+ object_set_profile(handle<thread> handle, handle<profile> profile, uint32 options)
+ -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/pager.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/pager.fidl
new file mode 100644
index 0000000..6c7c581
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/pager.fidl
@@ -0,0 +1,36 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol pager {
+ /// Create a new pager object.
+ /// Rights: None.
+ pager_create(uint32 options) -> (status status, handle<pager> out);
+
+ /// Create a pager owned vmo.
+ /// Rights: pager must be of type ZX_OBJ_TYPE_PAGER.
+ /// Rights: port must be of type ZX_OBJ_TYPE_PORT and have ZX_RIGHT_WRITE.
+ pager_create_vmo(handle<pager> pager, uint32 options, handle<port> port, uint64 key, uint64 size)
+ -> (status status, handle<vmo> out);
+
+ /// Detaches a vmo from a pager.
+ /// Rights: pager must be of type ZX_OBJ_TYPE_PAGER.
+ /// Rights: vmo must be of type ZX_OBJ_TYPE_VMO.
+ pager_detach_vmo(handle<pager> pager, handle<vmo> vmo) -> (status status);
+
+ /// Supply pages into a pager owned vmo.
+ /// Rights: pager must be of type ZX_OBJ_TYPE_PAGER.
+ /// Rights: pager_vmo must be of type ZX_OBJ_TYPE_VMO.
+ /// Rights: aux_vmo must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_READ and have ZX_RIGHT_WRITE.
+ pager_supply_pages(handle<pager> pager,
+ handle<vmo> pager_vmo,
+ uint64 offset,
+ uint64 length,
+ handle<vmo> aux_vmo,
+ uint64 aux_offset)
+ -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/pc.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/pc.fidl
new file mode 100644
index 0000000..cb10baa
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/pc.fidl
@@ -0,0 +1,12 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol pc {
+ /// Rights: handle must have resource kind ZX_RSRC_KIND_ROOT.
+ pc_firmware_tables(handle<resource> handle) -> (status status, paddr acpi_rsdp, paddr smbios);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/pci.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/pci.fidl
new file mode 100644
index 0000000..d5c80db
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/pci.fidl
@@ -0,0 +1,127 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+// TODO(cja): This makes some assumptions that anything in an arch's PIO region
+// is going to be defined as a base address and size. This will need to be
+// updated to a per-platform structure in the event that doesn't pan out
+// in the future.
+struct PciBar {
+ uint32 id;
+ uint32 type;
+ usize size;
+ // TODO(scottmg): Unnamed union.
+ //union {
+ // uintptr_t addr;
+ // zx_handle_t handle;
+ //};
+};
+
+// Defines and structures related to zx_pci_*()
+// Info returned to dev manager for PCIe devices when probing.
+struct PcieDeviceInfo {
+ uint16 vendor_id;
+ uint16 device_id;
+
+ uint8 base_class;
+ uint8 sub_class;
+ uint8 program_interface;
+ uint8 revision_id;
+
+ uint8 bus_id;
+ uint8 dev_id;
+ uint8 func_id;
+};
+
+// TODO(scottmg): Lots of constants here.
+
+// TODO(scottmg): This one is hard.
+struct PciInitArg {
+ // TODO(scottmg): [][][] array.
+ // zx_pci_irq_swizzle_lut_t dev_pin_to_global_irq;
+
+ uint32 num_irqs;
+ //struct {
+ // uint32_t global_irq;
+ // bool level_triggered;
+ // bool active_high;
+ //} irqs[ZX_PCI_MAX_IRQS];
+
+ uint32 addr_window_count;
+ // TODO(scottmg): struct-hack sized.
+ //struct {
+ // uint64_t base;
+ // size_t size;
+ // uint8_t bus_start;
+ // uint8_t bus_end;
+ // uint8_t cfg_space_type;
+ // bool has_ecam;
+ //} addr_windows[];
+};
+
+[Transport = "Syscall"]
+protocol pci {
+ /// Rights: handle must have resource kind ZX_RSRC_KIND_ROOT.
+ pci_get_nth_device(handle<resource> handle, uint32 index)
+ -> (status status, PcieDeviceInfo out_info, handle out_handle);
+
+ /// Rights: handle must be of type ZX_OBJ_TYPE_PCI_DEVICE and have ZX_RIGHT_WRITE.
+ pci_enable_bus_master(handle<pcidevice> handle, bool enable) -> (status status);
+
+ /// Rights: handle must be of type ZX_OBJ_TYPE_PCI_DEVICE and have ZX_RIGHT_WRITE.
+ pci_reset_device(handle<pcidevice> handle) -> (status status);
+
+ // TODO(scottmg): In banjo/abigen out_val wasn't optional, but was an input
+ // OUT, so didn't get the __NONNULL() tag, so we match by making it optional
+ // here. I think this is probably not the intention, and it should be
+ // non-optional.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_PCI_DEVICE and have ZX_RIGHT_READ and have ZX_RIGHT_WRITE.
+ pci_config_read(handle<pcidevice> handle, uint16 offset, usize width)
+ -> (status status, optional_uint32 out_val);
+
+ /// Rights: handle must be of type ZX_OBJ_TYPE_PCI_DEVICE and have ZX_RIGHT_READ and have ZX_RIGHT_WRITE.
+ pci_config_write(handle<pcidevice> handle, uint16 offset, usize width, uint32 val)
+ -> (status status);
+
+ /// Rights: handle must have resource kind ZX_RSRC_KIND_ROOT.
+ pci_cfg_pio_rw(handle<resource> handle,
+ uint8 bus,
+ uint8 dev,
+ uint8 func,
+ uint8 offset,
+ mutable_uint32 val,
+ usize width,
+ bool write)
+ -> (status status);
+
+ // TODO(scottmg): type of out_handle?
+ // TODO(scottmg): In banjo/abigen out_bar wasn't optional, but was an input
+ // OUT, so has no __NONNULL(). I think this is probably not the intention.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_PCI_DEVICE and have ZX_RIGHT_READ and have ZX_RIGHT_WRITE.
+ pci_get_bar(handle<pcidevice> handle, uint32 bar_num)
+ -> (status status, optional_PciBar out_bar, handle out_handle);
+
+ /// Rights: handle must be of type ZX_OBJ_TYPE_PCI_DEVICE and have ZX_RIGHT_READ.
+ pci_map_interrupt(handle<pcidevice> handle, int32 which_irq)
+ -> (status status, handle out_handle);
+
+ /// Rights: handle must be of type ZX_OBJ_TYPE_PCI_DEVICE and have ZX_RIGHT_READ.
+ pci_query_irq_mode(handle<pcidevice> handle, uint32 mode)
+ -> (status status, uint32 out_max_irqs);
+
+ /// Rights: handle must be of type ZX_OBJ_TYPE_PCI_DEVICE and have ZX_RIGHT_WRITE.
+ pci_set_irq_mode(handle<pcidevice> handle, uint32 mode, uint32 requested_irq_count)
+ -> (status status);
+
+ // Note that init_buf isn't a vector of PciInitArg, it's a variable sized
+ // structure starting with a zx_pci_init_arg_t.
+ /// Rights: handle must have resource kind ZX_RSRC_KIND_ROOT.
+ pci_init(handle<resource> handle, PciInitArg init_buf, uint32 len) -> (status status);
+
+ /// Rights: handle must have resource kind ZX_RSRC_KIND_ROOT.
+ pci_add_subtract_io_range(handle<resource> handle, bool mmio, uint64 base, uint64 len, bool add)
+ -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/pmt.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/pmt.fidl
new file mode 100644
index 0000000..0e37311
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/pmt.fidl
@@ -0,0 +1,13 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol pmt {
+ // TODO(ZX-2967): handle ZX_OBJ_TYPE_PMT; No rights required?
+ /// Unpin pages and revoke device access to them.
+ pmt_unpin(handle<pmt> handle) -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/port.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/port.fidl
new file mode 100644
index 0000000..b07fb7b
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/port.fidl
@@ -0,0 +1,146 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+// port_packet_t::type ZX_PKT_TYPE_USER.
+union PacketUser {
+ 1: array<uint64>:4 u64;
+ 2: array<uint32>:8 u32;
+ 3: array<uint16>:16 u16;
+ 4: array<int8>:32 c8;
+};
+
+// port_packet_t::type ZX_PKT_TYPE_SIGNAL_ONE.
+struct PacketSignal {
+ signals trigger;
+ signals observed;
+ uint64 count;
+ uint64 reserved0;
+ uint64 reserved1;
+};
+
+struct PacketException {
+ uint64 pid;
+ uint64 tid;
+ uint64 reserved0;
+ uint64 reserved1;
+};
+
+struct PacketGuestBell {
+ gpaddr addr;
+ uint64 reserved0;
+ uint64 reserved1;
+ uint64 reserved2;
+};
+
+// TODO(scottmg): Arch-specific definition.
+struct PacketGuestMem {
+ gpaddr addr;
+ //#if __aarch64__
+ //uint8_t access_size;
+ //bool sign_extend;
+ //uint8_t xt;
+ //bool read;
+ //uint64_t data;
+ //uint64_t reserved;
+ //#elif __x86_64__
+ //// NOTE: x86 instructions are guaranteed to be 15 bytes or fewer.
+ //#define X86_MAX_INST_LEN 15u
+ //uint8_t inst_len;
+ //uint8_t inst_buf[X86_MAX_INST_LEN];
+ //// This is the default operand size as determined by the CS and EFER register (Volume 3,
+ //// Section 5.2.1). If operating in 64-bit mode then near branches and all instructions, except
+ //// far branches, that implicitly reference the RSP will actually have a default operand size of
+ //// 64-bits (Volume 2, Section 2.2.1.7), and not the 32-bits that will be given here.
+ //uint8_t default_operand_size;
+ //uint8_t reserved[7];
+ //#endif
+};
+
+struct PacketGuestIo {
+ uint16 port;
+ uint8 access_size;
+ bool input;
+ // TODO(scottmg): Unnamed union.
+ //union {
+ // uint8_t u8;
+ // uint16_t u16;
+ // uint32_t u32;
+ // uint8_t data[4];
+ //};
+ uint64 reserved0;
+ uint64 reserved1;
+ uint64 reserved2;
+};
+
+struct PacketGuestVcpu {
+ // TODO(scottmg): Unnamed union.
+ //union {
+ // struct {
+ // uint64_t mask;
+ // uint8_t vector;
+ // } interrupt;
+ // struct {
+ // uint64_t id;
+ // zx_gpaddr_t entry;
+ // } startup;
+ //};
+ uint8 type;
+ uint64 reserved;
+};
+
+struct PacketInterrupt {
+ time timestamp;
+ uint64 reserved0;
+ uint64 reserved1;
+ uint64 reserved2;
+};
+
+struct PacketPageRequest {
+ uint16 command;
+ uint16 flags;
+ uint32 reserved0;
+ uint64 offset;
+ uint64 length;
+ uint64 reserved1;
+};
+
+struct PortPacket {
+ uint64 key;
+ uint32 type;
+ status status;
+ // TODO(scottmg): Unnamed union.
+ // union {
+ PacketUser user;
+ PacketSignal signal;
+ PacketException exception;
+ PacketGuestBell guest_bell;
+ PacketGuestMem guest_mem;
+ PacketGuestIo guest_io;
+ PacketGuestVcpu guest_vcpu;
+ PacketInterrupt interrupt;
+ PacketPageRequest page_request;
+ // };
+};
+
+[Transport = "Syscall"]
+protocol port {
+ /// Create an IO port.
+ port_create(uint32 options) -> (status status, handle<port> out);
+
+ /// Queue a packet to a port.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_PORT and have ZX_RIGHT_WRITE.
+ port_queue(handle<port> handle, PortPacket packet) -> (status status);
+
+ /// Wait for a packet arrival in a port.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_PORT and have ZX_RIGHT_READ.
+ [blocking]
+ port_wait(handle<port> handle, time deadline) -> (status status, optional_PortPacket packet);
+
+ /// Cancels async port notifications on an object.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_PORT and have ZX_RIGHT_WRITE.
+ port_cancel(handle<port> handle, handle source, uint64 key) -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/process.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/process.fidl
new file mode 100644
index 0000000..b9c3eb3
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/process.fidl
@@ -0,0 +1,38 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol process {
+ /// Exits the currently running process.
+ [noreturn]
+ process_exit(int64 retcode);
+
+ // TODO(ZX-2967): job with ZX_RIGHT_WRITE is also accepted.
+ /// Create a new process.
+ /// Rights: job must be of type ZX_OBJ_TYPE_JOB and have ZX_RIGHT_MANAGE_PROCESS.
+ process_create(handle<job> job, string name, uint32 options)
+ -> (status status, handle<process> proc_handle, handle<vmar> vmar_handle);
+
+ /// Start execution on a process.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_PROCESS and have ZX_RIGHT_WRITE.
+ /// Rights: thread must be of type ZX_OBJ_TYPE_THREAD and have ZX_RIGHT_WRITE.
+ /// Rights: arg1 must have ZX_RIGHT_TRANSFER.
+ process_start(handle<process> handle, handle<thread> thread,
+ vaddr entry, vaddr stack,
+ handle arg1, uintptr arg2)
+ -> (status status);
+
+ /// Read from the given process's address space.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_PROCESS and have ZX_RIGHT_READ and have ZX_RIGHT_WRITE.
+ process_read_memory(handle<process> handle, vaddr vaddr)
+ -> (status status, vector_void buffer, usize actual);
+
+ /// Write into the given process's address space.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_PROCESS and have ZX_RIGHT_WRITE.
+ process_write_memory(handle<process> handle, vaddr vaddr, vector_void buffer)
+ -> (status status, usize actual);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/profile.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/profile.fidl
new file mode 100644
index 0000000..c808f4d
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/profile.fidl
@@ -0,0 +1,43 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+enum ProfileInfoType {
+ ZX_PROFILE_INFO_SCHEDULER = 1;
+};
+
+union ProfileScheduler {
+ 1: int32 priority;
+ 2: uint32 boost;
+ 3: uint32 deboost;
+ 4: uint32 quantum;
+};
+
+const int32 ZX_PRIORITY_LOWEST = 0;
+const int32 ZX_PRIORITY_LOW = 8;
+const int32 ZX_PRIORITY_DEFAULT = 16;
+const int32 ZX_PRIORITY_HIGH = 24;
+const int32 ZX_PRIORITY_HIGHEST = 31;
+
+union ProfileInfoData {
+ 1: ProfileScheduler scheduler;
+};
+
+struct ProfileInfo {
+ ProfileInfoType type;
+ // TODO(scottmg): This needs to be presented as an unnamed union in C, and
+ // ProfileInfoData doesn't really need a name. Not sure if the semantics of
+ // fidl unions make sense here.
+ ProfileInfoData unnamed;
+};
+
+[Transport = "Syscall"]
+protocol profile {
+ /// Create a scheduler profile.
+ /// Rights: root_job must be of type ZX_OBJ_TYPE_JOB and have ZX_RIGHT_MANAGE_PROCESS.
+ profile_create(handle<job> root_job, uint32 options, ProfileInfo profile)
+ -> (status status, handle<profile> out);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/resource.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/resource.fidl
new file mode 100644
index 0000000..1854504
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/resource.fidl
@@ -0,0 +1,18 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol resource {
+ /// Create a resource object.
+ /// Rights: parent_rsrc must be of type ZX_OBJ_TYPE_RESOURCE and have ZX_RIGHT_WRITE.
+ resource_create(handle<resource> parent_rsrc,
+ uint32 options,
+ uint64 base,
+ usize size,
+ string name)
+ -> (status status, handle<resource> resource_out);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/rights.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/rights.fidl
new file mode 100644
index 0000000..69ba88f
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/rights.fidl
@@ -0,0 +1,36 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+// TODO(scottmg): (1 << 4) notation or something else for bits would be nice.
+bits rights : uint32 {
+ // TODO(scottmg): "bits members must be powers of two"
+ // NONE = 0x00000000;
+ DUPLICATE = 0x00000001;
+ TRANSFER = 0x00000002;
+ READ = 0x00000004;
+ WRITE = 0x00000008;
+ EXECUTE = 0x00000010;
+ MAP = 0x00000020;
+ GET_PROPERTY = 0x00000040;
+ SET_PROPERTY = 0x00000080;
+ ENUMERATE = 0x00000100;
+ DESTROY = 0x00000200;
+ SET_POLICY = 0x00000400;
+ GET_POLICY = 0x00000800;
+ SIGNAL = 0x00001000;
+ SIGNAL_PEER = 0x00002000;
+ WAIT = 0x00004000;
+ INSPECT = 0x00008000;
+ MANAGE_JOB = 0x00010000;
+ MANAGE_PROCESS = 0x00020000;
+ MANAGE_THREAD = 0x00040000;
+ APPLY_PROFILE = 0x00080000;
+ SAME_RIGHTS = 0x80000000;
+
+ // TODO(scottmg): Derived settings using |, &, ~, e.g.:
+ // BASIC = (TRANSFER | DUPLICATE | WAIT | INSPECT);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/smc.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/smc.fidl
new file mode 100644
index 0000000..b039311
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/smc.fidl
@@ -0,0 +1,36 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+// TODO(scottmg): ARM_SMC_xyz.
+
+struct SmcParameters {
+ uint32 func_id;
+ uint64 arg1;
+ uint64 arg2;
+ uint64 arg3;
+ uint64 arg4;
+ uint64 arg5;
+ uint64 arg6;
+ uint16 client_id;
+ uint16 secure_os_id;
+};
+
+struct SmcResult {
+ uint64 arg0;
+ uint64 arg1;
+ uint64 arg2;
+ uint64 arg3;
+ uint64 arg6; // at least one implementation uses it as a way to return session_id.
+};
+
+[Transport = "Syscall"]
+protocol smc {
+ // TODO(ZX-2967): handle No rights required?
+ // TODO(scottmg): No handle type?
+ /// Make Secure Monitor Call (SMC) from user space.
+ smc_call(handle handle, SmcParameters parameters) -> (status status, SmcResult out_smc_result);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/socket.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/socket.fidl
new file mode 100644
index 0000000..00f7159
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/socket.fidl
@@ -0,0 +1,26 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol socket {
+ /// Create a socket.
+ socket_create(uint32 options) -> (status status, handle out0, handle out1);
+
+ /// Write data to a socket.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_SOCKET and have ZX_RIGHT_WRITE.
+ socket_write(handle<socket> handle, uint32 options, vector_void buffer)
+ -> (status status, optional_usize actual);
+
+ /// Read data from a socket.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_SOCKET and have ZX_RIGHT_READ.
+ socket_read(handle<socket> handle, uint32 options)
+ -> (status status, vector_void buffer, optional_usize actual);
+
+ /// Prevent reading or writing.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_SOCKET and have ZX_RIGHT_WRITE.
+ socket_shutdown(handle<socket> handle, uint32 options) -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/stream.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/stream.fidl
new file mode 100644
index 0000000..cf6cdbd
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/stream.fidl
@@ -0,0 +1,44 @@
+// Copyright 2020 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+enum stream_seek_origin : uint32 {
+ START = 0;
+ CURRENT = 1;
+ END = 2;
+};
+
+[Transport = "Syscall"]
+protocol stream {
+ /// Create a stream from a VMO.
+ stream_create(uint32 options, handle<vmo> vmo, off seek)
+ -> (status status, handle<stream> out_stream);
+
+ /// Write data to a stream at the current seek offset.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_STREAM and have ZX_RIGHT_WRITE.
+ stream_writev(handle<stream> handle, uint32 options, vector_iovec vector)
+ -> (status status, optional_usize actual);
+
+ /// Write data to a stream at the given offset.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_STREAM and have ZX_RIGHT_WRITE.
+ stream_writev_at(handle<stream> handle, uint32 options, off offset, vector_iovec vector)
+ -> (status status, optional_usize actual);
+
+ /// Read data from a stream at the current seek offset.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_STREAM and have ZX_RIGHT_READ.
+ stream_readv(handle<stream> handle, uint32 options)
+ -> (status status, vector_iovec vector, optional_usize actual);
+
+ /// Read data from a stream at the given offset.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_STREAM and have ZX_RIGHT_READ.
+ stream_readv_at(handle<stream> handle, uint32 options, off offset)
+ -> (status status, vector_iovec vector, optional_usize actual);
+
+ /// Modify the seek offset.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_STREAM and have ZX_RIGHT_READ or have ZX_RIGHT_WRITE.
+ stream_seek(handle<stream> handle, stream_seek_origin whence, int64 offset)
+ -> (status status, optional_off out_seek);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/syscall.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/syscall.fidl
new file mode 100644
index 0000000..06e5683
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/syscall.fidl
@@ -0,0 +1,46 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol syscall {
+ [testonly]
+ syscall_test_0() -> (status status);
+
+ [testonly,
+ test_category1]
+ syscall_test_1(int32 a) -> (status status);
+
+ [testonly,
+ test_category1]
+ syscall_test_2(int32 a, int32 b) -> (status status);
+
+ [testonly,
+ test_category2]
+ syscall_test_3(int32 a, int32 b, int32 c) -> (status status);
+
+ [testonly]
+ syscall_test_4(int32 a, int32 b, int32 c, int32 d) -> (status status);
+
+ [testonly]
+ syscall_test_5(int32 a, int32 b, int32 c, int32 d, int32 e) -> (status status);
+
+ [testonly]
+ syscall_test_6(int32 a, int32 b, int32 c, int32 d, int32 e, int32 f) -> (status status);
+
+ [testonly]
+ syscall_test_7(int32 a, int32 b, int32 c, int32 d, int32 e, int32 f, int32 g) -> (status status);
+
+ [testonly]
+ syscall_test_8(int32 a, int32 b, int32 c, int32 d, int32 e, int32 f, int32 g, int32 h)
+ -> (status status);
+
+ [testonly]
+ syscall_test_wrapper(int32 a, int32 b, int32 c) -> (status status);
+
+ [testonly]
+ syscall_test_handle_create(status return_value) -> (status status, handle<event> out);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/system.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/system.fidl
new file mode 100644
index 0000000..12ada66
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/system.fidl
@@ -0,0 +1,65 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+struct SystemPowerctlArg {
+ // TODO(scottmg): More unnamed unions.
+ //union {
+ // struct {
+ // uint8_t target_s_state; // Value between 1 and 5 indicating which S-state
+ // uint8_t sleep_type_a; // Value from ACPI VM (SLP_TYPa)
+ // uint8_t sleep_type_b; // Value from ACPI VM (SLP_TYPb)
+ // } acpi_transition_s_state;
+ // struct {
+ // uint32_t power_limit; // PL1 value in milliwatts
+ // uint32_t time_window; // PL1 time window in microseconds
+ // uint8_t clamp; // PL1 clamping enable
+ // uint8_t enable; // PL1 enable
+ // } x86_power_limit;
+ //};
+};
+
+[Transport = "Syscall"]
+protocol system {
+ [const, vdsocall]
+ system_get_dcache_line_size() -> (uint32 size);
+
+ /// Get number of logical processors on the system.
+ [const, vdsocall]
+ system_get_num_cpus() -> (uint32 count);
+
+ /// Get version string for system.
+ [const, vdsocall]
+ system_get_version_string() -> (string_view version);
+
+ /// Get amount of physical memory on the system.
+ [vdsocall]
+ system_get_physmem() -> (uint64 physmem);
+
+ // TODO(scottmg): "features" has a features attribute. I'm not sure if/how it's used.
+ /// Get supported hardware capabilities.
+ [vdsocall]
+ system_get_features(uint32 kind) -> (status status, uint32 features);
+
+ /// Retrieve a handle to a system event.
+ /// Rights: None.
+ system_get_event(handle<job> root_job, uint32 kind) -> (status status, handle<event> event);
+
+ /// Soft reboot the system with a new kernel and bootimage.
+ /// Rights: resource must have resource kind ZX_RSRC_KIND_ROOT.
+ /// Rights: kernel_vmo must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_READ.
+ /// Rights: bootimage_vmo must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_READ.
+ system_mexec(handle<resource> resource, handle<vmo> kernel_vmo, handle<vmo> bootimage_vmo)
+ -> (status status);
+
+ /// Return a ZBI containing ZBI entries necessary to boot this system.
+ /// Rights: resource must have resource kind ZX_RSRC_KIND_ROOT.
+ system_mexec_payload_get(handle<resource> resource) -> (status status, vector_void buffer);
+
+ /// Rights: resource must have resource kind ZX_RSRC_KIND_ROOT.
+ system_powerctl(handle<resource> resource, uint32 cmd, SystemPowerctlArg arg)
+ -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/task.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/task.fidl
new file mode 100644
index 0000000..56cc556
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/task.fidl
@@ -0,0 +1,29 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol task {
+ // TODO(scottmg): Need something like handle<task> in this file to mean {job, process, thread}.
+ // Or otherwise some way to express multiple options for constraints on inputs in this protocol.
+
+ /// Suspend the given task. Currently only thread or process handles may be suspended.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_THREAD or ZX_OBJ_TYPE_PROCESS and have ZX_RIGHT_WRITE.
+ task_suspend(handle handle) -> (status status, handle token);
+
+ /// Suspend the given task. Currently only thread or process handles may be suspended.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_THREAD or ZX_OBJ_TYPE_PROCESS and have ZX_RIGHT_WRITE.
+ task_suspend_token(handle handle) -> (status status, handle token);
+
+ /// Create an exception channel for a given job, process, or thread.
+ /// Rights: handle must have ZX_RIGHT_INSPECT and have ZX_RIGHT_DUPLICATE and have ZX_RIGHT_TRANSFER and have ZX_RIGHT_MANAGE_THREAD.
+ /// Rights: If handle is of type ZX_OBJ_TYPE_JOB or ZX_OBJ_TYPE_PROCESS, it must have ZX_RIGHT_ENUMERATE.
+ task_create_exception_channel(handle handle, uint32 options) -> (status status, handle<channel> out);
+
+ /// Kill the provided task (job, process, or thread).
+ /// Rights: handle must have ZX_RIGHT_DESTROY.
+ task_kill(handle handle) -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/thread.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/thread.fidl
new file mode 100644
index 0000000..9754d05
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/thread.fidl
@@ -0,0 +1,31 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol thread {
+ /// Terminate the current running thread.
+ [noreturn]
+ thread_exit();
+
+ /// Create a thread.
+ /// Rights: process must be of type ZX_OBJ_TYPE_PROCESS and have ZX_RIGHT_MANAGE_THREAD.
+ thread_create(handle<process> process, string name, uint32 options)
+ -> (status status, handle<thread> out);
+
+ /// Start execution on a thread.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_THREAD and have ZX_RIGHT_MANAGE_THREAD.
+ thread_start(handle<thread> handle, vaddr thread_entry, vaddr stack, uintptr arg1, uintptr arg2)
+ -> (status status);
+
+ /// Read one aspect of thread state.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_THREAD and have ZX_RIGHT_READ.
+ thread_read_state(handle<thread> handle, uint32 kind) -> (status status, vector_void buffer);
+
+ /// Write one aspect of thread state.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_THREAD and have ZX_RIGHT_WRITE.
+ thread_write_state(handle<thread> handle, uint32 kind, vector_void buffer) -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/timer.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/timer.fidl
new file mode 100644
index 0000000..1eae5a9
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/timer.fidl
@@ -0,0 +1,20 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol timer {
+ /// Create a timer.
+ timer_create(uint32 options, Clock clock_id) -> (status status, handle<timer> out);
+
+ /// Start a timer.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_TIMER and have ZX_RIGHT_WRITE.
+ timer_set(handle<timer> handle, time deadline, duration slack) -> (status status);
+
+ /// Cancel a timer.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_TIMER and have ZX_RIGHT_WRITE.
+ timer_cancel(handle<timer> handle) -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/vcpu.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/vcpu.fidl
new file mode 100644
index 0000000..72cc954
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/vcpu.fidl
@@ -0,0 +1,31 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol vcpu {
+ /// Create a VCPU.
+ /// Rights: guest must be of type ZX_OBJ_TYPE_GUEST and have ZX_RIGHT_MANAGE_PROCESS.
+ vcpu_create(handle<guest> guest, uint32 options, vaddr entry) -> (status status, handle<vcpu> out);
+
+ // See port.fidl for definition of PortPacket.
+ /// Resume execution of a VCPU.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_VCPU and have ZX_RIGHT_EXECUTE.
+ [blocking]
+ vcpu_resume(handle<vcpu> handle) -> (status status, PortPacket packet);
+
+ /// Raise an interrupt on a VCPU.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_VCPU and have ZX_RIGHT_SIGNAL.
+ vcpu_interrupt(handle<vcpu> handle, uint32 vector) -> (status status);
+
+ /// Read the state of a VCPU.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_VCPU and have ZX_RIGHT_READ.
+ vcpu_read_state(handle<vcpu> handle, uint32 kind) -> (status status, vector_void buffer);
+
+ /// Write the state of a VCPU.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_VCPU and have ZX_RIGHT_WRITE.
+ vcpu_write_state(handle<vcpu> handle, uint32 kind, vector_void buffer) -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/vmar.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/vmar.fidl
new file mode 100644
index 0000000..0256623
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/vmar.fidl
@@ -0,0 +1,53 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+using VmOption = uint32;
+
+// TODO(scottmg): bits for ZX_VM_xyz flags, and const for ZX_VM_ALIGN_xyz.
+
+[Transport = "Syscall"]
+protocol vmar {
+ /// Allocate a new subregion.
+ /// Rights: If options & ZX_VM_CAN_MAP_READ, parent_vmar must be of type ZX_OBJ_TYPE_VMAR and have ZX_RIGHT_READ.
+ /// Rights: If options & ZX_VM_CAN_MAP_WRITE, parent_vmar must be of type ZX_OBJ_TYPE_VMAR and have ZX_RIGHT_WRITE.
+ /// Rights: If options & ZX_VM_CAN_MAP_EXECUTE, parent_vmar must be of type ZX_OBJ_TYPE_VMAR and have ZX_RIGHT_EXECUTE.
+ vmar_allocate(handle<vmar> parent_vmar, VmOption options, usize offset, usize size)
+ -> (status status, handle<vmar> child_vmar, vaddr child_addr);
+
+ // TODO(ZX-2967): handle No rights required?
+ /// Destroy a virtual memory address region.
+ vmar_destroy(handle<vmar> handle) -> (status status);
+
+ // TODO(ZX-2399): TODO handle and vmo and options must all match, and options can't specify them.
+ /// Add a memory mapping.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_VMAR.
+ /// Rights: vmo must be of type ZX_OBJ_TYPE_VMO.
+ vmar_map(handle<vmar> handle, VmOption options, usize vmar_offset,
+ handle<vmo> vmo, uint64 vmo_offset,
+ usize len)
+ -> (status status, vaddr mapped_addr);
+
+ // TODO(ZX-2967): handle No rights required?
+ /// Unmap virtual memory pages.
+ vmar_unmap(handle<vmo> handle, vaddr addr, usize len) -> (status status);
+
+ /// Set protection of virtual memory pages.
+ /// Rights: If options & ZX_VM_PERM_READ, handle must be of type ZX_OBJ_TYPE_VMAR and have ZX_RIGHT_READ.
+ /// Rights: If options & ZX_VM_PERM_WRITE, handle must be of type ZX_OBJ_TYPE_VMAR and have ZX_RIGHT_WRITE.
+ /// Rights: If options & ZX_VM_PERM_EXECUTE, handle must be of type ZX_OBJ_TYPE_VMAR and have ZX_RIGHT_EXECUTE.
+ vmar_protect(handle<vmo> handle, VmOption options, vaddr addr, usize len) -> (status status);
+
+ /// Perform an operation on VMOs mapped into this VMAR.
+ /// Rights: If op is ZX_VMO_OP_DECOMMIT, affected mappings must be writable.
+ [Blocking]
+ vmar_op_range(handle<vmar> handle,
+ uint32 op,
+ vaddr address,
+ usize size,
+ mutable_vector_void buffer)
+ -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/vmo.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/vmo.fidl
new file mode 100644
index 0000000..060d4cd
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/vmo.fidl
@@ -0,0 +1,81 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol vmo {
+ /// Create a VM object.
+ vmo_create(uint64 size, uint32 options) -> (status status, handle<vmo> out);
+
+ // TODO(scottmg): This syscall is very weird, it's currently:
+ // (handle, buffer, offset, buffer_size)
+ // rather than:
+ // (handle, buffer, buffer_size, offset)
+ // which means the vector<byte> buffer won't work. Unfortunately offset and
+ // buffer_size have the same underlying type, so moving them will be
+ // error-prone.
+ /// Read bytes from the VMO.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_READ.
+ [blocking,
+ ArgReorder = "handle, buffer, offset, buffer_size"]
+ vmo_read(handle<vmo> handle, uint64 offset) -> (status status, vector_void buffer);
+
+ // TODO(scottmg): Same problem as Read() above.
+ /// Write bytes to the VMO.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_WRITE.
+ [blocking,
+ ArgReorder = "handle, buffer, offset, buffer_size"]
+ vmo_write(handle<vmo> handle, vector_void buffer, uint64 offset) -> (status status);
+
+ // TODO(ZX-2967): No rights required?
+ /// Read the current size of a VMO object.
+ vmo_get_size(handle<vmo> handle) -> (status status, uint64 size);
+
+ /// Resize a VMO object.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_WRITE.
+ vmo_set_size(handle<vmo> handle, uint64 size) -> (status status);
+
+ /// Perform an operation on a range of a VMO.
+ /// Rights: If op is ZX_VMO_OP_COMMIT, handle must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_WRITE.
+ /// Rights: If op is ZX_VMO_OP_DECOMMIT, handle must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_WRITE.
+ /// Rights: If op is ZX_VMO_OP_CACHE_SYNC, handle must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_READ.
+ /// Rights: If op is ZX_VMO_OP_CACHE_INVALIDATE, handle must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_WRITE.
+ /// Rights: If op is ZX_VMO_OP_CACHE_CLEAN, handle must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_READ.
+ /// Rights: If op is ZX_VMO_OP_CACHE_CLEAN_INVALIDATE, handle must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_READ.
+ [blocking]
+ vmo_op_range(handle<vmo> handle,
+ uint32 op,
+ uint64 offset,
+ uint64 size,
+ mutable_vector_void buffer)
+ -> (status status);
+
+ /// Create a child of a VM Object.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_DUPLICATE and have ZX_RIGHT_READ.
+ vmo_create_child(handle<vmo> handle, uint32 options, uint64 offset, uint64 size)
+ -> (status status, handle<vmo> out);
+
+ /// Set the caching policy for pages held by a VMO.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_MAP.
+ vmo_set_cache_policy(handle<vmo> handle, uint32 cache_policy) -> (status status);
+
+ // TODO(ZX-2967): handle: No rights required, ZX_RIGHT_EXECUTE added to dup out
+ // TODO(ZX-2967): vmex == ZX_HANDLE_INVALID also accepted.
+ /// Add execute rights to a VMO.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_VMO.
+ /// Rights: vmex must have resource kind ZX_RSRC_KIND_VMEX.
+ vmo_replace_as_executable([Release] handle<vmo> handle, handle<resource> vmex)
+ -> (status status, handle<vmo> out);
+
+ /// Rights: bti must be of type ZX_OBJ_TYPE_BTI and have ZX_RIGHT_MAP.
+ vmo_create_contiguous(handle<bti> bti, usize size, uint32 alignment_log2)
+ -> (status status, handle<vmo> out);
+
+ /// Create a VM object referring to a specific contiguous range of physical memory.
+ /// Rights: resource must have resource kind ZX_RSRC_KIND_MMIO.
+ vmo_create_physical(handle<resource> resource, paddr paddr, usize size)
+ -> (status status, handle<vmo> out);
+};
diff --git a/third_party/fuchsia-sdk/arch/arm64/vdso/zx.fidl b/third_party/fuchsia-sdk/arch/arm64/vdso/zx.fidl
new file mode 100644
index 0000000..ac9903a
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/arm64/vdso/zx.fidl
@@ -0,0 +1,41 @@
+// 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.
+
+// TODO(scottmg): This library is temporarily "zz" instead of "zx" because a
+// "zx" is force-injected by fidlc. Eventually, we'll stop that and use this one
+// instead as "zx". fxb/39732.
+library zz;
+
+using status = int32;
+
+using time = int64;
+using duration = int64;
+using ticks = uint64;
+
+using koid = uint64;
+
+using vaddr = uint64;
+using paddr = uint64;
+using paddr32 = uint32;
+using gpaddr = uint64;
+using off = uint64;
+
+// TODO(scottmg): Not sure what this is.
+using procarg = uint32;
+
+const uint64 CHANNEL_MAX_MSG_BYTES = 65536;
+const uint64 CHANNEL_MAX_MSG_HANDLES = 64;
+
+// TODO(scottmg): == size_t, not sure if this is a good idea.
+using usize = uint64;
+
+// TODO(scottmg): == uintptr_t, not sure if this is a good idea.
+using uintptr = uint64;
+
+// TODO(scottmg): Maybe a void for vector<void> (or vector<any>?) to distinguish
+// polymorphic arguments that are passed as void* from buffers of bytes.
+
+using signals = uint32;
+// TODO(scottmg): Lots of aliases/variations required here. Not sure if bits
+// make sense.
diff --git a/third_party/fuchsia-sdk/arch/x64/dist/VkLayer_core_validation.so b/third_party/fuchsia-sdk/arch/x64/dist/VkLayer_core_validation.so
new file mode 100755
index 0000000..3d351d3
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/dist/VkLayer_core_validation.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/x64/dist/VkLayer_image_pipe_swapchain.so b/third_party/fuchsia-sdk/arch/x64/dist/VkLayer_image_pipe_swapchain.so
new file mode 100755
index 0000000..a01a3c4
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/dist/VkLayer_image_pipe_swapchain.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/x64/dist/VkLayer_khronos_validation.so b/third_party/fuchsia-sdk/arch/x64/dist/VkLayer_khronos_validation.so
new file mode 100755
index 0000000..eb9075c
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/dist/VkLayer_khronos_validation.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/x64/dist/VkLayer_object_lifetimes.so b/third_party/fuchsia-sdk/arch/x64/dist/VkLayer_object_lifetimes.so
new file mode 100755
index 0000000..c22b3cd
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/dist/VkLayer_object_lifetimes.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/x64/dist/VkLayer_stateless_validation.so b/third_party/fuchsia-sdk/arch/x64/dist/VkLayer_stateless_validation.so
new file mode 100755
index 0000000..2afde9e
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/dist/VkLayer_stateless_validation.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/x64/dist/VkLayer_thread_safety.so b/third_party/fuchsia-sdk/arch/x64/dist/VkLayer_thread_safety.so
new file mode 100755
index 0000000..05b60b5
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/dist/VkLayer_thread_safety.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/x64/dist/VkLayer_unique_objects.so b/third_party/fuchsia-sdk/arch/x64/dist/VkLayer_unique_objects.so
new file mode 100755
index 0000000..d9289de
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/dist/VkLayer_unique_objects.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/x64/dist/libasync-default.so b/third_party/fuchsia-sdk/arch/x64/dist/libasync-default.so
new file mode 100755
index 0000000..8882194
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/dist/libasync-default.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/x64/dist/libfdio.so b/third_party/fuchsia-sdk/arch/x64/dist/libfdio.so
new file mode 100755
index 0000000..5d93240
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/dist/libfdio.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/x64/dist/libmemfs.so b/third_party/fuchsia-sdk/arch/x64/dist/libmemfs.so
new file mode 100755
index 0000000..b2a80bd
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/dist/libmemfs.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/x64/dist/libsvc.so b/third_party/fuchsia-sdk/arch/x64/dist/libsvc.so
new file mode 100755
index 0000000..c2d28cb
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/dist/libsvc.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/x64/dist/libsyslog.so b/third_party/fuchsia-sdk/arch/x64/dist/libsyslog.so
new file mode 100755
index 0000000..d4b4bca
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/dist/libsyslog.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/x64/dist/libtrace-engine.so b/third_party/fuchsia-sdk/arch/x64/dist/libtrace-engine.so
new file mode 100755
index 0000000..cf0b787
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/dist/libtrace-engine.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/x64/dist/libtrace-provider-so.so b/third_party/fuchsia-sdk/arch/x64/dist/libtrace-provider-so.so
new file mode 100755
index 0000000..5bc691a
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/dist/libtrace-provider-so.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/x64/dist/libvulkan.so b/third_party/fuchsia-sdk/arch/x64/dist/libvulkan.so
new file mode 100755
index 0000000..6fc7a98
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/dist/libvulkan.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/x64/lib/libasync-default.so b/third_party/fuchsia-sdk/arch/x64/lib/libasync-default.so
new file mode 100755
index 0000000..fc8f68a
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/lib/libasync-default.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/x64/lib/libasync-loop-default.a b/third_party/fuchsia-sdk/arch/x64/lib/libasync-loop-default.a
new file mode 100644
index 0000000..7782b25
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/lib/libasync-loop-default.a
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/x64/lib/libfdio.so b/third_party/fuchsia-sdk/arch/x64/lib/libfdio.so
new file mode 100755
index 0000000..06422b1
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/lib/libfdio.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/x64/lib/libmemfs.so b/third_party/fuchsia-sdk/arch/x64/lib/libmemfs.so
new file mode 100755
index 0000000..71d9539
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/lib/libmemfs.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/x64/lib/libsvc.so b/third_party/fuchsia-sdk/arch/x64/lib/libsvc.so
new file mode 100755
index 0000000..c2d28cb
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/lib/libsvc.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/x64/lib/libsync.a b/third_party/fuchsia-sdk/arch/x64/lib/libsync.a
new file mode 100644
index 0000000..521c6a3
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/lib/libsync.a
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/x64/lib/libsyslog.so b/third_party/fuchsia-sdk/arch/x64/lib/libsyslog.so
new file mode 100755
index 0000000..ccb6eeb
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/lib/libsyslog.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/x64/lib/libtrace-engine.so b/third_party/fuchsia-sdk/arch/x64/lib/libtrace-engine.so
new file mode 100755
index 0000000..4892d09
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/lib/libtrace-engine.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/x64/lib/libtrace-provider-so.so b/third_party/fuchsia-sdk/arch/x64/lib/libtrace-provider-so.so
new file mode 100755
index 0000000..f82f809
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/lib/libtrace-provider-so.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/x64/lib/libvulkan.so b/third_party/fuchsia-sdk/arch/x64/lib/libvulkan.so
new file mode 100755
index 0000000..6fc7a98
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/lib/libvulkan.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/dist/lib/ld.so.1 b/third_party/fuchsia-sdk/arch/x64/sysroot/dist/lib/ld.so.1
new file mode 100755
index 0000000..f589b62
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/dist/lib/ld.so.1
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/alloca.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/alloca.h
new file mode 100644
index 0000000..7deb5b9
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/alloca.h
@@ -0,0 +1,21 @@
+#ifndef SYSROOT_ALLOCA_H_
+#define SYSROOT_ALLOCA_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_size_t
+#include <bits/alltypes.h>
+
+void* alloca(size_t);
+
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_ALLOCA_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/ar.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/ar.h
new file mode 100644
index 0000000..d0d4176
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/ar.h
@@ -0,0 +1,25 @@
+#ifndef SYSROOT_AR_H_
+#define SYSROOT_AR_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ARMAG "!<arch>\n"
+#define SARMAG 8
+#define ARFMAG "`\n"
+
+struct ar_hdr {
+ char ar_name[16];
+ char ar_date[12];
+ char ar_uid[6], ar_gid[6];
+ char ar_mode[8];
+ char ar_size[10];
+ char ar_fmag[2];
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_AR_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/arpa/ftp.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/arpa/ftp.h
new file mode 100644
index 0000000..7d86bec
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/arpa/ftp.h
@@ -0,0 +1,37 @@
+#ifndef SYSROOT_ARPA_FTP_H_
+#define SYSROOT_ARPA_FTP_H_
+
+#define PRELIM 1
+#define COMPLETE 2
+#define CONTINUE 3
+#define TRANSIENT 4
+#define ERROR 5
+#define TYPE_A 1
+#define TYPE_E 2
+#define TYPE_I 3
+#define TYPE_L 4
+#define FORM_N 1
+#define FORM_T 2
+#define FORM_C 3
+#define STRU_F 1
+#define STRU_R 2
+#define STRU_P 3
+#define MODE_S 1
+#define MODE_B 2
+#define MODE_C 3
+#define REC_ESC '\377'
+#define REC_EOR '\001'
+#define REC_EOF '\002'
+#define BLK_EOR 0x80
+#define BLK_EOF 0x40
+#define BLK_ERRORS 0x20
+#define BLK_RESTART 0x10
+#define BLK_BYTECOUNT 2
+#ifdef FTP_NAMES
+char* modenames[] = {"0", "Stream", "Block", "Compressed"};
+char* strunames[] = {"0", "File", "Record", "Page"};
+char* typenames[] = {"0", "ASCII", "EBCDIC", "Image", "Local"};
+char* formnames[] = {"0", "Nonprint", "Telnet", "Carriage-control"};
+#endif
+
+#endif // SYSROOT_ARPA_FTP_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/arpa/inet.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/arpa/inet.h
new file mode 100644
index 0000000..4fa0af5
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/arpa/inet.h
@@ -0,0 +1,36 @@
+#ifndef SYSROOT_ARPA_INET_H_
+#define SYSROOT_ARPA_INET_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <netinet/in.h>
+
+uint32_t htonl(uint32_t);
+uint16_t htons(uint16_t);
+uint32_t ntohl(uint32_t);
+uint16_t ntohs(uint16_t);
+
+in_addr_t inet_addr(const char*);
+in_addr_t inet_network(const char*);
+char* inet_ntoa(struct in_addr);
+int inet_pton(int, const char* __restrict, void* __restrict);
+const char* inet_ntop(int, const void* __restrict, char* __restrict, socklen_t);
+
+int inet_aton(const char*, struct in_addr*);
+struct in_addr inet_makeaddr(in_addr_t, in_addr_t);
+in_addr_t inet_lnaof(struct in_addr);
+in_addr_t inet_netof(struct in_addr);
+
+#undef INET_ADDRSTRLEN
+#undef INET6_ADDRSTRLEN
+#define INET_ADDRSTRLEN 16
+#define INET6_ADDRSTRLEN 46
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_ARPA_INET_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/arpa/nameser.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/arpa/nameser.h
new file mode 100644
index 0000000..734d205
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/arpa/nameser.h
@@ -0,0 +1,451 @@
+#ifndef SYSROOT_ARPA_NAMESER_H_
+#define SYSROOT_ARPA_NAMESER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define __NAMESER 19991006
+#define NS_PACKETSZ 512
+#define NS_MAXDNAME 1025
+#define NS_MAXMSG 65535
+#define NS_MAXCDNAME 255
+#define NS_MAXLABEL 63
+#define NS_HFIXEDSZ 12
+#define NS_QFIXEDSZ 4
+#define NS_RRFIXEDSZ 10
+#define NS_INT32SZ 4
+#define NS_INT16SZ 2
+#define NS_INT8SZ 1
+#define NS_INADDRSZ 4
+#define NS_IN6ADDRSZ 16
+#define NS_CMPRSFLGS 0xc0
+#define NS_DEFAULTPORT 53
+
+typedef enum __ns_sect {
+ ns_s_qd = 0,
+ ns_s_zn = 0,
+ ns_s_an = 1,
+ ns_s_pr = 1,
+ ns_s_ns = 2,
+ ns_s_ud = 2,
+ ns_s_ar = 3,
+ ns_s_max = 4
+} ns_sect;
+
+typedef struct __ns_msg {
+ const unsigned char *_msg, *_eom;
+ uint16_t _id, _flags, _counts[ns_s_max];
+ const unsigned char* _sections[ns_s_max];
+ ns_sect _sect;
+ int _rrnum;
+ const unsigned char* _msg_ptr;
+} ns_msg;
+
+struct _ns_flagdata {
+ int mask, shift;
+};
+extern const struct _ns_flagdata _ns_flagdata[];
+
+#define ns_msg_id(handle) ((handle)._id + 0)
+#define ns_msg_base(handle) ((handle)._msg + 0)
+#define ns_msg_end(handle) ((handle)._eom + 0)
+#define ns_msg_size(handle) ((handle)._eom - (handle)._msg)
+#define ns_msg_count(handle, section) ((handle)._counts[section] + 0)
+#define ns_msg_getflag(handle, flag) \
+ (((handle)._flags & _ns_flagdata[flag].mask) >> _ns_flagdata[flag].shift)
+
+typedef struct __ns_rr {
+ char name[NS_MAXDNAME];
+ uint16_t type;
+ uint16_t rr_class;
+ uint32_t ttl;
+ uint16_t rdlength;
+ const unsigned char* rdata;
+} ns_rr;
+
+#define ns_rr_name(rr) (((rr).name[0] != '\0') ? (rr).name : ".")
+#define ns_rr_type(rr) ((ns_type)((rr).type + 0))
+#define ns_rr_class(rr) ((ns_class)((rr).rr_class + 0))
+#define ns_rr_ttl(rr) ((rr).ttl + 0)
+#define ns_rr_rdlen(rr) ((rr).rdlength + 0)
+#define ns_rr_rdata(rr) ((rr).rdata + 0)
+
+typedef enum __ns_flag {
+ ns_f_qr,
+ ns_f_opcode,
+ ns_f_aa,
+ ns_f_tc,
+ ns_f_rd,
+ ns_f_ra,
+ ns_f_z,
+ ns_f_ad,
+ ns_f_cd,
+ ns_f_rcode,
+ ns_f_max
+} ns_flag;
+
+typedef enum __ns_opcode {
+ ns_o_query = 0,
+ ns_o_iquery = 1,
+ ns_o_status = 2,
+ ns_o_notify = 4,
+ ns_o_update = 5,
+ ns_o_max = 6
+} ns_opcode;
+
+typedef enum __ns_rcode {
+ ns_r_noerror = 0,
+ ns_r_formerr = 1,
+ ns_r_servfail = 2,
+ ns_r_nxdomain = 3,
+ ns_r_notimpl = 4,
+ ns_r_refused = 5,
+ ns_r_yxdomain = 6,
+ ns_r_yxrrset = 7,
+ ns_r_nxrrset = 8,
+ ns_r_notauth = 9,
+ ns_r_notzone = 10,
+ ns_r_max = 11,
+ ns_r_badvers = 16,
+ ns_r_badsig = 16,
+ ns_r_badkey = 17,
+ ns_r_badtime = 18
+} ns_rcode;
+
+typedef enum __ns_update_operation {
+ ns_uop_delete = 0,
+ ns_uop_add = 1,
+ ns_uop_max = 2
+} ns_update_operation;
+
+struct ns_tsig_key {
+ char name[NS_MAXDNAME], alg[NS_MAXDNAME];
+ unsigned char* data;
+ int len;
+};
+typedef struct ns_tsig_key ns_tsig_key;
+
+struct ns_tcp_tsig_state {
+ int counter;
+ struct dst_key* key;
+ void* ctx;
+ unsigned char sig[NS_PACKETSZ];
+ int siglen;
+};
+typedef struct ns_tcp_tsig_state ns_tcp_tsig_state;
+
+#define NS_TSIG_FUDGE 300
+#define NS_TSIG_TCP_COUNT 100
+#define NS_TSIG_ALG_HMAC_MD5 "HMAC-MD5.SIG-ALG.REG.INT"
+
+#define NS_TSIG_ERROR_NO_TSIG -10
+#define NS_TSIG_ERROR_NO_SPACE -11
+#define NS_TSIG_ERROR_FORMERR -12
+
+typedef enum __ns_type {
+ ns_t_invalid = 0,
+ ns_t_a = 1,
+ ns_t_ns = 2,
+ ns_t_md = 3,
+ ns_t_mf = 4,
+ ns_t_cname = 5,
+ ns_t_soa = 6,
+ ns_t_mb = 7,
+ ns_t_mg = 8,
+ ns_t_mr = 9,
+ ns_t_null = 10,
+ ns_t_wks = 11,
+ ns_t_ptr = 12,
+ ns_t_hinfo = 13,
+ ns_t_minfo = 14,
+ ns_t_mx = 15,
+ ns_t_txt = 16,
+ ns_t_rp = 17,
+ ns_t_afsdb = 18,
+ ns_t_x25 = 19,
+ ns_t_isdn = 20,
+ ns_t_rt = 21,
+ ns_t_nsap = 22,
+ ns_t_nsap_ptr = 23,
+ ns_t_sig = 24,
+ ns_t_key = 25,
+ ns_t_px = 26,
+ ns_t_gpos = 27,
+ ns_t_aaaa = 28,
+ ns_t_loc = 29,
+ ns_t_nxt = 30,
+ ns_t_eid = 31,
+ ns_t_nimloc = 32,
+ ns_t_srv = 33,
+ ns_t_atma = 34,
+ ns_t_naptr = 35,
+ ns_t_kx = 36,
+ ns_t_cert = 37,
+ ns_t_a6 = 38,
+ ns_t_dname = 39,
+ ns_t_sink = 40,
+ ns_t_opt = 41,
+ ns_t_apl = 42,
+ ns_t_tkey = 249,
+ ns_t_tsig = 250,
+ ns_t_ixfr = 251,
+ ns_t_axfr = 252,
+ ns_t_mailb = 253,
+ ns_t_maila = 254,
+ ns_t_any = 255,
+ ns_t_zxfr = 256,
+ ns_t_max = 65536
+} ns_type;
+
+#define ns_t_qt_p(t) (ns_t_xfr_p(t) || (t) == ns_t_any || (t) == ns_t_mailb || (t) == ns_t_maila)
+#define ns_t_mrr_p(t) ((t) == ns_t_tsig || (t) == ns_t_opt)
+#define ns_t_rr_p(t) (!ns_t_qt_p(t) && !ns_t_mrr_p(t))
+#define ns_t_udp_p(t) ((t) != ns_t_axfr && (t) != ns_t_zxfr)
+#define ns_t_xfr_p(t) ((t) == ns_t_axfr || (t) == ns_t_ixfr || (t) == ns_t_zxfr)
+
+typedef enum __ns_class {
+ ns_c_invalid = 0,
+ ns_c_in = 1,
+ ns_c_2 = 2,
+ ns_c_chaos = 3,
+ ns_c_hs = 4,
+ ns_c_none = 254,
+ ns_c_any = 255,
+ ns_c_max = 65536
+} ns_class;
+
+typedef enum __ns_key_types {
+ ns_kt_rsa = 1,
+ ns_kt_dh = 2,
+ ns_kt_dsa = 3,
+ ns_kt_private = 254
+} ns_key_types;
+
+typedef enum __ns_cert_types {
+ cert_t_pkix = 1,
+ cert_t_spki = 2,
+ cert_t_pgp = 3,
+ cert_t_url = 253,
+ cert_t_oid = 254
+} ns_cert_types;
+
+#define NS_KEY_TYPEMASK 0xC000
+#define NS_KEY_TYPE_AUTH_CONF 0x0000
+#define NS_KEY_TYPE_CONF_ONLY 0x8000
+#define NS_KEY_TYPE_AUTH_ONLY 0x4000
+#define NS_KEY_TYPE_NO_KEY 0xC000
+#define NS_KEY_NO_AUTH 0x8000
+#define NS_KEY_NO_CONF 0x4000
+#define NS_KEY_RESERVED2 0x2000
+#define NS_KEY_EXTENDED_FLAGS 0x1000
+#define NS_KEY_RESERVED4 0x0800
+#define NS_KEY_RESERVED5 0x0400
+#define NS_KEY_NAME_TYPE 0x0300
+#define NS_KEY_NAME_USER 0x0000
+#define NS_KEY_NAME_ENTITY 0x0200
+#define NS_KEY_NAME_ZONE 0x0100
+#define NS_KEY_NAME_RESERVED 0x0300
+#define NS_KEY_RESERVED8 0x0080
+#define NS_KEY_RESERVED9 0x0040
+#define NS_KEY_RESERVED10 0x0020
+#define NS_KEY_RESERVED11 0x0010
+#define NS_KEY_SIGNATORYMASK 0x000F
+#define NS_KEY_RESERVED_BITMASK \
+ (NS_KEY_RESERVED2 | NS_KEY_RESERVED4 | NS_KEY_RESERVED5 | NS_KEY_RESERVED8 | NS_KEY_RESERVED9 | \
+ NS_KEY_RESERVED10 | NS_KEY_RESERVED11)
+#define NS_KEY_RESERVED_BITMASK2 0xFFFF
+#define NS_ALG_MD5RSA 1
+#define NS_ALG_DH 2
+#define NS_ALG_DSA 3
+#define NS_ALG_DSS NS_ALG_DSA
+#define NS_ALG_EXPIRE_ONLY 253
+#define NS_ALG_PRIVATE_OID 254
+
+#define NS_KEY_PROT_TLS 1
+#define NS_KEY_PROT_EMAIL 2
+#define NS_KEY_PROT_DNSSEC 3
+#define NS_KEY_PROT_IPSEC 4
+#define NS_KEY_PROT_ANY 255
+
+#define NS_MD5RSA_MIN_BITS 512
+#define NS_MD5RSA_MAX_BITS 4096
+#define NS_MD5RSA_MAX_BYTES ((NS_MD5RSA_MAX_BITS + 7 / 8) * 2 + 3)
+#define NS_MD5RSA_MAX_BASE64 (((NS_MD5RSA_MAX_BYTES + 2) / 3) * 4)
+#define NS_MD5RSA_MIN_SIZE ((NS_MD5RSA_MIN_BITS + 7) / 8)
+#define NS_MD5RSA_MAX_SIZE ((NS_MD5RSA_MAX_BITS + 7) / 8)
+
+#define NS_DSA_SIG_SIZE 41
+#define NS_DSA_MIN_SIZE 213
+#define NS_DSA_MAX_BYTES 405
+
+#define NS_SIG_TYPE 0
+#define NS_SIG_ALG 2
+#define NS_SIG_LABELS 3
+#define NS_SIG_OTTL 4
+#define NS_SIG_EXPIR 8
+#define NS_SIG_SIGNED 12
+#define NS_SIG_FOOT 16
+#define NS_SIG_SIGNER 18
+#define NS_NXT_BITS 8
+#define NS_NXT_BIT_SET(n, p) (p[(n) / NS_NXT_BITS] |= (0x80 >> ((n) % NS_NXT_BITS)))
+#define NS_NXT_BIT_CLEAR(n, p) (p[(n) / NS_NXT_BITS] &= ~(0x80 >> ((n) % NS_NXT_BITS)))
+#define NS_NXT_BIT_ISSET(n, p) (p[(n) / NS_NXT_BITS] & (0x80 >> ((n) % NS_NXT_BITS)))
+#define NS_NXT_MAX 127
+
+#define NS_OPT_DNSSEC_OK 0x8000U
+#define NS_OPT_NSID 3
+
+#define NS_GET16(s, cp) (void)((s) = ns_get16(((cp) += 2) - 2))
+#define NS_GET32(l, cp) (void)((l) = ns_get32(((cp) += 4) - 4))
+#define NS_PUT16(s, cp) ns_put16((s), ((cp) += 2) - 2)
+#define NS_PUT32(l, cp) ns_put32((l), ((cp) += 4) - 4)
+
+unsigned ns_get16(const unsigned char*);
+unsigned long ns_get32(const unsigned char*);
+void ns_put16(unsigned, unsigned char*);
+void ns_put32(unsigned long, unsigned char*);
+
+int ns_initparse(const unsigned char*, int, ns_msg*);
+int ns_parserr(ns_msg*, ns_sect, int, ns_rr*);
+int ns_skiprr(const unsigned char*, const unsigned char*, ns_sect, int);
+int ns_name_uncompress(const unsigned char*, const unsigned char*, const unsigned char*, char*,
+ size_t);
+
+#define __BIND 19950621
+
+typedef struct {
+ unsigned id : 16;
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned qr : 1;
+ unsigned opcode : 4;
+ unsigned aa : 1;
+ unsigned tc : 1;
+ unsigned rd : 1;
+ unsigned ra : 1;
+ unsigned unused : 1;
+ unsigned ad : 1;
+ unsigned cd : 1;
+ unsigned rcode : 4;
+#else
+ unsigned rd : 1;
+ unsigned tc : 1;
+ unsigned aa : 1;
+ unsigned opcode : 4;
+ unsigned qr : 1;
+ unsigned rcode : 4;
+ unsigned cd : 1;
+ unsigned ad : 1;
+ unsigned unused : 1;
+ unsigned ra : 1;
+#endif
+ unsigned qdcount : 16;
+ unsigned ancount : 16;
+ unsigned nscount : 16;
+ unsigned arcount : 16;
+} HEADER;
+
+#define PACKETSZ NS_PACKETSZ
+#define MAXDNAME NS_MAXDNAME
+#define MAXCDNAME NS_MAXCDNAME
+#define MAXLABEL NS_MAXLABEL
+#define HFIXEDSZ NS_HFIXEDSZ
+#define QFIXEDSZ NS_QFIXEDSZ
+#define RRFIXEDSZ NS_RRFIXEDSZ
+#define INT32SZ NS_INT32SZ
+#define INT16SZ NS_INT16SZ
+#define INT8SZ NS_INT8SZ
+#define INADDRSZ NS_INADDRSZ
+#define IN6ADDRSZ NS_IN6ADDRSZ
+#define INDIR_MASK NS_CMPRSFLGS
+#define NAMESERVER_PORT NS_DEFAULTPORT
+
+#define S_ZONE ns_s_zn
+#define S_PREREQ ns_s_pr
+#define S_UPDATE ns_s_ud
+#define S_ADDT ns_s_ar
+
+#define QUERY ns_o_query
+#define IQUERY ns_o_iquery
+#define STATUS ns_o_status
+#define NS_NOTIFY_OP ns_o_notify
+#define NS_UPDATE_OP ns_o_update
+
+#define NOERROR ns_r_noerror
+#define FORMERR ns_r_formerr
+#define SERVFAIL ns_r_servfail
+#define NXDOMAIN ns_r_nxdomain
+#define NOTIMP ns_r_notimpl
+#define REFUSED ns_r_refused
+#define YXDOMAIN ns_r_yxdomain
+#define YXRRSET ns_r_yxrrset
+#define NXRRSET ns_r_nxrrset
+#define NOTAUTH ns_r_notauth
+#define NOTZONE ns_r_notzone
+
+#define DELETE ns_uop_delete
+#define ADD ns_uop_add
+
+#define T_A ns_t_a
+#define T_NS ns_t_ns
+#define T_MD ns_t_md
+#define T_MF ns_t_mf
+#define T_CNAME ns_t_cname
+#define T_SOA ns_t_soa
+#define T_MB ns_t_mb
+#define T_MG ns_t_mg
+#define T_MR ns_t_mr
+#define T_NULL ns_t_null
+#define T_WKS ns_t_wks
+#define T_PTR ns_t_ptr
+#define T_HINFO ns_t_hinfo
+#define T_MINFO ns_t_minfo
+#define T_MX ns_t_mx
+#define T_TXT ns_t_txt
+#define T_RP ns_t_rp
+#define T_AFSDB ns_t_afsdb
+#define T_X25 ns_t_x25
+#define T_ISDN ns_t_isdn
+#define T_RT ns_t_rt
+#define T_NSAP ns_t_nsap
+#define T_NSAP_PTR ns_t_nsap_ptr
+#define T_SIG ns_t_sig
+#define T_KEY ns_t_key
+#define T_PX ns_t_px
+#define T_GPOS ns_t_gpos
+#define T_AAAA ns_t_aaaa
+#define T_LOC ns_t_loc
+#define T_NXT ns_t_nxt
+#define T_EID ns_t_eid
+#define T_NIMLOC ns_t_nimloc
+#define T_SRV ns_t_srv
+#define T_ATMA ns_t_atma
+#define T_NAPTR ns_t_naptr
+#define T_A6 ns_t_a6
+#define T_DNAME ns_t_dname
+#define T_TSIG ns_t_tsig
+#define T_IXFR ns_t_ixfr
+#define T_AXFR ns_t_axfr
+#define T_MAILB ns_t_mailb
+#define T_MAILA ns_t_maila
+#define T_ANY ns_t_any
+
+#define C_IN ns_c_in
+#define C_CHAOS ns_c_chaos
+#define C_HS ns_c_hs
+#define C_NONE ns_c_none
+#define C_ANY ns_c_any
+
+#define GETSHORT NS_GET16
+#define GETLONG NS_GET32
+#define PUTSHORT NS_PUT16
+#define PUTLONG NS_PUT32
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_ARPA_NAMESER_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/arpa/nameser_compat.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/arpa/nameser_compat.h
new file mode 100644
index 0000000..ee3b1a9
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/arpa/nameser_compat.h
@@ -0,0 +1 @@
+#include <arpa/nameser.h>
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/arpa/telnet.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/arpa/telnet.h
new file mode 100644
index 0000000..2da3eda
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/arpa/telnet.h
@@ -0,0 +1,279 @@
+#ifndef SYSROOT_ARPA_TELNET_H_
+#define SYSROOT_ARPA_TELNET_H_
+
+#define IAC 255
+#define DONT 254
+#define DO 253
+#define WONT 252
+#define WILL 251
+#define SB 250
+#define GA 249
+#define EL 248
+#define EC 247
+#define AYT 246
+#define AO 245
+#define IP 244
+#define BREAK 243
+#define DM 242
+#define NOP 241
+#define SE 240
+#define EOR 239
+#define ABORT 238
+#define SUSP 237
+#define xEOF 236
+
+#define SYNCH 242
+
+#define telcmds \
+ ((char[][6]){"EOF", "SUSP", "ABORT", "EOR", "SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", \
+ "EC", "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC", 0})
+
+#define TELCMD_FIRST xEOF
+#define TELCMD_LAST IAC
+#define TELCMD_OK(x) ((unsigned int)(x) <= TELCMD_LAST && (unsigned int)(x) >= TELCMD_FIRST)
+#define TELCMD(x) telcmds[(x)-TELCMD_FIRST]
+
+#define TELOPT_BINARY 0
+#define TELOPT_ECHO 1
+#define TELOPT_RCP 2
+#define TELOPT_SGA 3
+#define TELOPT_NAMS 4
+#define TELOPT_STATUS 5
+#define TELOPT_TM 6
+#define TELOPT_RCTE 7
+#define TELOPT_NAOL 8
+#define TELOPT_NAOP 9
+#define TELOPT_NAOCRD 10
+#define TELOPT_NAOHTS 11
+#define TELOPT_NAOHTD 12
+#define TELOPT_NAOFFD 13
+#define TELOPT_NAOVTS 14
+#define TELOPT_NAOVTD 15
+#define TELOPT_NAOLFD 16
+#define TELOPT_XASCII 17
+#define TELOPT_LOGOUT 18
+#define TELOPT_BM 19
+#define TELOPT_DET 20
+#define TELOPT_SUPDUP 21
+#define TELOPT_SUPDUPOUTPUT 22
+#define TELOPT_SNDLOC 23
+#define TELOPT_TTYPE 24
+#define TELOPT_EOR 25
+#define TELOPT_TUID 26
+#define TELOPT_OUTMRK 27
+#define TELOPT_TTYLOC 28
+#define TELOPT_3270REGIME 29
+#define TELOPT_X3PAD 30
+#define TELOPT_NAWS 31
+#define TELOPT_TSPEED 32
+#define TELOPT_LFLOW 33
+#define TELOPT_LINEMODE 34
+#define TELOPT_XDISPLOC 35
+#define TELOPT_OLD_ENVIRON 36
+#define TELOPT_AUTHENTICATION 37 /* Authenticate */
+#define TELOPT_ENCRYPT 38
+#define TELOPT_NEW_ENVIRON 39
+#define TELOPT_EXOPL 255
+
+#define NTELOPTS (1 + TELOPT_NEW_ENVIRON)
+#ifdef TELOPTS
+char* telopts[NTELOPTS + 1] = {
+ "BINARY",
+ "ECHO",
+ "RCP",
+ "SUPPRESS GO AHEAD",
+ "NAME",
+ "STATUS",
+ "TIMING MARK",
+ "RCTE",
+ "NAOL",
+ "NAOP",
+ "NAOCRD",
+ "NAOHTS",
+ "NAOHTD",
+ "NAOFFD",
+ "NAOVTS",
+ "NAOVTD",
+ "NAOLFD",
+ "EXTEND ASCII",
+ "LOGOUT",
+ "BYTE MACRO",
+ "DATA ENTRY TERMINAL",
+ "SUPDUP",
+ "SUPDUP OUTPUT",
+ "SEND LOCATION",
+ "TERMINAL TYPE",
+ "END OF RECORD",
+ "TACACS UID",
+ "OUTPUT MARKING",
+ "TTYLOC",
+ "3270 REGIME",
+ "X.3 PAD",
+ "NAWS",
+ "TSPEED",
+ "LFLOW",
+ "LINEMODE",
+ "XDISPLOC",
+ "OLD-ENVIRON",
+ "AUTHENTICATION",
+ "ENCRYPT",
+ "NEW-ENVIRON",
+ 0,
+};
+#define TELOPT_FIRST TELOPT_BINARY
+#define TELOPT_LAST TELOPT_NEW_ENVIRON
+#define TELOPT_OK(x) ((unsigned int)(x) <= TELOPT_LAST)
+#define TELOPT(x) telopts[(x)-TELOPT_FIRST]
+#endif
+
+#define TELQUAL_IS 0
+#define TELQUAL_SEND 1
+#define TELQUAL_INFO 2
+#define TELQUAL_REPLY 2
+#define TELQUAL_NAME 3
+
+#define LFLOW_OFF 0
+#define LFLOW_ON 1
+#define LFLOW_RESTART_ANY 2
+#define LFLOW_RESTART_XON 3
+
+#define LM_MODE 1
+#define LM_FORWARDMASK 2
+#define LM_SLC 3
+
+#define MODE_EDIT 0x01
+#define MODE_TRAPSIG 0x02
+#define MODE_ACK 0x04
+#define MODE_SOFT_TAB 0x08
+#define MODE_LIT_ECHO 0x10
+
+#define MODE_MASK 0x1f
+
+#define MODE_FLOW 0x0100
+#define MODE_ECHO 0x0200
+#define MODE_INBIN 0x0400
+#define MODE_OUTBIN 0x0800
+#define MODE_FORCE 0x1000
+
+#define SLC_SYNCH 1
+#define SLC_BRK 2
+#define SLC_IP 3
+#define SLC_AO 4
+#define SLC_AYT 5
+#define SLC_EOR 6
+#define SLC_ABORT 7
+#define SLC_EOF 8
+#define SLC_SUSP 9
+#define SLC_EC 10
+#define SLC_EL 11
+#define SLC_EW 12
+#define SLC_RP 13
+#define SLC_LNEXT 14
+#define SLC_XON 15
+#define SLC_XOFF 16
+#define SLC_FORW1 17
+#define SLC_FORW2 18
+
+#define NSLC 18
+
+#define SLC_NAMELIST \
+ "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", "ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \
+ "LNEXT", "XON", "XOFF", "FORW1", "FORW2", 0,
+#ifdef SLC_NAMES
+char* slc_names[] = {SLC_NAMELIST};
+#else
+extern char* slc_names[];
+#define SLC_NAMES SLC_NAMELIST
+#endif
+
+#define SLC_NAME_OK(x) ((unsigned int)(x) <= NSLC)
+#define SLC_NAME(x) slc_names[x]
+
+#define SLC_NOSUPPORT 0
+#define SLC_CANTCHANGE 1
+#define SLC_VARIABLE 2
+#define SLC_DEFAULT 3
+#define SLC_LEVELBITS 0x03
+
+#define SLC_FUNC 0
+#define SLC_FLAGS 1
+#define SLC_VALUE 2
+
+#define SLC_ACK 0x80
+#define SLC_FLUSHIN 0x40
+#define SLC_FLUSHOUT 0x20
+
+#define OLD_ENV_VAR 1
+#define OLD_ENV_VALUE 0
+#define NEW_ENV_VAR 0
+#define NEW_ENV_VALUE 1
+#define ENV_ESC 2
+#define ENV_USERVAR 3
+
+#define AUTH_WHO_CLIENT 0
+#define AUTH_WHO_SERVER 1
+#define AUTH_WHO_MASK 1
+
+#define AUTH_HOW_ONE_WAY 0
+#define AUTH_HOW_MUTUAL 2
+#define AUTH_HOW_MASK 2
+
+#define AUTHTYPE_NULL 0
+#define AUTHTYPE_KERBEROS_V4 1
+#define AUTHTYPE_KERBEROS_V5 2
+#define AUTHTYPE_SPX 3
+#define AUTHTYPE_MINK 4
+#define AUTHTYPE_CNT 5
+
+#define AUTHTYPE_TEST 99
+
+#ifdef AUTH_NAMES
+char* authtype_names[] = {
+ "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", 0,
+};
+#else
+extern char* authtype_names[];
+#endif
+
+#define AUTHTYPE_NAME_OK(x) ((unsigned int)(x) < AUTHTYPE_CNT)
+#define AUTHTYPE_NAME(x) authtype_names[x]
+
+#define ENCRYPT_IS 0
+#define ENCRYPT_SUPPORT 1
+#define ENCRYPT_REPLY 2
+#define ENCRYPT_START 3
+#define ENCRYPT_END 4
+#define ENCRYPT_REQSTART 5
+#define ENCRYPT_REQEND 6
+#define ENCRYPT_ENC_KEYID 7
+#define ENCRYPT_DEC_KEYID 8
+#define ENCRYPT_CNT 9
+
+#define ENCTYPE_ANY 0
+#define ENCTYPE_DES_CFB64 1
+#define ENCTYPE_DES_OFB64 2
+#define ENCTYPE_CNT 3
+
+#ifdef ENCRYPT_NAMES
+char* encrypt_names[] = {
+ "IS", "SUPPORT", "REPLY", "START", "END", "REQUEST-START",
+ "REQUEST-END", "ENC-KEYID", "DEC-KEYID", 0,
+};
+char* enctype_names[] = {
+ "ANY",
+ "DES_CFB64",
+ "DES_OFB64",
+ 0,
+};
+#else
+extern char* encrypt_names[];
+extern char* enctype_names[];
+#endif
+
+#define ENCRYPT_NAME_OK(x) ((unsigned int)(x) < ENCRYPT_CNT)
+#define ENCRYPT_NAME(x) encrypt_names[x]
+
+#define ENCTYPE_NAME_OK(x) ((unsigned int)(x) < ENCTYPE_CNT)
+#define ENCTYPE_NAME(x) enctype_names[x]
+
+#endif // SYSROOT_ARPA_TELNET_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/arpa/tftp.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/arpa/tftp.h
new file mode 100644
index 0000000..e091368
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/arpa/tftp.h
@@ -0,0 +1,32 @@
+#ifndef SYSROOT_ARPA_TFTP_H_
+#define SYSROOT_ARPA_TFTP_H_
+
+#define SEGSIZE 512
+#define RRQ 01
+#define WRQ 02
+#define DATA 03
+#define ACK 04
+#define ERROR 05
+struct tftphdr {
+ short th_opcode;
+ union {
+ unsigned short tu_block;
+ short tu_code;
+ char tu_stuff[1];
+ } th_u;
+ char th_data[1];
+};
+#define th_block th_u.tu_block
+#define th_code th_u.tu_code
+#define th_stuff th_u.tu_stuff
+#define th_msg th_data
+#define EUNDEF 0
+#define ENOTFOUND 1
+#define EACCESS 2
+#define ENOSPACE 3
+#define EBADOP 4
+#define EBADID 5
+#define EEXISTS 6
+#define ENOUSER 7
+
+#endif // SYSROOT_ARPA_TFTP_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/assert.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/assert.h
new file mode 100644
index 0000000..02e96dc
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/assert.h
@@ -0,0 +1,23 @@
+#include <features.h>
+
+#undef assert
+
+#ifdef NDEBUG
+#define assert(x) (void)0
+#else
+#define assert(x) ((void)((x) || (__assert_fail(#x, __FILE__, __LINE__, __func__), 0)))
+#endif
+
+#if __STDC_VERSION__ >= 201112L && !defined(__cplusplus) && !defined(static_assert)
+#define static_assert _Static_assert
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void __assert_fail(const char*, const char*, int, const char*);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/aarch64/endian.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/aarch64/endian.h
new file mode 100644
index 0000000..7a74d2f
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/aarch64/endian.h
@@ -0,0 +1,5 @@
+#if __AARCH64EB__
+#define __BYTE_ORDER __BIG_ENDIAN
+#else
+#define __BYTE_ORDER __LITTLE_ENDIAN
+#endif
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/aarch64/fenv.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/aarch64/fenv.h
new file mode 100644
index 0000000..a370540
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/aarch64/fenv.h
@@ -0,0 +1,19 @@
+#define FE_INVALID 1
+#define FE_DIVBYZERO 2
+#define FE_OVERFLOW 4
+#define FE_UNDERFLOW 8
+#define FE_INEXACT 16
+#define FE_ALL_EXCEPT 31
+#define FE_TONEAREST 0
+#define FE_DOWNWARD 0x800000
+#define FE_UPWARD 0x400000
+#define FE_TOWARDZERO 0xc00000
+
+typedef unsigned int fexcept_t;
+
+typedef struct {
+ unsigned int __fpcr;
+ unsigned int __fpsr;
+} fenv_t;
+
+#define FE_DFL_ENV ((const fenv_t*)-1)
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/aarch64/io.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/aarch64/io.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/aarch64/io.h
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/aarch64/ioctl.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/aarch64/ioctl.h
new file mode 100644
index 0000000..40835ba
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/aarch64/ioctl.h
@@ -0,0 +1,213 @@
+#define _IOC(a, b, c, d) (((a) << 30) | ((b) << 8) | (c) | ((d) << 16))
+#define _IOC_NONE 0U
+#define _IOC_WRITE 1U
+#define _IOC_READ 2U
+
+#define _IO(a, b) _IOC(_IOC_NONE, (a), (b), 0)
+#define _IOW(a, b, c) _IOC(_IOC_WRITE, (a), (b), sizeof(c))
+#define _IOR(a, b, c) _IOC(_IOC_READ, (a), (b), sizeof(c))
+#define _IOWR(a, b, c) _IOC(_IOC_READ | _IOC_WRITE, (a), (b), sizeof(c))
+
+#define TCGETS 0x5401
+#define TCSETS 0x5402
+#define TCSETSW 0x5403
+#define TCSETSF 0x5404
+#define TCGETA 0x5405
+#define TCSETA 0x5406
+#define TCSETAW 0x5407
+#define TCSETAF 0x5408
+#define TCSBRK 0x5409
+#define TCXONC 0x540A
+#define TCFLSH 0x540B
+#define TIOCEXCL 0x540C
+#define TIOCNXCL 0x540D
+#define TIOCSCTTY 0x540E
+#define TIOCGPGRP 0x540F
+#define TIOCSPGRP 0x5410
+#define TIOCOUTQ 0x5411
+#define TIOCSTI 0x5412
+#define TIOCGWINSZ 0x5413
+#define TIOCSWINSZ 0x5414
+#define TIOCMGET 0x5415
+#define TIOCMBIS 0x5416
+#define TIOCMBIC 0x5417
+#define TIOCMSET 0x5418
+#define TIOCGSOFTCAR 0x5419
+#define TIOCSSOFTCAR 0x541A
+#define FIONREAD 0x541B
+#define TIOCINQ FIONREAD
+#define TIOCLINUX 0x541C
+#define TIOCCONS 0x541D
+#define TIOCGSERIAL 0x541E
+#define TIOCSSERIAL 0x541F
+#define TIOCPKT 0x5420
+#define FIONBIO 0x5421
+#define TIOCNOTTY 0x5422
+#define TIOCSETD 0x5423
+#define TIOCGETD 0x5424
+#define TCSBRKP 0x5425
+#define TIOCTTYGSTRUCT 0x5426
+#define TIOCSBRK 0x5427
+#define TIOCCBRK 0x5428
+#define TIOCGSID 0x5429
+#define TIOCGRS485 0x542E
+#define TIOCSRS485 0x542F
+#define TIOCGPTN _IOR('T', 0x30, unsigned int)
+#define TIOCSPTLCK _IOW('T', 0x31, int)
+#define TIOCGDEV _IOR('T', 0x32, unsigned int)
+#define TCGETX 0x5432
+#define TCSETX 0x5433
+#define TCSETXF 0x5434
+#define TCSETXW 0x5435
+#define TIOCSIG 0x40045436
+#define TIOCVHANGUP 0x5437
+#define TIOCGPKT 0x80045438
+#define TIOCGPTLCK 0x80045439
+#define TIOCGEXCL 0x80045440
+
+#define FIONCLEX 0x5450
+#define FIOCLEX 0x5451
+#define FIOASYNC 0x5452
+#define TIOCSERCONFIG 0x5453
+#define TIOCSERGWILD 0x5454
+#define TIOCSERSWILD 0x5455
+#define TIOCGLCKTRMIOS 0x5456
+#define TIOCSLCKTRMIOS 0x5457
+#define TIOCSERGSTRUCT 0x5458
+#define TIOCSERGETLSR 0x5459
+#define TIOCSERGETMULTI 0x545A
+#define TIOCSERSETMULTI 0x545B
+
+#define TIOCMIWAIT 0x545C
+#define TIOCGICOUNT 0x545D
+#define FIOQSIZE 0x5460
+
+#define TIOCPKT_DATA 0
+#define TIOCPKT_FLUSHREAD 1
+#define TIOCPKT_FLUSHWRITE 2
+#define TIOCPKT_STOP 4
+#define TIOCPKT_START 8
+#define TIOCPKT_NOSTOP 16
+#define TIOCPKT_DOSTOP 32
+#define TIOCPKT_IOCTL 64
+
+#define TIOCSER_TEMT 0x01
+
+struct winsize {
+ unsigned short ws_row;
+ unsigned short ws_col;
+ unsigned short ws_xpixel;
+ unsigned short ws_ypixel;
+};
+
+#define TIOCM_LE 0x001
+#define TIOCM_DTR 0x002
+#define TIOCM_RTS 0x004
+#define TIOCM_ST 0x008
+#define TIOCM_SR 0x010
+#define TIOCM_CTS 0x020
+#define TIOCM_CAR 0x040
+#define TIOCM_RNG 0x080
+#define TIOCM_DSR 0x100
+#define TIOCM_CD TIOCM_CAR
+#define TIOCM_RI TIOCM_RNG
+#define TIOCM_OUT1 0x2000
+#define TIOCM_OUT2 0x4000
+#define TIOCM_LOOP 0x8000
+#define TIOCM_MODEM_BITS TIOCM_OUT2
+
+#define N_TTY 0
+#define N_SLIP 1
+#define N_MOUSE 2
+#define N_PPP 3
+#define N_STRIP 4
+#define N_AX25 5
+#define N_X25 6
+#define N_6PACK 7
+#define N_MASC 8
+#define N_R3964 9
+#define N_PROFIBUS_FDL 10
+#define N_IRDA 11
+#define N_SMSBLOCK 12
+#define N_HDLC 13
+#define N_SYNC_PPP 14
+#define N_HCI 15
+#define N_GIGASET_M101 16
+#define N_SLCAN 17
+#define N_PPS 18
+#define N_V253 19
+#define N_CAIF 20
+#define N_GSM0710 21
+#define N_TI_WL 22
+#define N_TRACESINK 23
+#define N_TRACEROUTER 24
+
+#define FIOSETOWN 0x8901
+#define SIOCSPGRP 0x8902
+#define FIOGETOWN 0x8903
+#define SIOCGPGRP 0x8904
+#define SIOCATMARK 0x8905
+#define SIOCGSTAMP 0x8906
+#define SIOCGSTAMPNS 0x8907
+
+#define SIOCADDRT 0x890B
+#define SIOCDELRT 0x890C
+#define SIOCRTMSG 0x890D
+
+#define SIOCGIFNAME 0x8910
+#define SIOCSIFLINK 0x8911
+#define SIOCGIFCONF 0x8912
+#define SIOCGIFFLAGS 0x8913
+#define SIOCSIFFLAGS 0x8914
+#define SIOCGIFADDR 0x8915
+#define SIOCSIFADDR 0x8916
+#define SIOCGIFDSTADDR 0x8917
+#define SIOCSIFDSTADDR 0x8918
+#define SIOCGIFBRDADDR 0x8919
+#define SIOCSIFBRDADDR 0x891a
+#define SIOCGIFNETMASK 0x891b
+#define SIOCSIFNETMASK 0x891c
+#define SIOCGIFMETRIC 0x891d
+#define SIOCSIFMETRIC 0x891e
+#define SIOCGIFMEM 0x891f
+#define SIOCSIFMEM 0x8920
+#define SIOCGIFMTU 0x8921
+#define SIOCSIFMTU 0x8922
+#define SIOCSIFHWADDR 0x8924
+#define SIOCGIFENCAP 0x8925
+#define SIOCSIFENCAP 0x8926
+#define SIOCGIFHWADDR 0x8927
+#define SIOCGIFSLAVE 0x8929
+#define SIOCSIFSLAVE 0x8930
+#define SIOCADDMULTI 0x8931
+#define SIOCDELMULTI 0x8932
+#define SIOCGIFINDEX 0x8933
+#define SIOGIFINDEX SIOCGIFINDEX
+#define SIOCSIFPFLAGS 0x8934
+#define SIOCGIFPFLAGS 0x8935
+#define SIOCDIFADDR 0x8936
+#define SIOCSIFHWBROADCAST 0x8937
+#define SIOCGIFCOUNT 0x8938
+
+#define SIOCGIFBR 0x8940
+#define SIOCSIFBR 0x8941
+
+#define SIOCGIFTXQLEN 0x8942
+#define SIOCSIFTXQLEN 0x8943
+
+#define SIOCDARP 0x8953
+#define SIOCGARP 0x8954
+#define SIOCSARP 0x8955
+
+#define SIOCDRARP 0x8960
+#define SIOCGRARP 0x8961
+#define SIOCSRARP 0x8962
+
+#define SIOCGIFMAP 0x8970
+#define SIOCSIFMAP 0x8971
+
+#define SIOCADDDLCI 0x8980
+#define SIOCDELDLCI 0x8981
+
+#define SIOCDEVPRIVATE 0x89F0
+#define SIOCPROTOPRIVATE 0x89E0
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/aarch64/ipc.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/aarch64/ipc.h
new file mode 100644
index 0000000..26161a2
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/aarch64/ipc.h
@@ -0,0 +1,14 @@
+struct ipc_perm {
+ key_t __ipc_perm_key;
+ uid_t uid;
+ gid_t gid;
+ uid_t cuid;
+ gid_t cgid;
+ mode_t mode;
+ unsigned short __ipc_perm_seq;
+
+ unsigned long __pad1;
+ unsigned long __pad2;
+};
+
+#define IPC_64 0
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/aarch64/reg.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/aarch64/reg.h
new file mode 100644
index 0000000..2633f39
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/aarch64/reg.h
@@ -0,0 +1,2 @@
+#undef __WORDSIZE
+#define __WORDSIZE 64
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/aarch64/setjmp.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/aarch64/setjmp.h
new file mode 100644
index 0000000..c37aeb8
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/aarch64/setjmp.h
@@ -0,0 +1 @@
+typedef unsigned long long int __jmp_buf[23];
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/aarch64/signal.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/aarch64/signal.h
new file mode 100644
index 0000000..64e57f3
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/aarch64/signal.h
@@ -0,0 +1,107 @@
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define MINSIGSTKSZ 6144
+#define SIGSTKSZ 12288
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+typedef unsigned long greg_t;
+typedef unsigned long gregset_t[34];
+
+typedef struct {
+ long double vregs[32];
+ unsigned int fpsr;
+ unsigned int fpcr;
+} fpregset_t;
+typedef struct sigcontext {
+ unsigned long fault_address;
+ unsigned long regs[31];
+ unsigned long sp, pc, pstate;
+ long double __reserved[256];
+} mcontext_t;
+
+#define FPSIMD_MAGIC 0x46508001
+#define ESR_MAGIC 0x45535201
+struct _aarch64_ctx {
+ unsigned int magic;
+ unsigned int size;
+};
+struct fpsimd_context {
+ struct _aarch64_ctx head;
+ unsigned int fpsr;
+ unsigned int fpcr;
+ long double vregs[32];
+};
+struct esr_context {
+ struct _aarch64_ctx head;
+ unsigned long esr;
+};
+#else
+typedef struct {
+ long double __regs[18 + 256];
+} mcontext_t;
+#endif
+
+struct sigaltstack {
+ void* ss_sp;
+ int ss_flags;
+ size_t ss_size;
+};
+
+typedef struct __ucontext {
+ unsigned long uc_flags;
+ struct ucontext* uc_link;
+ stack_t uc_stack;
+ sigset_t uc_sigmask;
+ mcontext_t uc_mcontext;
+} ucontext_t;
+
+#define SA_NOCLDSTOP 1
+#define SA_NOCLDWAIT 2
+#define SA_SIGINFO 4
+#define SA_ONSTACK 0x08000000
+#define SA_RESTART 0x10000000
+#define SA_NODEFER 0x40000000
+#define SA_RESETHAND 0x80000000
+#define SA_RESTORER 0x04000000
+
+#endif
+
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGIOT SIGABRT
+#define SIGBUS 7
+#define SIGFPE 8
+#define SIGKILL 9
+#define SIGUSR1 10
+#define SIGSEGV 11
+#define SIGUSR2 12
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGSTKFLT 16
+#define SIGCHLD 17
+#define SIGCONT 18
+#define SIGSTOP 19
+#define SIGTSTP 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGURG 23
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGIO 29
+#define SIGPOLL 29
+#define SIGPWR 30
+#define SIGSYS 31
+#define SIGUNUSED SIGSYS
+
+#define _NSIG 65
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/aarch64/stat.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/aarch64/stat.h
new file mode 100644
index 0000000..02102fa
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/aarch64/stat.h
@@ -0,0 +1,18 @@
+struct stat {
+ dev_t st_dev;
+ ino_t st_ino;
+ mode_t st_mode;
+ nlink_t st_nlink;
+ uid_t st_uid;
+ gid_t st_gid;
+ dev_t st_rdev;
+ unsigned long __pad;
+ off_t st_size;
+ blksize_t st_blksize;
+ int __pad2;
+ blkcnt_t st_blocks;
+ struct timespec st_atim;
+ struct timespec st_mtim;
+ struct timespec st_ctim;
+ unsigned __unused1[2];
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/alltypes.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/alltypes.h
new file mode 100644
index 0000000..95da44c
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/alltypes.h
@@ -0,0 +1,544 @@
+#if defined(__cplusplus) && !defined(__clang__)
+#define __C11_ATOMIC(t) t
+#else
+#define __C11_ATOMIC(t) _Atomic(t)
+#endif
+
+#if defined(__NEED_uint8_t) && !defined(__DEFINED_uint8_t)
+typedef __UINT8_TYPE__ uint8_t;
+#define __DEFINED_uint8_t
+#endif
+
+#if defined(__NEED_uint16_t) && !defined(__DEFINED_uint16_t)
+typedef __UINT16_TYPE__ uint16_t;
+#define __DEFINED_uint16_t
+#endif
+
+#if defined(__NEED_uint32_t) && !defined(__DEFINED_uint32_t)
+typedef __UINT32_TYPE__ uint32_t;
+#define __DEFINED_uint32_t
+#endif
+
+#if defined(__NEED_uint64_t) && !defined(__DEFINED_uint64_t)
+typedef __UINT64_TYPE__ uint64_t;
+#define __DEFINED_uint64_t
+#endif
+
+#if defined(__NEED_int8_t) && !defined(__DEFINED_int8_t)
+typedef __INT8_TYPE__ int8_t;
+#define __DEFINED_int8_t
+#endif
+
+#if defined(__NEED_int16_t) && !defined(__DEFINED_int16_t)
+typedef __INT16_TYPE__ int16_t;
+#define __DEFINED_int16_t
+#endif
+
+#if defined(__NEED_int32_t) && !defined(__DEFINED_int32_t)
+typedef __INT32_TYPE__ int32_t;
+#define __DEFINED_int32_t
+#endif
+
+#if defined(__NEED_int64_t) && !defined(__DEFINED_int64_t)
+typedef __INT64_TYPE__ int64_t;
+#define __DEFINED_int64_t
+#endif
+
+#if defined(__NEED_uint_least8_t) && !defined(__DEFINED_uint_least8_t)
+typedef __UINT_LEAST8_TYPE__ uint_least8_t;
+#define __DEFINED_uint_least8_t
+#endif
+
+#if defined(__NEED_uint_least16_t) && !defined(__DEFINED_uint_least16_t)
+typedef __UINT_LEAST16_TYPE__ uint_least16_t;
+#define __DEFINED_uint_least16_t
+#endif
+
+#if defined(__NEED_uint_least32_t) && !defined(__DEFINED_uint_least32_t)
+typedef __UINT_LEAST32_TYPE__ uint_least32_t;
+#define __DEFINED_uint_least32_t
+#endif
+
+#if defined(__NEED_uint_least64_t) && !defined(__DEFINED_uint_least64_t)
+typedef __UINT_LEAST64_TYPE__ uint_least64_t;
+#define __DEFINED_uint_least64_t
+#endif
+
+#if defined(__NEED_int_least8_t) && !defined(__DEFINED_int_least8_t)
+typedef __INT_LEAST8_TYPE__ int_least8_t;
+#define __DEFINED_int_least8_t
+#endif
+
+#if defined(__NEED_int_least16_t) && !defined(__DEFINED_int_least16_t)
+typedef __INT_LEAST16_TYPE__ int_least16_t;
+#define __DEFINED_int_least16_t
+#endif
+
+#if defined(__NEED_int_least32_t) && !defined(__DEFINED_int_least32_t)
+typedef __INT_LEAST32_TYPE__ int_least32_t;
+#define __DEFINED_int_least32_t
+#endif
+
+#if defined(__NEED_int_least64_t) && !defined(__DEFINED_int_least64_t)
+typedef __INT_LEAST64_TYPE__ int_least64_t;
+#define __DEFINED_int_least64_t
+#endif
+
+#if defined(__NEED_uint_fast8_t) && !defined(__DEFINED_uint_fast8_t)
+typedef __UINT_FAST8_TYPE__ uint_fast8_t;
+#define __DEFINED_uint_fast8_t
+#endif
+
+#if defined(__NEED_uint_fast16_t) && !defined(__DEFINED_uint_fast16_t)
+typedef __UINT_FAST16_TYPE__ uint_fast16_t;
+#define __DEFINED_uint_fast16_t
+#endif
+
+#if defined(__NEED_uint_fast32_t) && !defined(__DEFINED_uint_fast32_t)
+typedef __UINT_FAST32_TYPE__ uint_fast32_t;
+#define __DEFINED_uint_fast32_t
+#endif
+
+#if defined(__NEED_uint_fast64_t) && !defined(__DEFINED_uint_fast64_t)
+typedef __UINT_FAST64_TYPE__ uint_fast64_t;
+#define __DEFINED_uint_fast64_t
+#endif
+
+#if defined(__NEED_int_fast8_t) && !defined(__DEFINED_int_fast8_t)
+typedef __INT_FAST8_TYPE__ int_fast8_t;
+#define __DEFINED_int_fast8_t
+#endif
+
+#if defined(__NEED_int_fast16_t) && !defined(__DEFINED_int_fast16_t)
+typedef __INT_FAST16_TYPE__ int_fast16_t;
+#define __DEFINED_int_fast16_t
+#endif
+
+#if defined(__NEED_int_fast32_t) && !defined(__DEFINED_int_fast32_t)
+typedef __INT_FAST32_TYPE__ int_fast32_t;
+#define __DEFINED_int_fast32_t
+#endif
+
+#if defined(__NEED_int_fast64_t) && !defined(__DEFINED_int_fast64_t)
+typedef __INT_FAST64_TYPE__ int_fast64_t;
+#define __DEFINED_int_fast64_t
+#endif
+
+#if defined(__NEED_intptr_t) && !defined(__DEFINED_intptr_t)
+typedef __INTPTR_TYPE__ intptr_t;
+#define __DEFINED_intptr_t
+#endif
+
+#if defined(__NEED_uintptr_t) && !defined(__DEFINED_uintptr_t)
+typedef __UINTPTR_TYPE__ uintptr_t;
+#define __DEFINED_uintptr_t
+#endif
+
+#if defined(__NEED_intmax_t) && !defined(__DEFINED_intmax_t)
+typedef __INTMAX_TYPE__ intmax_t;
+#define __DEFINED_intmax_t
+#endif
+
+#if defined(__NEED_uintmax_t) && !defined(__DEFINED_uintmax_t)
+typedef __UINTMAX_TYPE__ uintmax_t;
+#define __DEFINED_uintmax_t
+#endif
+
+#ifndef __cplusplus
+#if defined(__NEED_wchar_t) && !defined(__DEFINED_wchar_t)
+typedef __WCHAR_TYPE__ wchar_t;
+#define __DEFINED_wchar_t
+#endif
+#endif
+
+#if defined(__NEED_wint_t) && !defined(__DEFINED_wint_t)
+typedef unsigned wint_t;
+#define __DEFINED_wint_t
+#endif
+
+#if defined(__NEED_wctype_t) && !defined(__DEFINED_wctype_t)
+typedef unsigned long wctype_t;
+#define __DEFINED_wctype_t
+#endif
+
+#if defined(__NEED_size_t) && !defined(__DEFINED_size_t)
+typedef __SIZE_TYPE__ size_t;
+#define __DEFINED_size_t
+#endif
+
+#if defined(__NEED_ptrdiff_t) && !defined(__DEFINED_ptrdiff_t)
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+#define __DEFINED_ptrdiff_t
+#endif
+
+#if defined(__NEED_va_list) && !defined(__DEFINED_va_list)
+typedef __builtin_va_list va_list;
+#define __DEFINED_va_list
+#endif
+
+#if defined(__NEED___isoc_va_list) && !defined(__DEFINED___isoc_va_list)
+typedef __builtin_va_list __isoc_va_list;
+#define __DEFINED___isoc_va_list
+#endif
+
+#if defined(__NEED_ssize_t) && !defined(__DEFINED_ssize_t)
+typedef long ssize_t;
+#define __DEFINED_ssize_t
+#endif
+
+#if defined(__NEED_time_t) && !defined(__DEFINED_time_t)
+typedef long time_t;
+#define __DEFINED_time_t
+#endif
+
+#if defined(__NEED_max_align_t) && !defined(__DEFINED_max_align_t)
+typedef struct {
+ long long __ll;
+ long double __ld;
+} max_align_t;
+#define __DEFINED_max_align_t
+#endif
+
+#if defined(__x86_64__) && defined(__FLT_EVAL_METHOD__) && __FLT_EVAL_METHOD__ == 2
+#if defined(__NEED_float_t) && !defined(__DEFINED_float_t)
+typedef long double float_t;
+#define __DEFINED_float_t
+#endif
+
+#if defined(__NEED_double_t) && !defined(__DEFINED_double_t)
+typedef long double double_t;
+#define __DEFINED_double_t
+#endif
+
+#else
+#if defined(__NEED_float_t) && !defined(__DEFINED_float_t)
+typedef float float_t;
+#define __DEFINED_float_t
+#endif
+
+#if defined(__NEED_double_t) && !defined(__DEFINED_double_t)
+typedef double double_t;
+#define __DEFINED_double_t
+#endif
+
+#endif
+
+#if defined(__NEED_suseconds_t) && !defined(__DEFINED_suseconds_t)
+typedef long suseconds_t;
+#define __DEFINED_suseconds_t
+#endif
+
+#if defined(__NEED_useconds_t) && !defined(__DEFINED_useconds_t)
+typedef unsigned useconds_t;
+#define __DEFINED_useconds_t
+#endif
+
+#if defined(__NEED_clockid_t) && !defined(__DEFINED_clockid_t)
+typedef int clockid_t;
+#define __DEFINED_clockid_t
+#endif
+
+#if defined(__NEED_clock_t) && !defined(__DEFINED_clock_t)
+typedef long clock_t;
+#define __DEFINED_clock_t
+#endif
+
+#if defined(__NEED_pid_t) && !defined(__DEFINED_pid_t)
+typedef int pid_t;
+#define __DEFINED_pid_t
+#endif
+
+#if defined(__NEED_id_t) && !defined(__DEFINED_id_t)
+typedef unsigned id_t;
+#define __DEFINED_id_t
+#endif
+
+#if defined(__NEED_uid_t) && !defined(__DEFINED_uid_t)
+typedef unsigned uid_t;
+#define __DEFINED_uid_t
+#endif
+
+#if defined(__NEED_gid_t) && !defined(__DEFINED_gid_t)
+typedef unsigned gid_t;
+#define __DEFINED_gid_t
+#endif
+
+#if defined(__NEED_register_t) && !defined(__DEFINED_register_t)
+typedef long register_t;
+#define __DEFINED_register_t
+#endif
+
+#if defined(__NEED_nlink_t) && !defined(__DEFINED_nlink_t)
+typedef unsigned long nlink_t;
+#define __DEFINED_nlink_t
+#endif
+
+#if defined(__NEED_off_t) && !defined(__DEFINED_off_t)
+typedef long long off_t;
+#define __DEFINED_off_t
+#endif
+
+#if defined(__NEED_ino_t) && !defined(__DEFINED_ino_t)
+typedef unsigned long long ino_t;
+#define __DEFINED_ino_t
+#endif
+
+#if defined(__NEED_dev_t) && !defined(__DEFINED_dev_t)
+typedef unsigned long long dev_t;
+#define __DEFINED_dev_t
+#endif
+
+#if defined(__NEED_blksize_t) && !defined(__DEFINED_blksize_t)
+typedef long blksize_t;
+#define __DEFINED_blksize_t
+#endif
+
+#if defined(__NEED_blkcnt_t) && !defined(__DEFINED_blkcnt_t)
+typedef long long blkcnt_t;
+#define __DEFINED_blkcnt_t
+#endif
+
+#if defined(__NEED_fsblkcnt_t) && !defined(__DEFINED_fsblkcnt_t)
+typedef unsigned long long fsblkcnt_t;
+#define __DEFINED_fsblkcnt_t
+#endif
+
+#if defined(__NEED_fsfilcnt_t) && !defined(__DEFINED_fsfilcnt_t)
+typedef unsigned long long fsfilcnt_t;
+#define __DEFINED_fsfilcnt_t
+#endif
+
+#if defined(__NEED_struct_iovec) && !defined(__DEFINED_struct_iovec)
+struct iovec {
+ void* iov_base;
+ size_t iov_len;
+};
+#define __DEFINED_struct_iovec
+#endif
+
+#if defined(__NEED_struct_timeval) && !defined(__DEFINED_struct_timeval)
+struct timeval {
+ time_t tv_sec;
+ suseconds_t tv_usec;
+};
+#define __DEFINED_struct_timeval
+#endif
+
+#if defined(__NEED_struct_timespec) && !defined(__DEFINED_struct_timespec)
+struct timespec {
+ time_t tv_sec;
+ long tv_nsec;
+};
+#define __DEFINED_struct_timespec
+#endif
+
+#if defined(__NEED_key_t) && !defined(__DEFINED_key_t)
+typedef int key_t;
+#define __DEFINED_key_t
+#endif
+
+#if defined(__NEED_timer_t) && !defined(__DEFINED_timer_t)
+typedef void* timer_t;
+#define __DEFINED_timer_t
+#endif
+
+#if defined(__NEED_regoff_t) && !defined(__DEFINED_regoff_t)
+typedef long regoff_t;
+#define __DEFINED_regoff_t
+#endif
+
+#if defined(__NEED_socklen_t) && !defined(__DEFINED_socklen_t)
+typedef unsigned socklen_t;
+#define __DEFINED_socklen_t
+#endif
+
+#if defined(__NEED_sa_family_t) && !defined(__DEFINED_sa_family_t)
+typedef unsigned short sa_family_t;
+#define __DEFINED_sa_family_t
+#endif
+
+#if defined(__NEED_FILE) && !defined(__DEFINED_FILE)
+typedef struct _IO_FILE FILE;
+#define __DEFINED_FILE
+#endif
+
+#if defined(__NEED_locale_t) && !defined(__DEFINED_locale_t)
+typedef struct __locale_struct* locale_t;
+#define __DEFINED_locale_t
+#endif
+
+#if defined(__NEED_mode_t) && !defined(__DEFINED_mode_t)
+typedef unsigned mode_t;
+#define __DEFINED_mode_t
+#endif
+
+#if defined(__NEED_sigset_t) && !defined(__DEFINED_sigset_t)
+typedef struct __sigset_t {
+ unsigned long __bits[128 / sizeof(long)];
+} sigset_t;
+#define __DEFINED_sigset_t
+#endif
+
+#if defined(__NEED_pthread_once_t) && !defined(__DEFINED_pthread_once_t)
+typedef __C11_ATOMIC(int) pthread_once_t;
+#define __DEFINED_pthread_once_t
+#endif
+
+#if defined(__NEED_once_flag) && !defined(__DEFINED_once_flag)
+typedef __C11_ATOMIC(int) once_flag;
+#define __DEFINED_once_flag
+#endif
+
+#if defined(__NEED_pthread_key_t) && !defined(__DEFINED_pthread_key_t)
+typedef unsigned pthread_key_t;
+#define __DEFINED_pthread_key_t
+#endif
+
+#if defined(__NEED_pthread_spinlock_t) && !defined(__DEFINED_pthread_spinlock_t)
+typedef __C11_ATOMIC(int) pthread_spinlock_t;
+#define __DEFINED_pthread_spinlock_t
+#endif
+
+#if defined(__NEED_pthread_mutexattr_t) && !defined(__DEFINED_pthread_mutexattr_t)
+typedef struct {
+ unsigned __attr;
+} pthread_mutexattr_t;
+#define __DEFINED_pthread_mutexattr_t
+#endif
+
+#if defined(__NEED_pthread_condattr_t) && !defined(__DEFINED_pthread_condattr_t)
+typedef struct {
+ unsigned __attr;
+} pthread_condattr_t;
+#define __DEFINED_pthread_condattr_t
+#endif
+
+#if defined(__NEED_pthread_barrierattr_t) && !defined(__DEFINED_pthread_barrierattr_t)
+typedef struct {
+ unsigned __attr;
+} pthread_barrierattr_t;
+#define __DEFINED_pthread_barrierattr_t
+#endif
+
+#if defined(__NEED_pthread_rwlockattr_t) && !defined(__DEFINED_pthread_rwlockattr_t)
+typedef struct {
+ unsigned __attr[2];
+} pthread_rwlockattr_t;
+#define __DEFINED_pthread_rwlockattr_t
+#endif
+
+#ifdef __cplusplus
+#if defined(__NEED_pthread_t) && !defined(__DEFINED_pthread_t)
+typedef unsigned long pthread_t;
+#define __DEFINED_pthread_t
+#endif
+
+#else
+#if defined(__NEED_pthread_t) && !defined(__DEFINED_pthread_t)
+typedef struct __pthread* pthread_t;
+#define __DEFINED_pthread_t
+#endif
+
+#endif
+
+#if defined(__NEED_mbstate_t) && !defined(__DEFINED_mbstate_t)
+typedef struct __mbstate_t {
+ unsigned __opaque1, __opaque2;
+} mbstate_t;
+#define __DEFINED_mbstate_t
+#endif
+
+#if defined(__NEED_pthread_attr_t) && !defined(__DEFINED_pthread_attr_t)
+typedef struct {
+ const char* __name;
+ int __c11;
+ size_t _a_stacksize;
+ size_t _a_guardsize;
+ void* _a_stackaddr;
+ int _a_detach;
+ int _a_sched;
+ int _a_policy;
+ int _a_prio;
+} pthread_attr_t;
+#define __DEFINED_pthread_attr_t
+#endif
+
+#if defined(__NEED_pthread_mutex_t) && !defined(__DEFINED_pthread_mutex_t)
+typedef struct {
+ unsigned _m_attr;
+ __C11_ATOMIC(int)
+ _m_lock;
+ __C11_ATOMIC(int)
+ _m_waiters;
+ int _m_count;
+} pthread_mutex_t;
+#define __DEFINED_pthread_mutex_t
+#endif
+
+#if defined(__NEED_mtx_t) && !defined(__DEFINED_mtx_t)
+typedef struct
+#if defined(__clang__)
+ __attribute__((__capability__("mutex")))
+#endif
+{
+ int __i[1];
+} mtx_t;
+#define __DEFINED_mtx_t
+#endif
+
+#if defined(__NEED_pthread_cond_t) && !defined(__DEFINED_pthread_cond_t)
+typedef struct {
+ void* _c_head;
+ int _c_clock;
+ void* _c_tail;
+ __C11_ATOMIC(int)
+ _c_lock;
+} pthread_cond_t;
+#define __DEFINED_pthread_cond_t
+#endif
+
+#if defined(__NEED_cnd_t) && !defined(__DEFINED_cnd_t)
+typedef struct {
+ void* _c_head;
+ int _c_clock;
+ void* _c_tail;
+ __C11_ATOMIC(int) _c_lock;
+} cnd_t;
+#define __DEFINED_cnd_t
+#endif
+
+#if defined(__NEED_pthread_rwlock_t) && !defined(__DEFINED_pthread_rwlock_t)
+typedef struct {
+ __C11_ATOMIC(int)
+ _rw_lock;
+ __C11_ATOMIC(int)
+ _rw_waiters;
+} pthread_rwlock_t;
+#define __DEFINED_pthread_rwlock_t
+#endif
+
+#if defined(__NEED_pthread_barrier_t) && !defined(__DEFINED_pthread_barrier_t)
+typedef struct {
+ __C11_ATOMIC(int)
+ _b_lock;
+ __C11_ATOMIC(int)
+ _b_waiters;
+ unsigned int _b_limit;
+ __C11_ATOMIC(int)
+ _b_count;
+ __C11_ATOMIC(int)
+ _b_waiters2;
+ void* _b_inst;
+} pthread_barrier_t;
+#define __DEFINED_pthread_barrier_t
+#endif
+
+#if defined(__NEED_sem_t) && !defined(__DEFINED_sem_t)
+typedef struct {
+ __C11_ATOMIC(int)
+ _s_value;
+ __C11_ATOMIC(int)
+ _s_waiters;
+} sem_t;
+#define __DEFINED_sem_t
+#endif
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/endian.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/endian.h
new file mode 100644
index 0000000..ed44e80
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/endian.h
@@ -0,0 +1,7 @@
+#if defined(__x86_64__)
+#include "x86_64/endian.h"
+#elif defined(__aarch64__)
+#include "aarch64/endian.h"
+#else
+#error Unsupported architecture!
+#endif
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/errno.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/errno.h
new file mode 100644
index 0000000..b9ebc31
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/errno.h
@@ -0,0 +1,134 @@
+#define EPERM 1
+#define ENOENT 2
+#define ESRCH 3
+#define EINTR 4
+#define EIO 5
+#define ENXIO 6
+#define E2BIG 7
+#define ENOEXEC 8
+#define EBADF 9
+#define ECHILD 10
+#define EAGAIN 11
+#define ENOMEM 12
+#define EACCES 13
+#define EFAULT 14
+#define ENOTBLK 15
+#define EBUSY 16
+#define EEXIST 17
+#define EXDEV 18
+#define ENODEV 19
+#define ENOTDIR 20
+#define EISDIR 21
+#define EINVAL 22
+#define ENFILE 23
+#define EMFILE 24
+#define ENOTTY 25
+#define ETXTBSY 26
+#define EFBIG 27
+#define ENOSPC 28
+#define ESPIPE 29
+#define EROFS 30
+#define EMLINK 31
+#define EPIPE 32
+#define EDOM 33
+#define ERANGE 34
+#define EDEADLK 35
+#define ENAMETOOLONG 36
+#define ENOLCK 37
+#define ENOSYS 38
+#define ENOTEMPTY 39
+#define ELOOP 40
+#define EWOULDBLOCK EAGAIN
+#define ENOMSG 42
+#define EIDRM 43
+#define ECHRNG 44
+#define EL2NSYNC 45
+#define EL3HLT 46
+#define EL3RST 47
+#define ELNRNG 48
+#define EUNATCH 49
+#define ENOCSI 50
+#define EL2HLT 51
+#define EBADE 52
+#define EBADR 53
+#define EXFULL 54
+#define ENOANO 55
+#define EBADRQC 56
+#define EBADSLT 57
+#define EDEADLOCK EDEADLK
+#define EBFONT 59
+#define ENOSTR 60
+#define ENODATA 61
+#define ETIME 62
+#define ENOSR 63
+#define ENONET 64
+#define ENOPKG 65
+#define EREMOTE 66
+#define ENOLINK 67
+#define EADV 68
+#define ESRMNT 69
+#define ECOMM 70
+#define EPROTO 71
+#define EMULTIHOP 72
+#define EDOTDOT 73
+#define EBADMSG 74
+#define EOVERFLOW 75
+#define ENOTUNIQ 76
+#define EBADFD 77
+#define EREMCHG 78
+#define ELIBACC 79
+#define ELIBBAD 80
+#define ELIBSCN 81
+#define ELIBMAX 82
+#define ELIBEXEC 83
+#define EILSEQ 84
+#define ERESTART 85
+#define ESTRPIPE 86
+#define EUSERS 87
+#define ENOTSOCK 88
+#define EDESTADDRREQ 89
+#define EMSGSIZE 90
+#define EPROTOTYPE 91
+#define ENOPROTOOPT 92
+#define EPROTONOSUPPORT 93
+#define ESOCKTNOSUPPORT 94
+#define EOPNOTSUPP 95
+#define ENOTSUP EOPNOTSUPP
+#define EPFNOSUPPORT 96
+#define EAFNOSUPPORT 97
+#define EADDRINUSE 98
+#define EADDRNOTAVAIL 99
+#define ENETDOWN 100
+#define ENETUNREACH 101
+#define ENETRESET 102
+#define ECONNABORTED 103
+#define ECONNRESET 104
+#define ENOBUFS 105
+#define EISCONN 106
+#define ENOTCONN 107
+#define ESHUTDOWN 108
+#define ETOOMANYREFS 109
+#define ETIMEDOUT 110
+#define ECONNREFUSED 111
+#define EHOSTDOWN 112
+#define EHOSTUNREACH 113
+#define EALREADY 114
+#define EINPROGRESS 115
+#define ESTALE 116
+#define EUCLEAN 117
+#define ENOTNAM 118
+#define ENAVAIL 119
+#define EISNAM 120
+#define EREMOTEIO 121
+#define EDQUOT 122
+#define ENOMEDIUM 123
+#define EMEDIUMTYPE 124
+#define ECANCELED 125
+#define ENOKEY 126
+#define EKEYEXPIRED 127
+#define EKEYREVOKED 128
+#define EKEYREJECTED 129
+#define EOWNERDEAD 130
+#define ENOTRECOVERABLE 131
+#define ERFKILL 132
+#define EHWPOISON 133
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/fcntl.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/fcntl.h
new file mode 100644
index 0000000..c96e45f
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/fcntl.h
@@ -0,0 +1,7 @@
+#if defined(__x86_64__)
+#include "x86_64/fcntl.h"
+#elif defined(__aarch64__)
+#include "aarch64/fcntl.h"
+#else
+#error Unsupported architecture!
+#endif
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/fenv.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/fenv.h
new file mode 100644
index 0000000..99ca0ba
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/fenv.h
@@ -0,0 +1,7 @@
+#if defined(__x86_64__)
+#include "x86_64/fenv.h"
+#elif defined(__aarch64__)
+#include "aarch64/fenv.h"
+#else
+#error Unsupported architecture!
+#endif
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/io.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/io.h
new file mode 100644
index 0000000..480bbaf
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/io.h
@@ -0,0 +1,7 @@
+#if defined(__x86_64__)
+#include "x86_64/io.h"
+#elif defined(__aarch64__)
+#include "aarch64/io.h"
+#else
+#error Unsupported architecture!
+#endif
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/ioctl.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/ioctl.h
new file mode 100644
index 0000000..d8bcfa3
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/ioctl.h
@@ -0,0 +1,7 @@
+#if defined(__x86_64__)
+#include "x86_64/ioctl.h"
+#elif defined(__aarch64__)
+#include "aarch64/ioctl.h"
+#else
+#error Unsupported architecture!
+#endif
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/ipc.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/ipc.h
new file mode 100644
index 0000000..a81d510
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/ipc.h
@@ -0,0 +1,7 @@
+#if defined(__x86_64__)
+#include "x86_64/ipc.h"
+#elif defined(__aarch64__)
+#include "aarch64/ipc.h"
+#else
+#error Unsupported architecture!
+#endif
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/limits.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/limits.h
new file mode 100644
index 0000000..8d1910b
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/limits.h
@@ -0,0 +1,8 @@
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define PAGE_SIZE 4096
+#define LONG_BIT 64
+#endif
+
+#define LONG_MAX 0x7fffffffffffffffL
+#define LLONG_MAX 0x7fffffffffffffffLL
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/msg.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/msg.h
new file mode 100644
index 0000000..1c8034b
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/msg.h
@@ -0,0 +1,12 @@
+struct msqid_ds {
+ struct ipc_perm msg_perm;
+ time_t msg_stime;
+ time_t msg_rtime;
+ time_t msg_ctime;
+ unsigned long msg_cbytes;
+ msgqnum_t msg_qnum;
+ msglen_t msg_qbytes;
+ pid_t msg_lspid;
+ pid_t msg_lrpid;
+ unsigned long __unused[2];
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/null.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/null.h
new file mode 100644
index 0000000..76e7b77
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/null.h
@@ -0,0 +1,15 @@
+// Copyright 2017 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
+
+#ifndef SYSROOT_BITS_NULL_H_
+#define SYSROOT_BITS_NULL_H_
+
+// The compiler's <stddef.h> defines NULL without defining anything
+// else if __need_NULL is defined first.
+#define __need_NULL
+#include <stddef.h>
+
+#endif // SYSROOT_BITS_NULL_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/poll.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/poll.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/poll.h
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/posix.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/posix.h
new file mode 100644
index 0000000..8068ce9
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/posix.h
@@ -0,0 +1,2 @@
+#define _POSIX_V6_LP64_OFF64 1
+#define _POSIX_V7_LP64_OFF64 1
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/reg.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/reg.h
new file mode 100644
index 0000000..ad220cc
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/reg.h
@@ -0,0 +1,7 @@
+#if defined(__x86_64__)
+#include "x86_64/reg.h"
+#elif defined(__aarch64__)
+#include "aarch64/reg.h"
+#else
+#error Unsupported architecture!
+#endif
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/resource.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/resource.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/resource.h
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/sem.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/sem.h
new file mode 100644
index 0000000..db4102f
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/sem.h
@@ -0,0 +1,14 @@
+struct semid_ds {
+ struct ipc_perm sem_perm;
+ time_t sem_otime;
+ time_t sem_ctime;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned short sem_nsems;
+ char __sem_nsems_pad[sizeof(time_t) - sizeof(short)];
+#else
+ char __sem_nsems_pad[sizeof(time_t) - sizeof(short)];
+ unsigned short sem_nsems;
+#endif
+ time_t __unused3;
+ time_t __unused4;
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/setjmp.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/setjmp.h
new file mode 100644
index 0000000..d42af58
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/setjmp.h
@@ -0,0 +1,7 @@
+#if defined(__x86_64__)
+#include "x86_64/setjmp.h"
+#elif defined(__aarch64__)
+#include "aarch64/setjmp.h"
+#else
+#error Unsupported architecture!
+#endif
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/shm.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/shm.h
new file mode 100644
index 0000000..a3b9dcc
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/shm.h
@@ -0,0 +1,24 @@
+#define SHMLBA 4096
+
+struct shmid_ds {
+ struct ipc_perm shm_perm;
+ size_t shm_segsz;
+ time_t shm_atime;
+ time_t shm_dtime;
+ time_t shm_ctime;
+ pid_t shm_cpid;
+ pid_t shm_lpid;
+ unsigned long shm_nattch;
+ unsigned long __pad1;
+ unsigned long __pad2;
+};
+
+struct shminfo {
+ unsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];
+};
+
+struct shm_info {
+ int __used_ids;
+ unsigned long shm_tot, shm_rss, shm_swp;
+ unsigned long __swap_attempts, __swap_successes;
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/signal.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/signal.h
new file mode 100644
index 0000000..021a17f
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/signal.h
@@ -0,0 +1,7 @@
+#if defined(__x86_64__)
+#include "x86_64/signal.h"
+#elif defined(__aarch64__)
+#include "aarch64/signal.h"
+#else
+#error Unsupported architecture!
+#endif
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/socket.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/socket.h
new file mode 100644
index 0000000..1127d5b
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/socket.h
@@ -0,0 +1,33 @@
+#include <endian.h>
+
+struct msghdr {
+ void* msg_name;
+ socklen_t msg_namelen;
+ struct iovec* msg_iov;
+#if __BYTE_ORDER == __BIG_ENDIAN
+ int __pad1, msg_iovlen;
+#else
+ int msg_iovlen, __pad1;
+#endif
+ void* msg_control;
+#if __BYTE_ORDER == __BIG_ENDIAN
+ int __pad2;
+ socklen_t msg_controllen;
+#else
+ socklen_t msg_controllen;
+ int __pad2;
+#endif
+ int msg_flags;
+};
+
+struct cmsghdr {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ int __pad1;
+ socklen_t cmsg_len;
+#else
+ socklen_t cmsg_len;
+ int __pad1;
+#endif
+ int cmsg_level;
+ int cmsg_type;
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/stat.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/stat.h
new file mode 100644
index 0000000..308b256
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/stat.h
@@ -0,0 +1,7 @@
+#if defined(__x86_64__)
+#include "x86_64/stat.h"
+#elif defined(__aarch64__)
+#include "aarch64/stat.h"
+#else
+#error Unsupported architecture!
+#endif
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/statfs.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/statfs.h
new file mode 100644
index 0000000..ef2bbe3
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/statfs.h
@@ -0,0 +1,7 @@
+struct statfs {
+ unsigned long f_type, f_bsize;
+ fsblkcnt_t f_blocks, f_bfree, f_bavail;
+ fsfilcnt_t f_files, f_ffree;
+ fsid_t f_fsid;
+ unsigned long f_namelen, f_frsize, f_flags, f_spare[4];
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/termios.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/termios.h
new file mode 100644
index 0000000..d9a7359
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/termios.h
@@ -0,0 +1,159 @@
+struct termios {
+ tcflag_t c_iflag;
+ tcflag_t c_oflag;
+ tcflag_t c_cflag;
+ tcflag_t c_lflag;
+ cc_t c_line;
+ cc_t c_cc[NCCS];
+ speed_t __c_ispeed;
+ speed_t __c_ospeed;
+};
+
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+#define IGNBRK 0000001
+#define BRKINT 0000002
+#define IGNPAR 0000004
+#define PARMRK 0000010
+#define INPCK 0000020
+#define ISTRIP 0000040
+#define INLCR 0000100
+#define IGNCR 0000200
+#define ICRNL 0000400
+#define IUCLC 0001000
+#define IXON 0002000
+#define IXANY 0004000
+#define IXOFF 0010000
+#define IMAXBEL 0020000
+#define IUTF8 0040000
+
+#define OPOST 0000001
+#define OLCUC 0000002
+#define ONLCR 0000004
+#define OCRNL 0000010
+#define ONOCR 0000020
+#define ONLRET 0000040
+#define OFILL 0000100
+#define OFDEL 0000200
+#define NLDLY 0000400
+#define NL0 0000000
+#define NL1 0000400
+#define CRDLY 0003000
+#define CR0 0000000
+#define CR1 0001000
+#define CR2 0002000
+#define CR3 0003000
+#define TABDLY 0014000
+#define TAB0 0000000
+#define TAB1 0004000
+#define TAB2 0010000
+#define TAB3 0014000
+#define BSDLY 0020000
+#define BS0 0000000
+#define BS1 0020000
+#define FFDLY 0100000
+#define FF0 0000000
+#define FF1 0100000
+
+#define VTDLY 0040000
+#define VT0 0000000
+#define VT1 0040000
+
+#define B0 0000000
+#define B50 0000001
+#define B75 0000002
+#define B110 0000003
+#define B134 0000004
+#define B150 0000005
+#define B200 0000006
+#define B300 0000007
+#define B600 0000010
+#define B1200 0000011
+#define B1800 0000012
+#define B2400 0000013
+#define B4800 0000014
+#define B9600 0000015
+#define B19200 0000016
+#define B38400 0000017
+
+#define B57600 0010001
+#define B115200 0010002
+#define B230400 0010003
+#define B460800 0010004
+#define B500000 0010005
+#define B576000 0010006
+#define B921600 0010007
+#define B1000000 0010010
+#define B1152000 0010011
+#define B1500000 0010012
+#define B2000000 0010013
+#define B2500000 0010014
+#define B3000000 0010015
+#define B3500000 0010016
+#define B4000000 0010017
+
+#define CBAUD 0010017
+
+#define CSIZE 0000060
+#define CS5 0000000
+#define CS6 0000020
+#define CS7 0000040
+#define CS8 0000060
+#define CSTOPB 0000100
+#define CREAD 0000200
+#define PARENB 0000400
+#define PARODD 0001000
+#define HUPCL 0002000
+#define CLOCAL 0004000
+
+#define ISIG 0000001
+#define ICANON 0000002
+#define ECHO 0000010
+#define ECHOE 0000020
+#define ECHOK 0000040
+#define ECHONL 0000100
+#define NOFLSH 0000200
+#define TOSTOP 0000400
+#define IEXTEN 0100000
+
+#define ECHOCTL 0001000
+#define ECHOPRT 0002000
+#define ECHOKE 0004000
+#define FLUSHO 0010000
+#define PENDIN 0040000
+
+#define TCOOFF 0
+#define TCOON 1
+#define TCIOFF 2
+#define TCION 3
+
+#define TCIFLUSH 0
+#define TCOFLUSH 1
+#define TCIOFLUSH 2
+
+#define TCSANOW 0
+#define TCSADRAIN 1
+#define TCSAFLUSH 2
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define CBAUDEX 0010000
+#define CRTSCTS 020000000000
+#define EXTPROC 0200000
+#define XTABS 0014000
+#endif
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/x86_64/endian.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/x86_64/endian.h
new file mode 100644
index 0000000..172c338
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/x86_64/endian.h
@@ -0,0 +1 @@
+#define __BYTE_ORDER __LITTLE_ENDIAN
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/x86_64/fenv.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/x86_64/fenv.h
new file mode 100644
index 0000000..32e7dbf
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/x86_64/fenv.h
@@ -0,0 +1,34 @@
+#define FE_INVALID 1
+#define __FE_DENORM 2
+#define FE_DIVBYZERO 4
+#define FE_OVERFLOW 8
+#define FE_UNDERFLOW 16
+#define FE_INEXACT 32
+
+#define FE_ALL_EXCEPT 63
+
+#define FE_TONEAREST 0
+#define FE_DOWNWARD 0x400
+#define FE_UPWARD 0x800
+#define FE_TOWARDZERO 0xc00
+
+typedef unsigned short fexcept_t;
+
+typedef struct {
+ unsigned short __control_word;
+ unsigned short __unused1;
+ unsigned short __status_word;
+ unsigned short __unused2;
+ unsigned short __tags;
+ unsigned short __unused3;
+ unsigned int __eip;
+ unsigned short __cs_selector;
+ unsigned int __opcode : 11;
+ unsigned int __unused4 : 5;
+ unsigned int __data_offset;
+ unsigned short __data_selector;
+ unsigned short __unused5;
+ unsigned int __mxcsr;
+} fenv_t;
+
+#define FE_DFL_ENV ((const fenv_t*)-1)
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/x86_64/io.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/x86_64/io.h
new file mode 100644
index 0000000..7234422
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/x86_64/io.h
@@ -0,0 +1,53 @@
+static __inline void outb(unsigned char __val, unsigned short __port) {
+ __asm__ volatile("outb %0,%1" : : "a"(__val), "dN"(__port));
+}
+
+static __inline void outw(unsigned short __val, unsigned short __port) {
+ __asm__ volatile("outw %0,%1" : : "a"(__val), "dN"(__port));
+}
+
+static __inline void outl(unsigned int __val, unsigned short __port) {
+ __asm__ volatile("outl %0,%1" : : "a"(__val), "dN"(__port));
+}
+
+static __inline unsigned char inb(unsigned short __port) {
+ unsigned char __val;
+ __asm__ volatile("inb %1,%0" : "=a"(__val) : "dN"(__port));
+ return __val;
+}
+
+static __inline unsigned short inw(unsigned short __port) {
+ unsigned short __val;
+ __asm__ volatile("inw %1,%0" : "=a"(__val) : "dN"(__port));
+ return __val;
+}
+
+static __inline unsigned int inl(unsigned short __port) {
+ unsigned int __val;
+ __asm__ volatile("inl %1,%0" : "=a"(__val) : "dN"(__port));
+ return __val;
+}
+
+static __inline void outsb(unsigned short __port, const void* __buf, unsigned long __n) {
+ __asm__ volatile("cld; rep; outsb" : "+S"(__buf), "+c"(__n) : "d"(__port));
+}
+
+static __inline void outsw(unsigned short __port, const void* __buf, unsigned long __n) {
+ __asm__ volatile("cld; rep; outsw" : "+S"(__buf), "+c"(__n) : "d"(__port));
+}
+
+static __inline void outsl(unsigned short __port, const void* __buf, unsigned long __n) {
+ __asm__ volatile("cld; rep; outsl" : "+S"(__buf), "+c"(__n) : "d"(__port));
+}
+
+static __inline void insb(unsigned short __port, void* __buf, unsigned long __n) {
+ __asm__ volatile("cld; rep; insb" : "+D"(__buf), "+c"(__n) : "d"(__port));
+}
+
+static __inline void insw(unsigned short __port, void* __buf, unsigned long __n) {
+ __asm__ volatile("cld; rep; insw" : "+D"(__buf), "+c"(__n) : "d"(__port));
+}
+
+static __inline void insl(unsigned short __port, void* __buf, unsigned long __n) {
+ __asm__ volatile("cld; rep; insl" : "+D"(__buf), "+c"(__n) : "d"(__port));
+}
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/x86_64/ioctl.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/x86_64/ioctl.h
new file mode 100644
index 0000000..bc8d16a
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/x86_64/ioctl.h
@@ -0,0 +1,197 @@
+#define _IOC(a, b, c, d) (((a) << 30) | ((b) << 8) | (c) | ((d) << 16))
+#define _IOC_NONE 0U
+#define _IOC_WRITE 1U
+#define _IOC_READ 2U
+
+#define _IO(a, b) _IOC(_IOC_NONE, (a), (b), 0)
+#define _IOW(a, b, c) _IOC(_IOC_WRITE, (a), (b), sizeof(c))
+#define _IOR(a, b, c) _IOC(_IOC_READ, (a), (b), sizeof(c))
+#define _IOWR(a, b, c) _IOC(_IOC_READ | _IOC_WRITE, (a), (b), sizeof(c))
+
+#define TCGETS 0x5401
+#define TCSETS 0x5402
+#define TCSETSW 0x5403
+#define TCSETSF 0x5404
+#define TCGETA 0x5405
+#define TCSETA 0x5406
+#define TCSETAW 0x5407
+#define TCSETAF 0x5408
+#define TCSBRK 0x5409
+#define TCXONC 0x540A
+#define TCFLSH 0x540B
+#define TIOCEXCL 0x540C
+#define TIOCNXCL 0x540D
+#define TIOCSCTTY 0x540E
+#define TIOCGPGRP 0x540F
+#define TIOCSPGRP 0x5410
+#define TIOCOUTQ 0x5411
+#define TIOCSTI 0x5412
+#define TIOCGWINSZ 0x5413
+#define TIOCSWINSZ 0x5414
+#define TIOCMGET 0x5415
+#define TIOCMBIS 0x5416
+#define TIOCMBIC 0x5417
+#define TIOCMSET 0x5418
+#define TIOCGSOFTCAR 0x5419
+#define TIOCSSOFTCAR 0x541A
+#define FIONREAD 0x541B
+#define TIOCINQ FIONREAD
+#define TIOCLINUX 0x541C
+#define TIOCCONS 0x541D
+#define TIOCGSERIAL 0x541E
+#define TIOCSSERIAL 0x541F
+#define TIOCPKT 0x5420
+#define FIONBIO 0x5421
+#define TIOCNOTTY 0x5422
+#define TIOCSETD 0x5423
+#define TIOCGETD 0x5424
+#define TCSBRKP 0x5425
+#define TIOCTTYGSTRUCT 0x5426
+#define TIOCSBRK 0x5427
+#define TIOCCBRK 0x5428
+#define TIOCGSID 0x5429
+#define TIOCGPTN 0x80045430
+#define TIOCSPTLCK 0x40045431
+#define TCGETX 0x5432
+#define TCSETX 0x5433
+#define TCSETXF 0x5434
+#define TCSETXW 0x5435
+
+#define FIONCLEX 0x5450
+#define FIOCLEX 0x5451
+#define FIOASYNC 0x5452
+#define TIOCSERCONFIG 0x5453
+#define TIOCSERGWILD 0x5454
+#define TIOCSERSWILD 0x5455
+#define TIOCGLCKTRMIOS 0x5456
+#define TIOCSLCKTRMIOS 0x5457
+#define TIOCSERGSTRUCT 0x5458
+#define TIOCSERGETLSR 0x5459
+#define TIOCSERGETMULTI 0x545A
+#define TIOCSERSETMULTI 0x545B
+
+#define TIOCMIWAIT 0x545C
+#define TIOCGICOUNT 0x545D
+#define TIOCGHAYESESP 0x545E
+#define TIOCSHAYESESP 0x545F
+#define FIOQSIZE 0x5460
+
+#define TIOCPKT_DATA 0
+#define TIOCPKT_FLUSHREAD 1
+#define TIOCPKT_FLUSHWRITE 2
+#define TIOCPKT_STOP 4
+#define TIOCPKT_START 8
+#define TIOCPKT_NOSTOP 16
+#define TIOCPKT_DOSTOP 32
+#define TIOCPKT_IOCTL 64
+
+#define TIOCSER_TEMT 0x01
+
+struct winsize {
+ unsigned short ws_row;
+ unsigned short ws_col;
+ unsigned short ws_xpixel;
+ unsigned short ws_ypixel;
+};
+
+#define TIOCM_LE 0x001
+#define TIOCM_DTR 0x002
+#define TIOCM_RTS 0x004
+#define TIOCM_ST 0x008
+#define TIOCM_SR 0x010
+#define TIOCM_CTS 0x020
+#define TIOCM_CAR 0x040
+#define TIOCM_RNG 0x080
+#define TIOCM_DSR 0x100
+#define TIOCM_CD TIOCM_CAR
+#define TIOCM_RI TIOCM_RNG
+#define TIOCM_OUT1 0x2000
+#define TIOCM_OUT2 0x4000
+#define TIOCM_LOOP 0x8000
+#define TIOCM_MODEM_BITS TIOCM_OUT2
+
+#define N_TTY 0
+#define N_SLIP 1
+#define N_MOUSE 2
+#define N_PPP 3
+#define N_STRIP 4
+#define N_AX25 5
+#define N_X25 6
+#define N_6PACK 7
+#define N_MASC 8
+#define N_R3964 9
+#define N_PROFIBUS_FDL 10
+#define N_IRDA 11
+#define N_SMSBLOCK 12
+#define N_HDLC 13
+#define N_SYNC_PPP 14
+#define N_HCI 15
+
+#define FIOSETOWN 0x8901
+#define SIOCSPGRP 0x8902
+#define FIOGETOWN 0x8903
+#define SIOCGPGRP 0x8904
+#define SIOCATMARK 0x8905
+#define SIOCGSTAMP 0x8906
+
+#define SIOCADDRT 0x890B
+#define SIOCDELRT 0x890C
+#define SIOCRTMSG 0x890D
+
+#define SIOCGIFNAME 0x8910
+#define SIOCSIFLINK 0x8911
+#define SIOCGIFCONF 0x8912
+#define SIOCGIFFLAGS 0x8913
+#define SIOCSIFFLAGS 0x8914
+#define SIOCGIFADDR 0x8915
+#define SIOCSIFADDR 0x8916
+#define SIOCGIFDSTADDR 0x8917
+#define SIOCSIFDSTADDR 0x8918
+#define SIOCGIFBRDADDR 0x8919
+#define SIOCSIFBRDADDR 0x891a
+#define SIOCGIFNETMASK 0x891b
+#define SIOCSIFNETMASK 0x891c
+#define SIOCGIFMETRIC 0x891d
+#define SIOCSIFMETRIC 0x891e
+#define SIOCGIFMEM 0x891f
+#define SIOCSIFMEM 0x8920
+#define SIOCGIFMTU 0x8921
+#define SIOCSIFMTU 0x8922
+#define SIOCSIFHWADDR 0x8924
+#define SIOCGIFENCAP 0x8925
+#define SIOCSIFENCAP 0x8926
+#define SIOCGIFHWADDR 0x8927
+#define SIOCGIFSLAVE 0x8929
+#define SIOCSIFSLAVE 0x8930
+#define SIOCADDMULTI 0x8931
+#define SIOCDELMULTI 0x8932
+#define SIOCGIFINDEX 0x8933
+#define SIOGIFINDEX SIOCGIFINDEX
+#define SIOCSIFPFLAGS 0x8934
+#define SIOCGIFPFLAGS 0x8935
+#define SIOCDIFADDR 0x8936
+#define SIOCSIFHWBROADCAST 0x8937
+#define SIOCGIFCOUNT 0x8938
+
+#define SIOCGIFBR 0x8940
+#define SIOCSIFBR 0x8941
+
+#define SIOCGIFTXQLEN 0x8942
+#define SIOCSIFTXQLEN 0x8943
+
+#define SIOCDARP 0x8953
+#define SIOCGARP 0x8954
+#define SIOCSARP 0x8955
+
+#define SIOCDRARP 0x8960
+#define SIOCGRARP 0x8961
+#define SIOCSRARP 0x8962
+
+#define SIOCGIFMAP 0x8970
+#define SIOCSIFMAP 0x8971
+
+#define SIOCADDDLCI 0x8980
+#define SIOCDELDLCI 0x8981
+
+#define SIOCDEVPRIVATE 0x89F0
+#define SIOCPROTOPRIVATE 0x89E0
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/x86_64/ipc.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/x86_64/ipc.h
new file mode 100644
index 0000000..c66f9ed
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/x86_64/ipc.h
@@ -0,0 +1,13 @@
+struct ipc_perm {
+ key_t __ipc_perm_key;
+ uid_t uid;
+ gid_t gid;
+ uid_t cuid;
+ gid_t cgid;
+ mode_t mode;
+ int __ipc_perm_seq;
+ long __pad1;
+ long __pad2;
+};
+
+#define IPC_64 0
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/x86_64/reg.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/x86_64/reg.h
new file mode 100644
index 0000000..12d43c5
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/x86_64/reg.h
@@ -0,0 +1,29 @@
+#undef __WORDSIZE
+#define __WORDSIZE 64
+#define R15 0
+#define R14 1
+#define R13 2
+#define R12 3
+#define RBP 4
+#define RBX 5
+#define R11 6
+#define R10 7
+#define R9 8
+#define R8 9
+#define RAX 10
+#define RCX 11
+#define RDX 12
+#define RSI 13
+#define RDI 14
+#define ORIG_RAX 15
+#define RIP 16
+#define CS 17
+#define EFLAGS 18
+#define RSP 19
+#define SS 20
+#define FS_BASE 21
+#define GS_BASE 22
+#define DS 23
+#define ES 24
+#define FS 25
+#define GS 26
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/x86_64/setjmp.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/x86_64/setjmp.h
new file mode 100644
index 0000000..29336e4
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/x86_64/setjmp.h
@@ -0,0 +1 @@
+typedef unsigned long long int __jmp_buf[9];
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/x86_64/signal.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/x86_64/signal.h
new file mode 100644
index 0000000..26095e9
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/x86_64/signal.h
@@ -0,0 +1,129 @@
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define MINSIGSTKSZ 2048
+#define SIGSTKSZ 8192
+#endif
+
+#ifdef _GNU_SOURCE
+#define REG_R8 0
+#define REG_R9 1
+#define REG_R10 2
+#define REG_R11 3
+#define REG_R12 4
+#define REG_R13 5
+#define REG_R14 6
+#define REG_R15 7
+#define REG_RDI 8
+#define REG_RSI 9
+#define REG_RBP 10
+#define REG_RBX 11
+#define REG_RDX 12
+#define REG_RAX 13
+#define REG_RCX 14
+#define REG_RSP 15
+#define REG_RIP 16
+#define REG_EFL 17
+#define REG_CSGSFS 18
+#define REG_ERR 19
+#define REG_TRAPNO 20
+#define REG_OLDMASK 21
+#define REG_CR2 22
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+typedef long long greg_t, gregset_t[23];
+typedef struct _fpstate {
+ unsigned short cwd, swd, ftw, fop;
+ unsigned long long rip, rdp;
+ unsigned mxcsr, mxcr_mask;
+ struct {
+ unsigned short significand[4], exponent, padding[3];
+ } _st[8];
+ struct {
+ unsigned element[4];
+ } _xmm[16];
+ unsigned padding[24];
+} * fpregset_t;
+struct sigcontext {
+ unsigned long r8, r9, r10, r11, r12, r13, r14, r15;
+ unsigned long rdi, rsi, rbp, rbx, rdx, rax, rcx, rsp, rip, eflags;
+ unsigned short cs, gs, fs, __pad0;
+ unsigned long err, trapno, oldmask, cr2;
+ struct _fpstate* fpstate;
+ unsigned long __reserved1[8];
+};
+typedef struct {
+ gregset_t gregs;
+ fpregset_t fpregs;
+ unsigned long long __reserved1[8];
+} mcontext_t;
+#else
+typedef struct {
+ unsigned long __space[32];
+} mcontext_t;
+#endif
+
+struct sigaltstack {
+ void* ss_sp;
+ int ss_flags;
+ size_t ss_size;
+};
+
+typedef struct __ucontext {
+ unsigned long uc_flags;
+ struct __ucontext* uc_link;
+ stack_t uc_stack;
+ mcontext_t uc_mcontext;
+ sigset_t uc_sigmask;
+ unsigned long __fpregs_mem[64];
+} ucontext_t;
+
+#define SA_NOCLDSTOP 1
+#define SA_NOCLDWAIT 2
+#define SA_SIGINFO 4
+#define SA_ONSTACK 0x08000000
+#define SA_RESTART 0x10000000
+#define SA_NODEFER 0x40000000
+#define SA_RESETHAND 0x80000000
+#define SA_RESTORER 0x04000000
+
+#endif
+
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGIOT SIGABRT
+#define SIGBUS 7
+#define SIGFPE 8
+#define SIGKILL 9
+#define SIGUSR1 10
+#define SIGSEGV 11
+#define SIGUSR2 12
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGSTKFLT 16
+#define SIGCHLD 17
+#define SIGCONT 18
+#define SIGSTOP 19
+#define SIGTSTP 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGURG 23
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGIO 29
+#define SIGPOLL 29
+#define SIGPWR 30
+#define SIGSYS 31
+#define SIGUNUSED SIGSYS
+
+#define _NSIG 65
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/x86_64/stat.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/x86_64/stat.h
new file mode 100644
index 0000000..9533ce5
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/bits/x86_64/stat.h
@@ -0,0 +1,22 @@
+/* copied from kernel definition, but with padding replaced
+ * by the corresponding correctly-sized userspace types. */
+
+struct stat {
+ dev_t st_dev;
+ ino_t st_ino;
+ nlink_t st_nlink;
+
+ mode_t st_mode;
+ uid_t st_uid;
+ gid_t st_gid;
+ unsigned int __pad0;
+ dev_t st_rdev;
+ off_t st_size;
+ blksize_t st_blksize;
+ blkcnt_t st_blocks;
+
+ struct timespec st_atim;
+ struct timespec st_mtim;
+ struct timespec st_ctim;
+ long __unused1[3];
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/byteswap.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/byteswap.h
new file mode 100644
index 0000000..54d1c36
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/byteswap.h
@@ -0,0 +1,21 @@
+#ifndef SYSROOT_BYTESWAP_H_
+#define SYSROOT_BYTESWAP_H_
+
+#include <features.h>
+#include <stdint.h>
+
+static __inline uint16_t __bswap_16(uint16_t __x) { return (uint16_t)(__x << 8 | __x >> 8); }
+
+static __inline uint32_t __bswap_32(uint32_t __x) {
+ return __x >> 24 | ((__x >> 8) & 0xff00) | ((__x << 8) & 0xff0000) | __x << 24;
+}
+
+static __inline uint64_t __bswap_64(uint64_t __x) {
+ return ((uint64_t)__bswap_32((uint32_t)__x)) << 32 | __bswap_32((uint32_t)(__x >> 32));
+}
+
+#define bswap_16(x) __bswap_16(x)
+#define bswap_32(x) __bswap_32(x)
+#define bswap_64(x) __bswap_64(x)
+
+#endif // SYSROOT_BYTESWAP_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/complex.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/complex.h
new file mode 100644
index 0000000..c4bb294
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/complex.h
@@ -0,0 +1,138 @@
+#ifndef SYSROOT_COMPLEX_H_
+#define SYSROOT_COMPLEX_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define complex _Complex
+#ifdef __GNUC__
+#define _Complex_I (__extension__(0.0f + 1.0fj))
+#else
+#define _Complex_I (0.0f + 1.0fj)
+#endif
+#define I _Complex_I
+
+double complex cacos(double complex);
+float complex cacosf(float complex);
+long double complex cacosl(long double complex);
+
+double complex casin(double complex);
+float complex casinf(float complex);
+long double complex casinl(long double complex);
+
+double complex catan(double complex);
+float complex catanf(float complex);
+long double complex catanl(long double complex);
+
+double complex ccos(double complex);
+float complex ccosf(float complex);
+long double complex ccosl(long double complex);
+
+double complex csin(double complex);
+float complex csinf(float complex);
+long double complex csinl(long double complex);
+
+double complex ctan(double complex);
+float complex ctanf(float complex);
+long double complex ctanl(long double complex);
+
+double complex cacosh(double complex);
+float complex cacoshf(float complex);
+long double complex cacoshl(long double complex);
+
+double complex casinh(double complex);
+float complex casinhf(float complex);
+long double complex casinhl(long double complex);
+
+double complex catanh(double complex);
+float complex catanhf(float complex);
+long double complex catanhl(long double complex);
+
+double complex ccosh(double complex);
+float complex ccoshf(float complex);
+long double complex ccoshl(long double complex);
+
+double complex csinh(double complex);
+float complex csinhf(float complex);
+long double complex csinhl(long double complex);
+
+double complex ctanh(double complex);
+float complex ctanhf(float complex);
+long double complex ctanhl(long double complex);
+
+double complex cexp(double complex);
+float complex cexpf(float complex);
+long double complex cexpl(long double complex);
+
+double complex clog(double complex);
+float complex clogf(float complex);
+long double complex clogl(long double complex);
+
+double cabs(double complex);
+float cabsf(float complex);
+long double cabsl(long double complex);
+
+double complex cpow(double complex, double complex);
+float complex cpowf(float complex, float complex);
+long double complex cpowl(long double complex, long double complex);
+
+double complex csqrt(double complex);
+float complex csqrtf(float complex);
+long double complex csqrtl(long double complex);
+
+double carg(double complex);
+float cargf(float complex);
+long double cargl(long double complex);
+
+double cimag(double complex);
+float cimagf(float complex);
+long double cimagl(long double complex);
+
+double complex conj(double complex);
+float complex conjf(float complex);
+long double complex conjl(long double complex);
+
+double complex cproj(double complex);
+float complex cprojf(float complex);
+long double complex cprojl(long double complex);
+
+double creal(double complex);
+float crealf(float complex);
+long double creall(long double complex);
+
+#ifndef __cplusplus
+#define __CIMAG(x, t) \
+ (+(union { \
+ _Complex t __z; \
+ t __xy[2]; \
+ }){(_Complex t)(x)} \
+ .__xy[1])
+
+#define creal(x) ((double)(x))
+#define crealf(x) ((float)(x))
+#define creall(x) ((long double)(x))
+
+#define cimag(x) __CIMAG(x, double)
+#define cimagf(x) __CIMAG(x, float)
+#define cimagl(x) __CIMAG(x, long double)
+#endif
+
+#if __STDC_VERSION__ >= 201112L
+#if defined(_Imaginary_I)
+#define __CMPLX(x, y, t) ((t)(x) + _Imaginary_I * (t)(y))
+#elif defined(__clang__)
+#define __CMPLX(x, y, t) (+(_Complex t){(t)(x), (t)(y)})
+#else
+#define __CMPLX(x, y, t) (__builtin_complex((t)(x), (t)(y)))
+#endif
+#define CMPLX(x, y) __CMPLX(x, y, double)
+#define CMPLXF(x, y) __CMPLX(x, y, float)
+#define CMPLXL(x, y) __CMPLX(x, y, long double)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_COMPLEX_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/cpio.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/cpio.h
new file mode 100644
index 0000000..21d069e
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/cpio.h
@@ -0,0 +1,29 @@
+#ifndef SYSROOT_CPIO_H_
+#define SYSROOT_CPIO_H_
+
+#define MAGIC "070707"
+
+#define C_IRUSR 000400
+#define C_IWUSR 000200
+#define C_IXUSR 000100
+#define C_IRGRP 000040
+#define C_IWGRP 000020
+#define C_IXGRP 000010
+#define C_IROTH 000004
+#define C_IWOTH 000002
+#define C_IXOTH 000001
+
+#define C_ISUID 004000
+#define C_ISGID 002000
+#define C_ISVTX 001000
+
+#define C_ISBLK 060000
+#define C_ISCHR 020000
+#define C_ISDIR 040000
+#define C_ISFIFO 010000
+#define C_ISSOCK 0140000
+#define C_ISLNK 0120000
+#define C_ISCTG 0110000
+#define C_ISREG 0100000
+
+#endif // SYSROOT_CPIO_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/ctype.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/ctype.h
new file mode 100644
index 0000000..12be80d
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/ctype.h
@@ -0,0 +1,52 @@
+#ifndef SYSROOT_CTYPE_H_
+#define SYSROOT_CTYPE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+int isalnum(int);
+int isalpha(int);
+int isblank(int);
+int iscntrl(int);
+int isdigit(int);
+int isgraph(int);
+int islower(int);
+int isprint(int);
+int ispunct(int);
+int isspace(int);
+int isupper(int);
+int isxdigit(int);
+int tolower(int);
+int toupper(int);
+
+#ifndef __cplusplus
+static __inline int __isspace(int _c) { return _c == ' ' || (unsigned)_c - '\t' < 5; }
+
+#define isalpha(a) (0 ? isalpha(a) : (((unsigned)(a) | 32) - 'a') < 26)
+#define isdigit(a) (0 ? isdigit(a) : ((unsigned)(a) - '0') < 10)
+#define islower(a) (0 ? islower(a) : ((unsigned)(a) - 'a') < 26)
+#define isupper(a) (0 ? isupper(a) : ((unsigned)(a) - 'A') < 26)
+#define isprint(a) (0 ? isprint(a) : ((unsigned)(a)-0x20) < 0x5f)
+#define isgraph(a) (0 ? isgraph(a) : ((unsigned)(a)-0x21) < 0x5e)
+#define isspace(a) __isspace(a)
+#endif
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+int isascii(int);
+int toascii(int);
+#define _tolower(a) ((a) | 0x20)
+#define _toupper(a) ((a)&0x5f)
+#define isascii(a) (0 ? isascii(a) : (unsigned)(a) < 128)
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_CTYPE_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/dirent.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/dirent.h
new file mode 100644
index 0000000..4542825
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/dirent.h
@@ -0,0 +1,67 @@
+#ifndef SYSROOT_DIRENT_H_
+#define SYSROOT_DIRENT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_ino_t
+#define __NEED_off_t
+#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+#define __NEED_size_t
+#endif
+
+#include <bits/alltypes.h>
+
+typedef struct __dirstream DIR;
+
+struct dirent {
+ ino_t d_ino;
+ off_t d_off;
+ unsigned short d_reclen;
+ unsigned char d_type;
+ char d_name[256];
+};
+
+#define d_fileno d_ino
+
+int closedir(DIR*);
+DIR* fdopendir(int);
+DIR* opendir(const char*);
+struct dirent* readdir(DIR*);
+int readdir_r(DIR* __restrict, struct dirent* __restrict, struct dirent** __restrict);
+void rewinddir(DIR*);
+void seekdir(DIR*, long);
+long telldir(DIR*);
+int dirfd(DIR*);
+
+int alphasort(const struct dirent**, const struct dirent**);
+int scandir(const char*, struct dirent***, int (*)(const struct dirent*),
+ int (*)(const struct dirent**, const struct dirent**));
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define DT_UNKNOWN 0
+#define DT_FIFO 1
+#define DT_CHR 2
+#define DT_DIR 4
+#define DT_BLK 6
+#define DT_REG 8
+#define DT_LNK 10
+#define DT_SOCK 12
+#define DT_WHT 14
+#define IFTODT(x) ((x) >> 12 & 017)
+#define DTTOIF(x) ((x) << 12)
+int getdents(int, struct dirent*, size_t);
+#endif
+
+#ifdef _GNU_SOURCE
+int versionsort(const struct dirent**, const struct dirent**);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_DIRENT_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/dlfcn.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/dlfcn.h
new file mode 100644
index 0000000..ff069c9
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/dlfcn.h
@@ -0,0 +1,42 @@
+#ifndef SYSROOT_DLFCN_H_
+#define SYSROOT_DLFCN_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define RTLD_LAZY 1
+#define RTLD_NOW 2
+#define RTLD_NOLOAD 4
+#define RTLD_NODELETE 4096
+#define RTLD_GLOBAL 256
+#define RTLD_LOCAL 0
+
+#define RTLD_NEXT ((void*)-1)
+#define RTLD_DEFAULT ((void*)0)
+
+#define RTLD_DI_LINKMAP 2
+
+int dlclose(void*);
+char* dlerror(void);
+void* dlopen(const char*, int);
+void* dlsym(void* __restrict, const char* __restrict);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+typedef struct {
+ const char* dli_fname;
+ void* dli_fbase;
+ const char* dli_sname;
+ void* dli_saddr;
+} Dl_info;
+int dladdr(const void*, Dl_info*);
+int dlinfo(void*, int, void*);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_DLFCN_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/elf.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/elf.h
new file mode 100644
index 0000000..88a35f0
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/elf.h
@@ -0,0 +1,2585 @@
+#ifndef SYSROOT_ELF_H_
+#define SYSROOT_ELF_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+typedef uint16_t Elf32_Half;
+typedef uint16_t Elf64_Half;
+
+typedef uint32_t Elf32_Word;
+typedef int32_t Elf32_Sword;
+typedef uint32_t Elf64_Word;
+typedef int32_t Elf64_Sword;
+
+typedef uint64_t Elf32_Xword;
+typedef int64_t Elf32_Sxword;
+typedef uint64_t Elf64_Xword;
+typedef int64_t Elf64_Sxword;
+
+typedef uint32_t Elf32_Addr;
+typedef uint64_t Elf64_Addr;
+
+typedef uint32_t Elf32_Off;
+typedef uint64_t Elf64_Off;
+
+typedef uint16_t Elf32_Section;
+typedef uint16_t Elf64_Section;
+
+typedef Elf32_Half Elf32_Versym;
+typedef Elf64_Half Elf64_Versym;
+
+#define EI_NIDENT (16)
+
+typedef struct {
+ unsigned char e_ident[EI_NIDENT];
+ Elf32_Half e_type;
+ Elf32_Half e_machine;
+ Elf32_Word e_version;
+ Elf32_Addr e_entry;
+ Elf32_Off e_phoff;
+ Elf32_Off e_shoff;
+ Elf32_Word e_flags;
+ Elf32_Half e_ehsize;
+ Elf32_Half e_phentsize;
+ Elf32_Half e_phnum;
+ Elf32_Half e_shentsize;
+ Elf32_Half e_shnum;
+ Elf32_Half e_shstrndx;
+} Elf32_Ehdr;
+
+typedef struct {
+ unsigned char e_ident[EI_NIDENT];
+ Elf64_Half e_type;
+ Elf64_Half e_machine;
+ Elf64_Word e_version;
+ Elf64_Addr e_entry;
+ Elf64_Off e_phoff;
+ Elf64_Off e_shoff;
+ Elf64_Word e_flags;
+ Elf64_Half e_ehsize;
+ Elf64_Half e_phentsize;
+ Elf64_Half e_phnum;
+ Elf64_Half e_shentsize;
+ Elf64_Half e_shnum;
+ Elf64_Half e_shstrndx;
+} Elf64_Ehdr;
+
+#define EI_MAG0 0
+#define ELFMAG0 0x7f
+
+#define EI_MAG1 1
+#define ELFMAG1 'E'
+
+#define EI_MAG2 2
+#define ELFMAG2 'L'
+
+#define EI_MAG3 3
+#define ELFMAG3 'F'
+
+#define ELFMAG "\177ELF"
+#define SELFMAG 4
+
+#define EI_CLASS 4
+#define ELFCLASSNONE 0
+#define ELFCLASS32 1
+#define ELFCLASS64 2
+#define ELFCLASSNUM 3
+
+#define EI_DATA 5
+#define ELFDATANONE 0
+#define ELFDATA2LSB 1
+#define ELFDATA2MSB 2
+#define ELFDATANUM 3
+
+#define EI_VERSION 6
+
+#define EI_OSABI 7
+#define ELFOSABI_NONE 0
+#define ELFOSABI_SYSV 0
+#define ELFOSABI_HPUX 1
+#define ELFOSABI_NETBSD 2
+#define ELFOSABI_LINUX 3
+#define ELFOSABI_GNU 3
+#define ELFOSABI_SOLARIS 6
+#define ELFOSABI_AIX 7
+#define ELFOSABI_IRIX 8
+#define ELFOSABI_FREEBSD 9
+#define ELFOSABI_TRU64 10
+#define ELFOSABI_MODESTO 11
+#define ELFOSABI_OPENBSD 12
+#define ELFOSABI_ARM 97
+#define ELFOSABI_STANDALONE 255
+
+#define EI_ABIVERSION 8
+
+#define EI_PAD 9
+
+#define ET_NONE 0
+#define ET_REL 1
+#define ET_EXEC 2
+#define ET_DYN 3
+#define ET_CORE 4
+#define ET_NUM 5
+#define ET_LOOS 0xfe00
+#define ET_HIOS 0xfeff
+#define ET_LOPROC 0xff00
+#define ET_HIPROC 0xffff
+
+#define EM_NONE 0
+#define EM_M32 1
+#define EM_SPARC 2
+#define EM_386 3
+#define EM_68K 4
+#define EM_88K 5
+#define EM_860 7
+#define EM_MIPS 8
+#define EM_S370 9
+#define EM_MIPS_RS3_LE 10
+
+#define EM_PARISC 15
+#define EM_VPP500 17
+#define EM_SPARC32PLUS 18
+#define EM_960 19
+#define EM_PPC 20
+#define EM_PPC64 21
+#define EM_S390 22
+
+#define EM_V800 36
+#define EM_FR20 37
+#define EM_RH32 38
+#define EM_RCE 39
+#define EM_ARM 40
+#define EM_FAKE_ALPHA 41
+#define EM_SH 42
+#define EM_SPARCV9 43
+#define EM_TRICORE 44
+#define EM_ARC 45
+#define EM_H8_300 46
+#define EM_H8_300H 47
+#define EM_H8S 48
+#define EM_H8_500 49
+#define EM_IA_64 50
+#define EM_MIPS_X 51
+#define EM_COLDFIRE 52
+#define EM_68HC12 53
+#define EM_MMA 54
+#define EM_PCP 55
+#define EM_NCPU 56
+#define EM_NDR1 57
+#define EM_STARCORE 58
+#define EM_ME16 59
+#define EM_ST100 60
+#define EM_TINYJ 61
+#define EM_X86_64 62
+#define EM_PDSP 63
+
+#define EM_FX66 66
+#define EM_ST9PLUS 67
+#define EM_ST7 68
+#define EM_68HC16 69
+#define EM_68HC11 70
+#define EM_68HC08 71
+#define EM_68HC05 72
+#define EM_SVX 73
+#define EM_ST19 74
+#define EM_VAX 75
+#define EM_CRIS 76
+#define EM_JAVELIN 77
+#define EM_FIREPATH 78
+#define EM_ZSP 79
+#define EM_MMIX 80
+#define EM_HUANY 81
+#define EM_PRISM 82
+#define EM_AVR 83
+#define EM_FR30 84
+#define EM_D10V 85
+#define EM_D30V 86
+#define EM_V850 87
+#define EM_M32R 88
+#define EM_MN10300 89
+#define EM_MN10200 90
+#define EM_PJ 91
+#define EM_OR1K 92
+#define EM_ARC_A5 93
+#define EM_XTENSA 94
+#define EM_AARCH64 183
+#define EM_TILEPRO 188
+#define EM_MICROBLAZE 189
+#define EM_TILEGX 191
+#define EM_NUM 192
+#define EM_ALPHA 0x9026
+
+#define EV_NONE 0
+#define EV_CURRENT 1
+#define EV_NUM 2
+
+typedef struct {
+ Elf32_Word sh_name;
+ Elf32_Word sh_type;
+ Elf32_Word sh_flags;
+ Elf32_Addr sh_addr;
+ Elf32_Off sh_offset;
+ Elf32_Word sh_size;
+ Elf32_Word sh_link;
+ Elf32_Word sh_info;
+ Elf32_Word sh_addralign;
+ Elf32_Word sh_entsize;
+} Elf32_Shdr;
+
+typedef struct {
+ Elf64_Word sh_name;
+ Elf64_Word sh_type;
+ Elf64_Xword sh_flags;
+ Elf64_Addr sh_addr;
+ Elf64_Off sh_offset;
+ Elf64_Xword sh_size;
+ Elf64_Word sh_link;
+ Elf64_Word sh_info;
+ Elf64_Xword sh_addralign;
+ Elf64_Xword sh_entsize;
+} Elf64_Shdr;
+
+#define SHN_UNDEF 0
+#define SHN_LORESERVE 0xff00
+#define SHN_LOPROC 0xff00
+#define SHN_BEFORE 0xff00
+
+#define SHN_AFTER 0xff01
+
+#define SHN_HIPROC 0xff1f
+#define SHN_LOOS 0xff20
+#define SHN_HIOS 0xff3f
+#define SHN_ABS 0xfff1
+#define SHN_COMMON 0xfff2
+#define SHN_XINDEX 0xffff
+#define SHN_HIRESERVE 0xffff
+
+#define SHT_NULL 0
+#define SHT_PROGBITS 1
+#define SHT_SYMTAB 2
+#define SHT_STRTAB 3
+#define SHT_RELA 4
+#define SHT_HASH 5
+#define SHT_DYNAMIC 6
+#define SHT_NOTE 7
+#define SHT_NOBITS 8
+#define SHT_REL 9
+#define SHT_SHLIB 10
+#define SHT_DYNSYM 11
+#define SHT_INIT_ARRAY 14
+#define SHT_FINI_ARRAY 15
+#define SHT_PREINIT_ARRAY 16
+#define SHT_GROUP 17
+#define SHT_SYMTAB_SHNDX 18
+#define SHT_NUM 19
+#define SHT_LOOS 0x60000000
+#define SHT_GNU_ATTRIBUTES 0x6ffffff5
+#define SHT_GNU_HASH 0x6ffffff6
+#define SHT_GNU_LIBLIST 0x6ffffff7
+#define SHT_CHECKSUM 0x6ffffff8
+#define SHT_LOSUNW 0x6ffffffa
+#define SHT_SUNW_move 0x6ffffffa
+#define SHT_SUNW_COMDAT 0x6ffffffb
+#define SHT_SUNW_syminfo 0x6ffffffc
+#define SHT_GNU_verdef 0x6ffffffd
+#define SHT_GNU_verneed 0x6ffffffe
+#define SHT_GNU_versym 0x6fffffff
+#define SHT_HISUNW 0x6fffffff
+#define SHT_HIOS 0x6fffffff
+#define SHT_LOPROC 0x70000000
+#define SHT_HIPROC 0x7fffffff
+#define SHT_LOUSER 0x80000000
+#define SHT_HIUSER 0x8fffffff
+
+#define SHF_WRITE (1 << 0)
+#define SHF_ALLOC (1 << 1)
+#define SHF_EXECINSTR (1 << 2)
+#define SHF_MERGE (1 << 4)
+#define SHF_STRINGS (1 << 5)
+#define SHF_INFO_LINK (1 << 6)
+#define SHF_LINK_ORDER (1 << 7)
+#define SHF_OS_NONCONFORMING (1 << 8)
+
+#define SHF_GROUP (1 << 9)
+#define SHF_TLS (1 << 10)
+#define SHF_MASKOS 0x0ff00000
+#define SHF_MASKPROC 0xf0000000
+#define SHF_ORDERED (1 << 30)
+#define SHF_EXCLUDE (1U << 31)
+
+#define GRP_COMDAT 0x1
+
+typedef struct {
+ Elf32_Word st_name;
+ Elf32_Addr st_value;
+ Elf32_Word st_size;
+ unsigned char st_info;
+ unsigned char st_other;
+ Elf32_Section st_shndx;
+} Elf32_Sym;
+
+typedef struct {
+ Elf64_Word st_name;
+ unsigned char st_info;
+ unsigned char st_other;
+ Elf64_Section st_shndx;
+ Elf64_Addr st_value;
+ Elf64_Xword st_size;
+} Elf64_Sym;
+
+typedef struct {
+ Elf32_Half si_boundto;
+ Elf32_Half si_flags;
+} Elf32_Syminfo;
+
+typedef struct {
+ Elf64_Half si_boundto;
+ Elf64_Half si_flags;
+} Elf64_Syminfo;
+
+#define SYMINFO_BT_SELF 0xffff
+#define SYMINFO_BT_PARENT 0xfffe
+#define SYMINFO_BT_LOWRESERVE 0xff00
+
+#define SYMINFO_FLG_DIRECT 0x0001
+#define SYMINFO_FLG_PASSTHRU 0x0002
+#define SYMINFO_FLG_COPY 0x0004
+#define SYMINFO_FLG_LAZYLOAD 0x0008
+
+#define SYMINFO_NONE 0
+#define SYMINFO_CURRENT 1
+#define SYMINFO_NUM 2
+
+#define ELF32_ST_BIND(val) (((unsigned char)(val)) >> 4)
+#define ELF32_ST_TYPE(val) ((val)&0xf)
+#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type)&0xf))
+
+#define ELF64_ST_BIND(val) ELF32_ST_BIND(val)
+#define ELF64_ST_TYPE(val) ELF32_ST_TYPE(val)
+#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO((bind), (type))
+
+#define STB_LOCAL 0
+#define STB_GLOBAL 1
+#define STB_WEAK 2
+#define STB_NUM 3
+#define STB_LOOS 10
+#define STB_GNU_UNIQUE 10
+#define STB_HIOS 12
+#define STB_LOPROC 13
+#define STB_HIPROC 15
+
+#define STT_NOTYPE 0
+#define STT_OBJECT 1
+#define STT_FUNC 2
+#define STT_SECTION 3
+#define STT_FILE 4
+#define STT_COMMON 5
+#define STT_TLS 6
+#define STT_NUM 7
+#define STT_LOOS 10
+#define STT_GNU_IFUNC 10
+#define STT_HIOS 12
+#define STT_LOPROC 13
+#define STT_HIPROC 15
+
+#define STN_UNDEF 0
+
+#define ELF32_ST_VISIBILITY(o) ((o)&0x03)
+#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY(o)
+
+#define STV_DEFAULT 0
+#define STV_INTERNAL 1
+#define STV_HIDDEN 2
+#define STV_PROTECTED 3
+
+typedef struct {
+ Elf32_Addr r_offset;
+ Elf32_Word r_info;
+} Elf32_Rel;
+
+typedef struct {
+ Elf64_Addr r_offset;
+ Elf64_Xword r_info;
+} Elf64_Rel;
+
+typedef struct {
+ Elf32_Addr r_offset;
+ Elf32_Word r_info;
+ Elf32_Sword r_addend;
+} Elf32_Rela;
+
+typedef struct {
+ Elf64_Addr r_offset;
+ Elf64_Xword r_info;
+ Elf64_Sxword r_addend;
+} Elf64_Rela;
+
+#define ELF32_R_SYM(val) ((val) >> 8)
+#define ELF32_R_TYPE(val) ((val)&0xff)
+#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type)&0xff))
+
+#define ELF64_R_SYM(i) ((i) >> 32)
+#define ELF64_R_TYPE(i) ((i)&0xffffffff)
+#define ELF64_R_INFO(sym, type) ((((Elf64_Xword)(sym)) << 32) + (type))
+
+typedef struct {
+ Elf32_Word p_type;
+ Elf32_Off p_offset;
+ Elf32_Addr p_vaddr;
+ Elf32_Addr p_paddr;
+ Elf32_Word p_filesz;
+ Elf32_Word p_memsz;
+ Elf32_Word p_flags;
+ Elf32_Word p_align;
+} Elf32_Phdr;
+
+typedef struct {
+ Elf64_Word p_type;
+ Elf64_Word p_flags;
+ Elf64_Off p_offset;
+ Elf64_Addr p_vaddr;
+ Elf64_Addr p_paddr;
+ Elf64_Xword p_filesz;
+ Elf64_Xword p_memsz;
+ Elf64_Xword p_align;
+} Elf64_Phdr;
+
+#define PT_NULL 0
+#define PT_LOAD 1
+#define PT_DYNAMIC 2
+#define PT_INTERP 3
+#define PT_NOTE 4
+#define PT_SHLIB 5
+#define PT_PHDR 6
+#define PT_TLS 7
+#define PT_NUM 8
+#define PT_LOOS 0x60000000
+#define PT_GNU_EH_FRAME 0x6474e550
+#define PT_GNU_STACK 0x6474e551
+#define PT_GNU_RELRO 0x6474e552
+#define PT_LOSUNW 0x6ffffffa
+#define PT_SUNWBSS 0x6ffffffa
+#define PT_SUNWSTACK 0x6ffffffb
+#define PT_HISUNW 0x6fffffff
+#define PT_HIOS 0x6fffffff
+#define PT_LOPROC 0x70000000
+#define PT_HIPROC 0x7fffffff
+
+#define PN_XNUM 0xffff
+
+#define PF_X (1 << 0)
+#define PF_W (1 << 1)
+#define PF_R (1 << 2)
+#define PF_MASKOS 0x0ff00000
+#define PF_MASKPROC 0xf0000000
+
+#define NT_PRSTATUS 1
+#define NT_FPREGSET 2
+#define NT_PRPSINFO 3
+#define NT_PRXREG 4
+#define NT_TASKSTRUCT 4
+#define NT_PLATFORM 5
+#define NT_AUXV 6
+#define NT_GWINDOWS 7
+#define NT_ASRS 8
+#define NT_PSTATUS 10
+#define NT_PSINFO 13
+#define NT_PRCRED 14
+#define NT_UTSNAME 15
+#define NT_LWPSTATUS 16
+#define NT_LWPSINFO 17
+#define NT_PRFPXREG 20
+#define NT_SIGINFO 0x53494749
+#define NT_FILE 0x46494c45
+#define NT_PRXFPREG 0x46e62b7f
+#define NT_PPC_VMX 0x100
+#define NT_PPC_SPE 0x101
+#define NT_PPC_VSX 0x102
+#define NT_386_TLS 0x200
+#define NT_386_IOPERM 0x201
+#define NT_X86_XSTATE 0x202
+#define NT_S390_HIGH_GPRS 0x300
+#define NT_S390_TIMER 0x301
+#define NT_S390_TODCMP 0x302
+#define NT_S390_TODPREG 0x303
+#define NT_S390_CTRS 0x304
+#define NT_S390_PREFIX 0x305
+#define NT_S390_LAST_BREAK 0x306
+#define NT_S390_SYSTEM_CALL 0x307
+#define NT_S390_TDB 0x308
+#define NT_ARM_VFP 0x400
+#define NT_ARM_TLS 0x401
+#define NT_ARM_HW_BREAK 0x402
+#define NT_ARM_HW_WATCH 0x403
+#define NT_METAG_CBUF 0x500
+#define NT_METAG_RPIPE 0x501
+#define NT_METAG_TLS 0x502
+#define NT_VERSION 1
+
+typedef struct {
+ Elf32_Sword d_tag;
+ union {
+ Elf32_Word d_val;
+ Elf32_Addr d_ptr;
+ } d_un;
+} Elf32_Dyn;
+
+typedef struct {
+ Elf64_Sxword d_tag;
+ union {
+ Elf64_Xword d_val;
+ Elf64_Addr d_ptr;
+ } d_un;
+} Elf64_Dyn;
+
+#define DT_NULL 0
+#define DT_NEEDED 1
+#define DT_PLTRELSZ 2
+#define DT_PLTGOT 3
+#define DT_HASH 4
+#define DT_STRTAB 5
+#define DT_SYMTAB 6
+#define DT_RELA 7
+#define DT_RELASZ 8
+#define DT_RELAENT 9
+#define DT_STRSZ 10
+#define DT_SYMENT 11
+#define DT_INIT 12
+#define DT_FINI 13
+#define DT_SONAME 14
+#define DT_RPATH 15
+#define DT_SYMBOLIC 16
+#define DT_REL 17
+#define DT_RELSZ 18
+#define DT_RELENT 19
+#define DT_PLTREL 20
+#define DT_DEBUG 21
+#define DT_TEXTREL 22
+#define DT_JMPREL 23
+#define DT_BIND_NOW 24
+#define DT_INIT_ARRAY 25
+#define DT_FINI_ARRAY 26
+#define DT_INIT_ARRAYSZ 27
+#define DT_FINI_ARRAYSZ 28
+#define DT_RUNPATH 29
+#define DT_FLAGS 30
+#define DT_ENCODING 32
+#define DT_PREINIT_ARRAY 32
+#define DT_PREINIT_ARRAYSZ 33
+#define DT_RELRSZ 35
+#define DT_RELR 36
+#define DT_RELRENT 37
+#define DT_NUM 38
+#define DT_LOOS 0x6000000d
+#define DT_HIOS 0x6ffff000
+#define DT_LOPROC 0x70000000
+#define DT_HIPROC 0x7fffffff
+#define DT_PROCNUM DT_MIPS_NUM
+
+#define DT_VALRNGLO 0x6ffffd00
+#define DT_GNU_PRELINKED 0x6ffffdf5
+#define DT_GNU_CONFLICTSZ 0x6ffffdf6
+#define DT_GNU_LIBLISTSZ 0x6ffffdf7
+#define DT_CHECKSUM 0x6ffffdf8
+#define DT_PLTPADSZ 0x6ffffdf9
+#define DT_MOVEENT 0x6ffffdfa
+#define DT_MOVESZ 0x6ffffdfb
+#define DT_FEATURE_1 0x6ffffdfc
+#define DT_POSFLAG_1 0x6ffffdfd
+
+#define DT_SYMINSZ 0x6ffffdfe
+#define DT_SYMINENT 0x6ffffdff
+#define DT_VALRNGHI 0x6ffffdff
+#define DT_VALTAGIDX(tag) (DT_VALRNGHI - (tag))
+#define DT_VALNUM 12
+
+#define DT_ADDRRNGLO 0x6ffffe00
+#define DT_GNU_HASH 0x6ffffef5
+#define DT_TLSDESC_PLT 0x6ffffef6
+#define DT_TLSDESC_GOT 0x6ffffef7
+#define DT_GNU_CONFLICT 0x6ffffef8
+#define DT_GNU_LIBLIST 0x6ffffef9
+#define DT_CONFIG 0x6ffffefa
+#define DT_DEPAUDIT 0x6ffffefb
+#define DT_AUDIT 0x6ffffefc
+#define DT_PLTPAD 0x6ffffefd
+#define DT_MOVETAB 0x6ffffefe
+#define DT_SYMINFO 0x6ffffeff
+#define DT_ADDRRNGHI 0x6ffffeff
+#define DT_ADDRTAGIDX(tag) (DT_ADDRRNGHI - (tag))
+#define DT_ADDRNUM 11
+
+#define DT_VERSYM 0x6ffffff0
+
+#define DT_RELACOUNT 0x6ffffff9
+#define DT_RELCOUNT 0x6ffffffa
+
+#define DT_FLAGS_1 0x6ffffffb
+#define DT_VERDEF 0x6ffffffc
+
+#define DT_VERDEFNUM 0x6ffffffd
+#define DT_VERNEED 0x6ffffffe
+
+#define DT_VERNEEDNUM 0x6fffffff
+#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag))
+#define DT_VERSIONTAGNUM 16
+
+#define DT_AUXILIARY 0x7ffffffd
+#define DT_FILTER 0x7fffffff
+#define DT_EXTRATAGIDX(tag) ((Elf32_Word) - ((Elf32_Sword)(tag) << 1 >> 1) - 1)
+#define DT_EXTRANUM 3
+
+#define DF_ORIGIN 0x00000001
+#define DF_SYMBOLIC 0x00000002
+#define DF_TEXTREL 0x00000004
+#define DF_BIND_NOW 0x00000008
+#define DF_STATIC_TLS 0x00000010
+
+#define DF_1_NOW 0x00000001
+#define DF_1_GLOBAL 0x00000002
+#define DF_1_GROUP 0x00000004
+#define DF_1_NODELETE 0x00000008
+#define DF_1_LOADFLTR 0x00000010
+#define DF_1_INITFIRST 0x00000020
+#define DF_1_NOOPEN 0x00000040
+#define DF_1_ORIGIN 0x00000080
+#define DF_1_DIRECT 0x00000100
+#define DF_1_TRANS 0x00000200
+#define DF_1_INTERPOSE 0x00000400
+#define DF_1_NODEFLIB 0x00000800
+#define DF_1_NODUMP 0x00001000
+#define DF_1_CONFALT 0x00002000
+#define DF_1_ENDFILTEE 0x00004000
+#define DF_1_DISPRELDNE 0x00008000
+#define DF_1_DISPRELPND 0x00010000
+#define DF_1_NODIRECT 0x00020000
+#define DF_1_IGNMULDEF 0x00040000
+#define DF_1_NOKSYMS 0x00080000
+#define DF_1_NOHDR 0x00100000
+#define DF_1_EDITED 0x00200000
+#define DF_1_NORELOC 0x00400000
+#define DF_1_SYMINTPOSE 0x00800000
+#define DF_1_GLOBAUDIT 0x01000000
+#define DF_1_SINGLETON 0x02000000
+
+#define DTF_1_PARINIT 0x00000001
+#define DTF_1_CONFEXP 0x00000002
+
+#define DF_P1_LAZYLOAD 0x00000001
+#define DF_P1_GROUPPERM 0x00000002
+
+typedef struct {
+ Elf32_Half vd_version;
+ Elf32_Half vd_flags;
+ Elf32_Half vd_ndx;
+ Elf32_Half vd_cnt;
+ Elf32_Word vd_hash;
+ Elf32_Word vd_aux;
+ Elf32_Word vd_next;
+} Elf32_Verdef;
+
+typedef struct {
+ Elf64_Half vd_version;
+ Elf64_Half vd_flags;
+ Elf64_Half vd_ndx;
+ Elf64_Half vd_cnt;
+ Elf64_Word vd_hash;
+ Elf64_Word vd_aux;
+ Elf64_Word vd_next;
+} Elf64_Verdef;
+
+#define VER_DEF_NONE 0
+#define VER_DEF_CURRENT 1
+#define VER_DEF_NUM 2
+
+#define VER_FLG_BASE 0x1
+#define VER_FLG_WEAK 0x2
+
+#define VER_NDX_LOCAL 0
+#define VER_NDX_GLOBAL 1
+#define VER_NDX_LORESERVE 0xff00
+#define VER_NDX_ELIMINATE 0xff01
+
+typedef struct {
+ Elf32_Word vda_name;
+ Elf32_Word vda_next;
+} Elf32_Verdaux;
+
+typedef struct {
+ Elf64_Word vda_name;
+ Elf64_Word vda_next;
+} Elf64_Verdaux;
+
+typedef struct {
+ Elf32_Half vn_version;
+ Elf32_Half vn_cnt;
+ Elf32_Word vn_file;
+ Elf32_Word vn_aux;
+ Elf32_Word vn_next;
+} Elf32_Verneed;
+
+typedef struct {
+ Elf64_Half vn_version;
+ Elf64_Half vn_cnt;
+ Elf64_Word vn_file;
+ Elf64_Word vn_aux;
+ Elf64_Word vn_next;
+} Elf64_Verneed;
+
+#define VER_NEED_NONE 0
+#define VER_NEED_CURRENT 1
+#define VER_NEED_NUM 2
+
+typedef struct {
+ Elf32_Word vna_hash;
+ Elf32_Half vna_flags;
+ Elf32_Half vna_other;
+ Elf32_Word vna_name;
+ Elf32_Word vna_next;
+} Elf32_Vernaux;
+
+typedef struct {
+ Elf64_Word vna_hash;
+ Elf64_Half vna_flags;
+ Elf64_Half vna_other;
+ Elf64_Word vna_name;
+ Elf64_Word vna_next;
+} Elf64_Vernaux;
+
+#define VER_FLG_WEAK 0x2
+
+typedef struct {
+ uint32_t a_type;
+ union {
+ uint32_t a_val;
+ } a_un;
+} Elf32_auxv_t;
+
+typedef struct {
+ uint64_t a_type;
+ union {
+ uint64_t a_val;
+ } a_un;
+} Elf64_auxv_t;
+
+#define AT_NULL 0
+#define AT_IGNORE 1
+#define AT_EXECFD 2
+#define AT_PHDR 3
+#define AT_PHENT 4
+#define AT_PHNUM 5
+#define AT_PAGESZ 6
+#define AT_BASE 7
+#define AT_FLAGS 8
+#define AT_ENTRY 9
+#define AT_NOTELF 10
+#define AT_UID 11
+#define AT_EUID 12
+#define AT_GID 13
+#define AT_EGID 14
+#define AT_CLKTCK 17
+
+#define AT_PLATFORM 15
+#define AT_HWCAP 16
+
+#define AT_FPUCW 18
+
+#define AT_DCACHEBSIZE 19
+#define AT_ICACHEBSIZE 20
+#define AT_UCACHEBSIZE 21
+
+#define AT_IGNOREPPC 22
+
+#define AT_SECURE 23
+
+#define AT_BASE_PLATFORM 24
+
+#define AT_RANDOM 25
+
+#define AT_HWCAP2 26
+
+#define AT_EXECFN 31
+
+#define AT_SYSINFO 32
+#define AT_SYSINFO_EHDR 33
+
+#define AT_L1I_CACHESHAPE 34
+#define AT_L1D_CACHESHAPE 35
+#define AT_L2_CACHESHAPE 36
+#define AT_L3_CACHESHAPE 37
+
+typedef struct {
+ Elf32_Word n_namesz;
+ Elf32_Word n_descsz;
+ Elf32_Word n_type;
+} Elf32_Nhdr;
+
+typedef struct {
+ Elf64_Word n_namesz;
+ Elf64_Word n_descsz;
+ Elf64_Word n_type;
+} Elf64_Nhdr;
+
+#define ELF_NOTE_SOLARIS "SUNW Solaris"
+
+#define ELF_NOTE_GNU "GNU"
+
+#define ELF_NOTE_PAGESIZE_HINT 1
+
+#define NT_GNU_ABI_TAG 1
+#define ELF_NOTE_ABI NT_GNU_ABI_TAG
+
+#define ELF_NOTE_OS_LINUX 0
+#define ELF_NOTE_OS_GNU 1
+#define ELF_NOTE_OS_SOLARIS2 2
+#define ELF_NOTE_OS_FREEBSD 3
+
+#define NT_GNU_BUILD_ID 3
+#define NT_GNU_GOLD_VERSION 4
+
+typedef struct {
+ Elf32_Xword m_value;
+ Elf32_Word m_info;
+ Elf32_Word m_poffset;
+ Elf32_Half m_repeat;
+ Elf32_Half m_stride;
+} Elf32_Move;
+
+typedef struct {
+ Elf64_Xword m_value;
+ Elf64_Xword m_info;
+ Elf64_Xword m_poffset;
+ Elf64_Half m_repeat;
+ Elf64_Half m_stride;
+} Elf64_Move;
+
+#define ELF32_M_SYM(info) ((info) >> 8)
+#define ELF32_M_SIZE(info) ((unsigned char)(info))
+#define ELF32_M_INFO(sym, size) (((sym) << 8) + (unsigned char)(size))
+
+#define ELF64_M_SYM(info) ELF32_M_SYM(info)
+#define ELF64_M_SIZE(info) ELF32_M_SIZE(info)
+#define ELF64_M_INFO(sym, size) ELF32_M_INFO(sym, size)
+
+#define EF_CPU32 0x00810000
+
+#define R_68K_NONE 0
+#define R_68K_32 1
+#define R_68K_16 2
+#define R_68K_8 3
+#define R_68K_PC32 4
+#define R_68K_PC16 5
+#define R_68K_PC8 6
+#define R_68K_GOT32 7
+#define R_68K_GOT16 8
+#define R_68K_GOT8 9
+#define R_68K_GOT32O 10
+#define R_68K_GOT16O 11
+#define R_68K_GOT8O 12
+#define R_68K_PLT32 13
+#define R_68K_PLT16 14
+#define R_68K_PLT8 15
+#define R_68K_PLT32O 16
+#define R_68K_PLT16O 17
+#define R_68K_PLT8O 18
+#define R_68K_COPY 19
+#define R_68K_GLOB_DAT 20
+#define R_68K_JMP_SLOT 21
+#define R_68K_RELATIVE 22
+#define R_68K_NUM 23
+
+#define R_386_NONE 0
+#define R_386_32 1
+#define R_386_PC32 2
+#define R_386_GOT32 3
+#define R_386_PLT32 4
+#define R_386_COPY 5
+#define R_386_GLOB_DAT 6
+#define R_386_JMP_SLOT 7
+#define R_386_RELATIVE 8
+#define R_386_GOTOFF 9
+#define R_386_GOTPC 10
+#define R_386_32PLT 11
+#define R_386_TLS_TPOFF 14
+#define R_386_TLS_IE 15
+#define R_386_TLS_GOTIE 16
+#define R_386_TLS_LE 17
+#define R_386_TLS_GD 18
+#define R_386_TLS_LDM 19
+#define R_386_16 20
+#define R_386_PC16 21
+#define R_386_8 22
+#define R_386_PC8 23
+#define R_386_TLS_GD_32 24
+#define R_386_TLS_GD_PUSH 25
+#define R_386_TLS_GD_CALL 26
+#define R_386_TLS_GD_POP 27
+#define R_386_TLS_LDM_32 28
+#define R_386_TLS_LDM_PUSH 29
+#define R_386_TLS_LDM_CALL 30
+#define R_386_TLS_LDM_POP 31
+#define R_386_TLS_LDO_32 32
+#define R_386_TLS_IE_32 33
+#define R_386_TLS_LE_32 34
+#define R_386_TLS_DTPMOD32 35
+#define R_386_TLS_DTPOFF32 36
+#define R_386_TLS_TPOFF32 37
+#define R_386_SIZE32 38
+#define R_386_TLS_GOTDESC 39
+#define R_386_TLS_DESC_CALL 40
+#define R_386_TLS_DESC 41
+#define R_386_IRELATIVE 42
+#define R_386_NUM 43
+
+#define STT_SPARC_REGISTER 13
+
+#define EF_SPARCV9_MM 3
+#define EF_SPARCV9_TSO 0
+#define EF_SPARCV9_PSO 1
+#define EF_SPARCV9_RMO 2
+#define EF_SPARC_LEDATA 0x800000
+#define EF_SPARC_EXT_MASK 0xFFFF00
+#define EF_SPARC_32PLUS 0x000100
+#define EF_SPARC_SUN_US1 0x000200
+#define EF_SPARC_HAL_R1 0x000400
+#define EF_SPARC_SUN_US3 0x000800
+
+#define R_SPARC_NONE 0
+#define R_SPARC_8 1
+#define R_SPARC_16 2
+#define R_SPARC_32 3
+#define R_SPARC_DISP8 4
+#define R_SPARC_DISP16 5
+#define R_SPARC_DISP32 6
+#define R_SPARC_WDISP30 7
+#define R_SPARC_WDISP22 8
+#define R_SPARC_HI22 9
+#define R_SPARC_22 10
+#define R_SPARC_13 11
+#define R_SPARC_LO10 12
+#define R_SPARC_GOT10 13
+#define R_SPARC_GOT13 14
+#define R_SPARC_GOT22 15
+#define R_SPARC_PC10 16
+#define R_SPARC_PC22 17
+#define R_SPARC_WPLT30 18
+#define R_SPARC_COPY 19
+#define R_SPARC_GLOB_DAT 20
+#define R_SPARC_JMP_SLOT 21
+#define R_SPARC_RELATIVE 22
+#define R_SPARC_UA32 23
+
+#define R_SPARC_PLT32 24
+#define R_SPARC_HIPLT22 25
+#define R_SPARC_LOPLT10 26
+#define R_SPARC_PCPLT32 27
+#define R_SPARC_PCPLT22 28
+#define R_SPARC_PCPLT10 29
+#define R_SPARC_10 30
+#define R_SPARC_11 31
+#define R_SPARC_64 32
+#define R_SPARC_OLO10 33
+#define R_SPARC_HH22 34
+#define R_SPARC_HM10 35
+#define R_SPARC_LM22 36
+#define R_SPARC_PC_HH22 37
+#define R_SPARC_PC_HM10 38
+#define R_SPARC_PC_LM22 39
+#define R_SPARC_WDISP16 40
+#define R_SPARC_WDISP19 41
+#define R_SPARC_GLOB_JMP 42
+#define R_SPARC_7 43
+#define R_SPARC_5 44
+#define R_SPARC_6 45
+#define R_SPARC_DISP64 46
+#define R_SPARC_PLT64 47
+#define R_SPARC_HIX22 48
+#define R_SPARC_LOX10 49
+#define R_SPARC_H44 50
+#define R_SPARC_M44 51
+#define R_SPARC_L44 52
+#define R_SPARC_REGISTER 53
+#define R_SPARC_UA64 54
+#define R_SPARC_UA16 55
+#define R_SPARC_TLS_GD_HI22 56
+#define R_SPARC_TLS_GD_LO10 57
+#define R_SPARC_TLS_GD_ADD 58
+#define R_SPARC_TLS_GD_CALL 59
+#define R_SPARC_TLS_LDM_HI22 60
+#define R_SPARC_TLS_LDM_LO10 61
+#define R_SPARC_TLS_LDM_ADD 62
+#define R_SPARC_TLS_LDM_CALL 63
+#define R_SPARC_TLS_LDO_HIX22 64
+#define R_SPARC_TLS_LDO_LOX10 65
+#define R_SPARC_TLS_LDO_ADD 66
+#define R_SPARC_TLS_IE_HI22 67
+#define R_SPARC_TLS_IE_LO10 68
+#define R_SPARC_TLS_IE_LD 69
+#define R_SPARC_TLS_IE_LDX 70
+#define R_SPARC_TLS_IE_ADD 71
+#define R_SPARC_TLS_LE_HIX22 72
+#define R_SPARC_TLS_LE_LOX10 73
+#define R_SPARC_TLS_DTPMOD32 74
+#define R_SPARC_TLS_DTPMOD64 75
+#define R_SPARC_TLS_DTPOFF32 76
+#define R_SPARC_TLS_DTPOFF64 77
+#define R_SPARC_TLS_TPOFF32 78
+#define R_SPARC_TLS_TPOFF64 79
+#define R_SPARC_GOTDATA_HIX22 80
+#define R_SPARC_GOTDATA_LOX10 81
+#define R_SPARC_GOTDATA_OP_HIX22 82
+#define R_SPARC_GOTDATA_OP_LOX10 83
+#define R_SPARC_GOTDATA_OP 84
+#define R_SPARC_H34 85
+#define R_SPARC_SIZE32 86
+#define R_SPARC_SIZE64 87
+#define R_SPARC_GNU_VTINHERIT 250
+#define R_SPARC_GNU_VTENTRY 251
+#define R_SPARC_REV32 252
+
+#define R_SPARC_NUM 253
+
+#define DT_SPARC_REGISTER 0x70000001
+#define DT_SPARC_NUM 2
+
+#define EF_MIPS_NOREORDER 1
+#define EF_MIPS_PIC 2
+#define EF_MIPS_CPIC 4
+#define EF_MIPS_XGOT 8
+#define EF_MIPS_64BIT_WHIRL 16
+#define EF_MIPS_ABI2 32
+#define EF_MIPS_ABI_ON32 64
+#define EF_MIPS_NAN2008 1024
+#define EF_MIPS_ARCH 0xf0000000
+
+#define EF_MIPS_ARCH_1 0x00000000
+#define EF_MIPS_ARCH_2 0x10000000
+#define EF_MIPS_ARCH_3 0x20000000
+#define EF_MIPS_ARCH_4 0x30000000
+#define EF_MIPS_ARCH_5 0x40000000
+#define EF_MIPS_ARCH_32 0x50000000
+#define EF_MIPS_ARCH_64 0x60000000
+#define EF_MIPS_ARCH_32R2 0x70000000
+#define EF_MIPS_ARCH_64R2 0x80000000
+
+#define E_MIPS_ARCH_1 0x00000000
+#define E_MIPS_ARCH_2 0x10000000
+#define E_MIPS_ARCH_3 0x20000000
+#define E_MIPS_ARCH_4 0x30000000
+#define E_MIPS_ARCH_5 0x40000000
+#define E_MIPS_ARCH_32 0x50000000
+#define E_MIPS_ARCH_64 0x60000000
+
+#define SHN_MIPS_ACOMMON 0xff00
+#define SHN_MIPS_TEXT 0xff01
+#define SHN_MIPS_DATA 0xff02
+#define SHN_MIPS_SCOMMON 0xff03
+#define SHN_MIPS_SUNDEFINED 0xff04
+
+#define SHT_MIPS_LIBLIST 0x70000000
+#define SHT_MIPS_MSYM 0x70000001
+#define SHT_MIPS_CONFLICT 0x70000002
+#define SHT_MIPS_GPTAB 0x70000003
+#define SHT_MIPS_UCODE 0x70000004
+#define SHT_MIPS_DEBUG 0x70000005
+#define SHT_MIPS_REGINFO 0x70000006
+#define SHT_MIPS_PACKAGE 0x70000007
+#define SHT_MIPS_PACKSYM 0x70000008
+#define SHT_MIPS_RELD 0x70000009
+#define SHT_MIPS_IFACE 0x7000000b
+#define SHT_MIPS_CONTENT 0x7000000c
+#define SHT_MIPS_OPTIONS 0x7000000d
+#define SHT_MIPS_SHDR 0x70000010
+#define SHT_MIPS_FDESC 0x70000011
+#define SHT_MIPS_EXTSYM 0x70000012
+#define SHT_MIPS_DENSE 0x70000013
+#define SHT_MIPS_PDESC 0x70000014
+#define SHT_MIPS_LOCSYM 0x70000015
+#define SHT_MIPS_AUXSYM 0x70000016
+#define SHT_MIPS_OPTSYM 0x70000017
+#define SHT_MIPS_LOCSTR 0x70000018
+#define SHT_MIPS_LINE 0x70000019
+#define SHT_MIPS_RFDESC 0x7000001a
+#define SHT_MIPS_DELTASYM 0x7000001b
+#define SHT_MIPS_DELTAINST 0x7000001c
+#define SHT_MIPS_DELTACLASS 0x7000001d
+#define SHT_MIPS_DWARF 0x7000001e
+#define SHT_MIPS_DELTADECL 0x7000001f
+#define SHT_MIPS_SYMBOL_LIB 0x70000020
+#define SHT_MIPS_EVENTS 0x70000021
+#define SHT_MIPS_TRANSLATE 0x70000022
+#define SHT_MIPS_PIXIE 0x70000023
+#define SHT_MIPS_XLATE 0x70000024
+#define SHT_MIPS_XLATE_DEBUG 0x70000025
+#define SHT_MIPS_WHIRL 0x70000026
+#define SHT_MIPS_EH_REGION 0x70000027
+#define SHT_MIPS_XLATE_OLD 0x70000028
+#define SHT_MIPS_PDR_EXCEPTION 0x70000029
+
+#define SHF_MIPS_GPREL 0x10000000
+#define SHF_MIPS_MERGE 0x20000000
+#define SHF_MIPS_ADDR 0x40000000
+#define SHF_MIPS_STRINGS 0x80000000
+#define SHF_MIPS_NOSTRIP 0x08000000
+#define SHF_MIPS_LOCAL 0x04000000
+#define SHF_MIPS_NAMES 0x02000000
+#define SHF_MIPS_NODUPE 0x01000000
+
+#define STO_MIPS_DEFAULT 0x0
+#define STO_MIPS_INTERNAL 0x1
+#define STO_MIPS_HIDDEN 0x2
+#define STO_MIPS_PROTECTED 0x3
+#define STO_MIPS_PLT 0x8
+#define STO_MIPS_SC_ALIGN_UNUSED 0xff
+
+#define STB_MIPS_SPLIT_COMMON 13
+
+typedef union {
+ struct {
+ Elf32_Word gt_current_g_value;
+ Elf32_Word gt_unused;
+ } gt_header;
+ struct {
+ Elf32_Word gt_g_value;
+ Elf32_Word gt_bytes;
+ } gt_entry;
+} Elf32_gptab;
+
+typedef struct {
+ Elf32_Word ri_gprmask;
+ Elf32_Word ri_cprmask[4];
+ Elf32_Sword ri_gp_value;
+} Elf32_RegInfo;
+
+typedef struct {
+ unsigned char kind;
+
+ unsigned char size;
+ Elf32_Section section;
+
+ Elf32_Word info;
+} Elf_Options;
+
+#define ODK_NULL 0
+#define ODK_REGINFO 1
+#define ODK_EXCEPTIONS 2
+#define ODK_PAD 3
+#define ODK_HWPATCH 4
+#define ODK_FILL 5
+#define ODK_TAGS 6
+#define ODK_HWAND 7
+#define ODK_HWOR 8
+
+#define OEX_FPU_MIN 0x1f
+#define OEX_FPU_MAX 0x1f00
+#define OEX_PAGE0 0x10000
+#define OEX_SMM 0x20000
+#define OEX_FPDBUG 0x40000
+#define OEX_PRECISEFP OEX_FPDBUG
+#define OEX_DISMISS 0x80000
+
+#define OEX_FPU_INVAL 0x10
+#define OEX_FPU_DIV0 0x08
+#define OEX_FPU_OFLO 0x04
+#define OEX_FPU_UFLO 0x02
+#define OEX_FPU_INEX 0x01
+
+#define OHW_R4KEOP 0x1
+#define OHW_R8KPFETCH 0x2
+#define OHW_R5KEOP 0x4
+#define OHW_R5KCVTL 0x8
+
+#define OPAD_PREFIX 0x1
+#define OPAD_POSTFIX 0x2
+#define OPAD_SYMBOL 0x4
+
+typedef struct {
+ Elf32_Word hwp_flags1;
+ Elf32_Word hwp_flags2;
+} Elf_Options_Hw;
+
+#define OHWA0_R4KEOP_CHECKED 0x00000001
+#define OHWA1_R4KEOP_CLEAN 0x00000002
+
+#define R_MIPS_NONE 0
+#define R_MIPS_16 1
+#define R_MIPS_32 2
+#define R_MIPS_REL32 3
+#define R_MIPS_26 4
+#define R_MIPS_HI16 5
+#define R_MIPS_LO16 6
+#define R_MIPS_GPREL16 7
+#define R_MIPS_LITERAL 8
+#define R_MIPS_GOT16 9
+#define R_MIPS_PC16 10
+#define R_MIPS_CALL16 11
+#define R_MIPS_GPREL32 12
+
+#define R_MIPS_SHIFT5 16
+#define R_MIPS_SHIFT6 17
+#define R_MIPS_64 18
+#define R_MIPS_GOT_DISP 19
+#define R_MIPS_GOT_PAGE 20
+#define R_MIPS_GOT_OFST 21
+#define R_MIPS_GOT_HI16 22
+#define R_MIPS_GOT_LO16 23
+#define R_MIPS_SUB 24
+#define R_MIPS_INSERT_A 25
+#define R_MIPS_INSERT_B 26
+#define R_MIPS_DELETE 27
+#define R_MIPS_HIGHER 28
+#define R_MIPS_HIGHEST 29
+#define R_MIPS_CALL_HI16 30
+#define R_MIPS_CALL_LO16 31
+#define R_MIPS_SCN_DISP 32
+#define R_MIPS_REL16 33
+#define R_MIPS_ADD_IMMEDIATE 34
+#define R_MIPS_PJUMP 35
+#define R_MIPS_RELGOT 36
+#define R_MIPS_JALR 37
+#define R_MIPS_TLS_DTPMOD32 38
+#define R_MIPS_TLS_DTPREL32 39
+#define R_MIPS_TLS_DTPMOD64 40
+#define R_MIPS_TLS_DTPREL64 41
+#define R_MIPS_TLS_GD 42
+#define R_MIPS_TLS_LDM 43
+#define R_MIPS_TLS_DTPREL_HI16 44
+#define R_MIPS_TLS_DTPREL_LO16 45
+#define R_MIPS_TLS_GOTTPREL 46
+#define R_MIPS_TLS_TPREL32 47
+#define R_MIPS_TLS_TPREL64 48
+#define R_MIPS_TLS_TPREL_HI16 49
+#define R_MIPS_TLS_TPREL_LO16 50
+#define R_MIPS_GLOB_DAT 51
+#define R_MIPS_COPY 126
+#define R_MIPS_JUMP_SLOT 127
+
+#define R_MIPS_NUM 128
+
+#define PT_MIPS_REGINFO 0x70000000
+#define PT_MIPS_RTPROC 0x70000001
+#define PT_MIPS_OPTIONS 0x70000002
+
+#define PF_MIPS_LOCAL 0x10000000
+
+#define DT_MIPS_RLD_VERSION 0x70000001
+#define DT_MIPS_TIME_STAMP 0x70000002
+#define DT_MIPS_ICHECKSUM 0x70000003
+#define DT_MIPS_IVERSION 0x70000004
+#define DT_MIPS_FLAGS 0x70000005
+#define DT_MIPS_BASE_ADDRESS 0x70000006
+#define DT_MIPS_MSYM 0x70000007
+#define DT_MIPS_CONFLICT 0x70000008
+#define DT_MIPS_LIBLIST 0x70000009
+#define DT_MIPS_LOCAL_GOTNO 0x7000000a
+#define DT_MIPS_CONFLICTNO 0x7000000b
+#define DT_MIPS_LIBLISTNO 0x70000010
+#define DT_MIPS_SYMTABNO 0x70000011
+#define DT_MIPS_UNREFEXTNO 0x70000012
+#define DT_MIPS_GOTSYM 0x70000013
+#define DT_MIPS_HIPAGENO 0x70000014
+#define DT_MIPS_RLD_MAP 0x70000016
+#define DT_MIPS_DELTA_CLASS 0x70000017
+#define DT_MIPS_DELTA_CLASS_NO 0x70000018
+
+#define DT_MIPS_DELTA_INSTANCE 0x70000019
+#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a
+
+#define DT_MIPS_DELTA_RELOC 0x7000001b
+#define DT_MIPS_DELTA_RELOC_NO 0x7000001c
+
+#define DT_MIPS_DELTA_SYM 0x7000001d
+
+#define DT_MIPS_DELTA_SYM_NO 0x7000001e
+
+#define DT_MIPS_DELTA_CLASSSYM 0x70000020
+
+#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021
+
+#define DT_MIPS_CXX_FLAGS 0x70000022
+#define DT_MIPS_PIXIE_INIT 0x70000023
+#define DT_MIPS_SYMBOL_LIB 0x70000024
+#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
+#define DT_MIPS_LOCAL_GOTIDX 0x70000026
+#define DT_MIPS_HIDDEN_GOTIDX 0x70000027
+#define DT_MIPS_PROTECTED_GOTIDX 0x70000028
+#define DT_MIPS_OPTIONS 0x70000029
+#define DT_MIPS_INTERFACE 0x7000002a
+#define DT_MIPS_DYNSTR_ALIGN 0x7000002b
+#define DT_MIPS_INTERFACE_SIZE 0x7000002c
+#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d
+
+#define DT_MIPS_PERF_SUFFIX 0x7000002e
+
+#define DT_MIPS_COMPACT_SIZE 0x7000002f
+#define DT_MIPS_GP_VALUE 0x70000030
+#define DT_MIPS_AUX_DYNAMIC 0x70000031
+
+#define DT_MIPS_PLTGOT 0x70000032
+
+#define DT_MIPS_RWPLT 0x70000034
+#define DT_MIPS_NUM 0x35
+
+#define RHF_NONE 0
+#define RHF_QUICKSTART (1 << 0)
+#define RHF_NOTPOT (1 << 1)
+#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2)
+#define RHF_NO_MOVE (1 << 3)
+#define RHF_SGI_ONLY (1 << 4)
+#define RHF_GUARANTEE_INIT (1 << 5)
+#define RHF_DELTA_C_PLUS_PLUS (1 << 6)
+#define RHF_GUARANTEE_START_INIT (1 << 7)
+#define RHF_PIXIE (1 << 8)
+#define RHF_DEFAULT_DELAY_LOAD (1 << 9)
+#define RHF_REQUICKSTART (1 << 10)
+#define RHF_REQUICKSTARTED (1 << 11)
+#define RHF_CORD (1 << 12)
+#define RHF_NO_UNRES_UNDEF (1 << 13)
+#define RHF_RLD_ORDER_SAFE (1 << 14)
+
+typedef struct {
+ Elf32_Word l_name;
+ Elf32_Word l_time_stamp;
+ Elf32_Word l_checksum;
+ Elf32_Word l_version;
+ Elf32_Word l_flags;
+} Elf32_Lib;
+
+typedef struct {
+ Elf64_Word l_name;
+ Elf64_Word l_time_stamp;
+ Elf64_Word l_checksum;
+ Elf64_Word l_version;
+ Elf64_Word l_flags;
+} Elf64_Lib;
+
+#define LL_NONE 0
+#define LL_EXACT_MATCH (1 << 0)
+#define LL_IGNORE_INT_VER (1 << 1)
+#define LL_REQUIRE_MINOR (1 << 2)
+#define LL_EXPORTS (1 << 3)
+#define LL_DELAY_LOAD (1 << 4)
+#define LL_DELTA (1 << 5)
+
+typedef Elf32_Addr Elf32_Conflict;
+
+#define EF_PARISC_TRAPNIL 0x00010000
+#define EF_PARISC_EXT 0x00020000
+#define EF_PARISC_LSB 0x00040000
+#define EF_PARISC_WIDE 0x00080000
+#define EF_PARISC_NO_KABP 0x00100000
+
+#define EF_PARISC_LAZYSWAP 0x00400000
+#define EF_PARISC_ARCH 0x0000ffff
+
+#define EFA_PARISC_1_0 0x020b
+#define EFA_PARISC_1_1 0x0210
+#define EFA_PARISC_2_0 0x0214
+
+#define SHN_PARISC_ANSI_COMMON 0xff00
+
+#define SHN_PARISC_HUGE_COMMON 0xff01
+
+#define SHT_PARISC_EXT 0x70000000
+#define SHT_PARISC_UNWIND 0x70000001
+#define SHT_PARISC_DOC 0x70000002
+
+#define SHF_PARISC_SHORT 0x20000000
+#define SHF_PARISC_HUGE 0x40000000
+#define SHF_PARISC_SBP 0x80000000
+
+#define STT_PARISC_MILLICODE 13
+
+#define STT_HP_OPAQUE (STT_LOOS + 0x1)
+#define STT_HP_STUB (STT_LOOS + 0x2)
+
+#define R_PARISC_NONE 0
+#define R_PARISC_DIR32 1
+#define R_PARISC_DIR21L 2
+#define R_PARISC_DIR17R 3
+#define R_PARISC_DIR17F 4
+#define R_PARISC_DIR14R 6
+#define R_PARISC_PCREL32 9
+#define R_PARISC_PCREL21L 10
+#define R_PARISC_PCREL17R 11
+#define R_PARISC_PCREL17F 12
+#define R_PARISC_PCREL14R 14
+#define R_PARISC_DPREL21L 18
+#define R_PARISC_DPREL14R 22
+#define R_PARISC_GPREL21L 26
+#define R_PARISC_GPREL14R 30
+#define R_PARISC_LTOFF21L 34
+#define R_PARISC_LTOFF14R 38
+#define R_PARISC_SECREL32 41
+#define R_PARISC_SEGBASE 48
+#define R_PARISC_SEGREL32 49
+#define R_PARISC_PLTOFF21L 50
+#define R_PARISC_PLTOFF14R 54
+#define R_PARISC_LTOFF_FPTR32 57
+#define R_PARISC_LTOFF_FPTR21L 58
+#define R_PARISC_LTOFF_FPTR14R 62
+#define R_PARISC_FPTR64 64
+#define R_PARISC_PLABEL32 65
+#define R_PARISC_PLABEL21L 66
+#define R_PARISC_PLABEL14R 70
+#define R_PARISC_PCREL64 72
+#define R_PARISC_PCREL22F 74
+#define R_PARISC_PCREL14WR 75
+#define R_PARISC_PCREL14DR 76
+#define R_PARISC_PCREL16F 77
+#define R_PARISC_PCREL16WF 78
+#define R_PARISC_PCREL16DF 79
+#define R_PARISC_DIR64 80
+#define R_PARISC_DIR14WR 83
+#define R_PARISC_DIR14DR 84
+#define R_PARISC_DIR16F 85
+#define R_PARISC_DIR16WF 86
+#define R_PARISC_DIR16DF 87
+#define R_PARISC_GPREL64 88
+#define R_PARISC_GPREL14WR 91
+#define R_PARISC_GPREL14DR 92
+#define R_PARISC_GPREL16F 93
+#define R_PARISC_GPREL16WF 94
+#define R_PARISC_GPREL16DF 95
+#define R_PARISC_LTOFF64 96
+#define R_PARISC_LTOFF14WR 99
+#define R_PARISC_LTOFF14DR 100
+#define R_PARISC_LTOFF16F 101
+#define R_PARISC_LTOFF16WF 102
+#define R_PARISC_LTOFF16DF 103
+#define R_PARISC_SECREL64 104
+#define R_PARISC_SEGREL64 112
+#define R_PARISC_PLTOFF14WR 115
+#define R_PARISC_PLTOFF14DR 116
+#define R_PARISC_PLTOFF16F 117
+#define R_PARISC_PLTOFF16WF 118
+#define R_PARISC_PLTOFF16DF 119
+#define R_PARISC_LTOFF_FPTR64 120
+#define R_PARISC_LTOFF_FPTR14WR 123
+#define R_PARISC_LTOFF_FPTR14DR 124
+#define R_PARISC_LTOFF_FPTR16F 125
+#define R_PARISC_LTOFF_FPTR16WF 126
+#define R_PARISC_LTOFF_FPTR16DF 127
+#define R_PARISC_LORESERVE 128
+#define R_PARISC_COPY 128
+#define R_PARISC_IPLT 129
+#define R_PARISC_EPLT 130
+#define R_PARISC_TPREL32 153
+#define R_PARISC_TPREL21L 154
+#define R_PARISC_TPREL14R 158
+#define R_PARISC_LTOFF_TP21L 162
+#define R_PARISC_LTOFF_TP14R 166
+#define R_PARISC_LTOFF_TP14F 167
+#define R_PARISC_TPREL64 216
+#define R_PARISC_TPREL14WR 219
+#define R_PARISC_TPREL14DR 220
+#define R_PARISC_TPREL16F 221
+#define R_PARISC_TPREL16WF 222
+#define R_PARISC_TPREL16DF 223
+#define R_PARISC_LTOFF_TP64 224
+#define R_PARISC_LTOFF_TP14WR 227
+#define R_PARISC_LTOFF_TP14DR 228
+#define R_PARISC_LTOFF_TP16F 229
+#define R_PARISC_LTOFF_TP16WF 230
+#define R_PARISC_LTOFF_TP16DF 231
+#define R_PARISC_GNU_VTENTRY 232
+#define R_PARISC_GNU_VTINHERIT 233
+#define R_PARISC_TLS_GD21L 234
+#define R_PARISC_TLS_GD14R 235
+#define R_PARISC_TLS_GDCALL 236
+#define R_PARISC_TLS_LDM21L 237
+#define R_PARISC_TLS_LDM14R 238
+#define R_PARISC_TLS_LDMCALL 239
+#define R_PARISC_TLS_LDO21L 240
+#define R_PARISC_TLS_LDO14R 241
+#define R_PARISC_TLS_DTPMOD32 242
+#define R_PARISC_TLS_DTPMOD64 243
+#define R_PARISC_TLS_DTPOFF32 244
+#define R_PARISC_TLS_DTPOFF64 245
+#define R_PARISC_TLS_LE21L R_PARISC_TPREL21L
+#define R_PARISC_TLS_LE14R R_PARISC_TPREL14R
+#define R_PARISC_TLS_IE21L R_PARISC_LTOFF_TP21L
+#define R_PARISC_TLS_IE14R R_PARISC_LTOFF_TP14R
+#define R_PARISC_TLS_TPREL32 R_PARISC_TPREL32
+#define R_PARISC_TLS_TPREL64 R_PARISC_TPREL64
+#define R_PARISC_HIRESERVE 255
+
+#define PT_HP_TLS (PT_LOOS + 0x0)
+#define PT_HP_CORE_NONE (PT_LOOS + 0x1)
+#define PT_HP_CORE_VERSION (PT_LOOS + 0x2)
+#define PT_HP_CORE_KERNEL (PT_LOOS + 0x3)
+#define PT_HP_CORE_COMM (PT_LOOS + 0x4)
+#define PT_HP_CORE_PROC (PT_LOOS + 0x5)
+#define PT_HP_CORE_LOADABLE (PT_LOOS + 0x6)
+#define PT_HP_CORE_STACK (PT_LOOS + 0x7)
+#define PT_HP_CORE_SHM (PT_LOOS + 0x8)
+#define PT_HP_CORE_MMF (PT_LOOS + 0x9)
+#define PT_HP_PARALLEL (PT_LOOS + 0x10)
+#define PT_HP_FASTBIND (PT_LOOS + 0x11)
+#define PT_HP_OPT_ANNOT (PT_LOOS + 0x12)
+#define PT_HP_HSL_ANNOT (PT_LOOS + 0x13)
+#define PT_HP_STACK (PT_LOOS + 0x14)
+
+#define PT_PARISC_ARCHEXT 0x70000000
+#define PT_PARISC_UNWIND 0x70000001
+
+#define PF_PARISC_SBP 0x08000000
+
+#define PF_HP_PAGE_SIZE 0x00100000
+#define PF_HP_FAR_SHARED 0x00200000
+#define PF_HP_NEAR_SHARED 0x00400000
+#define PF_HP_CODE 0x01000000
+#define PF_HP_MODIFY 0x02000000
+#define PF_HP_LAZYSWAP 0x04000000
+#define PF_HP_SBP 0x08000000
+
+#define EF_ALPHA_32BIT 1
+#define EF_ALPHA_CANRELAX 2
+
+#define SHT_ALPHA_DEBUG 0x70000001
+#define SHT_ALPHA_REGINFO 0x70000002
+
+#define SHF_ALPHA_GPREL 0x10000000
+
+#define STO_ALPHA_NOPV 0x80
+#define STO_ALPHA_STD_GPLOAD 0x88
+
+#define R_ALPHA_NONE 0
+#define R_ALPHA_REFLONG 1
+#define R_ALPHA_REFQUAD 2
+#define R_ALPHA_GPREL32 3
+#define R_ALPHA_LITERAL 4
+#define R_ALPHA_LITUSE 5
+#define R_ALPHA_GPDISP 6
+#define R_ALPHA_BRADDR 7
+#define R_ALPHA_HINT 8
+#define R_ALPHA_SREL16 9
+#define R_ALPHA_SREL32 10
+#define R_ALPHA_SREL64 11
+#define R_ALPHA_GPRELHIGH 17
+#define R_ALPHA_GPRELLOW 18
+#define R_ALPHA_GPREL16 19
+#define R_ALPHA_COPY 24
+#define R_ALPHA_GLOB_DAT 25
+#define R_ALPHA_JMP_SLOT 26
+#define R_ALPHA_RELATIVE 27
+#define R_ALPHA_TLS_GD_HI 28
+#define R_ALPHA_TLSGD 29
+#define R_ALPHA_TLS_LDM 30
+#define R_ALPHA_DTPMOD64 31
+#define R_ALPHA_GOTDTPREL 32
+#define R_ALPHA_DTPREL64 33
+#define R_ALPHA_DTPRELHI 34
+#define R_ALPHA_DTPRELLO 35
+#define R_ALPHA_DTPREL16 36
+#define R_ALPHA_GOTTPREL 37
+#define R_ALPHA_TPREL64 38
+#define R_ALPHA_TPRELHI 39
+#define R_ALPHA_TPRELLO 40
+#define R_ALPHA_TPREL16 41
+
+#define R_ALPHA_NUM 46
+
+#define LITUSE_ALPHA_ADDR 0
+#define LITUSE_ALPHA_BASE 1
+#define LITUSE_ALPHA_BYTOFF 2
+#define LITUSE_ALPHA_JSR 3
+#define LITUSE_ALPHA_TLS_GD 4
+#define LITUSE_ALPHA_TLS_LDM 5
+
+#define DT_ALPHA_PLTRO (DT_LOPROC + 0)
+#define DT_ALPHA_NUM 1
+
+#define EF_PPC_EMB 0x80000000
+
+#define EF_PPC_RELOCATABLE 0x00010000
+#define EF_PPC_RELOCATABLE_LIB 0x00008000
+
+#define R_PPC_NONE 0
+#define R_PPC_ADDR32 1
+#define R_PPC_ADDR24 2
+#define R_PPC_ADDR16 3
+#define R_PPC_ADDR16_LO 4
+#define R_PPC_ADDR16_HI 5
+#define R_PPC_ADDR16_HA 6
+#define R_PPC_ADDR14 7
+#define R_PPC_ADDR14_BRTAKEN 8
+#define R_PPC_ADDR14_BRNTAKEN 9
+#define R_PPC_REL24 10
+#define R_PPC_REL14 11
+#define R_PPC_REL14_BRTAKEN 12
+#define R_PPC_REL14_BRNTAKEN 13
+#define R_PPC_GOT16 14
+#define R_PPC_GOT16_LO 15
+#define R_PPC_GOT16_HI 16
+#define R_PPC_GOT16_HA 17
+#define R_PPC_PLTREL24 18
+#define R_PPC_COPY 19
+#define R_PPC_GLOB_DAT 20
+#define R_PPC_JMP_SLOT 21
+#define R_PPC_RELATIVE 22
+#define R_PPC_LOCAL24PC 23
+#define R_PPC_UADDR32 24
+#define R_PPC_UADDR16 25
+#define R_PPC_REL32 26
+#define R_PPC_PLT32 27
+#define R_PPC_PLTREL32 28
+#define R_PPC_PLT16_LO 29
+#define R_PPC_PLT16_HI 30
+#define R_PPC_PLT16_HA 31
+#define R_PPC_SDAREL16 32
+#define R_PPC_SECTOFF 33
+#define R_PPC_SECTOFF_LO 34
+#define R_PPC_SECTOFF_HI 35
+#define R_PPC_SECTOFF_HA 36
+
+#define R_PPC_TLS 67
+#define R_PPC_DTPMOD32 68
+#define R_PPC_TPREL16 69
+#define R_PPC_TPREL16_LO 70
+#define R_PPC_TPREL16_HI 71
+#define R_PPC_TPREL16_HA 72
+#define R_PPC_TPREL32 73
+#define R_PPC_DTPREL16 74
+#define R_PPC_DTPREL16_LO 75
+#define R_PPC_DTPREL16_HI 76
+#define R_PPC_DTPREL16_HA 77
+#define R_PPC_DTPREL32 78
+#define R_PPC_GOT_TLSGD16 79
+#define R_PPC_GOT_TLSGD16_LO 80
+#define R_PPC_GOT_TLSGD16_HI 81
+#define R_PPC_GOT_TLSGD16_HA 82
+#define R_PPC_GOT_TLSLD16 83
+#define R_PPC_GOT_TLSLD16_LO 84
+#define R_PPC_GOT_TLSLD16_HI 85
+#define R_PPC_GOT_TLSLD16_HA 86
+#define R_PPC_GOT_TPREL16 87
+#define R_PPC_GOT_TPREL16_LO 88
+#define R_PPC_GOT_TPREL16_HI 89
+#define R_PPC_GOT_TPREL16_HA 90
+#define R_PPC_GOT_DTPREL16 91
+#define R_PPC_GOT_DTPREL16_LO 92
+#define R_PPC_GOT_DTPREL16_HI 93
+#define R_PPC_GOT_DTPREL16_HA 94
+
+#define R_PPC_EMB_NADDR32 101
+#define R_PPC_EMB_NADDR16 102
+#define R_PPC_EMB_NADDR16_LO 103
+#define R_PPC_EMB_NADDR16_HI 104
+#define R_PPC_EMB_NADDR16_HA 105
+#define R_PPC_EMB_SDAI16 106
+#define R_PPC_EMB_SDA2I16 107
+#define R_PPC_EMB_SDA2REL 108
+#define R_PPC_EMB_SDA21 109
+#define R_PPC_EMB_MRKREF 110
+#define R_PPC_EMB_RELSEC16 111
+#define R_PPC_EMB_RELST_LO 112
+#define R_PPC_EMB_RELST_HI 113
+#define R_PPC_EMB_RELST_HA 114
+#define R_PPC_EMB_BIT_FLD 115
+#define R_PPC_EMB_RELSDA 116
+
+#define R_PPC_DIAB_SDA21_LO 180
+#define R_PPC_DIAB_SDA21_HI 181
+#define R_PPC_DIAB_SDA21_HA 182
+#define R_PPC_DIAB_RELSDA_LO 183
+#define R_PPC_DIAB_RELSDA_HI 184
+#define R_PPC_DIAB_RELSDA_HA 185
+
+#define R_PPC_IRELATIVE 248
+
+#define R_PPC_REL16 249
+#define R_PPC_REL16_LO 250
+#define R_PPC_REL16_HI 251
+#define R_PPC_REL16_HA 252
+
+#define R_PPC_TOC16 255
+
+#define DT_PPC_GOT (DT_LOPROC + 0)
+#define DT_PPC_NUM 1
+
+#define R_PPC64_NONE R_PPC_NONE
+#define R_PPC64_ADDR32 R_PPC_ADDR32
+#define R_PPC64_ADDR24 R_PPC_ADDR24
+#define R_PPC64_ADDR16 R_PPC_ADDR16
+#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO
+#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI
+#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA
+#define R_PPC64_ADDR14 R_PPC_ADDR14
+#define R_PPC64_ADDR14_BRTAKEN R_PPC_ADDR14_BRTAKEN
+#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN
+#define R_PPC64_REL24 R_PPC_REL24
+#define R_PPC64_REL14 R_PPC_REL14
+#define R_PPC64_REL14_BRTAKEN R_PPC_REL14_BRTAKEN
+#define R_PPC64_REL14_BRNTAKEN R_PPC_REL14_BRNTAKEN
+#define R_PPC64_GOT16 R_PPC_GOT16
+#define R_PPC64_GOT16_LO R_PPC_GOT16_LO
+#define R_PPC64_GOT16_HI R_PPC_GOT16_HI
+#define R_PPC64_GOT16_HA R_PPC_GOT16_HA
+
+#define R_PPC64_COPY R_PPC_COPY
+#define R_PPC64_GLOB_DAT R_PPC_GLOB_DAT
+#define R_PPC64_JMP_SLOT R_PPC_JMP_SLOT
+#define R_PPC64_RELATIVE R_PPC_RELATIVE
+
+#define R_PPC64_UADDR32 R_PPC_UADDR32
+#define R_PPC64_UADDR16 R_PPC_UADDR16
+#define R_PPC64_REL32 R_PPC_REL32
+#define R_PPC64_PLT32 R_PPC_PLT32
+#define R_PPC64_PLTREL32 R_PPC_PLTREL32
+#define R_PPC64_PLT16_LO R_PPC_PLT16_LO
+#define R_PPC64_PLT16_HI R_PPC_PLT16_HI
+#define R_PPC64_PLT16_HA R_PPC_PLT16_HA
+
+#define R_PPC64_SECTOFF R_PPC_SECTOFF
+#define R_PPC64_SECTOFF_LO R_PPC_SECTOFF_LO
+#define R_PPC64_SECTOFF_HI R_PPC_SECTOFF_HI
+#define R_PPC64_SECTOFF_HA R_PPC_SECTOFF_HA
+#define R_PPC64_ADDR30 37
+#define R_PPC64_ADDR64 38
+#define R_PPC64_ADDR16_HIGHER 39
+#define R_PPC64_ADDR16_HIGHERA 40
+#define R_PPC64_ADDR16_HIGHEST 41
+#define R_PPC64_ADDR16_HIGHESTA 42
+#define R_PPC64_UADDR64 43
+#define R_PPC64_REL64 44
+#define R_PPC64_PLT64 45
+#define R_PPC64_PLTREL64 46
+#define R_PPC64_TOC16 47
+#define R_PPC64_TOC16_LO 48
+#define R_PPC64_TOC16_HI 49
+#define R_PPC64_TOC16_HA 50
+#define R_PPC64_TOC 51
+#define R_PPC64_PLTGOT16 52
+#define R_PPC64_PLTGOT16_LO 53
+#define R_PPC64_PLTGOT16_HI 54
+#define R_PPC64_PLTGOT16_HA 55
+
+#define R_PPC64_ADDR16_DS 56
+#define R_PPC64_ADDR16_LO_DS 57
+#define R_PPC64_GOT16_DS 58
+#define R_PPC64_GOT16_LO_DS 59
+#define R_PPC64_PLT16_LO_DS 60
+#define R_PPC64_SECTOFF_DS 61
+#define R_PPC64_SECTOFF_LO_DS 62
+#define R_PPC64_TOC16_DS 63
+#define R_PPC64_TOC16_LO_DS 64
+#define R_PPC64_PLTGOT16_DS 65
+#define R_PPC64_PLTGOT16_LO_DS 66
+
+#define R_PPC64_TLS 67
+#define R_PPC64_DTPMOD64 68
+#define R_PPC64_TPREL16 69
+#define R_PPC64_TPREL16_LO 70
+#define R_PPC64_TPREL16_HI 71
+#define R_PPC64_TPREL16_HA 72
+#define R_PPC64_TPREL64 73
+#define R_PPC64_DTPREL16 74
+#define R_PPC64_DTPREL16_LO 75
+#define R_PPC64_DTPREL16_HI 76
+#define R_PPC64_DTPREL16_HA 77
+#define R_PPC64_DTPREL64 78
+#define R_PPC64_GOT_TLSGD16 79
+#define R_PPC64_GOT_TLSGD16_LO 80
+#define R_PPC64_GOT_TLSGD16_HI 81
+#define R_PPC64_GOT_TLSGD16_HA 82
+#define R_PPC64_GOT_TLSLD16 83
+#define R_PPC64_GOT_TLSLD16_LO 84
+#define R_PPC64_GOT_TLSLD16_HI 85
+#define R_PPC64_GOT_TLSLD16_HA 86
+#define R_PPC64_GOT_TPREL16_DS 87
+#define R_PPC64_GOT_TPREL16_LO_DS 88
+#define R_PPC64_GOT_TPREL16_HI 89
+#define R_PPC64_GOT_TPREL16_HA 90
+#define R_PPC64_GOT_DTPREL16_DS 91
+#define R_PPC64_GOT_DTPREL16_LO_DS 92
+#define R_PPC64_GOT_DTPREL16_HI 93
+#define R_PPC64_GOT_DTPREL16_HA 94
+#define R_PPC64_TPREL16_DS 95
+#define R_PPC64_TPREL16_LO_DS 96
+#define R_PPC64_TPREL16_HIGHER 97
+#define R_PPC64_TPREL16_HIGHERA 98
+#define R_PPC64_TPREL16_HIGHEST 99
+#define R_PPC64_TPREL16_HIGHESTA 100
+#define R_PPC64_DTPREL16_DS 101
+#define R_PPC64_DTPREL16_LO_DS 102
+#define R_PPC64_DTPREL16_HIGHER 103
+#define R_PPC64_DTPREL16_HIGHERA 104
+#define R_PPC64_DTPREL16_HIGHEST 105
+#define R_PPC64_DTPREL16_HIGHESTA 106
+
+#define R_PPC64_JMP_IREL 247
+#define R_PPC64_IRELATIVE 248
+#define R_PPC64_REL16 249
+#define R_PPC64_REL16_LO 250
+#define R_PPC64_REL16_HI 251
+#define R_PPC64_REL16_HA 252
+
+#define DT_PPC64_GLINK (DT_LOPROC + 0)
+#define DT_PPC64_OPD (DT_LOPROC + 1)
+#define DT_PPC64_OPDSZ (DT_LOPROC + 2)
+#define DT_PPC64_NUM 3
+
+#define EF_ARM_RELEXEC 0x01
+#define EF_ARM_HASENTRY 0x02
+#define EF_ARM_INTERWORK 0x04
+#define EF_ARM_APCS_26 0x08
+#define EF_ARM_APCS_FLOAT 0x10
+#define EF_ARM_PIC 0x20
+#define EF_ARM_ALIGN8 0x40
+#define EF_ARM_NEW_ABI 0x80
+#define EF_ARM_OLD_ABI 0x100
+#define EF_ARM_SOFT_FLOAT 0x200
+#define EF_ARM_VFP_FLOAT 0x400
+#define EF_ARM_MAVERICK_FLOAT 0x800
+
+#define EF_ARM_ABI_FLOAT_SOFT 0x200
+#define EF_ARM_ABI_FLOAT_HARD 0x400
+
+#define EF_ARM_SYMSARESORTED 0x04
+#define EF_ARM_DYNSYMSUSESEGIDX 0x08
+#define EF_ARM_MAPSYMSFIRST 0x10
+#define EF_ARM_EABIMASK 0XFF000000
+
+#define EF_ARM_BE8 0x00800000
+#define EF_ARM_LE8 0x00400000
+
+#define EF_ARM_EABI_VERSION(flags) ((flags)&EF_ARM_EABIMASK)
+#define EF_ARM_EABI_UNKNOWN 0x00000000
+#define EF_ARM_EABI_VER1 0x01000000
+#define EF_ARM_EABI_VER2 0x02000000
+#define EF_ARM_EABI_VER3 0x03000000
+#define EF_ARM_EABI_VER4 0x04000000
+#define EF_ARM_EABI_VER5 0x05000000
+
+#define STT_ARM_TFUNC STT_LOPROC
+#define STT_ARM_16BIT STT_HIPROC
+
+#define SHF_ARM_ENTRYSECT 0x10000000
+#define SHF_ARM_COMDEF 0x80000000
+
+#define PF_ARM_SB 0x10000000
+
+#define PF_ARM_PI 0x20000000
+#define PF_ARM_ABS 0x40000000
+
+#define PT_ARM_EXIDX (PT_LOPROC + 1)
+
+#define SHT_ARM_EXIDX (SHT_LOPROC + 1)
+#define SHT_ARM_PREEMPTMAP (SHT_LOPROC + 2)
+#define SHT_ARM_ATTRIBUTES (SHT_LOPROC + 3)
+
+#define R_AARCH64_NONE 0
+#define R_AARCH64_ABS64 257
+#define R_AARCH64_ABS32 258
+#define R_AARCH64_ABS16 259
+#define R_AARCH64_PREL64 260
+#define R_AARCH64_PREL32 261
+#define R_AARCH64_PREL16 262
+#define R_AARCH64_MOVW_UABS_G0 263
+#define R_AARCH64_MOVW_UABS_G0_NC 264
+#define R_AARCH64_MOVW_UABS_G1 265
+#define R_AARCH64_MOVW_UABS_G1_NC 266
+#define R_AARCH64_MOVW_UABS_G2 267
+#define R_AARCH64_MOVW_UABS_G2_NC 268
+#define R_AARCH64_MOVW_UABS_G3 269
+#define R_AARCH64_MOVW_SABS_G0 270
+#define R_AARCH64_MOVW_SABS_G1 271
+#define R_AARCH64_MOVW_SABS_G2 272
+#define R_AARCH64_LD_PREL_LO19 273
+#define R_AARCH64_ADR_PREL_LO21 274
+#define R_AARCH64_ADR_PREL_PG_HI21 275
+#define R_AARCH64_ADR_PREL_PG_HI21_NC 276
+#define R_AARCH64_ADD_ABS_LO12_NC 277
+#define R_AARCH64_LDST8_ABS_LO12_NC 278
+#define R_AARCH64_TSTBR14 279
+#define R_AARCH64_CONDBR19 280
+#define R_AARCH64_JUMP26 282
+#define R_AARCH64_CALL26 283
+#define R_AARCH64_LDST16_ABS_LO12_NC 284
+#define R_AARCH64_LDST32_ABS_LO12_NC 285
+#define R_AARCH64_LDST64_ABS_LO12_NC 286
+#define R_AARCH64_MOVW_PREL_G0 287
+#define R_AARCH64_MOVW_PREL_G0_NC 288
+#define R_AARCH64_MOVW_PREL_G1 289
+#define R_AARCH64_MOVW_PREL_G1_NC 290
+#define R_AARCH64_MOVW_PREL_G2 291
+#define R_AARCH64_MOVW_PREL_G2_NC 292
+#define R_AARCH64_MOVW_PREL_G3 293
+#define R_AARCH64_LDST128_ABS_LO12_NC 299
+#define R_AARCH64_MOVW_GOTOFF_G0 300
+#define R_AARCH64_MOVW_GOTOFF_G0_NC 301
+#define R_AARCH64_MOVW_GOTOFF_G1 302
+#define R_AARCH64_MOVW_GOTOFF_G1_NC 303
+#define R_AARCH64_MOVW_GOTOFF_G2 304
+#define R_AARCH64_MOVW_GOTOFF_G2_NC 305
+#define R_AARCH64_MOVW_GOTOFF_G3 306
+#define R_AARCH64_GOTREL64 307
+#define R_AARCH64_GOTREL32 308
+#define R_AARCH64_GOT_LD_PREL19 309
+#define R_AARCH64_LD64_GOTOFF_LO15 310
+#define R_AARCH64_ADR_GOT_PAGE 311
+#define R_AARCH64_LD64_GOT_LO12_NC 312
+#define R_AARCH64_LD64_GOTPAGE_LO15 313
+#define R_AARCH64_TLSGD_ADR_PREL21 512
+#define R_AARCH64_TLSGD_ADR_PAGE21 513
+#define R_AARCH64_TLSGD_ADD_LO12_NC 514
+#define R_AARCH64_TLSGD_MOVW_G1 515
+#define R_AARCH64_TLSGD_MOVW_G0_NC 516
+#define R_AARCH64_TLSLD_ADR_PREL21 517
+#define R_AARCH64_TLSLD_ADR_PAGE21 518
+#define R_AARCH64_TLSLD_ADD_LO12_NC 519
+#define R_AARCH64_TLSLD_MOVW_G1 520
+#define R_AARCH64_TLSLD_MOVW_G0_NC 521
+#define R_AARCH64_TLSLD_LD_PREL19 522
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527
+#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540
+#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541
+#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542
+#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543
+#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548
+#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559
+#define R_AARCH64_TLSDESC_LD_PREL19 560
+#define R_AARCH64_TLSDESC_ADR_PREL21 561
+#define R_AARCH64_TLSDESC_ADR_PAGE21 562
+#define R_AARCH64_TLSDESC_LD64_LO12 563
+#define R_AARCH64_TLSDESC_ADD_LO12 564
+#define R_AARCH64_TLSDESC_OFF_G1 565
+#define R_AARCH64_TLSDESC_OFF_G0_NC 566
+#define R_AARCH64_TLSDESC_LDR 567
+#define R_AARCH64_TLSDESC_ADD 568
+#define R_AARCH64_TLSDESC_CALL 569
+#define R_AARCH64_TLSLE_LDST128_TPREL_LO12 570
+#define R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC 571
+#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12 572
+#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC 573
+#define R_AARCH64_COPY 1024
+#define R_AARCH64_GLOB_DAT 1025
+#define R_AARCH64_JUMP_SLOT 1026
+#define R_AARCH64_RELATIVE 1027
+#define R_AARCH64_TLS_DTPMOD64 1028
+#define R_AARCH64_TLS_DTPREL64 1029
+#define R_AARCH64_TLS_TPREL64 1030
+#define R_AARCH64_TLSDESC 1031
+
+#define R_ARM_NONE 0
+#define R_ARM_PC24 1
+#define R_ARM_ABS32 2
+#define R_ARM_REL32 3
+#define R_ARM_PC13 4
+#define R_ARM_ABS16 5
+#define R_ARM_ABS12 6
+#define R_ARM_THM_ABS5 7
+#define R_ARM_ABS8 8
+#define R_ARM_SBREL32 9
+#define R_ARM_THM_PC22 10
+#define R_ARM_THM_PC8 11
+#define R_ARM_AMP_VCALL9 12
+#define R_ARM_TLS_DESC 13
+#define R_ARM_THM_SWI8 14
+#define R_ARM_XPC25 15
+#define R_ARM_THM_XPC22 16
+#define R_ARM_TLS_DTPMOD32 17
+#define R_ARM_TLS_DTPOFF32 18
+#define R_ARM_TLS_TPOFF32 19
+#define R_ARM_COPY 20
+#define R_ARM_GLOB_DAT 21
+#define R_ARM_JUMP_SLOT 22
+#define R_ARM_RELATIVE 23
+#define R_ARM_GOTOFF 24
+#define R_ARM_GOTPC 25
+#define R_ARM_GOT32 26
+#define R_ARM_PLT32 27
+#define R_ARM_CALL 28
+#define R_ARM_JUMP24 29
+#define R_ARM_THM_JUMP24 30
+#define R_ARM_BASE_ABS 31
+#define R_ARM_ALU_PCREL_7_0 32
+#define R_ARM_ALU_PCREL_15_8 33
+#define R_ARM_ALU_PCREL_23_15 34
+#define R_ARM_LDR_SBREL_11_0 35
+#define R_ARM_ALU_SBREL_19_12 36
+#define R_ARM_ALU_SBREL_27_20 37
+#define R_ARM_TARGET1 38
+#define R_ARM_SBREL31 39
+#define R_ARM_V4BX 40
+#define R_ARM_TARGET2 41
+#define R_ARM_PREL31 42
+#define R_ARM_MOVW_ABS_NC 43
+#define R_ARM_MOVT_ABS 44
+#define R_ARM_MOVW_PREL_NC 45
+#define R_ARM_MOVT_PREL 46
+#define R_ARM_THM_MOVW_ABS_NC 47
+#define R_ARM_THM_MOVT_ABS 48
+#define R_ARM_THM_MOVW_PREL_NC 49
+#define R_ARM_THM_MOVT_PREL 50
+#define R_ARM_THM_JUMP19 51
+#define R_ARM_THM_JUMP6 52
+#define R_ARM_THM_ALU_PREL_11_0 53
+#define R_ARM_THM_PC12 54
+#define R_ARM_ABS32_NOI 55
+#define R_ARM_REL32_NOI 56
+#define R_ARM_ALU_PC_G0_NC 57
+#define R_ARM_ALU_PC_G0 58
+#define R_ARM_ALU_PC_G1_NC 59
+#define R_ARM_ALU_PC_G1 60
+#define R_ARM_ALU_PC_G2 61
+#define R_ARM_LDR_PC_G1 62
+#define R_ARM_LDR_PC_G2 63
+#define R_ARM_LDRS_PC_G0 64
+#define R_ARM_LDRS_PC_G1 65
+#define R_ARM_LDRS_PC_G2 66
+#define R_ARM_LDC_PC_G0 67
+#define R_ARM_LDC_PC_G1 68
+#define R_ARM_LDC_PC_G2 69
+#define R_ARM_ALU_SB_G0_NC 70
+#define R_ARM_ALU_SB_G0 71
+#define R_ARM_ALU_SB_G1_NC 72
+#define R_ARM_ALU_SB_G1 73
+#define R_ARM_ALU_SB_G2 74
+#define R_ARM_LDR_SB_G0 75
+#define R_ARM_LDR_SB_G1 76
+#define R_ARM_LDR_SB_G2 77
+#define R_ARM_LDRS_SB_G0 78
+#define R_ARM_LDRS_SB_G1 79
+#define R_ARM_LDRS_SB_G2 80
+#define R_ARM_LDC_SB_G0 81
+#define R_ARM_LDC_SB_G1 82
+#define R_ARM_LDC_SB_G2 83
+#define R_ARM_MOVW_BREL_NC 84
+#define R_ARM_MOVT_BREL 85
+#define R_ARM_MOVW_BREL 86
+#define R_ARM_THM_MOVW_BREL_NC 87
+#define R_ARM_THM_MOVT_BREL 88
+#define R_ARM_THM_MOVW_BREL 89
+#define R_ARM_TLS_GOTDESC 90
+#define R_ARM_TLS_CALL 91
+#define R_ARM_TLS_DESCSEQ 92
+#define R_ARM_THM_TLS_CALL 93
+#define R_ARM_PLT32_ABS 94
+#define R_ARM_GOT_ABS 95
+#define R_ARM_GOT_PREL 96
+#define R_ARM_GOT_BREL12 97
+#define R_ARM_GOTOFF12 98
+#define R_ARM_GOTRELAX 99
+#define R_ARM_GNU_VTENTRY 100
+#define R_ARM_GNU_VTINHERIT 101
+#define R_ARM_THM_PC11 102
+#define R_ARM_THM_PC9 103
+#define R_ARM_TLS_GD32 104
+
+#define R_ARM_TLS_LDM32 105
+
+#define R_ARM_TLS_LDO32 106
+
+#define R_ARM_TLS_IE32 107
+
+#define R_ARM_TLS_LE32 108
+#define R_ARM_TLS_LDO12 109
+#define R_ARM_TLS_LE12 110
+#define R_ARM_TLS_IE12GP 111
+#define R_ARM_ME_TOO 128
+#define R_ARM_THM_TLS_DESCSEQ 129
+#define R_ARM_THM_TLS_DESCSEQ16 129
+#define R_ARM_THM_TLS_DESCSEQ32 130
+#define R_ARM_THM_GOT_BREL12 131
+#define R_ARM_IRELATIVE 160
+#define R_ARM_RXPC25 249
+#define R_ARM_RSBREL32 250
+#define R_ARM_THM_RPC22 251
+#define R_ARM_RREL32 252
+#define R_ARM_RABS22 253
+#define R_ARM_RPC24 254
+#define R_ARM_RBASE 255
+
+#define R_ARM_NUM 256
+
+#define EF_IA_64_MASKOS 0x0000000f
+#define EF_IA_64_ABI64 0x00000010
+#define EF_IA_64_ARCH 0xff000000
+
+#define PT_IA_64_ARCHEXT (PT_LOPROC + 0)
+#define PT_IA_64_UNWIND (PT_LOPROC + 1)
+#define PT_IA_64_HP_OPT_ANOT (PT_LOOS + 0x12)
+#define PT_IA_64_HP_HSL_ANOT (PT_LOOS + 0x13)
+#define PT_IA_64_HP_STACK (PT_LOOS + 0x14)
+
+#define PF_IA_64_NORECOV 0x80000000
+
+#define SHT_IA_64_EXT (SHT_LOPROC + 0)
+#define SHT_IA_64_UNWIND (SHT_LOPROC + 1)
+
+#define SHF_IA_64_SHORT 0x10000000
+#define SHF_IA_64_NORECOV 0x20000000
+
+#define DT_IA_64_PLT_RESERVE (DT_LOPROC + 0)
+#define DT_IA_64_NUM 1
+
+#define R_IA64_NONE 0x00
+#define R_IA64_IMM14 0x21
+#define R_IA64_IMM22 0x22
+#define R_IA64_IMM64 0x23
+#define R_IA64_DIR32MSB 0x24
+#define R_IA64_DIR32LSB 0x25
+#define R_IA64_DIR64MSB 0x26
+#define R_IA64_DIR64LSB 0x27
+#define R_IA64_GPREL22 0x2a
+#define R_IA64_GPREL64I 0x2b
+#define R_IA64_GPREL32MSB 0x2c
+#define R_IA64_GPREL32LSB 0x2d
+#define R_IA64_GPREL64MSB 0x2e
+#define R_IA64_GPREL64LSB 0x2f
+#define R_IA64_LTOFF22 0x32
+#define R_IA64_LTOFF64I 0x33
+#define R_IA64_PLTOFF22 0x3a
+#define R_IA64_PLTOFF64I 0x3b
+#define R_IA64_PLTOFF64MSB 0x3e
+#define R_IA64_PLTOFF64LSB 0x3f
+#define R_IA64_FPTR64I 0x43
+#define R_IA64_FPTR32MSB 0x44
+#define R_IA64_FPTR32LSB 0x45
+#define R_IA64_FPTR64MSB 0x46
+#define R_IA64_FPTR64LSB 0x47
+#define R_IA64_PCREL60B 0x48
+#define R_IA64_PCREL21B 0x49
+#define R_IA64_PCREL21M 0x4a
+#define R_IA64_PCREL21F 0x4b
+#define R_IA64_PCREL32MSB 0x4c
+#define R_IA64_PCREL32LSB 0x4d
+#define R_IA64_PCREL64MSB 0x4e
+#define R_IA64_PCREL64LSB 0x4f
+#define R_IA64_LTOFF_FPTR22 0x52
+#define R_IA64_LTOFF_FPTR64I 0x53
+#define R_IA64_LTOFF_FPTR32MSB 0x54
+#define R_IA64_LTOFF_FPTR32LSB 0x55
+#define R_IA64_LTOFF_FPTR64MSB 0x56
+#define R_IA64_LTOFF_FPTR64LSB 0x57
+#define R_IA64_SEGREL32MSB 0x5c
+#define R_IA64_SEGREL32LSB 0x5d
+#define R_IA64_SEGREL64MSB 0x5e
+#define R_IA64_SEGREL64LSB 0x5f
+#define R_IA64_SECREL32MSB 0x64
+#define R_IA64_SECREL32LSB 0x65
+#define R_IA64_SECREL64MSB 0x66
+#define R_IA64_SECREL64LSB 0x67
+#define R_IA64_REL32MSB 0x6c
+#define R_IA64_REL32LSB 0x6d
+#define R_IA64_REL64MSB 0x6e
+#define R_IA64_REL64LSB 0x6f
+#define R_IA64_LTV32MSB 0x74
+#define R_IA64_LTV32LSB 0x75
+#define R_IA64_LTV64MSB 0x76
+#define R_IA64_LTV64LSB 0x77
+#define R_IA64_PCREL21BI 0x79
+#define R_IA64_PCREL22 0x7a
+#define R_IA64_PCREL64I 0x7b
+#define R_IA64_IPLTMSB 0x80
+#define R_IA64_IPLTLSB 0x81
+#define R_IA64_COPY 0x84
+#define R_IA64_SUB 0x85
+#define R_IA64_LTOFF22X 0x86
+#define R_IA64_LDXMOV 0x87
+#define R_IA64_TPREL14 0x91
+#define R_IA64_TPREL22 0x92
+#define R_IA64_TPREL64I 0x93
+#define R_IA64_TPREL64MSB 0x96
+#define R_IA64_TPREL64LSB 0x97
+#define R_IA64_LTOFF_TPREL22 0x9a
+#define R_IA64_DTPMOD64MSB 0xa6
+#define R_IA64_DTPMOD64LSB 0xa7
+#define R_IA64_LTOFF_DTPMOD22 0xaa
+#define R_IA64_DTPREL14 0xb1
+#define R_IA64_DTPREL22 0xb2
+#define R_IA64_DTPREL64I 0xb3
+#define R_IA64_DTPREL32MSB 0xb4
+#define R_IA64_DTPREL32LSB 0xb5
+#define R_IA64_DTPREL64MSB 0xb6
+#define R_IA64_DTPREL64LSB 0xb7
+#define R_IA64_LTOFF_DTPREL22 0xba
+
+#define R_SH_NONE 0
+#define R_SH_DIR32 1
+#define R_SH_REL32 2
+#define R_SH_DIR8WPN 3
+#define R_SH_IND12W 4
+#define R_SH_DIR8WPL 5
+#define R_SH_DIR8WPZ 6
+#define R_SH_DIR8BP 7
+#define R_SH_DIR8W 8
+#define R_SH_DIR8L 9
+#define R_SH_SWITCH16 25
+#define R_SH_SWITCH32 26
+#define R_SH_USES 27
+#define R_SH_COUNT 28
+#define R_SH_ALIGN 29
+#define R_SH_CODE 30
+#define R_SH_DATA 31
+#define R_SH_LABEL 32
+#define R_SH_SWITCH8 33
+#define R_SH_GNU_VTINHERIT 34
+#define R_SH_GNU_VTENTRY 35
+#define R_SH_TLS_GD_32 144
+#define R_SH_TLS_LD_32 145
+#define R_SH_TLS_LDO_32 146
+#define R_SH_TLS_IE_32 147
+#define R_SH_TLS_LE_32 148
+#define R_SH_TLS_DTPMOD32 149
+#define R_SH_TLS_DTPOFF32 150
+#define R_SH_TLS_TPOFF32 151
+#define R_SH_GOT32 160
+#define R_SH_PLT32 161
+#define R_SH_COPY 162
+#define R_SH_GLOB_DAT 163
+#define R_SH_JMP_SLOT 164
+#define R_SH_RELATIVE 165
+#define R_SH_GOTOFF 166
+#define R_SH_GOTPC 167
+#define R_SH_GOT20 201
+#define R_SH_GOTOFF20 202
+#define R_SH_GOTFUNCDESC 203
+#define R_SH_GOTFUNCDEST20 204
+#define R_SH_GOTOFFFUNCDESC 205
+#define R_SH_GOTOFFFUNCDEST20 206
+#define R_SH_FUNCDESC 207
+#define R_SH_FUNCDESC_VALUE 208
+
+#define R_SH_NUM 256
+
+#define R_390_NONE 0
+#define R_390_8 1
+#define R_390_12 2
+#define R_390_16 3
+#define R_390_32 4
+#define R_390_PC32 5
+#define R_390_GOT12 6
+#define R_390_GOT32 7
+#define R_390_PLT32 8
+#define R_390_COPY 9
+#define R_390_GLOB_DAT 10
+#define R_390_JMP_SLOT 11
+#define R_390_RELATIVE 12
+#define R_390_GOTOFF32 13
+#define R_390_GOTPC 14
+#define R_390_GOT16 15
+#define R_390_PC16 16
+#define R_390_PC16DBL 17
+#define R_390_PLT16DBL 18
+#define R_390_PC32DBL 19
+#define R_390_PLT32DBL 20
+#define R_390_GOTPCDBL 21
+#define R_390_64 22
+#define R_390_PC64 23
+#define R_390_GOT64 24
+#define R_390_PLT64 25
+#define R_390_GOTENT 26
+#define R_390_GOTOFF16 27
+#define R_390_GOTOFF64 28
+#define R_390_GOTPLT12 29
+#define R_390_GOTPLT16 30
+#define R_390_GOTPLT32 31
+#define R_390_GOTPLT64 32
+#define R_390_GOTPLTENT 33
+#define R_390_PLTOFF16 34
+#define R_390_PLTOFF32 35
+#define R_390_PLTOFF64 36
+#define R_390_TLS_LOAD 37
+#define R_390_TLS_GDCALL 38
+
+#define R_390_TLS_LDCALL 39
+
+#define R_390_TLS_GD32 40
+
+#define R_390_TLS_GD64 41
+
+#define R_390_TLS_GOTIE12 42
+
+#define R_390_TLS_GOTIE32 43
+
+#define R_390_TLS_GOTIE64 44
+
+#define R_390_TLS_LDM32 45
+
+#define R_390_TLS_LDM64 46
+
+#define R_390_TLS_IE32 47
+
+#define R_390_TLS_IE64 48
+
+#define R_390_TLS_IEENT 49
+
+#define R_390_TLS_LE32 50
+
+#define R_390_TLS_LE64 51
+
+#define R_390_TLS_LDO32 52
+
+#define R_390_TLS_LDO64 53
+
+#define R_390_TLS_DTPMOD 54
+#define R_390_TLS_DTPOFF 55
+#define R_390_TLS_TPOFF 56
+
+#define R_390_20 57
+#define R_390_GOT20 58
+#define R_390_GOTPLT20 59
+#define R_390_TLS_GOTIE20 60
+
+#define R_390_NUM 61
+
+#define R_CRIS_NONE 0
+#define R_CRIS_8 1
+#define R_CRIS_16 2
+#define R_CRIS_32 3
+#define R_CRIS_8_PCREL 4
+#define R_CRIS_16_PCREL 5
+#define R_CRIS_32_PCREL 6
+#define R_CRIS_GNU_VTINHERIT 7
+#define R_CRIS_GNU_VTENTRY 8
+#define R_CRIS_COPY 9
+#define R_CRIS_GLOB_DAT 10
+#define R_CRIS_JUMP_SLOT 11
+#define R_CRIS_RELATIVE 12
+#define R_CRIS_16_GOT 13
+#define R_CRIS_32_GOT 14
+#define R_CRIS_16_GOTPLT 15
+#define R_CRIS_32_GOTPLT 16
+#define R_CRIS_32_GOTREL 17
+#define R_CRIS_32_PLT_GOTREL 18
+#define R_CRIS_32_PLT_PCREL 19
+
+#define R_CRIS_NUM 20
+
+#define R_X86_64_NONE 0
+#define R_X86_64_64 1
+#define R_X86_64_PC32 2
+#define R_X86_64_GOT32 3
+#define R_X86_64_PLT32 4
+#define R_X86_64_COPY 5
+#define R_X86_64_GLOB_DAT 6
+#define R_X86_64_JUMP_SLOT 7
+#define R_X86_64_RELATIVE 8
+#define R_X86_64_GOTPCREL 9
+
+#define R_X86_64_32 10
+#define R_X86_64_32S 11
+#define R_X86_64_16 12
+#define R_X86_64_PC16 13
+#define R_X86_64_8 14
+#define R_X86_64_PC8 15
+#define R_X86_64_DTPMOD64 16
+#define R_X86_64_DTPOFF64 17
+#define R_X86_64_TPOFF64 18
+#define R_X86_64_TLSGD 19
+
+#define R_X86_64_TLSLD 20
+
+#define R_X86_64_DTPOFF32 21
+#define R_X86_64_GOTTPOFF 22
+
+#define R_X86_64_TPOFF32 23
+#define R_X86_64_PC64 24
+#define R_X86_64_GOTOFF64 25
+#define R_X86_64_GOTPC32 26
+#define R_X86_64_GOT64 27
+#define R_X86_64_GOTPCREL64 28
+#define R_X86_64_GOTPC64 29
+#define R_X86_64_GOTPLT64 30
+#define R_X86_64_PLTOFF64 31
+#define R_X86_64_SIZE32 32
+#define R_X86_64_SIZE64 33
+
+#define R_X86_64_GOTPC32_TLSDESC 34
+#define R_X86_64_TLSDESC_CALL 35
+
+#define R_X86_64_TLSDESC 36
+#define R_X86_64_IRELATIVE 37
+#define R_X86_64_RELATIVE64 38
+#define R_X86_64_NUM 39
+
+#define R_MN10300_NONE 0
+#define R_MN10300_32 1
+#define R_MN10300_16 2
+#define R_MN10300_8 3
+#define R_MN10300_PCREL32 4
+#define R_MN10300_PCREL16 5
+#define R_MN10300_PCREL8 6
+#define R_MN10300_GNU_VTINHERIT 7
+#define R_MN10300_GNU_VTENTRY 8
+#define R_MN10300_24 9
+#define R_MN10300_GOTPC32 10
+#define R_MN10300_GOTPC16 11
+#define R_MN10300_GOTOFF32 12
+#define R_MN10300_GOTOFF24 13
+#define R_MN10300_GOTOFF16 14
+#define R_MN10300_PLT32 15
+#define R_MN10300_PLT16 16
+#define R_MN10300_GOT32 17
+#define R_MN10300_GOT24 18
+#define R_MN10300_GOT16 19
+#define R_MN10300_COPY 20
+#define R_MN10300_GLOB_DAT 21
+#define R_MN10300_JMP_SLOT 22
+#define R_MN10300_RELATIVE 23
+
+#define R_MN10300_NUM 24
+
+#define R_M32R_NONE 0
+#define R_M32R_16 1
+#define R_M32R_32 2
+#define R_M32R_24 3
+#define R_M32R_10_PCREL 4
+#define R_M32R_18_PCREL 5
+#define R_M32R_26_PCREL 6
+#define R_M32R_HI16_ULO 7
+#define R_M32R_HI16_SLO 8
+#define R_M32R_LO16 9
+#define R_M32R_SDA16 10
+#define R_M32R_GNU_VTINHERIT 11
+#define R_M32R_GNU_VTENTRY 12
+
+#define R_M32R_16_RELA 33
+#define R_M32R_32_RELA 34
+#define R_M32R_24_RELA 35
+#define R_M32R_10_PCREL_RELA 36
+#define R_M32R_18_PCREL_RELA 37
+#define R_M32R_26_PCREL_RELA 38
+#define R_M32R_HI16_ULO_RELA 39
+#define R_M32R_HI16_SLO_RELA 40
+#define R_M32R_LO16_RELA 41
+#define R_M32R_SDA16_RELA 42
+#define R_M32R_RELA_GNU_VTINHERIT 43
+#define R_M32R_RELA_GNU_VTENTRY 44
+#define R_M32R_REL32 45
+
+#define R_M32R_GOT24 48
+#define R_M32R_26_PLTREL 49
+#define R_M32R_COPY 50
+#define R_M32R_GLOB_DAT 51
+#define R_M32R_JMP_SLOT 52
+#define R_M32R_RELATIVE 53
+#define R_M32R_GOTOFF 54
+#define R_M32R_GOTPC24 55
+#define R_M32R_GOT16_HI_ULO 56
+
+#define R_M32R_GOT16_HI_SLO 57
+
+#define R_M32R_GOT16_LO 58
+#define R_M32R_GOTPC_HI_ULO 59
+
+#define R_M32R_GOTPC_HI_SLO 60
+
+#define R_M32R_GOTPC_LO 61
+
+#define R_M32R_GOTOFF_HI_ULO 62
+
+#define R_M32R_GOTOFF_HI_SLO 63
+
+#define R_M32R_GOTOFF_LO 64
+#define R_M32R_NUM 256
+
+#define R_MICROBLAZE_NONE 0
+#define R_MICROBLAZE_32 1
+#define R_MICROBLAZE_32_PCREL 2
+#define R_MICROBLAZE_64_PCREL 3
+#define R_MICROBLAZE_32_PCREL_LO 4
+#define R_MICROBLAZE_64 5
+#define R_MICROBLAZE_32_LO 6
+#define R_MICROBLAZE_SRO32 7
+#define R_MICROBLAZE_SRW32 8
+#define R_MICROBLAZE_64_NONE 9
+#define R_MICROBLAZE_32_SYM_OP_SYM 10
+#define R_MICROBLAZE_GNU_VTINHERIT 11
+#define R_MICROBLAZE_GNU_VTENTRY 12
+#define R_MICROBLAZE_GOTPC_64 13
+#define R_MICROBLAZE_GOT_64 14
+#define R_MICROBLAZE_PLT_64 15
+#define R_MICROBLAZE_REL 16
+#define R_MICROBLAZE_JUMP_SLOT 17
+#define R_MICROBLAZE_GLOB_DAT 18
+#define R_MICROBLAZE_GOTOFF_64 19
+#define R_MICROBLAZE_GOTOFF_32 20
+#define R_MICROBLAZE_COPY 21
+#define R_MICROBLAZE_TLS 22
+#define R_MICROBLAZE_TLSGD 23
+#define R_MICROBLAZE_TLSLD 24
+#define R_MICROBLAZE_TLSDTPMOD32 25
+#define R_MICROBLAZE_TLSDTPREL32 26
+#define R_MICROBLAZE_TLSDTPREL64 27
+#define R_MICROBLAZE_TLSGOTTPREL32 28
+#define R_MICROBLAZE_TLSTPREL32 29
+
+#define R_OR1K_NONE 0
+#define R_OR1K_32 1
+#define R_OR1K_16 2
+#define R_OR1K_8 3
+#define R_OR1K_LO_16_IN_INSN 4
+#define R_OR1K_HI_16_IN_INSN 5
+#define R_OR1K_INSN_REL_26 6
+#define R_OR1K_GNU_VTENTRY 7
+#define R_OR1K_GNU_VTINHERIT 8
+#define R_OR1K_32_PCREL 9
+#define R_OR1K_16_PCREL 10
+#define R_OR1K_8_PCREL 11
+#define R_OR1K_GOTPC_HI16 12
+#define R_OR1K_GOTPC_LO16 13
+#define R_OR1K_GOT16 14
+#define R_OR1K_PLT26 15
+#define R_OR1K_GOTOFF_HI16 16
+#define R_OR1K_GOTOFF_LO16 17
+#define R_OR1K_COPY 18
+#define R_OR1K_GLOB_DAT 19
+#define R_OR1K_JMP_SLOT 20
+#define R_OR1K_RELATIVE 21
+#define R_OR1K_TLS_GD_HI16 22
+#define R_OR1K_TLS_GD_LO16 23
+#define R_OR1K_TLS_LDM_HI16 24
+#define R_OR1K_TLS_LDM_LO16 25
+#define R_OR1K_TLS_LDO_HI16 26
+#define R_OR1K_TLS_LDO_LO16 27
+#define R_OR1K_TLS_IE_HI16 28
+#define R_OR1K_TLS_IE_LO16 29
+#define R_OR1K_TLS_LE_HI16 30
+#define R_OR1K_TLS_LE_LO16 31
+#define R_OR1K_TLS_TPOFF 32
+#define R_OR1K_TLS_DTPOFF 33
+#define R_OR1K_TLS_DTPMOD 34
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_ELF_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/endian.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/endian.h
new file mode 100644
index 0000000..5ca6625
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/endian.h
@@ -0,0 +1,77 @@
+#ifndef SYSROOT_ENDIAN_H_
+#define SYSROOT_ENDIAN_H_
+
+#include <features.h>
+
+#define __LITTLE_ENDIAN 1234
+#define __BIG_ENDIAN 4321
+#define __PDP_ENDIAN 3412
+
+#if defined(__GNUC__) && defined(__BYTE_ORDER__)
+#define __BYTE_ORDER __BYTE_ORDER__
+#else
+#include <bits/endian.h>
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#define BIG_ENDIAN __BIG_ENDIAN
+#define LITTLE_ENDIAN __LITTLE_ENDIAN
+#define PDP_ENDIAN __PDP_ENDIAN
+#define BYTE_ORDER __BYTE_ORDER
+
+#include <stdint.h>
+
+static __inline uint16_t __bswap16(uint16_t __x) { return (uint16_t)(__x << 8 | __x >> 8); }
+
+static __inline uint32_t __bswap32(uint32_t __x) {
+ return (uint32_t)(__x >> 24 | ((__x >> 8) & 0xff00) | ((__x << 8) & 0xff0000) | __x << 24);
+}
+
+static __inline uint64_t __bswap64(uint64_t __x) {
+ return ((uint64_t)__bswap32((uint32_t)__x)) << 32 | (uint64_t)__bswap32((uint32_t)(__x >> 32));
+}
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define htobe16(x) __bswap16(x)
+#define be16toh(x) __bswap16(x)
+#define betoh16(x) __bswap16(x)
+#define htobe32(x) __bswap32(x)
+#define be32toh(x) __bswap32(x)
+#define betoh32(x) __bswap32(x)
+#define htobe64(x) __bswap64(x)
+#define be64toh(x) __bswap64(x)
+#define betoh64(x) __bswap64(x)
+#define htole16(x) (uint16_t)(x)
+#define le16toh(x) (uint16_t)(x)
+#define letoh16(x) (uint16_t)(x)
+#define htole32(x) (uint32_t)(x)
+#define le32toh(x) (uint32_t)(x)
+#define letoh32(x) (uint32_t)(x)
+#define htole64(x) (uint64_t)(x)
+#define le64toh(x) (uint64_t)(x)
+#define letoh64(x) (uint64_t)(x)
+#else
+#define htobe16(x) (uint16_t)(x)
+#define be16toh(x) (uint16_t)(x)
+#define betoh16(x) (uint16_t)(x)
+#define htobe32(x) (uint32_t)(x)
+#define be32toh(x) (uint32_t)(x)
+#define betoh32(x) (uint32_t)(x)
+#define htobe64(x) (uint64_t)(x)
+#define be64toh(x) (uint64_t)(x)
+#define betoh64(x) (uint64_t)(x)
+#define htole16(x) __bswap16(x)
+#define le16toh(x) __bswap16(x)
+#define letoh16(x) __bswap16(x)
+#define htole32(x) __bswap32(x)
+#define le32toh(x) __bswap32(x)
+#define letoh32(x) __bswap32(x)
+#define htole64(x) __bswap64(x)
+#define le64toh(x) __bswap64(x)
+#define letoh64(x) __bswap64(x)
+#endif
+
+#endif
+
+#endif // SYSROOT_ENDIAN_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/err.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/err.h
new file mode 100644
index 0000000..29842fe
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/err.h
@@ -0,0 +1,25 @@
+#ifndef SYSROOT_ERR_H_
+#define SYSROOT_ERR_H_
+
+#include <features.h>
+#include <stdarg.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void warn(const char*, ...);
+void vwarn(const char*, va_list);
+void warnx(const char*, ...);
+void vwarnx(const char*, va_list);
+
+_Noreturn void err(int, const char*, ...);
+_Noreturn void verr(int, const char*, va_list);
+_Noreturn void errx(int, const char*, ...);
+_Noreturn void verrx(int, const char*, va_list);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_ERR_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/errno.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/errno.h
new file mode 100644
index 0000000..af13f58
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/errno.h
@@ -0,0 +1,23 @@
+#ifndef SYSROOT_ERRNO_H_
+#define SYSROOT_ERRNO_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <bits/errno.h>
+
+int* __errno_location(void);
+#define errno (*__errno_location())
+
+#ifdef _GNU_SOURCE
+extern char *program_invocation_short_name, *program_invocation_name;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_ERRNO_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/fcntl.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/fcntl.h
new file mode 100644
index 0000000..e5e47bd
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/fcntl.h
@@ -0,0 +1,224 @@
+#ifndef SYSROOT_FCNTL_H_
+#define SYSROOT_FCNTL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_off_t
+#define __NEED_pid_t
+#define __NEED_mode_t
+
+#ifdef _GNU_SOURCE
+#define __NEED_size_t
+#define __NEED_ssize_t
+#define __NEED_struct_iovec
+#endif
+
+#include <bits/alltypes.h>
+
+struct flock {
+ short l_type;
+ short l_whence;
+ off_t l_start;
+ off_t l_len;
+ pid_t l_pid;
+};
+
+int creat(const char*, mode_t);
+int fcntl(int, int, ...);
+int open(const char*, int, ...);
+int openat(int, const char*, int, ...);
+int posix_fadvise(int, off_t, off_t, int);
+int posix_fallocate(int, off_t, off_t);
+
+#define O_SEARCH O_PATH
+#define O_EXEC O_PATH
+
+// clang-format off
+#define O_ACCMODE (03 | O_SEARCH)
+#define O_RDONLY 00
+#define O_WRONLY 01
+#define O_RDWR 02
+
+// Flags which align with ZXIO_FS_*
+// system/ulib/fdio/unistd.c asserts that these flags are aligned
+// with the ZXIO_FS_* versions.
+#define O_CREAT 0x00010000
+#define O_EXCL 0x00020000
+#define O_TRUNC 0x00040000
+#define O_DIRECTORY 0x00080000
+#define O_APPEND 0x00100000
+#define O_PATH 0x00400000
+#ifdef _ALL_SOURCE
+#define O_NOREMOTE 0x00200000
+#define O_ADMIN 0x00000004
+#endif
+
+// Flags which do not align with ZXIO_FS_*
+#define O_NONBLOCK 0x00000010
+#define O_DSYNC 0x00000020
+#define O_SYNC (0x00000040 | O_DSYNC)
+#define O_RSYNC O_SYNC
+#define O_NOFOLLOW 0x00000080
+#define O_CLOEXEC 0x00000100
+#define O_NOCTTY 0x00000200
+#define O_ASYNC 0x00000400
+#define O_DIRECT 0x00000800
+#define O_LARGEFILE 0x00001000
+#define O_NOATIME 0x00002000
+#define O_TMPFILE 0x00004000
+
+// clang-format on
+
+#define O_NDELAY O_NONBLOCK
+
+#define F_DUPFD 0
+#define F_GETFD 1
+#define F_SETFD 2
+#define F_GETFL 3
+#define F_SETFL 4
+
+#define F_GETLK 5
+#define F_SETLK 6
+#define F_SETLKW 7
+
+#define F_SETOWN 8
+#define F_GETOWN 9
+#define F_SETSIG 10
+#define F_GETSIG 11
+
+#define F_SETOWN_EX 15
+#define F_GETOWN_EX 16
+
+#define F_GETOWNER_UIDS 17
+
+#define F_OFD_GETLK 36
+#define F_OFD_SETLK 37
+#define F_OFD_SETLKW 38
+
+#define F_DUPFD_CLOEXEC 1030
+
+#define F_RDLCK 0
+#define F_WRLCK 1
+#define F_UNLCK 2
+
+#define FD_CLOEXEC 1
+
+#define AT_FDCWD (-100)
+#define AT_SYMLINK_NOFOLLOW 0x100
+#define AT_REMOVEDIR 0x200
+#define AT_SYMLINK_FOLLOW 0x400
+#define AT_EACCESS 0x200
+
+#define POSIX_FADV_NORMAL 0
+#define POSIX_FADV_RANDOM 1
+#define POSIX_FADV_SEQUENTIAL 2
+#define POSIX_FADV_WILLNEED 3
+#define POSIX_FADV_DONTNEED 4
+#define POSIX_FADV_NOREUSE 5
+
+#undef SEEK_SET
+#undef SEEK_CUR
+#undef SEEK_END
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
+#ifndef S_IRUSR
+#define S_ISUID 04000
+#define S_ISGID 02000
+#define S_ISVTX 01000
+#define S_IRUSR 0400
+#define S_IWUSR 0200
+#define S_IXUSR 0100
+#define S_IRWXU 0700
+#define S_IRGRP 0040
+#define S_IWGRP 0020
+#define S_IXGRP 0010
+#define S_IRWXG 0070
+#define S_IROTH 0004
+#define S_IWOTH 0002
+#define S_IXOTH 0001
+#define S_IRWXO 0007
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define AT_NO_AUTOMOUNT 0x800
+#define AT_EMPTY_PATH 0x1000
+
+#define FAPPEND O_APPEND
+#define FFSYNC O_FSYNC
+#define FASYNC O_ASYNC
+#define FNONBLOCK O_NONBLOCK
+#define FNDELAY O_NDELAY
+
+#define F_OK 0
+#define R_OK 4
+#define W_OK 2
+#define X_OK 1
+#define F_ULOCK 0
+#define F_LOCK 1
+#define F_TLOCK 2
+#define F_TEST 3
+
+#define F_SETLEASE 1024
+#define F_GETLEASE 1025
+#define F_NOTIFY 1026
+#define F_CANCELLK 1029
+#define F_SETPIPE_SZ 1031
+#define F_GETPIPE_SZ 1032
+#define F_ADD_SEALS 1033
+#define F_GET_SEALS 1034
+
+#define F_SEAL_SEAL 0x0001
+#define F_SEAL_SHRINK 0x0002
+#define F_SEAL_GROW 0x0004
+#define F_SEAL_WRITE 0x0008
+
+#define DN_ACCESS 0x00000001
+#define DN_MODIFY 0x00000002
+#define DN_CREATE 0x00000004
+#define DN_DELETE 0x00000008
+#define DN_RENAME 0x00000010
+#define DN_ATTRIB 0x00000020
+#define DN_MULTISHOT 0x80000000
+
+int lockf(int, int, off_t);
+#endif
+
+#if defined(_GNU_SOURCE)
+#define F_OWNER_TID 0
+#define F_OWNER_PID 1
+#define F_OWNER_PGRP 2
+#define F_OWNER_GID 2
+struct f_owner_ex {
+ int type;
+ pid_t pid;
+};
+#define FALLOC_FL_KEEP_SIZE 1
+#define FALLOC_FL_PUNCH_HOLE 2
+#define SYNC_FILE_RANGE_WAIT_BEFORE 1
+#define SYNC_FILE_RANGE_WRITE 2
+#define SYNC_FILE_RANGE_WAIT_AFTER 4
+#define SPLICE_F_MOVE 1
+#define SPLICE_F_NONBLOCK 2
+#define SPLICE_F_MORE 4
+#define SPLICE_F_GIFT 8
+int fallocate(int, int, off_t, off_t);
+#define fallocate64 fallocate
+ssize_t readahead(int, off_t, size_t);
+int sync_file_range(int, off_t, off_t, unsigned);
+ssize_t vmsplice(int, const struct iovec*, size_t, unsigned);
+ssize_t splice(int, off_t*, int, off_t*, size_t, unsigned);
+ssize_t tee(int, int, size_t, unsigned);
+#define loff_t off_t
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_FCNTL_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/features.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/features.h
new file mode 100644
index 0000000..1520efb
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/features.h
@@ -0,0 +1,35 @@
+#ifndef SYSROOT_FEATURES_H_
+#define SYSROOT_FEATURES_H_
+
+#if defined(_ALL_SOURCE) && !defined(_GNU_SOURCE)
+#define _GNU_SOURCE 1
+#endif
+
+#if !defined(_BSD_SOURCE)
+#define _BSD_SOURCE 1
+#endif
+
+#if !defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE) && \
+ !defined(_GNU_SOURCE) && !defined(_BSD_SOURCE) && !defined(__STRICT_ANSI__)
+#define _BSD_SOURCE 1
+#define _XOPEN_SOURCE 700
+#endif
+
+#if __STDC_VERSION__ >= 199901L
+#define __restrict restrict
+#elif !defined(__GNUC__)
+#define __restrict
+#endif
+
+#if __STDC_VERSION__ >= 199901L || defined(__cplusplus)
+#define __inline inline
+#endif
+
+#if __STDC_VERSION__ >= 201112L
+#elif defined(__GNUC__)
+#define _Noreturn __attribute__((__noreturn__))
+#else
+#define _Noreturn
+#endif
+
+#endif // SYSROOT_FEATURES_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/fenv.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/fenv.h
new file mode 100644
index 0000000..391f59f
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/fenv.h
@@ -0,0 +1,28 @@
+#ifndef SYSROOT_FENV_H_
+#define SYSROOT_FENV_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <bits/fenv.h>
+
+int feclearexcept(int);
+int fegetexceptflag(fexcept_t*, int);
+int feraiseexcept(int);
+int fesetexceptflag(const fexcept_t*, int);
+int fetestexcept(int);
+
+int fegetround(void);
+int fesetround(int);
+
+int fegetenv(fenv_t*);
+int feholdexcept(fenv_t*);
+int fesetenv(const fenv_t*);
+int feupdateenv(const fenv_t*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_FENV_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/fmtmsg.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/fmtmsg.h
new file mode 100644
index 0000000..51abcc5
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/fmtmsg.h
@@ -0,0 +1,47 @@
+#ifndef SYSROOT_FMTMSG_H_
+#define SYSROOT_FMTMSG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MM_HARD 1
+#define MM_SOFT 2
+#define MM_FIRM 4
+
+#define MM_APPL 8
+#define MM_UTIL 16
+#define MM_OPSYS 32
+
+#define MM_RECOVER 64
+#define MM_NRECOV 128
+
+#define MM_PRINT 256
+#define MM_CONSOLE 512
+
+#define MM_NULLMC 0L
+
+#define MM_HALT 1
+#define MM_ERROR 2
+#define MM_WARNING 3
+#define MM_INFO 4
+#define MM_NOSEV 0
+
+#define MM_OK 0
+#define MM_NOTOK (-1)
+#define MM_NOMSG 1
+#define MM_NOCON 4
+
+#define MM_NULLLBL ((char*)0)
+#define MM_NULLTXT ((char*)0)
+#define MM_NULLACT ((char*)0)
+#define MM_NULLTAG ((char*)0)
+#define MM_NULLSEV 0
+
+int fmtmsg(long, const char*, int, const char*, const char*, const char*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_FMTMSG_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/fnmatch.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/fnmatch.h
new file mode 100644
index 0000000..2e0f6cc
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/fnmatch.h
@@ -0,0 +1,24 @@
+#ifndef SYSROOT_FNMATCH_H_
+#define SYSROOT_FNMATCH_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define FNM_PATHNAME 0x1
+#define FNM_NOESCAPE 0x2
+#define FNM_PERIOD 0x4
+#define FNM_LEADING_DIR 0x8
+#define FNM_CASEFOLD 0x10
+#define FNM_FILE_NAME FNM_PATHNAME
+
+#define FNM_NOMATCH 1
+#define FNM_NOSYS (-1)
+
+int fnmatch(const char*, const char*, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_FNMATCH_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/getopt.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/getopt.h
new file mode 100644
index 0000000..bcc632d
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/getopt.h
@@ -0,0 +1,30 @@
+#ifndef SYSROOT_GETOPT_H_
+#define SYSROOT_GETOPT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int getopt(int, char* const[], const char*);
+extern char* optarg;
+extern int optind, opterr, optopt, optreset;
+
+struct option {
+ const char* name;
+ int has_arg;
+ int* flag;
+ int val;
+};
+
+int getopt_long(int, char* const*, const char*, const struct option*, int*);
+int getopt_long_only(int, char* const*, const char*, const struct option*, int*);
+
+#define no_argument 0
+#define required_argument 1
+#define optional_argument 2
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_GETOPT_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/glob.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/glob.h
new file mode 100644
index 0000000..98ff3f6
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/glob.h
@@ -0,0 +1,43 @@
+#ifndef SYSROOT_GLOB_H_
+#define SYSROOT_GLOB_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+typedef struct {
+ size_t gl_pathc;
+ char** gl_pathv;
+ size_t gl_offs;
+ int __dummy1;
+ void* __dummy2[5];
+} glob_t;
+
+int glob(const char* __restrict, int, int (*)(const char*, int), glob_t* __restrict);
+void globfree(glob_t*);
+
+#define GLOB_ERR 0x01
+#define GLOB_MARK 0x02
+#define GLOB_NOSORT 0x04
+#define GLOB_DOOFFS 0x08
+#define GLOB_NOCHECK 0x10
+#define GLOB_APPEND 0x20
+#define GLOB_NOESCAPE 0x40
+#define GLOB_PERIOD 0x80
+
+#define GLOB_NOSPACE 1
+#define GLOB_ABORTED 2
+#define GLOB_NOMATCH 3
+#define GLOB_NOSYS 4
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_GLOB_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/grp.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/grp.h
new file mode 100644
index 0000000..4cfdd08
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/grp.h
@@ -0,0 +1,51 @@
+#ifndef SYSROOT_GRP_H_
+#define SYSROOT_GRP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+#define __NEED_gid_t
+
+#ifdef _GNU_SOURCE
+#define __NEED_FILE
+#endif
+
+#include <bits/alltypes.h>
+
+struct group {
+ char* gr_name;
+ char* gr_passwd;
+ gid_t gr_gid;
+ char** gr_mem;
+};
+
+struct group* getgrgid(gid_t);
+struct group* getgrnam(const char*);
+
+int getgrgid_r(gid_t, struct group*, char*, size_t, struct group**);
+int getgrnam_r(const char*, struct group*, char*, size_t, struct group**);
+
+struct group* getgrent(void);
+void endgrent(void);
+void setgrent(void);
+
+#ifdef _GNU_SOURCE
+struct group* fgetgrent(FILE* stream);
+int putgrent(const struct group*, FILE*);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+int getgrouplist(const char*, gid_t, gid_t*, int*);
+int setgroups(size_t, const gid_t*);
+int initgroups(const char*, gid_t);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_GRP_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/iconv.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/iconv.h
new file mode 100644
index 0000000..c0c056b
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/iconv.h
@@ -0,0 +1,24 @@
+#ifndef SYSROOT_ICONV_H_
+#define SYSROOT_ICONV_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+typedef void* iconv_t;
+
+iconv_t iconv_open(const char*, const char*);
+size_t iconv(iconv_t, char** __restrict, size_t* __restrict, char** __restrict, size_t* __restrict);
+int iconv_close(iconv_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_ICONV_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/ifaddrs.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/ifaddrs.h
new file mode 100644
index 0000000..908945e
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/ifaddrs.h
@@ -0,0 +1,34 @@
+#ifndef SYSROOT_IFADDRS_H_
+#define SYSROOT_IFADDRS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+
+struct ifaddrs {
+ struct ifaddrs* ifa_next;
+ char* ifa_name;
+ unsigned ifa_flags;
+ struct sockaddr* ifa_addr;
+ struct sockaddr* ifa_netmask;
+ union {
+ struct sockaddr* ifu_broadaddr;
+ struct sockaddr* ifu_dstaddr;
+ } ifa_ifu;
+ void* ifa_data;
+};
+#define ifa_broadaddr ifa_ifu.ifu_broadaddr
+#define ifa_dstaddr ifa_ifu.ifu_dstaddr
+
+void freeifaddrs(struct ifaddrs* ifp);
+int getifaddrs(struct ifaddrs** ifap);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_IFADDRS_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/inttypes.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/inttypes.h
new file mode 100644
index 0000000..43bf604
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/inttypes.h
@@ -0,0 +1,356 @@
+#ifndef SYSROOT_INTTYPES_H_
+#define SYSROOT_INTTYPES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#define __NEED_wchar_t
+#include <bits/alltypes.h>
+
+typedef struct {
+ intmax_t quot, rem;
+} imaxdiv_t;
+
+intmax_t imaxabs(intmax_t);
+imaxdiv_t imaxdiv(intmax_t, intmax_t);
+
+intmax_t strtoimax(const char* __restrict, char** __restrict, int);
+uintmax_t strtoumax(const char* __restrict, char** __restrict, int);
+
+intmax_t wcstoimax(const wchar_t* __restrict, wchar_t** __restrict, int);
+uintmax_t wcstoumax(const wchar_t* __restrict, wchar_t** __restrict, int);
+
+// Clang predefines macros __<type>_FMT<letter>__ for each type,
+// with <letter> being i and for signed types, and o, u, x, and X
+// for unsigned types. That lets <inttypes.h> do its work without
+// any special knowledge of what the underlying types are.
+// Unfortunately, GCC does not define these macros.
+#ifndef __INTMAX_FMTd__
+
+#define __INT8_FMT_MODIFIER__ "hh"
+#define __INT16_FMT_MODIFIER__ "h"
+#define __INT32_FMT_MODIFIER__ ""
+
+#define __INT_LEAST8_FMT_MODIFIER__ __INT8_FMT_MODIFIER__
+#define __INT_LEAST16_FMT_MODIFIER__ __INT16_FMT_MODIFIER__
+#define __INT_LEAST32_FMT_MODIFIER__ __INT32_FMT_MODIFIER__
+#define __INT_LEAST64_FMT_MODIFIER__ __INT64_FMT_MODIFIER__
+
+// The *-elf and arm-eabi GCC targets use 'int' for the fast{8,16,32}
+// types. On LP64 systems, 'long' is used for the fast64 type.
+#define __INT_FAST8_FMT_MODIFIER__ ""
+#define __INT_FAST16_FMT_MODIFIER__ ""
+#define __INT_FAST32_FMT_MODIFIER__ ""
+#define __INT_FAST64_FMT_MODIFIER__ "l"
+
+// On machines where 'long' types are 64 bits, the compiler defines
+// __INT64_TYPE__ et al using 'long', not 'long long', though both are
+// 64-bit types.
+#define __INT64_FMT_MODIFIER__ "l"
+#define __INTPTR_FMT_MODIFIER__ "l"
+
+#define __INTMAX_FMT_MODIFIER__ __INT64_FMT_MODIFIER__
+
+#define __INTMAX_FMTd__ __INTMAX_FMT_MODIFIER__ "d"
+#define __INTMAX_FMTi__ __INTMAX_FMT_MODIFIER__ "i"
+#define __UINTMAX_FMTo__ __INTMAX_FMT_MODIFIER__ "o"
+#define __UINTMAX_FMTu__ __INTMAX_FMT_MODIFIER__ "u"
+#define __UINTMAX_FMTx__ __INTMAX_FMT_MODIFIER__ "x"
+#define __UINTMAX_FMTX__ __INTMAX_FMT_MODIFIER__ "X"
+#define __INTPTR_FMTd__ __INTPTR_FMT_MODIFIER__ "d"
+#define __INTPTR_FMTi__ __INTPTR_FMT_MODIFIER__ "i"
+#define __UINTPTR_FMTo__ __INTPTR_FMT_MODIFIER__ "o"
+#define __UINTPTR_FMTu__ __INTPTR_FMT_MODIFIER__ "u"
+#define __UINTPTR_FMTx__ __INTPTR_FMT_MODIFIER__ "x"
+#define __UINTPTR_FMTX__ __INTPTR_FMT_MODIFIER__ "X"
+#define __INT8_FMTd__ __INT8_FMT_MODIFIER__ "d"
+#define __INT8_FMTi__ __INT8_FMT_MODIFIER__ "i"
+#define __INT16_FMTd__ __INT16_FMT_MODIFIER__ "d"
+#define __INT16_FMTi__ __INT16_FMT_MODIFIER__ "i"
+#define __INT32_FMTd__ __INT32_FMT_MODIFIER__ "d"
+#define __INT32_FMTi__ __INT32_FMT_MODIFIER__ "i"
+#define __INT64_FMTd__ __INT64_FMT_MODIFIER__ "d"
+#define __INT64_FMTi__ __INT64_FMT_MODIFIER__ "i"
+#define __UINT8_FMTo__ __INT8_FMT_MODIFIER__ "o"
+#define __UINT8_FMTu__ __INT8_FMT_MODIFIER__ "u"
+#define __UINT8_FMTx__ __INT8_FMT_MODIFIER__ "x"
+#define __UINT8_FMTX__ __INT8_FMT_MODIFIER__ "X"
+#define __UINT16_FMTo__ __INT16_FMT_MODIFIER__ "o"
+#define __UINT16_FMTu__ __INT16_FMT_MODIFIER__ "u"
+#define __UINT16_FMTx__ __INT16_FMT_MODIFIER__ "x"
+#define __UINT16_FMTX__ __INT16_FMT_MODIFIER__ "X"
+#define __UINT32_FMTo__ __INT32_FMT_MODIFIER__ "o"
+#define __UINT32_FMTu__ __INT32_FMT_MODIFIER__ "u"
+#define __UINT32_FMTx__ __INT32_FMT_MODIFIER__ "x"
+#define __UINT32_FMTX__ __INT32_FMT_MODIFIER__ "X"
+#define __UINT64_FMTo__ __INT64_FMT_MODIFIER__ "o"
+#define __UINT64_FMTu__ __INT64_FMT_MODIFIER__ "u"
+#define __UINT64_FMTx__ __INT64_FMT_MODIFIER__ "x"
+#define __UINT64_FMTX__ __INT64_FMT_MODIFIER__ "X"
+#define __INT_LEAST8_FMTd__ __INT_LEAST8_FMT_MODIFIER__ "d"
+#define __INT_LEAST8_FMTi__ __INT_LEAST8_FMT_MODIFIER__ "i"
+#define __UINT_LEAST8_FMTo__ __INT_LEAST8_FMT_MODIFIER__ "o"
+#define __UINT_LEAST8_FMTu__ __INT_LEAST8_FMT_MODIFIER__ "u"
+#define __UINT_LEAST8_FMTx__ __INT_LEAST8_FMT_MODIFIER__ "x"
+#define __UINT_LEAST8_FMTX__ __INT_LEAST8_FMT_MODIFIER__ "X"
+#define __INT_LEAST16_FMTd__ __INT_LEAST16_FMT_MODIFIER__ "d"
+#define __INT_LEAST16_FMTi__ __INT_LEAST16_FMT_MODIFIER__ "i"
+#define __UINT_LEAST16_FMTo__ __INT_LEAST16_FMT_MODIFIER__ "o"
+#define __UINT_LEAST16_FMTu__ __INT_LEAST16_FMT_MODIFIER__ "u"
+#define __UINT_LEAST16_FMTx__ __INT_LEAST16_FMT_MODIFIER__ "x"
+#define __UINT_LEAST16_FMTX__ __INT_LEAST16_FMT_MODIFIER__ "X"
+#define __INT_LEAST32_FMTd__ __INT_LEAST32_FMT_MODIFIER__ "d"
+#define __INT_LEAST32_FMTi__ __INT_LEAST32_FMT_MODIFIER__ "i"
+#define __UINT_LEAST32_FMTo__ __INT_LEAST32_FMT_MODIFIER__ "o"
+#define __UINT_LEAST32_FMTu__ __INT_LEAST32_FMT_MODIFIER__ "u"
+#define __UINT_LEAST32_FMTx__ __INT_LEAST32_FMT_MODIFIER__ "x"
+#define __UINT_LEAST32_FMTX__ __INT_LEAST32_FMT_MODIFIER__ "X"
+#define __INT_LEAST64_FMTd__ __INT_LEAST64_FMT_MODIFIER__ "d"
+#define __INT_LEAST64_FMTi__ __INT_LEAST64_FMT_MODIFIER__ "i"
+#define __UINT_LEAST64_FMTo__ __INT_LEAST64_FMT_MODIFIER__ "o"
+#define __UINT_LEAST64_FMTu__ __INT_LEAST64_FMT_MODIFIER__ "u"
+#define __UINT_LEAST64_FMTx__ __INT_LEAST64_FMT_MODIFIER__ "x"
+#define __UINT_LEAST64_FMTX__ __INT_LEAST64_FMT_MODIFIER__ "X"
+#define __INT_FAST8_FMTd__ __INT_FAST8_FMT_MODIFIER__ "d"
+#define __INT_FAST8_FMTi__ __INT_FAST8_FMT_MODIFIER__ "i"
+#define __UINT_FAST8_FMTo__ __INT_FAST8_FMT_MODIFIER__ "o"
+#define __UINT_FAST8_FMTu__ __INT_FAST8_FMT_MODIFIER__ "u"
+#define __UINT_FAST8_FMTx__ __INT_FAST8_FMT_MODIFIER__ "x"
+#define __UINT_FAST8_FMTX__ __INT_FAST8_FMT_MODIFIER__ "X"
+#define __INT_FAST16_FMTd__ __INT_FAST16_FMT_MODIFIER__ "d"
+#define __INT_FAST16_FMTi__ __INT_FAST16_FMT_MODIFIER__ "i"
+#define __UINT_FAST16_FMTo__ __INT_FAST16_FMT_MODIFIER__ "o"
+#define __UINT_FAST16_FMTu__ __INT_FAST16_FMT_MODIFIER__ "u"
+#define __UINT_FAST16_FMTx__ __INT_FAST16_FMT_MODIFIER__ "x"
+#define __UINT_FAST16_FMTX__ __INT_FAST16_FMT_MODIFIER__ "X"
+#define __INT_FAST32_FMTd__ __INT_FAST32_FMT_MODIFIER__ "d"
+#define __INT_FAST32_FMTi__ __INT_FAST32_FMT_MODIFIER__ "i"
+#define __UINT_FAST32_FMTo__ __INT_FAST32_FMT_MODIFIER__ "o"
+#define __UINT_FAST32_FMTu__ __INT_FAST32_FMT_MODIFIER__ "u"
+#define __UINT_FAST32_FMTx__ __INT_FAST32_FMT_MODIFIER__ "x"
+#define __UINT_FAST32_FMTX__ __INT_FAST32_FMT_MODIFIER__ "X"
+#define __INT_FAST64_FMTd__ __INT_FAST64_FMT_MODIFIER__ "d"
+#define __INT_FAST64_FMTi__ __INT_FAST64_FMT_MODIFIER__ "i"
+#define __UINT_FAST64_FMTo__ __INT_FAST64_FMT_MODIFIER__ "o"
+#define __UINT_FAST64_FMTu__ __INT_FAST64_FMT_MODIFIER__ "u"
+#define __UINT_FAST64_FMTx__ __INT_FAST64_FMT_MODIFIER__ "x"
+#define __UINT_FAST64_FMTX__ __INT_FAST64_FMT_MODIFIER__ "X"
+
+#endif
+
+#define PRId8 __INT8_FMTd__
+#define PRId16 __INT16_FMTd__
+#define PRId32 __INT32_FMTd__
+#define PRId64 __INT64_FMTd__
+
+#define PRIdLEAST8 __INT_LEAST8_FMTd__
+#define PRIdLEAST16 __INT_LEAST16_FMTd__
+#define PRIdLEAST32 __INT_LEAST32_FMTd__
+#define PRIdLEAST64 __INT_LEAST64_FMTd__
+
+#define PRIdFAST8 __INT_FAST8_FMTd__
+#define PRIdFAST16 __INT_FAST16_FMTd__
+#define PRIdFAST32 __INT_FAST32_FMTd__
+#define PRIdFAST64 __INT_FAST64_FMTd__
+
+#define PRIi8 __INT8_FMTi__
+#define PRIi16 __INT16_FMTi__
+#define PRIi32 __INT32_FMTi__
+#define PRIi64 __INT64_FMTi__
+
+#define PRIiLEAST8 __INT_LEAST8_FMTi__
+#define PRIiLEAST16 __INT_LEAST16_FMTi__
+#define PRIiLEAST32 __INT_LEAST32_FMTi__
+#define PRIiLEAST64 __INT_LEAST64_FMTi__
+
+#define PRIiFAST8 __INT_FAST8_FMTi__
+#define PRIiFAST16 __INT_FAST16_FMTi__
+#define PRIiFAST32 __INT_FAST32_FMTi__
+#define PRIiFAST64 __INT_FAST64_FMTi__
+
+#define PRIo8 __UINT8_FMTo__
+#define PRIo16 __UINT16_FMTo__
+#define PRIo32 __UINT32_FMTo__
+#define PRIo64 __UINT64_FMTo__
+
+#define PRIoLEAST8 __UINT_LEAST8_FMTo__
+#define PRIoLEAST16 __UINT_LEAST16_FMTo__
+#define PRIoLEAST32 __UINT_LEAST32_FMTo__
+#define PRIoLEAST64 __UINT_LEAST64_FMTo__
+
+#define PRIoFAST8 __UINT_FAST8_FMTo__
+#define PRIoFAST16 __UINT_FAST16_FMTo__
+#define PRIoFAST32 __UINT_FAST32_FMTo__
+#define PRIoFAST64 __UINT_FAST64_FMTo__
+
+#define PRIu8 __UINT8_FMTu__
+#define PRIu16 __UINT16_FMTu__
+#define PRIu32 __UINT32_FMTu__
+#define PRIu64 __UINT64_FMTu__
+
+#define PRIuLEAST8 __UINT_LEAST8_FMTu__
+#define PRIuLEAST16 __UINT_LEAST16_FMTu__
+#define PRIuLEAST32 __UINT_LEAST32_FMTu__
+#define PRIuLEAST64 __UINT_LEAST64_FMTu__
+
+#define PRIuFAST8 __UINT_FAST8_FMTu__
+#define PRIuFAST16 __UINT_FAST16_FMTu__
+#define PRIuFAST32 __UINT_FAST32_FMTu__
+#define PRIuFAST64 __UINT_FAST64_FMTu__
+
+#define PRIx8 __UINT8_FMTx__
+#define PRIx16 __UINT16_FMTx__
+#define PRIx32 __UINT32_FMTx__
+#define PRIx64 __UINT64_FMTx__
+
+#define PRIxLEAST8 __UINT_LEAST8_FMTx__
+#define PRIxLEAST16 __UINT_LEAST16_FMTx__
+#define PRIxLEAST32 __UINT_LEAST32_FMTx__
+#define PRIxLEAST64 __UINT_LEAST64_FMTx__
+
+#define PRIxFAST8 __UINT_FAST8_FMTx__
+#define PRIxFAST16 __UINT_FAST16_FMTx__
+#define PRIxFAST32 __UINT_FAST32_FMTx__
+#define PRIxFAST64 __UINT_FAST64_FMTx__
+
+#define PRIX8 __UINT8_FMTX__
+#define PRIX16 __UINT16_FMTX__
+#define PRIX32 __UINT32_FMTX__
+#define PRIX64 __UINT64_FMTX__
+
+#define PRIXLEAST8 __UINT_LEAST8_FMTX__
+#define PRIXLEAST16 __UINT_LEAST16_FMTX__
+#define PRIXLEAST32 __UINT_LEAST32_FMTX__
+#define PRIXLEAST64 __UINT_LEAST64_FMTX__
+
+#define PRIXFAST8 __UINT_FAST8_FMTX__
+#define PRIXFAST16 __UINT_FAST16_FMTX__
+#define PRIXFAST32 __UINT_FAST32_FMTX__
+#define PRIXFAST64 __UINT_FAST64_FMTX__
+
+#define PRIdMAX __INTMAX_FMTd__
+#define PRIiMAX __INTMAX_FMTi__
+#define PRIoMAX __UINTMAX_FMTo__
+#define PRIuMAX __UINTMAX_FMTu__
+#define PRIxMAX __UINTMAX_FMTx__
+#define PRIXMAX __UINTMAX_FMTX__
+
+#define PRIdPTR __INTPTR_FMTd__
+#define PRIiPTR __INTPTR_FMTi__
+#define PRIoPTR __UINTPTR_FMTo__
+#define PRIuPTR __UINTPTR_FMTu__
+#define PRIxPTR __UINTPTR_FMTx__
+#define PRIXPTR __UINTPTR_FMTX__
+
+#define SCNd8 __INT8_FMTd__
+#define SCNd16 __INT16_FMTd__
+#define SCNd32 __INT32_FMTd__
+#define SCNd64 __INT64_FMTd__
+
+#define SCNdLEAST8 __INT_LEAST8_FMTd__
+#define SCNdLEAST16 __INT_LEAST16_FMTd__
+#define SCNdLEAST32 __INT_LEAST32_FMTd__
+#define SCNdLEAST64 __INT_LEAST64_FMTd__
+
+#define SCNdFAST8 __INT_FAST8_FMTd__
+#define SCNdFAST16 __INT_FAST16_FMTd__
+#define SCNdFAST32 __INT_FAST32_FMTd__
+#define SCNdFAST64 __INT_FAST64_FMTd__
+
+#define SCNi8 __INT8_FMTi__
+#define SCNi16 __INT16_FMTi__
+#define SCNi32 __INT32_FMTi__
+#define SCNi64 __INT64_FMTi__
+
+#define SCNiLEAST8 __INT_LEAST8_FMTi__
+#define SCNiLEAST16 __INT_LEAST16_FMTi__
+#define SCNiLEAST32 __INT_LEAST32_FMTi__
+#define SCNiLEAST64 __INT_LEAST64_FMTi__
+
+#define SCNiFAST8 __INT_FAST8_FMTi__
+#define SCNiFAST16 __INT_FAST16_FMTi__
+#define SCNiFAST32 __INT_FAST32_FMTi__
+#define SCNiFAST64 __INT_FAST64_FMTi__
+
+#define SCNo8 __UINT8_FMTo__
+#define SCNo16 __UINT16_FMTo__
+#define SCNo32 __UINT32_FMTo__
+#define SCNo64 __UINT64_FMTo__
+
+#define SCNoLEAST8 __UINT_LEAST8_FMTo__
+#define SCNoLEAST16 __UINT_LEAST16_FMTo__
+#define SCNoLEAST32 __UINT_LEAST32_FMTo__
+#define SCNoLEAST64 __UINT_LEAST64_FMTo__
+
+#define SCNoFAST8 __UINT_FAST8_FMTo__
+#define SCNoFAST16 __UINT_FAST16_FMTo__
+#define SCNoFAST32 __UINT_FAST32_FMTo__
+#define SCNoFAST64 __UINT_FAST64_FMTo__
+
+#define SCNu8 __UINT8_FMTu__
+#define SCNu16 __UINT16_FMTu__
+#define SCNu32 __UINT32_FMTu__
+#define SCNu64 __UINT64_FMTu__
+
+#define SCNuLEAST8 __UINT_LEAST8_FMTu__
+#define SCNuLEAST16 __UINT_LEAST16_FMTu__
+#define SCNuLEAST32 __UINT_LEAST32_FMTu__
+#define SCNuLEAST64 __UINT_LEAST64_FMTu__
+
+#define SCNuFAST8 __UINT_FAST8_FMTu__
+#define SCNuFAST16 __UINT_FAST16_FMTu__
+#define SCNuFAST32 __UINT_FAST32_FMTu__
+#define SCNuFAST64 __UINT_FAST64_FMTu__
+
+#define SCNx8 __UINT8_FMTx__
+#define SCNx16 __UINT16_FMTx__
+#define SCNx32 __UINT32_FMTx__
+#define SCNx64 __UINT64_FMTx__
+
+#define SCNxLEAST8 __UINT_LEAST8_FMTx__
+#define SCNxLEAST16 __UINT_LEAST16_FMTx__
+#define SCNxLEAST32 __UINT_LEAST32_FMTx__
+#define SCNxLEAST64 __UINT_LEAST64_FMTx__
+
+#define SCNxFAST8 __UINT_FAST8_FMTx__
+#define SCNxFAST16 __UINT_FAST16_FMTx__
+#define SCNxFAST32 __UINT_FAST32_FMTx__
+#define SCNxFAST64 __UINT_FAST64_FMTx__
+
+#define SCNX8 __UINT8_FMTX__
+#define SCNX16 __UINT16_FMTX__
+#define SCNX32 __UINT32_FMTX__
+#define SCNX64 __UINT64_FMTX__
+
+#define SCNXLEAST8 __UINT_LEAST8_FMTX__
+#define SCNXLEAST16 __UINT_LEAST16_FMTX__
+#define SCNXLEAST32 __UINT_LEAST32_FMTX__
+#define SCNXLEAST64 __UINT_LEAST64_FMTX__
+
+#define SCNXFAST8 __UINT_FAST8_FMTX__
+#define SCNXFAST16 __UINT_FAST16_FMTX__
+#define SCNXFAST32 __UINT_FAST32_FMTX__
+#define SCNXFAST64 __UINT_FAST64_FMTX__
+
+#define SCNdMAX __INTMAX_FMTd__
+#define SCNiMAX __INTMAX_FMTi__
+#define SCNoMAX __UINTMAX_FMTo__
+#define SCNuMAX __UINTMAX_FMTu__
+#define SCNxMAX __UINTMAX_FMTx__
+#define SCNXMAX __UINTMAX_FMTX__
+
+#define SCNdPTR __INTPTR_FMTd__
+#define SCNiPTR __INTPTR_FMTi__
+#define SCNoPTR __UINTPTR_FMTo__
+#define SCNuPTR __UINTPTR_FMTu__
+#define SCNxPTR __UINTPTR_FMTx__
+#define SCNXPTR __UINTPTR_FMTX__
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_INTTYPES_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/iso646.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/iso646.h
new file mode 100644
index 0000000..8b7dda8
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/iso646.h
@@ -0,0 +1,20 @@
+#ifndef SYSROOT_ISO646_H_
+#define SYSROOT_ISO646_H_
+
+#ifndef __cplusplus
+
+#define and &&
+#define and_eq &=
+#define bitand &
+#define bitor |
+#define compl ~
+#define not !
+#define not_eq !=
+#define or ||
+#define or_eq |=
+#define xor ^
+#define xor_eq ^=
+
+#endif
+
+#endif // SYSROOT_ISO646_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/langinfo.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/langinfo.h
new file mode 100644
index 0000000..a14fcfd
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/langinfo.h
@@ -0,0 +1,92 @@
+#ifndef SYSROOT_LANGINFO_H_
+#define SYSROOT_LANGINFO_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <nl_types.h>
+
+#define __NEED_locale_t
+
+#include <bits/alltypes.h>
+
+#define ABDAY_1 0x20000
+#define ABDAY_2 0x20001
+#define ABDAY_3 0x20002
+#define ABDAY_4 0x20003
+#define ABDAY_5 0x20004
+#define ABDAY_6 0x20005
+#define ABDAY_7 0x20006
+
+#define DAY_1 0x20007
+#define DAY_2 0x20008
+#define DAY_3 0x20009
+#define DAY_4 0x2000A
+#define DAY_5 0x2000B
+#define DAY_6 0x2000C
+#define DAY_7 0x2000D
+
+#define ABMON_1 0x2000E
+#define ABMON_2 0x2000F
+#define ABMON_3 0x20010
+#define ABMON_4 0x20011
+#define ABMON_5 0x20012
+#define ABMON_6 0x20013
+#define ABMON_7 0x20014
+#define ABMON_8 0x20015
+#define ABMON_9 0x20016
+#define ABMON_10 0x20017
+#define ABMON_11 0x20018
+#define ABMON_12 0x20019
+
+#define MON_1 0x2001A
+#define MON_2 0x2001B
+#define MON_3 0x2001C
+#define MON_4 0x2001D
+#define MON_5 0x2001E
+#define MON_6 0x2001F
+#define MON_7 0x20020
+#define MON_8 0x20021
+#define MON_9 0x20022
+#define MON_10 0x20023
+#define MON_11 0x20024
+#define MON_12 0x20025
+
+#define AM_STR 0x20026
+#define PM_STR 0x20027
+
+#define D_T_FMT 0x20028
+#define D_FMT 0x20029
+#define T_FMT 0x2002A
+#define T_FMT_AMPM 0x2002B
+
+#define ERA 0x2002C
+#define ERA_D_FMT 0x2002E
+#define ALT_DIGITS 0x2002F
+#define ERA_D_T_FMT 0x20030
+#define ERA_T_FMT 0x20031
+
+#define CODESET 14
+
+#define CRNCYSTR 0x4000F
+
+#define RADIXCHAR 0x10000
+#define THOUSEP 0x10001
+#define YESEXPR 0x50000
+#define NOEXPR 0x50001
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define YESSTR 0x50002
+#define NOSTR 0x50003
+#endif
+
+char* nl_langinfo(nl_item);
+char* nl_langinfo_l(nl_item, locale_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_LANGINFO_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/libgen.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/libgen.h
new file mode 100644
index 0000000..f7f79b6
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/libgen.h
@@ -0,0 +1,15 @@
+#ifndef SYSROOT_LIBGEN_H_
+#define SYSROOT_LIBGEN_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+char* dirname(char*);
+char* basename(char*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_LIBGEN_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/limits.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/limits.h
new file mode 100644
index 0000000..cf60386
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/limits.h
@@ -0,0 +1,153 @@
+#ifndef SYSROOT_LIMITS_H_
+#define SYSROOT_LIMITS_H_
+
+#include <features.h>
+
+/* Most limits are system-specific */
+
+#include <bits/limits.h>
+
+/* Support signed or unsigned plain-char */
+
+#if '\0' - 1 > 0
+#define CHAR_MIN 0
+#define CHAR_MAX 255
+#else
+#define CHAR_MIN (-128)
+#define CHAR_MAX 127
+#endif
+
+/* Some universal constants... */
+
+#define CHAR_BIT 8
+#define SCHAR_MIN (-128)
+#define SCHAR_MAX 127
+#define UCHAR_MAX 255
+#define SHRT_MIN (-1 - 0x7fff)
+#define SHRT_MAX 0x7fff
+#define USHRT_MAX 0xffff
+#define INT_MIN (-1 - 0x7fffffff)
+#define INT_MAX 0x7fffffff
+#define UINT_MAX 0xffffffffU
+#define LONG_MIN (-LONG_MAX - 1)
+#define ULONG_MAX (2UL * LONG_MAX + 1)
+#define LLONG_MIN (-LLONG_MAX - 1)
+#define ULLONG_MAX (2ULL * LLONG_MAX + 1)
+
+#define MB_LEN_MAX 4
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#define PIPE_BUF 4096
+#ifdef PAGE_SIZE
+#define PAGESIZE PAGE_SIZE
+#endif
+#define FILESIZEBITS 64
+#define NAME_MAX 255
+#define SYMLINK_MAX 255
+#define PATH_MAX 4096
+#define NZERO 20
+#define NGROUPS_MAX 32
+#define IOV_MAX 1024
+#define SYMLOOP_MAX 40
+#define WORD_BIT 32
+#define SSIZE_MAX LONG_MAX
+#define TZNAME_MAX 6
+#define TTY_NAME_MAX 32
+#define HOST_NAME_MAX 255
+
+/* Implementation choices... */
+
+#define PTHREAD_KEYS_MAX 128
+#define PTHREAD_STACK_MIN 3072
+#define PTHREAD_DESTRUCTOR_ITERATIONS 4
+#define SEM_VALUE_MAX 0x7fffffff
+#define SEM_NSEMS_MAX 256
+#define DELAYTIMER_MAX 0x7fffffff
+#define MQ_PRIO_MAX 32768
+#define LOGIN_NAME_MAX 256
+
+/* Arbitrary numbers... */
+
+#define BC_BASE_MAX 99
+#define BC_DIM_MAX 2048
+#define BC_SCALE_MAX 99
+#define BC_STRING_MAX 1000
+#define CHARCLASS_NAME_MAX 14
+#define COLL_WEIGHTS_MAX 2
+#define EXPR_NEST_MAX 32
+#define LINE_MAX 4096
+#define RE_DUP_MAX 255
+
+#define NL_ARGMAX 9
+#define NL_LANGMAX 32
+#define NL_MSGMAX 32767
+#define NL_SETMAX 255
+#define NL_TEXTMAX 2048
+
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || \
+ (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE + 0 < 700)
+
+#define NL_NMAX 16
+
+#endif
+
+/* POSIX/SUS requirements follow. These numbers come directly
+ * from SUS and have nothing to do with the host system. */
+
+#define _POSIX_AIO_LISTIO_MAX 2
+#define _POSIX_AIO_MAX 1
+#define _POSIX_ARG_MAX 4096
+#define _POSIX_CHILD_MAX 25
+#define _POSIX_CLOCKRES_MIN 20000000
+#define _POSIX_DELAYTIMER_MAX 32
+#define _POSIX_HOST_NAME_MAX 255
+#define _POSIX_LINK_MAX 8
+#define _POSIX_LOGIN_NAME_MAX 9
+#define _POSIX_MAX_CANON 255
+#define _POSIX_MAX_INPUT 255
+#define _POSIX_MQ_OPEN_MAX 8
+#define _POSIX_MQ_PRIO_MAX 32
+#define _POSIX_NAME_MAX 14
+#define _POSIX_NGROUPS_MAX 8
+#define _POSIX_OPEN_MAX 20
+#define _POSIX_PATH_MAX 256
+#define _POSIX_PIPE_BUF 512
+#define _POSIX_RE_DUP_MAX 255
+#define _POSIX_RTSIG_MAX 8
+#define _POSIX_SEM_NSEMS_MAX 256
+#define _POSIX_SEM_VALUE_MAX 32767
+#define _POSIX_SIGQUEUE_MAX 32
+#define _POSIX_SSIZE_MAX 32767
+#define _POSIX_STREAM_MAX 8
+#define _POSIX_SS_REPL_MAX 4
+#define _POSIX_SYMLINK_MAX 255
+#define _POSIX_SYMLOOP_MAX 8
+#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4
+#define _POSIX_THREAD_KEYS_MAX 128
+#define _POSIX_THREAD_THREADS_MAX 64
+#define _POSIX_TIMER_MAX 32
+#define _POSIX_TRACE_EVENT_NAME_MAX 30
+#define _POSIX_TRACE_NAME_MAX 8
+#define _POSIX_TRACE_SYS_MAX 8
+#define _POSIX_TRACE_USER_EVENT_MAX 32
+#define _POSIX_TTY_NAME_MAX 9
+#define _POSIX_TZNAME_MAX 6
+#define _POSIX2_BC_BASE_MAX 99
+#define _POSIX2_BC_DIM_MAX 2048
+#define _POSIX2_BC_SCALE_MAX 99
+#define _POSIX2_BC_STRING_MAX 1000
+#define _POSIX2_CHARCLASS_NAME_MAX 14
+#define _POSIX2_COLL_WEIGHTS_MAX 2
+#define _POSIX2_EXPR_NEST_MAX 32
+#define _POSIX2_LINE_MAX 2048
+#define _POSIX2_RE_DUP_MAX 255
+
+#define _XOPEN_IOV_MAX 16
+#define _XOPEN_NAME_MAX 255
+#define _XOPEN_PATH_MAX 1024
+
+#endif // SYSROOT_LIMITS_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/link.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/link.h
new file mode 100644
index 0000000..78ebd48
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/link.h
@@ -0,0 +1,61 @@
+#ifndef SYSROOT_LINK_H_
+#define SYSROOT_LINK_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <elf.h>
+#define __NEED_size_t
+#define __NEED_uint32_t
+#include <bits/alltypes.h>
+
+#define ElfW(type) Elf64_##type
+
+/* this is the same everywhere except alpha and s390 */
+typedef uint32_t Elf_Symndx;
+
+struct dl_phdr_info {
+ ElfW(Addr) dlpi_addr;
+ const char* dlpi_name;
+ const ElfW(Phdr) * dlpi_phdr;
+ ElfW(Half) dlpi_phnum;
+ unsigned long long int dlpi_adds;
+ unsigned long long int dlpi_subs;
+ size_t dlpi_tls_modid;
+ void* dlpi_tls_data;
+};
+
+struct link_map {
+ ElfW(Addr) l_addr;
+ char* l_name;
+ ElfW(Dyn) * l_ld;
+ struct link_map *l_next, *l_prev;
+};
+
+struct r_debug {
+ int r_version;
+ struct link_map* r_map;
+ ElfW(Addr) r_brk;
+
+ /* This is the address of a function internal to the run-time linker
+ that triggers a debug trap. This function will always be called
+ when the linker begins to map in a library or unmap it, and again
+ when the mapping change is complete.
+
+ The debugger can compare the address of a sw exception to this value
+ to determine whether the debug trap was triggered by the run-time
+ linker. */
+ ElfW(Addr) r_brk_on_load;
+
+ enum { RT_CONSISTENT, RT_ADD, RT_DELETE } r_state;
+ ElfW(Addr) r_ldbase;
+};
+
+int dl_iterate_phdr(int (*)(struct dl_phdr_info*, size_t, void*), void*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_LINK_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/locale.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/locale.h
new file mode 100644
index 0000000..ce78a02
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/locale.h
@@ -0,0 +1,79 @@
+#ifndef SYSROOT_LOCALE_H_
+#define SYSROOT_LOCALE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <bits/null.h>
+
+#define LC_CTYPE 0
+#define LC_NUMERIC 1
+#define LC_TIME 2
+#define LC_COLLATE 3
+#define LC_MONETARY 4
+#define LC_MESSAGES 5
+#define LC_ALL 6
+
+struct lconv {
+ char* decimal_point;
+ char* thousands_sep;
+ char* grouping;
+
+ char* int_curr_symbol;
+ char* currency_symbol;
+ char* mon_decimal_point;
+ char* mon_thousands_sep;
+ char* mon_grouping;
+ char* positive_sign;
+ char* negative_sign;
+ char int_frac_digits;
+ char frac_digits;
+ char p_cs_precedes;
+ char p_sep_by_space;
+ char n_cs_precedes;
+ char n_sep_by_space;
+ char p_sign_posn;
+ char n_sign_posn;
+ char int_p_cs_precedes;
+ char int_p_sep_by_space;
+ char int_n_cs_precedes;
+ char int_n_sep_by_space;
+ char int_p_sign_posn;
+ char int_n_sign_posn;
+};
+
+char* setlocale(int, const char*);
+struct lconv* localeconv(void);
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#define __NEED_locale_t
+
+#include <bits/alltypes.h>
+
+#define LC_GLOBAL_LOCALE ((locale_t)-1)
+
+#define LC_CTYPE_MASK (1 << LC_CTYPE)
+#define LC_NUMERIC_MASK (1 << LC_NUMERIC)
+#define LC_TIME_MASK (1 << LC_TIME)
+#define LC_COLLATE_MASK (1 << LC_COLLATE)
+#define LC_MONETARY_MASK (1 << LC_MONETARY)
+#define LC_MESSAGES_MASK (1 << LC_MESSAGES)
+#define LC_ALL_MASK 0x7fffffff
+
+locale_t duplocale(locale_t);
+void freelocale(locale_t);
+locale_t newlocale(int, const char*, locale_t);
+locale_t uselocale(locale_t);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_LOCALE_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/malloc.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/malloc.h
new file mode 100644
index 0000000..6abb854
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/malloc.h
@@ -0,0 +1,25 @@
+#ifndef SYSROOT_MALLOC_H_
+#define SYSROOT_MALLOC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+void* malloc(size_t);
+void* calloc(size_t, size_t);
+void* realloc(void*, size_t);
+void free(void*);
+void* valloc(size_t);
+void* memalign(size_t, size_t);
+
+size_t malloc_usable_size(void*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_MALLOC_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/math.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/math.h
new file mode 100644
index 0000000..089c266
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/math.h
@@ -0,0 +1,430 @@
+#ifndef SYSROOT_MATH_H_
+#define SYSROOT_MATH_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_float_t
+#define __NEED_double_t
+#include <bits/alltypes.h>
+
+#if 100 * __GNUC__ + __GNUC_MINOR__ >= 303
+#define NAN __builtin_nanf("")
+#define INFINITY __builtin_inff()
+#else
+#define NAN (0.0f / 0.0f)
+#define INFINITY 1e5000f
+#endif
+
+#define HUGE_VALF INFINITY
+#define HUGE_VAL ((double)INFINITY)
+#define HUGE_VALL ((long double)INFINITY)
+
+#define MATH_ERRNO 1
+#define MATH_ERREXCEPT 2
+#define math_errhandling 2
+
+#define FP_ILOGBNAN (-1 - (int)(((unsigned)-1) >> 1))
+#define FP_ILOGB0 FP_ILOGBNAN
+
+#define FP_NAN 0
+#define FP_INFINITE 1
+#define FP_ZERO 2
+#define FP_SUBNORMAL 3
+#define FP_NORMAL 4
+
+int __fpclassify(double);
+int __fpclassifyf(float);
+int __fpclassifyl(long double);
+
+static __inline unsigned __FLOAT_BITS(float __f) {
+ union {
+ float __f;
+ unsigned __i;
+ } __u;
+ __u.__f = __f;
+ return __u.__i;
+}
+static __inline unsigned long long __DOUBLE_BITS(double __f) {
+ union {
+ double __f;
+ unsigned long long __i;
+ } __u;
+ __u.__f = __f;
+ return __u.__i;
+}
+
+#define fpclassify(x) \
+ (sizeof(x) == sizeof(float) ? __fpclassifyf(x) \
+ : sizeof(x) == sizeof(double) ? __fpclassify(x) : __fpclassifyl(x))
+
+#define isinf(x) \
+ (sizeof(x) == sizeof(float) \
+ ? (__FLOAT_BITS(x) & 0x7fffffff) == 0x7f800000 \
+ : sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL >> 1) == 0x7ffULL << 52 \
+ : __fpclassifyl(x) == FP_INFINITE)
+
+#define isnan(x) \
+ (sizeof(x) == sizeof(float) \
+ ? (__FLOAT_BITS(x) & 0x7fffffff) > 0x7f800000 \
+ : sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL >> 1) > 0x7ffULL << 52 \
+ : __fpclassifyl(x) == FP_NAN)
+
+#define isnormal(x) \
+ (sizeof(x) == sizeof(float) ? ((__FLOAT_BITS(x) + 0x00800000) & 0x7fffffff) >= 0x01000000 \
+ : sizeof(x) == sizeof(double) ? ((__DOUBLE_BITS(x) + (1ULL << 52)) & \
+ -1ULL >> 1) >= 1ULL << 53 \
+ : __fpclassifyl(x) == FP_NORMAL)
+
+#define isfinite(x) \
+ (sizeof(x) == sizeof(float) \
+ ? (__FLOAT_BITS(x) & 0x7fffffff) < 0x7f800000 \
+ : sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL >> 1) < 0x7ffULL << 52 \
+ : __fpclassifyl(x) > FP_INFINITE)
+
+int __signbit(double);
+int __signbitf(float);
+int __signbitl(long double);
+
+#define signbit(x) \
+ (sizeof(x) == sizeof(float) \
+ ? (int)(__FLOAT_BITS(x) >> 31) \
+ : sizeof(x) == sizeof(double) ? (int)(__DOUBLE_BITS(x) >> 63) : __signbitl(x))
+
+#define isunordered(x, y) __builtin_isunordered(x, y)
+
+#define __ISREL_DEF(rel, op, type) \
+ static __inline int __is##rel(type __x, type __y) { return !isunordered(__x, __y) && __x op __y; }
+
+__ISREL_DEF(lessf, <, float_t)
+__ISREL_DEF(less, <, double_t)
+__ISREL_DEF(lessl, <, long double)
+__ISREL_DEF(lessequalf, <=, float_t)
+__ISREL_DEF(lessequal, <=, double_t)
+__ISREL_DEF(lessequall, <=, long double)
+__ISREL_DEF(lessgreaterf, !=, float_t)
+__ISREL_DEF(lessgreater, !=, double_t)
+__ISREL_DEF(lessgreaterl, !=, long double)
+__ISREL_DEF(greaterf, >, float_t)
+__ISREL_DEF(greater, >, double_t)
+__ISREL_DEF(greaterl, >, long double)
+__ISREL_DEF(greaterequalf, >=, float_t)
+__ISREL_DEF(greaterequal, >=, double_t)
+__ISREL_DEF(greaterequall, >=, long double)
+
+#define isless(x, y) __builtin_isless(x, y)
+#define islessequal(x, y) __builtin_islessequal(x, y)
+#define islessgreater(x, y) __builtin_islessgreater(x, y)
+#define isgreater(x, y) __builtin_isgreater(x, y)
+#define isgreaterequal(x, y) __builtin_isgreaterequal(x, y)
+
+double acos(double);
+float acosf(float);
+long double acosl(long double);
+
+double acosh(double);
+float acoshf(float);
+long double acoshl(long double);
+
+double asin(double);
+float asinf(float);
+long double asinl(long double);
+
+double asinh(double);
+float asinhf(float);
+long double asinhl(long double);
+
+double atan(double);
+float atanf(float);
+long double atanl(long double);
+
+double atan2(double, double);
+float atan2f(float, float);
+long double atan2l(long double, long double);
+
+double atanh(double);
+float atanhf(float);
+long double atanhl(long double);
+
+double cbrt(double);
+float cbrtf(float);
+long double cbrtl(long double);
+
+double ceil(double);
+float ceilf(float);
+long double ceill(long double);
+
+double copysign(double, double);
+float copysignf(float, float);
+long double copysignl(long double, long double);
+
+double cos(double);
+float cosf(float);
+long double cosl(long double);
+
+double cosh(double);
+float coshf(float);
+long double coshl(long double);
+
+double erf(double);
+float erff(float);
+long double erfl(long double);
+
+double erfc(double);
+float erfcf(float);
+long double erfcl(long double);
+
+double exp(double);
+float expf(float);
+long double expl(long double);
+
+double exp2(double);
+float exp2f(float);
+long double exp2l(long double);
+
+double expm1(double);
+float expm1f(float);
+long double expm1l(long double);
+
+double fabs(double);
+float fabsf(float);
+long double fabsl(long double);
+
+double fdim(double, double);
+float fdimf(float, float);
+long double fdiml(long double, long double);
+
+double floor(double);
+float floorf(float);
+long double floorl(long double);
+
+double fma(double, double, double);
+float fmaf(float, float, float);
+long double fmal(long double, long double, long double);
+
+double fmax(double, double);
+float fmaxf(float, float);
+long double fmaxl(long double, long double);
+
+double fmin(double, double);
+float fminf(float, float);
+long double fminl(long double, long double);
+
+double fmod(double, double);
+float fmodf(float, float);
+long double fmodl(long double, long double);
+
+double frexp(double, int*);
+float frexpf(float, int*);
+long double frexpl(long double, int*);
+
+double hypot(double, double);
+float hypotf(float, float);
+long double hypotl(long double, long double);
+
+int ilogb(double);
+int ilogbf(float);
+int ilogbl(long double);
+
+double ldexp(double, int);
+float ldexpf(float, int);
+long double ldexpl(long double, int);
+
+double lgamma(double);
+float lgammaf(float);
+long double lgammal(long double);
+
+long long llrint(double);
+long long llrintf(float);
+long long llrintl(long double);
+
+long long llround(double);
+long long llroundf(float);
+long long llroundl(long double);
+
+double log(double);
+float logf(float);
+long double logl(long double);
+
+double log10(double);
+float log10f(float);
+long double log10l(long double);
+
+double log1p(double);
+float log1pf(float);
+long double log1pl(long double);
+
+double log2(double);
+float log2f(float);
+long double log2l(long double);
+
+double logb(double);
+float logbf(float);
+long double logbl(long double);
+
+long lrint(double);
+long lrintf(float);
+long lrintl(long double);
+
+long lround(double);
+long lroundf(float);
+long lroundl(long double);
+
+double modf(double, double*);
+float modff(float, float*);
+long double modfl(long double, long double*);
+
+double nan(const char*);
+float nanf(const char*);
+long double nanl(const char*);
+
+double nearbyint(double);
+float nearbyintf(float);
+long double nearbyintl(long double);
+
+double nextafter(double, double);
+float nextafterf(float, float);
+long double nextafterl(long double, long double);
+
+double nexttoward(double, long double);
+float nexttowardf(float, long double);
+long double nexttowardl(long double, long double);
+
+double pow(double, double);
+float powf(float, float);
+long double powl(long double, long double);
+
+double remainder(double, double);
+float remainderf(float, float);
+long double remainderl(long double, long double);
+
+double remquo(double, double, int*);
+float remquof(float, float, int*);
+long double remquol(long double, long double, int*);
+
+double rint(double);
+float rintf(float);
+long double rintl(long double);
+
+double round(double);
+float roundf(float);
+long double roundl(long double);
+
+double scalbln(double, long);
+float scalblnf(float, long);
+long double scalblnl(long double, long);
+
+double scalbn(double, int);
+float scalbnf(float, int);
+long double scalbnl(long double, int);
+
+double sin(double);
+float sinf(float);
+long double sinl(long double);
+
+double sinh(double);
+float sinhf(float);
+long double sinhl(long double);
+
+double sqrt(double);
+float sqrtf(float);
+long double sqrtl(long double);
+
+double tan(double);
+float tanf(float);
+long double tanl(long double);
+
+double tanh(double);
+float tanhf(float);
+long double tanhl(long double);
+
+double tgamma(double);
+float tgammaf(float);
+long double tgammal(long double);
+
+double trunc(double);
+float truncf(float);
+long double truncl(long double);
+
+#if defined(_XOPEN_SOURCE) || defined(_BSD_SOURCE)
+#undef MAXFLOAT
+#define MAXFLOAT 3.40282346638528859812e+38F
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define M_E 2.7182818284590452354 /* e */
+#define M_LOG2E 1.4426950408889634074 /* log_2 e */
+#define M_LOG10E 0.43429448190325182765 /* log_10 e */
+#define M_LN2 0.69314718055994530942 /* log_e 2 */
+#define M_LN10 2.30258509299404568402 /* log_e 10 */
+#define M_PI 3.14159265358979323846 /* pi */
+#define M_PI_2 1.57079632679489661923 /* pi/2 */
+#define M_PI_4 0.78539816339744830962 /* pi/4 */
+#define M_1_PI 0.31830988618379067154 /* 1/pi */
+#define M_2_PI 0.63661977236758134308 /* 2/pi */
+#define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */
+#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */
+#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
+
+extern int signgam;
+
+double j0(double);
+double j1(double);
+double jn(int, double);
+
+double y0(double);
+double y1(double);
+double yn(int, double);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define HUGE 3.40282346638528859812e+38F
+
+double drem(double, double);
+float dremf(float, float);
+
+int finite(double);
+int finitef(float);
+
+double scalb(double, double);
+float scalbf(float, float);
+
+double significand(double);
+float significandf(float);
+
+double lgamma_r(double, int*);
+float lgammaf_r(float, int*);
+
+float j0f(float);
+float j1f(float);
+float jnf(int, float);
+
+float y0f(float);
+float y1f(float);
+float ynf(int, float);
+#endif
+
+#ifdef _GNU_SOURCE
+long double lgammal_r(long double, int*);
+
+void sincos(double, double*, double*);
+void sincosf(float, float*, float*);
+void sincosl(long double, long double*, long double*);
+
+double exp10(double);
+float exp10f(float);
+long double exp10l(long double);
+
+double pow10(double);
+float pow10f(float);
+long double pow10l(long double);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_MATH_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/memory.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/memory.h
new file mode 100644
index 0000000..3b2f590
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/memory.h
@@ -0,0 +1 @@
+#include <string.h>
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/monetary.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/monetary.h
new file mode 100644
index 0000000..d1955fa
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/monetary.h
@@ -0,0 +1,23 @@
+#ifndef SYSROOT_MONETARY_H_
+#define SYSROOT_MONETARY_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_ssize_t
+#define __NEED_size_t
+#define __NEED_locale_t
+
+#include <bits/alltypes.h>
+
+ssize_t strfmon(char* __restrict, size_t, const char* __restrict, ...);
+ssize_t strfmon_l(char* __restrict, size_t, locale_t, const char* __restrict, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_MONETARY_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/net/ethernet.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/net/ethernet.h
new file mode 100644
index 0000000..9cee87d
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/net/ethernet.h
@@ -0,0 +1,53 @@
+#ifndef SYSROOT_NET_ETHERNET_H_
+#define SYSROOT_NET_ETHERNET_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <netinet/if_ether.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+struct ether_addr {
+ uint8_t ether_addr_octet[ETH_ALEN];
+};
+
+struct ether_header {
+ uint8_t ether_dhost[ETH_ALEN];
+ uint8_t ether_shost[ETH_ALEN];
+ uint16_t ether_type;
+};
+
+#define ETHERTYPE_PUP 0x0200
+#define ETHERTYPE_SPRITE 0x0500
+#define ETHERTYPE_IP 0x0800
+#define ETHERTYPE_ARP 0x0806
+#define ETHERTYPE_REVARP 0x8035
+#define ETHERTYPE_AT 0x809B
+#define ETHERTYPE_AARP 0x80F3
+#define ETHERTYPE_VLAN 0x8100
+#define ETHERTYPE_IPX 0x8137
+#define ETHERTYPE_IPV6 0x86dd
+#define ETHERTYPE_LOOPBACK 0x9000
+
+#define ETHER_ADDR_LEN ETH_ALEN
+#define ETHER_TYPE_LEN 2
+#define ETHER_CRC_LEN 4
+#define ETHER_HDR_LEN ETH_HLEN
+#define ETHER_MIN_LEN (ETH_ZLEN + ETHER_CRC_LEN)
+#define ETHER_MAX_LEN (ETH_FRAME_LEN + ETHER_CRC_LEN)
+
+#define ETHER_IS_VALID_LEN(foo) ((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN)
+
+#define ETHERTYPE_TRAIL 0x1000
+#define ETHERTYPE_NTRAILER 16
+
+#define ETHERMTU ETH_DATA_LEN
+#define ETHERMIN (ETHER_MIN_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_NET_ETHERNET_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/net/if.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/net/if.h
new file mode 100644
index 0000000..e97c3ee
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/net/if.h
@@ -0,0 +1,132 @@
+#ifndef SYSROOT_NET_IF_H_
+#define SYSROOT_NET_IF_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define IF_NAMESIZE 16
+
+struct if_nameindex {
+ unsigned int if_index;
+ char* if_name;
+};
+
+unsigned int if_nametoindex(const char*);
+char* if_indextoname(unsigned int, char*);
+struct if_nameindex* if_nameindex(void);
+void if_freenameindex(struct if_nameindex*);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#include <sys/socket.h>
+
+#define IFF_UP 0x1
+#define IFF_BROADCAST 0x2
+#define IFF_DEBUG 0x4
+#define IFF_LOOPBACK 0x8
+#define IFF_POINTOPOINT 0x10
+#define IFF_NOTRAILERS 0x20
+#define IFF_RUNNING 0x40
+#define IFF_NOARP 0x80
+#define IFF_PROMISC 0x100
+#define IFF_ALLMULTI 0x200
+#define IFF_MASTER 0x400
+#define IFF_SLAVE 0x800
+#define IFF_MULTICAST 0x1000
+#define IFF_PORTSEL 0x2000
+#define IFF_AUTOMEDIA 0x4000
+#define IFF_DYNAMIC 0x8000
+#define IFF_LOWER_UP 0x10000
+#define IFF_DORMANT 0x20000
+#define IFF_ECHO 0x40000
+#define IFF_VOLATILE \
+ (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_BROADCAST | IFF_ECHO | IFF_MASTER | IFF_SLAVE | \
+ IFF_RUNNING | IFF_LOWER_UP | IFF_DORMANT)
+
+struct ifaddr {
+ struct sockaddr ifa_addr;
+ union {
+ struct sockaddr ifu_broadaddr;
+ struct sockaddr ifu_dstaddr;
+ } ifa_ifu;
+ struct iface* ifa_ifp;
+ struct ifaddr* ifa_next;
+};
+
+#define ifa_broadaddr ifa_ifu.ifu_broadaddr
+#define ifa_dstaddr ifa_ifu.ifu_dstaddr
+
+struct ifmap {
+ unsigned long int mem_start;
+ unsigned long int mem_end;
+ unsigned short int base_addr;
+ unsigned char irq;
+ unsigned char dma;
+ unsigned char port;
+};
+
+#define IFHWADDRLEN 6
+#define IFNAMSIZ IF_NAMESIZE
+
+struct ifreq {
+ union {
+ char ifrn_name[IFNAMSIZ];
+ } ifr_ifrn;
+ union {
+ struct sockaddr ifru_addr;
+ struct sockaddr ifru_dstaddr;
+ struct sockaddr ifru_broadaddr;
+ struct sockaddr ifru_netmask;
+ struct sockaddr ifru_hwaddr;
+ short int ifru_flags;
+ int ifru_ivalue;
+ int ifru_mtu;
+ struct ifmap ifru_map;
+ char ifru_slave[IFNAMSIZ];
+ char ifru_newname[IFNAMSIZ];
+ void* ifru_data;
+ } ifr_ifru;
+};
+
+#define ifr_name ifr_ifrn.ifrn_name
+#define ifr_hwaddr ifr_ifru.ifru_hwaddr
+#define ifr_addr ifr_ifru.ifru_addr
+#define ifr_dstaddr ifr_ifru.ifru_dstaddr
+#define ifr_broadaddr ifr_ifru.ifru_broadaddr
+#define ifr_netmask ifr_ifru.ifru_netmask
+#define ifr_flags ifr_ifru.ifru_flags
+#define ifr_metric ifr_ifru.ifru_ivalue
+#define ifr_mtu ifr_ifru.ifru_mtu
+#define ifr_map ifr_ifru.ifru_map
+#define ifr_slave ifr_ifru.ifru_slave
+#define ifr_data ifr_ifru.ifru_data
+#define ifr_ifindex ifr_ifru.ifru_ivalue
+#define ifr_bandwidth ifr_ifru.ifru_ivalue
+#define ifr_qlen ifr_ifru.ifru_ivalue
+#define ifr_newname ifr_ifru.ifru_newname
+#define _IOT_ifreq _IOT(_IOTS(char), IFNAMSIZ, _IOTS(char), 16, 0, 0)
+#define _IOT_ifreq_short _IOT(_IOTS(char), IFNAMSIZ, _IOTS(short), 1, 0, 0)
+#define _IOT_ifreq_int _IOT(_IOTS(char), IFNAMSIZ, _IOTS(int), 1, 0, 0)
+
+struct ifconf {
+ int ifc_len;
+ union {
+ void* ifcu_buf;
+ struct ifreq* ifcu_req;
+ } ifc_ifcu;
+};
+
+#define ifc_buf ifc_ifcu.ifcu_buf
+#define ifc_req ifc_ifcu.ifcu_req
+#define _IOT_ifconf _IOT(_IOTS(struct ifconf), 1, 0, 0, 0, 0)
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_NET_IF_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/net/if_arp.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/net/if_arp.h
new file mode 100644
index 0000000..40b902d
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/net/if_arp.h
@@ -0,0 +1,139 @@
+/* Nonstandard header */
+
+#ifndef SYSROOT_NET_IF_ARP_H_
+#define SYSROOT_NET_IF_ARP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <inttypes.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#define MAX_ADDR_LEN 7
+
+#define ARPOP_REQUEST 1
+#define ARPOP_REPLY 2
+#define ARPOP_RREQUEST 3
+#define ARPOP_RREPLY 4
+#define ARPOP_InREQUEST 8
+#define ARPOP_InREPLY 9
+#define ARPOP_NAK 10
+
+struct arphdr {
+ uint16_t ar_hrd;
+ uint16_t ar_pro;
+ uint8_t ar_hln;
+ uint8_t ar_pln;
+ uint16_t ar_op;
+};
+
+#define ARPHRD_NETROM 0
+#define ARPHRD_ETHER 1
+#define ARPHRD_EETHER 2
+#define ARPHRD_AX25 3
+#define ARPHRD_PRONET 4
+#define ARPHRD_CHAOS 5
+#define ARPHRD_IEEE802 6
+#define ARPHRD_ARCNET 7
+#define ARPHRD_APPLETLK 8
+#define ARPHRD_DLCI 15
+#define ARPHRD_ATM 19
+#define ARPHRD_METRICOM 23
+#define ARPHRD_IEEE1394 24
+#define ARPHRD_EUI64 27
+#define ARPHRD_INFINIBAND 32
+#define ARPHRD_SLIP 256
+#define ARPHRD_CSLIP 257
+#define ARPHRD_SLIP6 258
+#define ARPHRD_CSLIP6 259
+#define ARPHRD_RSRVD 260
+#define ARPHRD_ADAPT 264
+#define ARPHRD_ROSE 270
+#define ARPHRD_X25 271
+#define ARPHRD_HWX25 272
+#define ARPHRD_CAN 280
+#define ARPHRD_PPP 512
+#define ARPHRD_CISCO 513
+#define ARPHRD_HDLC ARPHRD_CISCO
+#define ARPHRD_LAPB 516
+#define ARPHRD_DDCMP 517
+#define ARPHRD_RAWHDLC 518
+
+#define ARPHRD_TUNNEL 768
+#define ARPHRD_TUNNEL6 769
+#define ARPHRD_FRAD 770
+#define ARPHRD_SKIP 771
+#define ARPHRD_LOOPBACK 772
+#define ARPHRD_LOCALTLK 773
+#define ARPHRD_FDDI 774
+#define ARPHRD_BIF 775
+#define ARPHRD_SIT 776
+#define ARPHRD_IPDDP 777
+#define ARPHRD_IPGRE 778
+#define ARPHRD_PIMREG 779
+#define ARPHRD_HIPPI 780
+#define ARPHRD_ASH 781
+#define ARPHRD_ECONET 782
+#define ARPHRD_IRDA 783
+#define ARPHRD_FCPP 784
+#define ARPHRD_FCAL 785
+#define ARPHRD_FCPL 786
+#define ARPHRD_FCFABRIC 787
+#define ARPHRD_IEEE802_TR 800
+#define ARPHRD_IEEE80211 801
+#define ARPHRD_IEEE80211_PRISM 802
+#define ARPHRD_IEEE80211_RADIOTAP 803
+#define ARPHRD_IEEE802154 804
+#define ARPHRD_IEEE802154_MONITOR 805
+#define ARPHRD_PHONET 820
+#define ARPHRD_PHONET_PIPE 821
+#define ARPHRD_CAIF 822
+#define ARPHRD_IP6GRE 823
+#define ARPHRD_NETLINK 824
+
+#define ARPHRD_VOID 0xFFFF
+#define ARPHRD_NONE 0xFFFE
+
+struct arpreq {
+ struct sockaddr arp_pa;
+ struct sockaddr arp_ha;
+ int arp_flags;
+ struct sockaddr arp_netmask;
+ char arp_dev[16];
+};
+
+struct arpreq_old {
+ struct sockaddr arp_pa;
+ struct sockaddr arp_ha;
+ int arp_flags;
+ struct sockaddr arp_netmask;
+};
+
+#define ATF_COM 0x02
+#define ATF_PERM 0x04
+#define ATF_PUBL 0x08
+#define ATF_USETRAILERS 0x10
+#define ATF_NETMASK 0x20
+#define ATF_DONTPUB 0x40
+#define ATF_MAGIC 0x80
+
+#define ARPD_UPDATE 0x01
+#define ARPD_LOOKUP 0x02
+#define ARPD_FLUSH 0x03
+
+struct arpd_request {
+ unsigned short req;
+ uint32_t ip;
+ unsigned long dev;
+ unsigned long stamp;
+ unsigned long updated;
+ unsigned char ha[MAX_ADDR_LEN];
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_NET_IF_ARP_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/net/route.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/net/route.h
new file mode 100644
index 0000000..dc5960b
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/net/route.h
@@ -0,0 +1,119 @@
+#ifndef SYSROOT_NET_ROUTE_H_
+#define SYSROOT_NET_ROUTE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <netinet/in.h>
+#include <stdint.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+struct rtentry {
+ unsigned long int rt_pad1;
+ struct sockaddr rt_dst;
+ struct sockaddr rt_gateway;
+ struct sockaddr rt_genmask;
+ unsigned short int rt_flags;
+ short int rt_pad2;
+ unsigned long int rt_pad3;
+ unsigned char rt_tos;
+ unsigned char rt_class;
+ short int rt_pad4[sizeof(long) / 2 - 1];
+ short int rt_metric;
+ char* rt_dev;
+ unsigned long int rt_mtu;
+ unsigned long int rt_window;
+ unsigned short int rt_irtt;
+};
+
+#define rt_mss rt_mtu
+
+struct in6_rtmsg {
+ struct in6_addr rtmsg_dst;
+ struct in6_addr rtmsg_src;
+ struct in6_addr rtmsg_gateway;
+ uint32_t rtmsg_type;
+ uint16_t rtmsg_dst_len;
+ uint16_t rtmsg_src_len;
+ uint32_t rtmsg_metric;
+ unsigned long int rtmsg_info;
+ uint32_t rtmsg_flags;
+ int rtmsg_ifindex;
+};
+
+#define RTF_UP 0x0001
+#define RTF_GATEWAY 0x0002
+
+#define RTF_HOST 0x0004
+#define RTF_REINSTATE 0x0008
+#define RTF_DYNAMIC 0x0010
+#define RTF_MODIFIED 0x0020
+#define RTF_MTU 0x0040
+#define RTF_MSS RTF_MTU
+#define RTF_WINDOW 0x0080
+#define RTF_IRTT 0x0100
+#define RTF_REJECT 0x0200
+#define RTF_STATIC 0x0400
+#define RTF_XRESOLVE 0x0800
+#define RTF_NOFORWARD 0x1000
+#define RTF_THROW 0x2000
+#define RTF_NOPMTUDISC 0x4000
+
+#define RTF_DEFAULT 0x00010000
+#define RTF_ALLONLINK 0x00020000
+#define RTF_ADDRCONF 0x00040000
+
+#define RTF_LINKRT 0x00100000
+#define RTF_NONEXTHOP 0x00200000
+
+#define RTF_CACHE 0x01000000
+#define RTF_FLOW 0x02000000
+#define RTF_POLICY 0x04000000
+
+#define RTCF_VALVE 0x00200000
+#define RTCF_MASQ 0x00400000
+#define RTCF_NAT 0x00800000
+#define RTCF_DOREDIRECT 0x01000000
+#define RTCF_LOG 0x02000000
+#define RTCF_DIRECTSRC 0x04000000
+
+#define RTF_LOCAL 0x80000000
+#define RTF_INTERFACE 0x40000000
+#define RTF_MULTICAST 0x20000000
+#define RTF_BROADCAST 0x10000000
+#define RTF_NAT 0x08000000
+
+#define RTF_ADDRCLASSMASK 0xF8000000
+#define RT_ADDRCLASS(flags) ((uint32_t)flags >> 23)
+
+#define RT_TOS(tos) ((tos)&IPTOS_TOS_MASK)
+
+#define RT_LOCALADDR(flags) ((flags & RTF_ADDRCLASSMASK) == (RTF_LOCAL | RTF_INTERFACE))
+
+#define RT_CLASS_UNSPEC 0
+#define RT_CLASS_DEFAULT 253
+
+#define RT_CLASS_MAIN 254
+#define RT_CLASS_LOCAL 255
+#define RT_CLASS_MAX 255
+
+#define RTMSG_ACK NLMSG_ACK
+#define RTMSG_OVERRUN NLMSG_OVERRUN
+
+#define RTMSG_NEWDEVICE 0x11
+#define RTMSG_DELDEVICE 0x12
+#define RTMSG_NEWROUTE 0x21
+#define RTMSG_DELROUTE 0x22
+#define RTMSG_NEWRULE 0x31
+#define RTMSG_DELRULE 0x32
+#define RTMSG_CONTROL 0x40
+
+#define RTMSG_AR_FAILED 0x51
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_NET_ROUTE_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/netdb.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/netdb.h
new file mode 100644
index 0000000..d5bb5ef
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/netdb.h
@@ -0,0 +1,155 @@
+#ifndef SYSROOT_NETDB_H_
+#define SYSROOT_NETDB_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <netinet/in.h>
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __NEED_size_t
+#include <bits/alltypes.h>
+#endif
+
+struct addrinfo {
+ int ai_flags;
+ int ai_family;
+ int ai_socktype;
+ int ai_protocol;
+ socklen_t ai_addrlen;
+ struct sockaddr* ai_addr;
+ char* ai_canonname;
+ struct addrinfo* ai_next;
+};
+
+#define IPPORT_RESERVED 1024
+
+#define AI_PASSIVE 0x01
+#define AI_CANONNAME 0x02
+#define AI_NUMERICHOST 0x04
+#define AI_V4MAPPED 0x08
+#define AI_ALL 0x10
+#define AI_ADDRCONFIG 0x20
+#define AI_NUMERICSERV 0x400
+
+#define NI_NUMERICHOST 0x01
+#define NI_NUMERICSERV 0x02
+#define NI_NOFQDN 0x04
+#define NI_NAMEREQD 0x08
+#define NI_DGRAM 0x10
+#define NI_NUMERICSCOPE 0x100
+
+#define EAI_BADFLAGS -1
+#define EAI_NONAME -2
+#define EAI_AGAIN -3
+#define EAI_FAIL -4
+#define EAI_FAMILY -6
+#define EAI_SOCKTYPE -7
+#define EAI_SERVICE -8
+#define EAI_MEMORY -10
+#define EAI_SYSTEM -11
+#define EAI_OVERFLOW -12
+
+int getaddrinfo(const char* __restrict, const char* __restrict, const struct addrinfo* __restrict,
+ struct addrinfo** __restrict);
+void freeaddrinfo(struct addrinfo*);
+int getnameinfo(const struct sockaddr* __restrict, socklen_t, char* __restrict, socklen_t,
+ char* __restrict, socklen_t, int);
+const char* gai_strerror(int);
+
+/* Legacy functions follow (marked OBsolete in SUS) */
+
+struct netent {
+ char* n_name;
+ char** n_aliases;
+ int n_addrtype;
+ uint32_t n_net;
+};
+
+struct hostent {
+ char* h_name;
+ char** h_aliases;
+ int h_addrtype;
+ int h_length;
+ char** h_addr_list;
+};
+#define h_addr h_addr_list[0]
+
+struct servent {
+ char* s_name;
+ char** s_aliases;
+ int s_port;
+ char* s_proto;
+};
+
+struct protoent {
+ char* p_name;
+ char** p_aliases;
+ int p_proto;
+};
+
+void sethostent(int);
+void endhostent(void);
+struct hostent* gethostent(void);
+
+void setnetent(int);
+void endnetent(void);
+struct netent* getnetent(void);
+struct netent* getnetbyaddr(uint32_t, int);
+struct netent* getnetbyname(const char*);
+
+void setservent(int);
+void endservent(void);
+struct servent* getservent(void);
+struct servent* getservbyname(const char*, const char*);
+struct servent* getservbyport(int, const char*);
+
+void setprotoent(int);
+void endprotoent(void);
+struct protoent* getprotoent(void);
+struct protoent* getprotobyname(const char*);
+struct protoent* getprotobynumber(int);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_POSIX_SOURCE) || \
+ (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE + 0 < 200809L) || \
+ (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE + 0 < 700)
+struct hostent* gethostbyname(const char*);
+struct hostent* gethostbyaddr(const void*, socklen_t, int);
+int* __h_errno_location(void);
+#define h_errno (*__h_errno_location())
+#define HOST_NOT_FOUND 1
+#define TRY_AGAIN 2
+#define NO_RECOVERY 3
+#define NO_DATA 4
+#define NO_ADDRESS NO_DATA
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+void herror(const char*);
+const char* hstrerror(int);
+int gethostbyname_r(const char*, struct hostent*, char*, size_t, struct hostent**, int*);
+int gethostbyname2_r(const char*, int, struct hostent*, char*, size_t, struct hostent**, int*);
+struct hostent* gethostbyname2(const char*, int);
+int gethostbyaddr_r(const void*, socklen_t, int, struct hostent*, char*, size_t, struct hostent**,
+ int*);
+int getservbyport_r(int, const char*, struct servent*, char*, size_t, struct servent**);
+int getservbyname_r(const char*, const char*, struct servent*, char*, size_t, struct servent**);
+#define EAI_NODATA -5
+#define EAI_ADDRFAMILY -9
+#define EAI_INPROGRESS -100
+#define EAI_CANCELED -101
+#define EAI_NOTCANCELED -102
+#define EAI_ALLDONE -103
+#define EAI_INTR -104
+#define EAI_IDN_ENCODE -105
+#define NI_MAXHOST 255
+#define NI_MAXSERV 32
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_NETDB_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/ether.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/ether.h
new file mode 100644
index 0000000..74668fb
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/ether.h
@@ -0,0 +1,22 @@
+#ifndef SYSROOT_NETINET_ETHER_H_
+#define SYSROOT_NETINET_ETHER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <netinet/if_ether.h>
+
+char* ether_ntoa(const struct ether_addr*);
+struct ether_addr* ether_aton(const char*);
+char* ether_ntoa_r(const struct ether_addr*, char*);
+struct ether_addr* ether_aton_r(const char*, struct ether_addr*);
+int ether_line(const char*, struct ether_addr*, char*);
+int ether_ntohost(char*, const struct ether_addr*);
+int ether_hostton(const char*, struct ether_addr*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_NETINET_ETHER_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/icmp6.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/icmp6.h
new file mode 100644
index 0000000..dde64cb
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/icmp6.h
@@ -0,0 +1,303 @@
+#ifndef SYSROOT_NETINET_ICMP6_H_
+#define SYSROOT_NETINET_ICMP6_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <netinet/in.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+
+#define ICMP6_FILTER 1
+
+#define ICMP6_FILTER_BLOCK 1
+#define ICMP6_FILTER_PASS 2
+#define ICMP6_FILTER_BLOCKOTHERS 3
+#define ICMP6_FILTER_PASSONLY 4
+
+struct icmp6_filter {
+ uint32_t icmp6_filt[8];
+};
+
+struct icmp6_hdr {
+ uint8_t icmp6_type;
+ uint8_t icmp6_code;
+ uint16_t icmp6_cksum;
+ union {
+ uint32_t icmp6_un_data32[1];
+ uint16_t icmp6_un_data16[2];
+ uint8_t icmp6_un_data8[4];
+ } icmp6_dataun;
+};
+
+#define icmp6_data32 icmp6_dataun.icmp6_un_data32
+#define icmp6_data16 icmp6_dataun.icmp6_un_data16
+#define icmp6_data8 icmp6_dataun.icmp6_un_data8
+#define icmp6_pptr icmp6_data32[0]
+#define icmp6_mtu icmp6_data32[0]
+#define icmp6_id icmp6_data16[0]
+#define icmp6_seq icmp6_data16[1]
+#define icmp6_maxdelay icmp6_data16[0]
+
+#define ICMP6_DST_UNREACH 1
+#define ICMP6_PACKET_TOO_BIG 2
+#define ICMP6_TIME_EXCEEDED 3
+#define ICMP6_PARAM_PROB 4
+
+#define ICMP6_INFOMSG_MASK 0x80
+
+#define ICMP6_ECHO_REQUEST 128
+#define ICMP6_ECHO_REPLY 129
+#define MLD_LISTENER_QUERY 130
+#define MLD_LISTENER_REPORT 131
+#define MLD_LISTENER_REDUCTION 132
+
+#define ICMP6_DST_UNREACH_NOROUTE 0
+#define ICMP6_DST_UNREACH_ADMIN 1
+#define ICMP6_DST_UNREACH_BEYONDSCOPE 2
+#define ICMP6_DST_UNREACH_ADDR 3
+#define ICMP6_DST_UNREACH_NOPORT 4
+
+#define ICMP6_TIME_EXCEED_TRANSIT 0
+#define ICMP6_TIME_EXCEED_REASSEMBLY 1
+
+#define ICMP6_PARAMPROB_HEADER 0
+#define ICMP6_PARAMPROB_NEXTHEADER 1
+#define ICMP6_PARAMPROB_OPTION 2
+
+#define ICMP6_FILTER_WILLPASS(type, filterp) \
+ ((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type)&31))) == 0)
+
+#define ICMP6_FILTER_WILLBLOCK(type, filterp) \
+ ((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type)&31))) != 0)
+
+#define ICMP6_FILTER_SETPASS(type, filterp) \
+ ((((filterp)->icmp6_filt[(type) >> 5]) &= ~(1 << ((type)&31))))
+
+#define ICMP6_FILTER_SETBLOCK(type, filterp) \
+ ((((filterp)->icmp6_filt[(type) >> 5]) |= (1 << ((type)&31))))
+
+#define ICMP6_FILTER_SETPASSALL(filterp) memset(filterp, 0, sizeof(struct icmp6_filter));
+
+#define ICMP6_FILTER_SETBLOCKALL(filterp) memset(filterp, 0xFF, sizeof(struct icmp6_filter));
+
+#define ND_ROUTER_SOLICIT 133
+#define ND_ROUTER_ADVERT 134
+#define ND_NEIGHBOR_SOLICIT 135
+#define ND_NEIGHBOR_ADVERT 136
+#define ND_REDIRECT 137
+
+struct nd_router_solicit {
+ struct icmp6_hdr nd_rs_hdr;
+};
+
+#define nd_rs_type nd_rs_hdr.icmp6_type
+#define nd_rs_code nd_rs_hdr.icmp6_code
+#define nd_rs_cksum nd_rs_hdr.icmp6_cksum
+#define nd_rs_reserved nd_rs_hdr.icmp6_data32[0]
+
+struct nd_router_advert {
+ struct icmp6_hdr nd_ra_hdr;
+ uint32_t nd_ra_reachable;
+ uint32_t nd_ra_retransmit;
+};
+
+#define nd_ra_type nd_ra_hdr.icmp6_type
+#define nd_ra_code nd_ra_hdr.icmp6_code
+#define nd_ra_cksum nd_ra_hdr.icmp6_cksum
+#define nd_ra_curhoplimit nd_ra_hdr.icmp6_data8[0]
+#define nd_ra_flags_reserved nd_ra_hdr.icmp6_data8[1]
+#define ND_RA_FLAG_MANAGED 0x80
+#define ND_RA_FLAG_OTHER 0x40
+#define ND_RA_FLAG_HOME_AGENT 0x20
+#define nd_ra_router_lifetime nd_ra_hdr.icmp6_data16[1]
+
+struct nd_neighbor_solicit {
+ struct icmp6_hdr nd_ns_hdr;
+ struct in6_addr nd_ns_target;
+};
+
+#define nd_ns_type nd_ns_hdr.icmp6_type
+#define nd_ns_code nd_ns_hdr.icmp6_code
+#define nd_ns_cksum nd_ns_hdr.icmp6_cksum
+#define nd_ns_reserved nd_ns_hdr.icmp6_data32[0]
+
+struct nd_neighbor_advert {
+ struct icmp6_hdr nd_na_hdr;
+ struct in6_addr nd_na_target;
+};
+
+#define nd_na_type nd_na_hdr.icmp6_type
+#define nd_na_code nd_na_hdr.icmp6_code
+#define nd_na_cksum nd_na_hdr.icmp6_cksum
+#define nd_na_flags_reserved nd_na_hdr.icmp6_data32[0]
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define ND_NA_FLAG_ROUTER 0x80000000
+#define ND_NA_FLAG_SOLICITED 0x40000000
+#define ND_NA_FLAG_OVERRIDE 0x20000000
+#else
+#define ND_NA_FLAG_ROUTER 0x00000080
+#define ND_NA_FLAG_SOLICITED 0x00000040
+#define ND_NA_FLAG_OVERRIDE 0x00000020
+#endif
+
+struct nd_redirect {
+ struct icmp6_hdr nd_rd_hdr;
+ struct in6_addr nd_rd_target;
+ struct in6_addr nd_rd_dst;
+};
+
+#define nd_rd_type nd_rd_hdr.icmp6_type
+#define nd_rd_code nd_rd_hdr.icmp6_code
+#define nd_rd_cksum nd_rd_hdr.icmp6_cksum
+#define nd_rd_reserved nd_rd_hdr.icmp6_data32[0]
+
+struct nd_opt_hdr {
+ uint8_t nd_opt_type;
+ uint8_t nd_opt_len;
+};
+
+#define ND_OPT_SOURCE_LINKADDR 1
+#define ND_OPT_TARGET_LINKADDR 2
+#define ND_OPT_PREFIX_INFORMATION 3
+#define ND_OPT_REDIRECTED_HEADER 4
+#define ND_OPT_MTU 5
+#define ND_OPT_RTR_ADV_INTERVAL 7
+#define ND_OPT_HOME_AGENT_INFO 8
+
+struct nd_opt_prefix_info {
+ uint8_t nd_opt_pi_type;
+ uint8_t nd_opt_pi_len;
+ uint8_t nd_opt_pi_prefix_len;
+ uint8_t nd_opt_pi_flags_reserved;
+ uint32_t nd_opt_pi_valid_time;
+ uint32_t nd_opt_pi_preferred_time;
+ uint32_t nd_opt_pi_reserved2;
+ struct in6_addr nd_opt_pi_prefix;
+};
+
+#define ND_OPT_PI_FLAG_ONLINK 0x80
+#define ND_OPT_PI_FLAG_AUTO 0x40
+#define ND_OPT_PI_FLAG_RADDR 0x20
+
+struct nd_opt_rd_hdr {
+ uint8_t nd_opt_rh_type;
+ uint8_t nd_opt_rh_len;
+ uint16_t nd_opt_rh_reserved1;
+ uint32_t nd_opt_rh_reserved2;
+};
+
+struct nd_opt_mtu {
+ uint8_t nd_opt_mtu_type;
+ uint8_t nd_opt_mtu_len;
+ uint16_t nd_opt_mtu_reserved;
+ uint32_t nd_opt_mtu_mtu;
+};
+
+struct mld_hdr {
+ struct icmp6_hdr mld_icmp6_hdr;
+ struct in6_addr mld_addr;
+};
+
+#define mld_type mld_icmp6_hdr.icmp6_type
+#define mld_code mld_icmp6_hdr.icmp6_code
+#define mld_cksum mld_icmp6_hdr.icmp6_cksum
+#define mld_maxdelay mld_icmp6_hdr.icmp6_data16[0]
+#define mld_reserved mld_icmp6_hdr.icmp6_data16[1]
+
+#define ICMP6_ROUTER_RENUMBERING 138
+
+struct icmp6_router_renum {
+ struct icmp6_hdr rr_hdr;
+ uint8_t rr_segnum;
+ uint8_t rr_flags;
+ uint16_t rr_maxdelay;
+ uint32_t rr_reserved;
+};
+
+#define rr_type rr_hdr.icmp6_type
+#define rr_code rr_hdr.icmp6_code
+#define rr_cksum rr_hdr.icmp6_cksum
+#define rr_seqnum rr_hdr.icmp6_data32[0]
+
+#define ICMP6_RR_FLAGS_TEST 0x80
+#define ICMP6_RR_FLAGS_REQRESULT 0x40
+#define ICMP6_RR_FLAGS_FORCEAPPLY 0x20
+#define ICMP6_RR_FLAGS_SPECSITE 0x10
+#define ICMP6_RR_FLAGS_PREVDONE 0x08
+
+struct rr_pco_match {
+ uint8_t rpm_code;
+ uint8_t rpm_len;
+ uint8_t rpm_ordinal;
+ uint8_t rpm_matchlen;
+ uint8_t rpm_minlen;
+ uint8_t rpm_maxlen;
+ uint16_t rpm_reserved;
+ struct in6_addr rpm_prefix;
+};
+
+#define RPM_PCO_ADD 1
+#define RPM_PCO_CHANGE 2
+#define RPM_PCO_SETGLOBAL 3
+
+struct rr_pco_use {
+ uint8_t rpu_uselen;
+ uint8_t rpu_keeplen;
+ uint8_t rpu_ramask;
+ uint8_t rpu_raflags;
+ uint32_t rpu_vltime;
+ uint32_t rpu_pltime;
+ uint32_t rpu_flags;
+ struct in6_addr rpu_prefix;
+};
+
+#define ICMP6_RR_PCOUSE_RAFLAGS_ONLINK 0x20
+#define ICMP6_RR_PCOUSE_RAFLAGS_AUTO 0x10
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80000000
+#define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40000000
+#else
+#define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80
+#define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40
+#endif
+
+struct rr_result {
+ uint16_t rrr_flags;
+ uint8_t rrr_ordinal;
+ uint8_t rrr_matchedlen;
+ uint32_t rrr_ifid;
+ struct in6_addr rrr_prefix;
+};
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define ICMP6_RR_RESULT_FLAGS_OOB 0x0002
+#define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0001
+#else
+#define ICMP6_RR_RESULT_FLAGS_OOB 0x0200
+#define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0100
+#endif
+
+struct nd_opt_adv_interval {
+ uint8_t nd_opt_adv_interval_type;
+ uint8_t nd_opt_adv_interval_len;
+ uint16_t nd_opt_adv_interval_reserved;
+ uint32_t nd_opt_adv_interval_ival;
+};
+
+struct nd_opt_home_agent_info {
+ uint8_t nd_opt_home_agent_info_type;
+ uint8_t nd_opt_home_agent_info_len;
+ uint16_t nd_opt_home_agent_info_reserved;
+ uint16_t nd_opt_home_agent_info_preference;
+ uint16_t nd_opt_home_agent_info_lifetime;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_NETINET_ICMP6_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/if_ether.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/if_ether.h
new file mode 100644
index 0000000..f826e96
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/if_ether.h
@@ -0,0 +1,128 @@
+#ifndef SYSROOT_NETINET_IF_ETHER_H_
+#define SYSROOT_NETINET_IF_ETHER_H_
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#define ETH_ALEN 6
+#define ETH_HLEN 14
+#define ETH_ZLEN 60
+#define ETH_DATA_LEN 1500
+#define ETH_FRAME_LEN 1514
+#define ETH_FCS_LEN 4
+
+#define ETH_P_LOOP 0x0060
+#define ETH_P_PUP 0x0200
+#define ETH_P_PUPAT 0x0201
+#define ETH_P_IP 0x0800
+#define ETH_P_X25 0x0805
+#define ETH_P_ARP 0x0806
+#define ETH_P_BPQ 0x08FF
+#define ETH_P_IEEEPUP 0x0a00
+#define ETH_P_IEEEPUPAT 0x0a01
+#define ETH_P_BATMAN 0x4305
+#define ETH_P_DEC 0x6000
+#define ETH_P_DNA_DL 0x6001
+#define ETH_P_DNA_RC 0x6002
+#define ETH_P_DNA_RT 0x6003
+#define ETH_P_LAT 0x6004
+#define ETH_P_DIAG 0x6005
+#define ETH_P_CUST 0x6006
+#define ETH_P_SCA 0x6007
+#define ETH_P_TEB 0x6558
+#define ETH_P_RARP 0x8035
+#define ETH_P_ATALK 0x809B
+#define ETH_P_AARP 0x80F3
+#define ETH_P_8021Q 0x8100
+#define ETH_P_IPX 0x8137
+#define ETH_P_IPV6 0x86DD
+#define ETH_P_PAUSE 0x8808
+#define ETH_P_SLOW 0x8809
+#define ETH_P_WCCP 0x883E
+#define ETH_P_MPLS_UC 0x8847
+#define ETH_P_MPLS_MC 0x8848
+#define ETH_P_ATMMPOA 0x884c
+#define ETH_P_PPP_DISC 0x8863
+#define ETH_P_PPP_SES 0x8864
+#define ETH_P_LINK_CTL 0x886c
+#define ETH_P_ATMFATE 0x8884
+#define ETH_P_PAE 0x888E
+#define ETH_P_AOE 0x88A2
+#define ETH_P_8021AD 0x88A8
+#define ETH_P_802_EX1 0x88B5
+#define ETH_P_TIPC 0x88CA
+#define ETH_P_8021AH 0x88E7
+#define ETH_P_MVRP 0x88F5
+#define ETH_P_1588 0x88F7
+#define ETH_P_PRP 0x88FB
+#define ETH_P_FCOE 0x8906
+#define ETH_P_TDLS 0x890D
+#define ETH_P_FIP 0x8914
+#define ETH_P_80221 0x8917
+#define ETH_P_LOOPBACK 0x9000
+#define ETH_P_QINQ1 0x9100
+#define ETH_P_QINQ2 0x9200
+#define ETH_P_QINQ3 0x9300
+#define ETH_P_EDSA 0xDADA
+#define ETH_P_AF_IUCV 0xFBFB
+
+#define ETH_P_802_3_MIN 0x0600
+
+#define ETH_P_802_3 0x0001
+#define ETH_P_AX25 0x0002
+#define ETH_P_ALL 0x0003
+#define ETH_P_802_2 0x0004
+#define ETH_P_SNAP 0x0005
+#define ETH_P_DDCMP 0x0006
+#define ETH_P_WAN_PPP 0x0007
+#define ETH_P_PPP_MP 0x0008
+#define ETH_P_LOCALTALK 0x0009
+#define ETH_P_CAN 0x000C
+#define ETH_P_CANFD 0x000D
+#define ETH_P_PPPTALK 0x0010
+#define ETH_P_TR_802_2 0x0011
+#define ETH_P_MOBITEX 0x0015
+#define ETH_P_CONTROL 0x0016
+#define ETH_P_IRDA 0x0017
+#define ETH_P_ECONET 0x0018
+#define ETH_P_HDLC 0x0019
+#define ETH_P_ARCNET 0x001A
+#define ETH_P_DSA 0x001B
+#define ETH_P_TRAILER 0x001C
+#define ETH_P_PHONET 0x00F5
+#define ETH_P_IEEE802154 0x00F6
+#define ETH_P_CAIF 0x00F7
+
+struct ethhdr {
+ uint8_t h_dest[ETH_ALEN];
+ uint8_t h_source[ETH_ALEN];
+ uint16_t h_proto;
+};
+
+#include <net/ethernet.h>
+#include <net/if_arp.h>
+
+struct ether_arp {
+ struct arphdr ea_hdr;
+ uint8_t arp_sha[ETH_ALEN];
+ uint8_t arp_spa[4];
+ uint8_t arp_tha[ETH_ALEN];
+ uint8_t arp_tpa[4];
+};
+#define arp_hrd ea_hdr.ar_hrd
+#define arp_pro ea_hdr.ar_pro
+#define arp_hln ea_hdr.ar_hln
+#define arp_pln ea_hdr.ar_pln
+#define arp_op ea_hdr.ar_op
+
+#define ETHER_MAP_IP_MULTICAST(ipaddr, enaddr) \
+ do { \
+ (enaddr)[0] = 0x01; \
+ (enaddr)[1] = 0x00; \
+ (enaddr)[2] = 0x5e; \
+ (enaddr)[3] = ((uint8_t*)ipaddr)[1] & 0x7f; \
+ (enaddr)[4] = ((uint8_t*)ipaddr)[2]; \
+ (enaddr)[5] = ((uint8_t*)ipaddr)[3]; \
+ } while (0)
+
+#endif // SYSROOT_NETINET_IF_ETHER_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/igmp.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/igmp.h
new file mode 100644
index 0000000..99eb989
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/igmp.h
@@ -0,0 +1,45 @@
+#ifndef SYSROOT_NETINET_IGMP_H_
+#define SYSROOT_NETINET_IGMP_H_
+
+#include <netinet/in.h>
+#include <stdint.h>
+
+struct igmp {
+ uint8_t igmp_type;
+ uint8_t igmp_code;
+ uint16_t igmp_cksum;
+ struct in_addr igmp_group;
+};
+
+#define IGMP_MINLEN 8
+
+#define IGMP_MEMBERSHIP_QUERY 0x11
+#define IGMP_V1_MEMBERSHIP_REPORT 0x12
+#define IGMP_V2_MEMBERSHIP_REPORT 0x16
+#define IGMP_V2_LEAVE_GROUP 0x17
+
+#define IGMP_DVMRP 0x13
+#define IGMP_PIM 0x14
+#define IGMP_TRACE 0x15
+
+#define IGMP_MTRACE_RESP 0x1e
+#define IGMP_MTRACE 0x1f
+
+#define IGMP_MAX_HOST_REPORT_DELAY 10
+#define IGMP_TIMER_SCALE 10
+
+#define IGMP_DELAYING_MEMBER 1
+#define IGMP_IDLE_MEMBER 2
+#define IGMP_LAZY_MEMBER 3
+#define IGMP_SLEEPING_MEMBER 4
+#define IGMP_AWAKENING_MEMBER 5
+
+#define IGMP_v1_ROUTER 1
+#define IGMP_v2_ROUTER 2
+
+#define IGMP_HOST_MEMBERSHIP_QUERY IGMP_MEMBERSHIP_QUERY
+#define IGMP_HOST_MEMBERSHIP_REPORT IGMP_V1_MEMBERSHIP_REPORT
+#define IGMP_HOST_NEW_MEMBERSHIP_REPORT IGMP_V2_MEMBERSHIP_REPORT
+#define IGMP_HOST_LEAVE_MESSAGE IGMP_V2_LEAVE_GROUP
+
+#endif // SYSROOT_NETINET_IGMP_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/in.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/in.h
new file mode 100644
index 0000000..6d18e44
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/in.h
@@ -0,0 +1,397 @@
+#ifndef SYSROOT_NETINET_IN_H_
+#define SYSROOT_NETINET_IN_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <inttypes.h>
+#include <sys/socket.h>
+
+typedef uint16_t in_port_t;
+typedef uint32_t in_addr_t;
+struct in_addr {
+ in_addr_t s_addr;
+};
+
+struct sockaddr_in {
+ sa_family_t sin_family;
+ in_port_t sin_port;
+ struct in_addr sin_addr;
+ uint8_t sin_zero[8];
+};
+
+struct in6_addr {
+ union {
+ uint8_t __s6_addr[16];
+ uint16_t __s6_addr16[8];
+ uint32_t __s6_addr32[4];
+ } __in6_union;
+};
+#define s6_addr __in6_union.__s6_addr
+#define s6_addr16 __in6_union.__s6_addr16
+#define s6_addr32 __in6_union.__s6_addr32
+
+struct sockaddr_in6 {
+ sa_family_t sin6_family;
+ in_port_t sin6_port;
+ uint32_t sin6_flowinfo;
+ struct in6_addr sin6_addr;
+ uint32_t sin6_scope_id;
+};
+
+struct ipv6_mreq {
+ struct in6_addr ipv6mr_multiaddr;
+ unsigned ipv6mr_interface;
+};
+
+#define INADDR_ANY ((in_addr_t)0x00000000)
+#define INADDR_BROADCAST ((in_addr_t)0xffffffff)
+#define INADDR_NONE ((in_addr_t)0xffffffff)
+#define INADDR_LOOPBACK ((in_addr_t)0x7f000001)
+
+#define INADDR_UNSPEC_GROUP ((in_addr_t)0xe0000000)
+#define INADDR_ALLHOSTS_GROUP ((in_addr_t)0xe0000001)
+#define INADDR_ALLRTRS_GROUP ((in_addr_t)0xe0000002)
+#define INADDR_MAX_LOCAL_GROUP ((in_addr_t)0xe00000ff)
+
+#define IN6ADDR_ANY_INIT \
+ { \
+ { \
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } \
+ } \
+ }
+#define IN6ADDR_LOOPBACK_INIT \
+ { \
+ { \
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } \
+ } \
+ }
+
+extern const struct in6_addr in6addr_any, in6addr_loopback;
+
+#undef INET_ADDRSTRLEN
+#undef INET6_ADDRSTRLEN
+#define INET_ADDRSTRLEN 16
+#define INET6_ADDRSTRLEN 46
+
+uint32_t htonl(uint32_t);
+uint16_t htons(uint16_t);
+uint32_t ntohl(uint32_t);
+uint16_t ntohs(uint16_t);
+
+#define IPPROTO_IP 0
+#define IPPROTO_HOPOPTS 0
+#define IPPROTO_ICMP 1
+#define IPPROTO_IGMP 2
+#define IPPROTO_IPIP 4
+#define IPPROTO_TCP 6
+#define IPPROTO_EGP 8
+#define IPPROTO_PUP 12
+#define IPPROTO_UDP 17
+#define IPPROTO_IDP 22
+#define IPPROTO_TP 29
+#define IPPROTO_DCCP 33
+#define IPPROTO_IPV6 41
+#define IPPROTO_ROUTING 43
+#define IPPROTO_FRAGMENT 44
+#define IPPROTO_RSVP 46
+#define IPPROTO_GRE 47
+#define IPPROTO_ESP 50
+#define IPPROTO_AH 51
+#define IPPROTO_ICMPV6 58
+#define IPPROTO_NONE 59
+#define IPPROTO_DSTOPTS 60
+#define IPPROTO_MTP 92
+#define IPPROTO_BEETPH 94
+#define IPPROTO_ENCAP 98
+#define IPPROTO_PIM 103
+#define IPPROTO_COMP 108
+#define IPPROTO_SCTP 132
+#define IPPROTO_MH 135
+#define IPPROTO_UDPLITE 136
+#define IPPROTO_MPLS 137
+#define IPPROTO_RAW 255
+#define IPPROTO_MAX 256
+
+#define IN6_IS_ADDR_UNSPECIFIED(a) \
+ (((uint32_t*)(a))[0] == 0 && ((uint32_t*)(a))[1] == 0 && ((uint32_t*)(a))[2] == 0 && \
+ ((uint32_t*)(a))[3] == 0)
+
+#define IN6_IS_ADDR_LOOPBACK(a) \
+ (((uint32_t*)(a))[0] == 0 && ((uint32_t*)(a))[1] == 0 && ((uint32_t*)(a))[2] == 0 && \
+ ((uint8_t*)(a))[12] == 0 && ((uint8_t*)(a))[13] == 0 && ((uint8_t*)(a))[14] == 0 && \
+ ((uint8_t*)(a))[15] == 1)
+
+#define IN6_IS_ADDR_MULTICAST(a) (((uint8_t*)(a))[0] == 0xff)
+
+#define IN6_IS_ADDR_LINKLOCAL(a) \
+ ((((uint8_t*)(a))[0]) == 0xfe && (((uint8_t*)(a))[1] & 0xc0) == 0x80)
+
+#define IN6_IS_ADDR_SITELOCAL(a) \
+ ((((uint8_t*)(a))[0]) == 0xfe && (((uint8_t*)(a))[1] & 0xc0) == 0xc0)
+
+#define IN6_IS_ADDR_V4MAPPED(a) \
+ (((uint32_t*)(a))[0] == 0 && ((uint32_t*)(a))[1] == 0 && ((uint8_t*)(a))[8] == 0 && \
+ ((uint8_t*)(a))[9] == 0 && ((uint8_t*)(a))[10] == 0xff && ((uint8_t*)(a))[11] == 0xff)
+
+#define IN6_IS_ADDR_V4COMPAT(a) \
+ (((uint32_t*)(a))[0] == 0 && ((uint32_t*)(a))[1] == 0 && ((uint32_t*)(a))[2] == 0 && \
+ ((uint8_t*)(a))[15] > 1)
+
+#define IN6_IS_ADDR_MC_NODELOCAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t*)(a))[1] & 0xf) == 0x1))
+
+#define IN6_IS_ADDR_MC_LINKLOCAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t*)(a))[1] & 0xf) == 0x2))
+
+#define IN6_IS_ADDR_MC_SITELOCAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t*)(a))[1] & 0xf) == 0x5))
+
+#define IN6_IS_ADDR_MC_ORGLOCAL(a) (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t*)(a))[1] & 0xf) == 0x8))
+
+#define IN6_IS_ADDR_MC_GLOBAL(a) (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t*)(a))[1] & 0xf) == 0xe))
+
+#define __ARE_4_EQUAL(a, b) \
+ (!((0 [a] - 0 [b]) | (1 [a] - 1 [b]) | (2 [a] - 2 [b]) | (3 [a] - 3 [b])))
+#define IN6_ARE_ADDR_EQUAL(a, b) __ARE_4_EQUAL((const uint32_t*)(a), (const uint32_t*)(b))
+
+#define IN_CLASSA(a) ((((in_addr_t)(a)) & 0x80000000) == 0)
+#define IN_CLASSA_NET 0xff000000
+#define IN_CLASSA_NSHIFT 24
+#define IN_CLASSA_HOST (0xffffffff & ~IN_CLASSA_NET)
+#define IN_CLASSA_MAX 128
+#define IN_CLASSB(a) ((((in_addr_t)(a)) & 0xc0000000) == 0x80000000)
+#define IN_CLASSB_NET 0xffff0000
+#define IN_CLASSB_NSHIFT 16
+#define IN_CLASSB_HOST (0xffffffff & ~IN_CLASSB_NET)
+#define IN_CLASSB_MAX 65536
+#define IN_CLASSC(a) ((((in_addr_t)(a)) & 0xe0000000) == 0xc0000000)
+#define IN_CLASSC_NET 0xffffff00
+#define IN_CLASSC_NSHIFT 8
+#define IN_CLASSC_HOST (0xffffffff & ~IN_CLASSC_NET)
+#define IN_CLASSD(a) ((((in_addr_t)(a)) & 0xf0000000) == 0xe0000000)
+#define IN_MULTICAST(a) IN_CLASSD(a)
+#define IN_EXPERIMENTAL(a) ((((in_addr_t)(a)) & 0xe0000000) == 0xe0000000)
+#define IN_BADCLASS(a) ((((in_addr_t)(a)) & 0xf0000000) == 0xf0000000)
+
+#define IN_LOOPBACKNET 127
+
+#define IP_TOS 1
+#define IP_TTL 2
+#define IP_HDRINCL 3
+#define IP_OPTIONS 4
+#define IP_ROUTER_ALERT 5
+#define IP_RECVOPTS 6
+#define IP_RETOPTS 7
+#define IP_PKTINFO 8
+#define IP_PKTOPTIONS 9
+#define IP_PMTUDISC 10
+#define IP_MTU_DISCOVER 10
+#define IP_RECVERR 11
+#define IP_RECVTTL 12
+#define IP_RECVTOS 13
+#define IP_MTU 14
+#define IP_FREEBIND 15
+#define IP_IPSEC_POLICY 16
+#define IP_XFRM_POLICY 17
+#define IP_PASSSEC 18
+#define IP_TRANSPARENT 19
+#define IP_ORIGDSTADDR 20
+#define IP_RECVORIGDSTADDR IP_ORIGDSTADDR
+#define IP_MINTTL 21
+#define IP_NODEFRAG 22
+#define IP_CHECKSUM 23
+#define IP_BIND_ADDRESS_NO_PORT 24
+#define IP_MULTICAST_IF 32
+#define IP_MULTICAST_TTL 33
+#define IP_MULTICAST_LOOP 34
+#define IP_ADD_MEMBERSHIP 35
+#define IP_DROP_MEMBERSHIP 36
+#define IP_UNBLOCK_SOURCE 37
+#define IP_BLOCK_SOURCE 38
+#define IP_ADD_SOURCE_MEMBERSHIP 39
+#define IP_DROP_SOURCE_MEMBERSHIP 40
+#define IP_MSFILTER 41
+#define IP_MULTICAST_ALL 49
+#define IP_UNICAST_IF 50
+
+#define IP_RECVRETOPTS IP_RETOPTS
+
+#define IP_PMTUDISC_DONT 0
+#define IP_PMTUDISC_WANT 1
+#define IP_PMTUDISC_DO 2
+#define IP_PMTUDISC_PROBE 3
+#define IP_PMTUDISC_INTERFACE 4
+#define IP_PMTUDISC_OMIT 5
+
+#define IP_DEFAULT_MULTICAST_TTL 1
+#define IP_DEFAULT_MULTICAST_LOOP 1
+#define IP_MAX_MEMBERSHIPS 20
+
+struct ip_opts {
+ struct in_addr ip_dst;
+ char ip_opts[40];
+};
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#define MCAST_JOIN_GROUP 42
+#define MCAST_BLOCK_SOURCE 43
+#define MCAST_UNBLOCK_SOURCE 44
+#define MCAST_LEAVE_GROUP 45
+#define MCAST_JOIN_SOURCE_GROUP 46
+#define MCAST_LEAVE_SOURCE_GROUP 47
+#define MCAST_MSFILTER 48
+
+#define MCAST_EXCLUDE 0
+#define MCAST_INCLUDE 1
+
+struct ip_mreq {
+ struct in_addr imr_multiaddr;
+ struct in_addr imr_interface;
+};
+
+struct ip_mreqn {
+ struct in_addr imr_multiaddr;
+ struct in_addr imr_address;
+ int imr_ifindex;
+};
+
+struct ip_mreq_source {
+ struct in_addr imr_multiaddr;
+ struct in_addr imr_interface;
+ struct in_addr imr_sourceaddr;
+};
+
+struct ip_msfilter {
+ struct in_addr imsf_multiaddr;
+ struct in_addr imsf_interface;
+ uint32_t imsf_fmode;
+ uint32_t imsf_numsrc;
+ struct in_addr imsf_slist[1];
+};
+#define IP_MSFILTER_SIZE(numsrc) \
+ (sizeof(struct ip_msfilter) - sizeof(struct in_addr) + (numsrc) * sizeof(struct in_addr))
+
+struct group_req {
+ uint32_t gr_interface;
+ struct sockaddr_storage gr_group;
+};
+
+struct group_source_req {
+ uint32_t gsr_interface;
+ struct sockaddr_storage gsr_group;
+ struct sockaddr_storage gsr_source;
+};
+
+struct group_filter {
+ uint32_t gf_interface;
+ struct sockaddr_storage gf_group;
+ uint32_t gf_fmode;
+ uint32_t gf_numsrc;
+ struct sockaddr_storage gf_slist[1];
+};
+#define GROUP_FILTER_SIZE(numsrc) \
+ (sizeof(struct group_filter) - sizeof(struct sockaddr_storage) + \
+ (numsrc) * sizeof(struct sockaddr_storage))
+
+struct in_pktinfo {
+ int ipi_ifindex;
+ struct in_addr ipi_spec_dst;
+ struct in_addr ipi_addr;
+};
+
+struct in6_pktinfo {
+ struct in6_addr ipi6_addr;
+ unsigned ipi6_ifindex;
+};
+
+struct ip6_mtuinfo {
+ struct sockaddr_in6 ip6m_addr;
+ uint32_t ip6m_mtu;
+};
+#endif
+
+#define IPV6_ADDRFORM 1
+#define IPV6_2292PKTINFO 2
+#define IPV6_2292HOPOPTS 3
+#define IPV6_2292DSTOPTS 4
+#define IPV6_2292RTHDR 5
+#define IPV6_2292PKTOPTIONS 6
+#define IPV6_CHECKSUM 7
+#define IPV6_2292HOPLIMIT 8
+#define IPV6_NEXTHOP 9
+#define IPV6_AUTHHDR 10
+#define IPV6_UNICAST_HOPS 16
+#define IPV6_MULTICAST_IF 17
+#define IPV6_MULTICAST_HOPS 18
+#define IPV6_MULTICAST_LOOP 19
+#define IPV6_JOIN_GROUP 20
+#define IPV6_LEAVE_GROUP 21
+#define IPV6_ROUTER_ALERT 22
+#define IPV6_MTU_DISCOVER 23
+#define IPV6_MTU 24
+#define IPV6_RECVERR 25
+#define IPV6_V6ONLY 26
+#define IPV6_JOIN_ANYCAST 27
+#define IPV6_LEAVE_ANYCAST 28
+#define IPV6_IPSEC_POLICY 34
+#define IPV6_XFRM_POLICY 35
+#define IPV6_HDRINCL 36
+
+#define IPV6_RECVPKTINFO 49
+#define IPV6_PKTINFO 50
+#define IPV6_RECVHOPLIMIT 51
+#define IPV6_HOPLIMIT 52
+#define IPV6_RECVHOPOPTS 53
+#define IPV6_HOPOPTS 54
+#define IPV6_RTHDRDSTOPTS 55
+#define IPV6_RECVRTHDR 56
+#define IPV6_RTHDR 57
+#define IPV6_RECVDSTOPTS 58
+#define IPV6_DSTOPTS 59
+#define IPV6_RECVPATHMTU 60
+#define IPV6_PATHMTU 61
+#define IPV6_DONTFRAG 62
+#define IPV6_RECVTCLASS 66
+#define IPV6_TCLASS 67
+#define IPV6_AUTOFLOWLABEL 70
+#define IPV6_ADDR_PREFERENCES 72
+#define IPV6_MINHOPCOUNT 73
+#define IPV6_ORIGDSTADDR 74
+#define IPV6_RECVORIGDSTADDR IPV6_ORIGDSTADDR
+#define IPV6_TRANSPARENT 75
+#define IPV6_UNICAST_IF 76
+
+#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
+#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
+#define IPV6_RXHOPOPTS IPV6_HOPOPTS
+#define IPV6_RXDSTOPTS IPV6_DSTOPTS
+
+#define IPV6_PMTUDISC_DONT 0
+#define IPV6_PMTUDISC_WANT 1
+#define IPV6_PMTUDISC_DO 2
+#define IPV6_PMTUDISC_PROBE 3
+#define IPV6_PMTUDISC_INTERFACE 4
+#define IPV6_PMTUDISC_OMIT 5
+
+#define IPV6_PREFER_SRC_TMP 0x0001
+#define IPV6_PREFER_SRC_PUBLIC 0x0002
+#define IPV6_PREFER_SRC_PUBTMP_DEFAULT 0x0100
+#define IPV6_PREFER_SRC_COA 0x0004
+#define IPV6_PREFER_SRC_HOME 0x0400
+#define IPV6_PREFER_SRC_CGA 0x0008
+#define IPV6_PREFER_SRC_NONCGA 0x0800
+
+#define IPV6_RTHDR_LOOSE 0
+#define IPV6_RTHDR_STRICT 1
+
+#define IPV6_RTHDR_TYPE_0 0
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_NETINET_IN_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/in_systm.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/in_systm.h
new file mode 100644
index 0000000..8e688ab
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/in_systm.h
@@ -0,0 +1,9 @@
+#ifndef SYSROOT_NETINET_IN_SYSTM_H_
+#define SYSROOT_NETINET_IN_SYSTM_H_
+
+#include <stdint.h>
+
+typedef uint16_t n_short;
+typedef uint32_t n_long, n_time;
+
+#endif // SYSROOT_NETINET_IN_SYSTM_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/ip.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/ip.h
new file mode 100644
index 0000000..c795ef0
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/ip.h
@@ -0,0 +1,198 @@
+#ifndef SYSROOT_NETINET_IP_H_
+#define SYSROOT_NETINET_IP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <endian.h>
+#include <netinet/in.h>
+#include <stdint.h>
+
+struct timestamp {
+ uint8_t len;
+ uint8_t ptr;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int flags : 4;
+ unsigned int overflow : 4;
+#else
+ unsigned int overflow : 4;
+ unsigned int flags : 4;
+#endif
+ uint32_t data[9];
+};
+
+struct iphdr {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int ihl : 4;
+ unsigned int version : 4;
+#else
+ unsigned int version : 4;
+ unsigned int ihl : 4;
+#endif
+ uint8_t tos;
+ uint16_t tot_len;
+ uint16_t id;
+ uint16_t frag_off;
+ uint8_t ttl;
+ uint8_t protocol;
+ uint16_t check;
+ uint32_t saddr;
+ uint32_t daddr;
+};
+
+struct ip {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int ip_hl : 4;
+ unsigned int ip_v : 4;
+#else
+ unsigned int ip_v : 4;
+ unsigned int ip_hl : 4;
+#endif
+ uint8_t ip_tos;
+ uint16_t ip_len;
+ uint16_t ip_id;
+ uint16_t ip_off;
+ uint8_t ip_ttl;
+ uint8_t ip_p;
+ uint16_t ip_sum;
+ struct in_addr ip_src, ip_dst;
+};
+
+#define IP_RF 0x8000
+#define IP_DF 0x4000
+#define IP_MF 0x2000
+#define IP_OFFMASK 0x1fff
+
+struct ip_timestamp {
+ uint8_t ipt_code;
+ uint8_t ipt_len;
+ uint8_t ipt_ptr;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int ipt_flg : 4;
+ unsigned int ipt_oflw : 4;
+#else
+ unsigned int ipt_oflw : 4;
+ unsigned int ipt_flg : 4;
+#endif
+ uint32_t data[9];
+};
+
+#define IPVERSION 4
+#define IP_MAXPACKET 65535
+
+#define IPTOS_ECN_MASK 0x03
+#define IPTOS_ECN(x) ((x)&IPTOS_ECN_MASK)
+#define IPTOS_ECN_NOT_ECT 0x00
+#define IPTOS_ECN_ECT1 0x01
+#define IPTOS_ECN_ECT0 0x02
+#define IPTOS_ECN_CE 0x03
+
+#define IPTOS_DSCP_MASK 0xfc
+#define IPTOS_DSCP(x) ((x)&IPTOS_DSCP_MASK)
+#define IPTOS_DSCP_AF11 0x28
+#define IPTOS_DSCP_AF12 0x30
+#define IPTOS_DSCP_AF13 0x38
+#define IPTOS_DSCP_AF21 0x48
+#define IPTOS_DSCP_AF22 0x50
+#define IPTOS_DSCP_AF23 0x58
+#define IPTOS_DSCP_AF31 0x68
+#define IPTOS_DSCP_AF32 0x70
+#define IPTOS_DSCP_AF33 0x78
+#define IPTOS_DSCP_AF41 0x88
+#define IPTOS_DSCP_AF42 0x90
+#define IPTOS_DSCP_AF43 0x98
+#define IPTOS_DSCP_EF 0xb8
+
+#define IPTOS_CLASS_MASK 0xe0
+#define IPTOS_CLASS(x) ((x)&IPTOS_CLASS_MASK)
+#define IPTOS_CLASS_CS0 0x00
+#define IPTOS_CLASS_CS1 0x20
+#define IPTOS_CLASS_CS2 0x40
+#define IPTOS_CLASS_CS3 0x60
+#define IPTOS_CLASS_CS4 0x80
+#define IPTOS_CLASS_CS5 0xa0
+#define IPTOS_CLASS_CS6 0xc0
+#define IPTOS_CLASS_CS7 0xe0
+#define IPTOS_CLASS_DEFAULT IPTOS_CLASS_CS0
+
+#define IPTOS_TOS_MASK 0x1E
+#define IPTOS_TOS(tos) ((tos)&IPTOS_TOS_MASK)
+#define IPTOS_LOWDELAY 0x10
+#define IPTOS_THROUGHPUT 0x08
+#define IPTOS_RELIABILITY 0x04
+#define IPTOS_LOWCOST 0x02
+#define IPTOS_MINCOST IPTOS_LOWCOST
+
+#define IPTOS_PREC_MASK 0xe0
+#define IPTOS_PREC(tos) ((tos)&IPTOS_PREC_MASK)
+#define IPTOS_PREC_NETCONTROL 0xe0
+#define IPTOS_PREC_INTERNETCONTROL 0xc0
+#define IPTOS_PREC_CRITIC_ECP 0xa0
+#define IPTOS_PREC_FLASHOVERRIDE 0x80
+#define IPTOS_PREC_FLASH 0x60
+#define IPTOS_PREC_IMMEDIATE 0x40
+#define IPTOS_PREC_PRIORITY 0x20
+#define IPTOS_PREC_ROUTINE 0x00
+
+#define IPOPT_COPY 0x80
+#define IPOPT_CLASS_MASK 0x60
+#define IPOPT_NUMBER_MASK 0x1f
+
+#define IPOPT_COPIED(o) ((o)&IPOPT_COPY)
+#define IPOPT_CLASS(o) ((o)&IPOPT_CLASS_MASK)
+#define IPOPT_NUMBER(o) ((o)&IPOPT_NUMBER_MASK)
+
+#define IPOPT_CONTROL 0x00
+#define IPOPT_RESERVED1 0x20
+#define IPOPT_DEBMEAS 0x40
+#define IPOPT_MEASUREMENT IPOPT_DEBMEAS
+#define IPOPT_RESERVED2 0x60
+
+#define IPOPT_EOL 0
+#define IPOPT_END IPOPT_EOL
+#define IPOPT_NOP 1
+#define IPOPT_NOOP IPOPT_NOP
+
+#define IPOPT_RR 7
+#define IPOPT_TS 68
+#define IPOPT_TIMESTAMP IPOPT_TS
+#define IPOPT_SECURITY 130
+#define IPOPT_SEC IPOPT_SECURITY
+#define IPOPT_LSRR 131
+#define IPOPT_SATID 136
+#define IPOPT_SID IPOPT_SATID
+#define IPOPT_SSRR 137
+#define IPOPT_RA 148
+
+#define IPOPT_OPTVAL 0
+#define IPOPT_OLEN 1
+#define IPOPT_OFFSET 2
+#define IPOPT_MINOFF 4
+
+#define MAX_IPOPTLEN 40
+
+#define IPOPT_TS_TSONLY 0
+#define IPOPT_TS_TSANDADDR 1
+#define IPOPT_TS_PRESPEC 3
+
+#define IPOPT_SECUR_UNCLASS 0x0000
+#define IPOPT_SECUR_CONFID 0xf135
+#define IPOPT_SECUR_EFTO 0x789a
+#define IPOPT_SECUR_MMMM 0xbc4d
+#define IPOPT_SECUR_RESTR 0xaf13
+#define IPOPT_SECUR_SECRET 0xd788
+#define IPOPT_SECUR_TOPSECRET 0x6bc5
+
+#define MAXTTL 255
+#define IPDEFTTL 64
+#define IPFRAGTTL 60
+#define IPTTLDEC 1
+
+#define IP_MSS 576
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_NETINET_IP_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/ip6.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/ip6.h
new file mode 100644
index 0000000..45f1c68
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/ip6.h
@@ -0,0 +1,142 @@
+#ifndef SYSROOT_NETINET_IP6_H_
+#define SYSROOT_NETINET_IP6_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <endian.h>
+#include <netinet/in.h>
+#include <stdint.h>
+
+struct ip6_hdr {
+ union {
+ struct ip6_hdrctl {
+ uint32_t ip6_un1_flow;
+ uint16_t ip6_un1_plen;
+ uint8_t ip6_un1_nxt;
+ uint8_t ip6_un1_hlim;
+ } ip6_un1;
+ uint8_t ip6_un2_vfc;
+ } ip6_ctlun;
+ struct in6_addr ip6_src;
+ struct in6_addr ip6_dst;
+};
+
+#define ip6_vfc ip6_ctlun.ip6_un2_vfc
+#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow
+#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen
+#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt
+#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim
+#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim
+
+struct ip6_ext {
+ uint8_t ip6e_nxt;
+ uint8_t ip6e_len;
+};
+
+struct ip6_hbh {
+ uint8_t ip6h_nxt;
+ uint8_t ip6h_len;
+};
+
+struct ip6_dest {
+ uint8_t ip6d_nxt;
+ uint8_t ip6d_len;
+};
+
+struct ip6_rthdr {
+ uint8_t ip6r_nxt;
+ uint8_t ip6r_len;
+ uint8_t ip6r_type;
+ uint8_t ip6r_segleft;
+};
+
+struct ip6_rthdr0 {
+ uint8_t ip6r0_nxt;
+ uint8_t ip6r0_len;
+ uint8_t ip6r0_type;
+ uint8_t ip6r0_segleft;
+ uint8_t ip6r0_reserved;
+ uint8_t ip6r0_slmap[3];
+ struct in6_addr ip6r0_addr[];
+};
+
+struct ip6_frag {
+ uint8_t ip6f_nxt;
+ uint8_t ip6f_reserved;
+ uint16_t ip6f_offlg;
+ uint32_t ip6f_ident;
+};
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define IP6F_OFF_MASK 0xfff8
+#define IP6F_RESERVED_MASK 0x0006
+#define IP6F_MORE_FRAG 0x0001
+#else
+#define IP6F_OFF_MASK 0xf8ff
+#define IP6F_RESERVED_MASK 0x0600
+#define IP6F_MORE_FRAG 0x0100
+#endif
+
+struct ip6_opt {
+ uint8_t ip6o_type;
+ uint8_t ip6o_len;
+};
+
+#define IP6OPT_TYPE(o) ((o)&0xc0)
+#define IP6OPT_TYPE_SKIP 0x00
+#define IP6OPT_TYPE_DISCARD 0x40
+#define IP6OPT_TYPE_FORCEICMP 0x80
+#define IP6OPT_TYPE_ICMP 0xc0
+#define IP6OPT_TYPE_MUTABLE 0x20
+
+#define IP6OPT_PAD1 0
+#define IP6OPT_PADN 1
+
+#define IP6OPT_JUMBO 0xc2
+#define IP6OPT_NSAP_ADDR 0xc3
+#define IP6OPT_TUNNEL_LIMIT 0x04
+#define IP6OPT_ROUTER_ALERT 0x05
+
+struct ip6_opt_jumbo {
+ uint8_t ip6oj_type;
+ uint8_t ip6oj_len;
+ uint8_t ip6oj_jumbo_len[4];
+};
+#define IP6OPT_JUMBO_LEN 6
+
+struct ip6_opt_nsap {
+ uint8_t ip6on_type;
+ uint8_t ip6on_len;
+ uint8_t ip6on_src_nsap_len;
+ uint8_t ip6on_dst_nsap_len;
+};
+
+struct ip6_opt_tunnel {
+ uint8_t ip6ot_type;
+ uint8_t ip6ot_len;
+ uint8_t ip6ot_encap_limit;
+};
+
+struct ip6_opt_router {
+ uint8_t ip6or_type;
+ uint8_t ip6or_len;
+ uint8_t ip6or_value[2];
+};
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define IP6_ALERT_MLD 0x0000
+#define IP6_ALERT_RSVP 0x0001
+#define IP6_ALERT_AN 0x0002
+#else
+#define IP6_ALERT_MLD 0x0000
+#define IP6_ALERT_RSVP 0x0100
+#define IP6_ALERT_AN 0x0200
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_NETINET_IP6_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/ip_icmp.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/ip_icmp.h
new file mode 100644
index 0000000..c239456
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/ip_icmp.h
@@ -0,0 +1,189 @@
+#ifndef SYSROOT_NETINET_IP_ICMP_H_
+#define SYSROOT_NETINET_IP_ICMP_H_
+
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct icmphdr {
+ uint8_t type;
+ uint8_t code;
+ uint16_t checksum;
+ union {
+ struct {
+ uint16_t id;
+ uint16_t sequence;
+ } echo;
+ uint32_t gateway;
+ struct {
+ uint16_t __unused;
+ uint16_t mtu;
+ } frag;
+ } un;
+};
+
+#define ICMP_ECHOREPLY 0
+#define ICMP_DEST_UNREACH 3
+#define ICMP_SOURCE_QUENCH 4
+#define ICMP_REDIRECT 5
+#define ICMP_ECHO 8
+#define ICMP_TIME_EXCEEDED 11
+#define ICMP_PARAMETERPROB 12
+#define ICMP_TIMESTAMP 13
+#define ICMP_TIMESTAMPREPLY 14
+#define ICMP_INFO_REQUEST 15
+#define ICMP_INFO_REPLY 16
+#define ICMP_ADDRESS 17
+#define ICMP_ADDRESSREPLY 18
+#define NR_ICMP_TYPES 18
+
+#define ICMP_NET_UNREACH 0
+#define ICMP_HOST_UNREACH 1
+#define ICMP_PROT_UNREACH 2
+#define ICMP_PORT_UNREACH 3
+#define ICMP_FRAG_NEEDED 4
+#define ICMP_SR_FAILED 5
+#define ICMP_NET_UNKNOWN 6
+#define ICMP_HOST_UNKNOWN 7
+#define ICMP_HOST_ISOLATED 8
+#define ICMP_NET_ANO 9
+#define ICMP_HOST_ANO 10
+#define ICMP_NET_UNR_TOS 11
+#define ICMP_HOST_UNR_TOS 12
+#define ICMP_PKT_FILTERED 13
+#define ICMP_PREC_VIOLATION 14
+#define ICMP_PREC_CUTOFF 15
+#define NR_ICMP_UNREACH 15
+
+#define ICMP_REDIR_NET 0
+#define ICMP_REDIR_HOST 1
+#define ICMP_REDIR_NETTOS 2
+#define ICMP_REDIR_HOSTTOS 3
+
+#define ICMP_EXC_TTL 0
+#define ICMP_EXC_FRAGTIME 1
+
+struct icmp_ra_addr {
+ uint32_t ira_addr;
+ uint32_t ira_preference;
+};
+
+struct icmp {
+ uint8_t icmp_type;
+ uint8_t icmp_code;
+ uint16_t icmp_cksum;
+ union {
+ uint8_t ih_pptr;
+ struct in_addr ih_gwaddr;
+ struct ih_idseq {
+ uint16_t icd_id;
+ uint16_t icd_seq;
+ } ih_idseq;
+ uint32_t ih_void;
+
+ struct ih_pmtu {
+ uint16_t ipm_void;
+ uint16_t ipm_nextmtu;
+ } ih_pmtu;
+
+ struct ih_rtradv {
+ uint8_t irt_num_addrs;
+ uint8_t irt_wpa;
+ uint16_t irt_lifetime;
+ } ih_rtradv;
+ } icmp_hun;
+ union {
+ struct {
+ uint32_t its_otime;
+ uint32_t its_rtime;
+ uint32_t its_ttime;
+ } id_ts;
+ struct {
+ struct ip idi_ip;
+ } id_ip;
+ struct icmp_ra_addr id_radv;
+ uint32_t id_mask;
+ uint8_t id_data[1];
+ } icmp_dun;
+};
+
+#define icmp_pptr icmp_hun.ih_pptr
+#define icmp_gwaddr icmp_hun.ih_gwaddr
+#define icmp_id icmp_hun.ih_idseq.icd_id
+#define icmp_seq icmp_hun.ih_idseq.icd_seq
+#define icmp_void icmp_hun.ih_void
+#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void
+#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu
+#define icmp_num_addrs icmp_hun.ih_rtradv.irt_num_addrs
+#define icmp_wpa icmp_hun.ih_rtradv.irt_wpa
+#define icmp_lifetime icmp_hun.ih_rtradv.irt_lifetime
+#define icmp_otime icmp_dun.id_ts.its_otime
+#define icmp_rtime icmp_dun.id_ts.its_rtime
+#define icmp_ttime icmp_dun.id_ts.its_ttime
+#define icmp_ip icmp_dun.id_ip.idi_ip
+#define icmp_radv icmp_dun.id_radv
+#define icmp_mask icmp_dun.id_mask
+#define icmp_data icmp_dun.id_data
+
+#define ICMP_MINLEN 8
+#define ICMP_TSLEN (8 + 3 * sizeof(n_time))
+#define ICMP_MASKLEN 12
+#define ICMP_ADVLENMIN (8 + sizeof(struct ip) + 8)
+#define ICMP_ADVLEN(p) (8 + ((p)->icmp_ip.ip_hl << 2) + 8)
+
+#define ICMP_UNREACH 3
+#define ICMP_SOURCEQUENCH 4
+#define ICMP_ROUTERADVERT 9
+#define ICMP_ROUTERSOLICIT 10
+#define ICMP_TIMXCEED 11
+#define ICMP_PARAMPROB 12
+#define ICMP_TSTAMP 13
+#define ICMP_TSTAMPREPLY 14
+#define ICMP_IREQ 15
+#define ICMP_IREQREPLY 16
+#define ICMP_MASKREQ 17
+#define ICMP_MASKREPLY 18
+#define ICMP_MAXTYPE 18
+
+#define ICMP_UNREACH_NET 0
+#define ICMP_UNREACH_HOST 1
+#define ICMP_UNREACH_PROTOCOL 2
+#define ICMP_UNREACH_PORT 3
+#define ICMP_UNREACH_NEEDFRAG 4
+#define ICMP_UNREACH_SRCFAIL 5
+#define ICMP_UNREACH_NET_UNKNOWN 6
+#define ICMP_UNREACH_HOST_UNKNOWN 7
+#define ICMP_UNREACH_ISOLATED 8
+#define ICMP_UNREACH_NET_PROHIB 9
+#define ICMP_UNREACH_HOST_PROHIB 10
+#define ICMP_UNREACH_TOSNET 11
+#define ICMP_UNREACH_TOSHOST 12
+#define ICMP_UNREACH_FILTER_PROHIB 13
+#define ICMP_UNREACH_HOST_PRECEDENCE 14
+#define ICMP_UNREACH_PRECEDENCE_CUTOFF 15
+
+#define ICMP_REDIRECT_NET 0
+#define ICMP_REDIRECT_HOST 1
+#define ICMP_REDIRECT_TOSNET 2
+#define ICMP_REDIRECT_TOSHOST 3
+
+#define ICMP_TIMXCEED_INTRANS 0
+#define ICMP_TIMXCEED_REASS 1
+
+#define ICMP_PARAMPROB_OPTABSENT 1
+
+#define ICMP_INFOTYPE(type) \
+ ((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || (type) == ICMP_ROUTERADVERT || \
+ (type) == ICMP_ROUTERSOLICIT || (type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \
+ (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || (type) == ICMP_MASKREQ || \
+ (type) == ICMP_MASKREPLY)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_NETINET_IP_ICMP_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/tcp.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/tcp.h
new file mode 100644
index 0000000..e892dd2
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/tcp.h
@@ -0,0 +1,201 @@
+#ifndef SYSROOT_NETINET_TCP_H_
+#define SYSROOT_NETINET_TCP_H_
+
+#include <features.h>
+
+#define TCP_NODELAY 1
+#define TCP_MAXSEG 2
+#define TCP_CORK 3
+#define TCP_KEEPIDLE 4
+#define TCP_KEEPINTVL 5
+#define TCP_KEEPCNT 6
+#define TCP_SYNCNT 7
+#define TCP_LINGER2 8
+#define TCP_DEFER_ACCEPT 9
+#define TCP_WINDOW_CLAMP 10
+#define TCP_INFO 11
+#define TCP_QUICKACK 12
+#define TCP_CONGESTION 13
+#define TCP_MD5SIG 14
+#define TCP_THIN_LINEAR_TIMEOUTS 16
+#define TCP_THIN_DUPACK 17
+#define TCP_USER_TIMEOUT 18
+#define TCP_REPAIR 19
+#define TCP_REPAIR_QUEUE 20
+#define TCP_QUEUE_SEQ 21
+#define TCP_REPAIR_OPTIONS 22
+#define TCP_FASTOPEN 23
+#define TCP_TIMESTAMP 24
+#define TCP_NOTSENT_LOWAT 25
+#define TCP_CC_INFO 26
+#define TCP_SAVE_SYN 27
+#define TCP_SAVED_SYN 28
+
+#define TCP_ESTABLISHED 1
+#define TCP_SYN_SENT 2
+#define TCP_SYN_RECV 3
+#define TCP_FIN_WAIT1 4
+#define TCP_FIN_WAIT2 5
+#define TCP_TIME_WAIT 6
+#define TCP_CLOSE 7
+#define TCP_CLOSE_WAIT 8
+#define TCP_LAST_ACK 9
+#define TCP_LISTEN 10
+#define TCP_CLOSING 11
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define TCPOPT_EOL 0
+#define TCPOPT_NOP 1
+#define TCPOPT_MAXSEG 2
+#define TCPOPT_WINDOW 3
+#define TCPOPT_SACK_PERMITTED 4
+#define TCPOPT_SACK 5
+#define TCPOPT_TIMESTAMP 8
+#define TCPOLEN_SACK_PERMITTED 2
+#define TCPOLEN_WINDOW 3
+#define TCPOLEN_MAXSEG 4
+#define TCPOLEN_TIMESTAMP 10
+
+#define SOL_TCP 6
+
+#include <endian.h>
+#include <stdint.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+typedef uint32_t tcp_seq;
+
+#define TH_FIN 0x01
+#define TH_SYN 0x02
+#define TH_RST 0x04
+#define TH_PUSH 0x08
+#define TH_ACK 0x10
+#define TH_URG 0x20
+
+struct tcphdr {
+#ifdef _GNU_SOURCE
+#ifdef __GNUC__
+ __extension__
+#endif
+ union {
+ struct {
+ uint16_t source;
+ uint16_t dest;
+ uint32_t seq;
+ uint32_t ack_seq;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ uint16_t res1 : 4;
+ uint16_t doff : 4;
+ uint16_t fin : 1;
+ uint16_t syn : 1;
+ uint16_t rst : 1;
+ uint16_t psh : 1;
+ uint16_t ack : 1;
+ uint16_t urg : 1;
+ uint16_t res2 : 2;
+#else
+ uint16_t doff : 4;
+ uint16_t res1 : 4;
+ uint16_t res2 : 2;
+ uint16_t urg : 1;
+ uint16_t ack : 1;
+ uint16_t psh : 1;
+ uint16_t rst : 1;
+ uint16_t syn : 1;
+ uint16_t fin : 1;
+#endif
+ uint16_t window;
+ uint16_t check;
+ uint16_t urg_ptr;
+ };
+ struct {
+#endif
+
+ uint16_t th_sport;
+ uint16_t th_dport;
+ uint32_t th_seq;
+ uint32_t th_ack;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ uint8_t th_x2 : 4;
+ uint8_t th_off : 4;
+#else
+ uint8_t th_off : 4;
+ uint8_t th_x2 : 4;
+#endif
+ uint8_t th_flags;
+ uint16_t th_win;
+ uint16_t th_sum;
+ uint16_t th_urp;
+
+#ifdef _GNU_SOURCE
+ };
+ };
+#endif
+};
+#endif
+
+#ifdef _GNU_SOURCE
+#define TCPI_OPT_TIMESTAMPS 1
+#define TCPI_OPT_SACK 2
+#define TCPI_OPT_WSCALE 4
+#define TCPI_OPT_ECN 8
+
+#define TCP_CA_Open 0
+#define TCP_CA_Disorder 1
+#define TCP_CA_CWR 2
+#define TCP_CA_Recovery 3
+#define TCP_CA_Loss 4
+
+struct tcp_info {
+ uint8_t tcpi_state;
+ uint8_t tcpi_ca_state;
+ uint8_t tcpi_retransmits;
+ uint8_t tcpi_probes;
+ uint8_t tcpi_backoff;
+ uint8_t tcpi_options;
+ uint8_t tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4;
+ uint32_t tcpi_rto;
+ uint32_t tcpi_ato;
+ uint32_t tcpi_snd_mss;
+ uint32_t tcpi_rcv_mss;
+ uint32_t tcpi_unacked;
+ uint32_t tcpi_sacked;
+ uint32_t tcpi_lost;
+ uint32_t tcpi_retrans;
+ uint32_t tcpi_fackets;
+ uint32_t tcpi_last_data_sent;
+ uint32_t tcpi_last_ack_sent;
+ uint32_t tcpi_last_data_recv;
+ uint32_t tcpi_last_ack_recv;
+ uint32_t tcpi_pmtu;
+ uint32_t tcpi_rcv_ssthresh;
+ uint32_t tcpi_rtt;
+ uint32_t tcpi_rttvar;
+ uint32_t tcpi_snd_ssthresh;
+ uint32_t tcpi_snd_cwnd;
+ uint32_t tcpi_advmss;
+ uint32_t tcpi_reordering;
+ uint32_t tcpi_rcv_rtt;
+ uint32_t tcpi_rcv_space;
+ uint32_t tcpi_total_retrans;
+ uint64_t tcpi_pacing_rate;
+ uint64_t tcpi_max_pacing_rate;
+ uint64_t tcpi_bytes_acked;
+ uint64_t tcpi_bytes_received;
+ uint32_t tcpi_segs_out;
+ uint32_t tcpi_segs_in;
+};
+
+#define TCP_MD5SIG_MAXKEYLEN 80
+
+struct tcp_md5sig {
+ struct sockaddr_storage tcpm_addr;
+ uint16_t __tcpm_pad1;
+ uint16_t tcpm_keylen;
+ uint32_t __tcpm_pad2;
+ uint8_t tcpm_key[TCP_MD5SIG_MAXKEYLEN];
+};
+
+#endif
+
+#endif // SYSROOT_NETINET_TCP_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/udp.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/udp.h
new file mode 100644
index 0000000..1a0fba7
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/netinet/udp.h
@@ -0,0 +1,38 @@
+#ifndef SYSROOT_NETINET_UDP_H_
+#define SYSROOT_NETINET_UDP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <stdint.h>
+
+#ifdef _GNU_SOURCE
+#define uh_sport source
+#define uh_dport dest
+#define uh_ulen len
+#define uh_sum check
+#endif
+
+struct udphdr {
+ uint16_t uh_sport;
+ uint16_t uh_dport;
+ uint16_t uh_ulen;
+ uint16_t uh_sum;
+};
+
+#define UDP_CORK 1
+#define UDP_ENCAP 100
+
+#define UDP_ENCAP_ESPINUDP_NON_IKE 1
+#define UDP_ENCAP_ESPINUDP 2
+#define UDP_ENCAP_L2TPINUDP 3
+
+#define SOL_UDP 17
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_NETINET_UDP_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/netpacket/packet.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/netpacket/packet.h
new file mode 100644
index 0000000..3066046
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/netpacket/packet.h
@@ -0,0 +1,61 @@
+#ifndef SYSROOT_NETPACKET_PACKET_H_
+#define SYSROOT_NETPACKET_PACKET_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct sockaddr_ll {
+ unsigned short sll_family, sll_protocol;
+ int sll_ifindex;
+ unsigned short sll_hatype;
+ unsigned char sll_pkttype, sll_halen;
+ unsigned char sll_addr[8];
+};
+
+struct packet_mreq {
+ int mr_ifindex;
+ unsigned short int mr_type, mr_alen;
+ unsigned char mr_address[8];
+};
+
+#define PACKET_HOST 0
+#define PACKET_BROADCAST 1
+#define PACKET_MULTICAST 2
+#define PACKET_OTHERHOST 3
+#define PACKET_OUTGOING 4
+#define PACKET_LOOPBACK 5
+#define PACKET_FASTROUTE 6
+
+#define PACKET_ADD_MEMBERSHIP 1
+#define PACKET_DROP_MEMBERSHIP 2
+#define PACKET_RECV_OUTPUT 3
+#define PACKET_RX_RING 5
+#define PACKET_STATISTICS 6
+#define PACKET_COPY_THRESH 7
+#define PACKET_AUXDATA 8
+#define PACKET_ORIGDEV 9
+#define PACKET_VERSION 10
+#define PACKET_HDRLEN 11
+#define PACKET_RESERVE 12
+#define PACKET_TX_RING 13
+#define PACKET_LOSS 14
+#define PACKET_VNET_HDR 15
+#define PACKET_TX_TIMESTAMP 16
+#define PACKET_TIMESTAMP 17
+#define PACKET_FANOUT 18
+#define PACKET_TX_HAS_OFF 19
+#define PACKET_QDISC_BYPASS 20
+#define PACKET_ROLLOVER_STATS 21
+#define PACKET_FANOUT_DATA 22
+
+#define PACKET_MR_MULTICAST 0
+#define PACKET_MR_PROMISC 1
+#define PACKET_MR_ALLMULTI 2
+#define PACKET_MR_UNICAST 3
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_NETPACKET_PACKET_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/nl_types.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/nl_types.h
new file mode 100644
index 0000000..e30f86e
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/nl_types.h
@@ -0,0 +1,22 @@
+#ifndef SYSROOT_NL_TYPES_H_
+#define SYSROOT_NL_TYPES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NL_SETD 1
+#define NL_CAT_LOCALE 1
+
+typedef int nl_item;
+typedef void* nl_catd;
+
+nl_catd catopen(const char*, int);
+char* catgets(nl_catd, int, int, const char*);
+int catclose(nl_catd);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_NL_TYPES_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/paths.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/paths.h
new file mode 100644
index 0000000..0ff06aa
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/paths.h
@@ -0,0 +1,28 @@
+#ifndef SYSROOT_PATHS_H_
+#define SYSROOT_PATHS_H_
+
+#define _PATH_DEFPATH "/usr/local/bin:/bin:/usr/bin"
+#define _PATH_STDPATH "/bin:/usr/bin:/sbin:/usr/sbin"
+
+#define _PATH_BSHELL "/bin/sh"
+#define _PATH_CONSOLE "/dev/console"
+#define _PATH_DEVNULL "/dev/null"
+#define _PATH_KLOG "/proc/kmsg"
+#define _PATH_MAILDIR "/var/mail"
+#define _PATH_MAN "/usr/share/man"
+#define _PATH_MNTTAB "/etc/fstab"
+#define _PATH_MOUNTED "/etc/mtab"
+#define _PATH_NOLOGIN "/etc/nologin"
+#define _PATH_SENDMAIL "/usr/sbin/sendmail"
+#define _PATH_SHELLS "/etc/shells"
+#define _PATH_TTY "/dev/tty"
+#define _PATH_VI "/usr/bin/vi"
+#define _PATH_WTMP "/dev/null/wtmp"
+
+#define _PATH_DEV "/dev/"
+#define _PATH_TMP "/tmp/"
+#define _PATH_VARDB "/var/lib/misc/"
+#define _PATH_VARRUN "/var/run/"
+#define _PATH_VARTMP "/var/tmp/"
+
+#endif // SYSROOT_PATHS_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/poll.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/poll.h
new file mode 100644
index 0000000..4c7c800
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/poll.h
@@ -0,0 +1,51 @@
+#ifndef SYSROOT_POLL_H_
+#define SYSROOT_POLL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <bits/poll.h>
+
+#define POLLIN 0x001
+#define POLLPRI 0x002
+#define POLLOUT 0x004
+#define POLLERR 0x008
+#define POLLHUP 0x010
+#define POLLNVAL 0x020
+#define POLLRDNORM 0x040
+#define POLLRDBAND 0x080
+#ifndef POLLWRNORM
+#define POLLWRNORM 0x100
+#define POLLWRBAND 0x200
+#endif
+#ifndef POLLMSG
+#define POLLMSG 0x400
+#define POLLRDHUP 0x2000
+#endif
+
+typedef unsigned long nfds_t;
+
+struct pollfd {
+ int fd;
+ short events;
+ short revents;
+};
+
+int poll(struct pollfd*, nfds_t, int);
+
+#ifdef _GNU_SOURCE
+#define __NEED_time_t
+#define __NEED_struct_timespec
+#define __NEED_sigset_t
+#include <bits/alltypes.h>
+int ppoll(struct pollfd*, nfds_t, const struct timespec*, const sigset_t*);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_POLL_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/pthread.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/pthread.h
new file mode 100644
index 0000000..d4b9f00
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/pthread.h
@@ -0,0 +1,200 @@
+#ifndef SYSROOT_PTHREAD_H_
+#define SYSROOT_PTHREAD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_time_t
+#define __NEED_clockid_t
+#define __NEED_struct_timespec
+#define __NEED_sigset_t
+#define __NEED_pthread_t
+#define __NEED_pthread_attr_t
+#define __NEED_pthread_mutexattr_t
+#define __NEED_pthread_condattr_t
+#define __NEED_pthread_rwlockattr_t
+#define __NEED_pthread_barrierattr_t
+#define __NEED_pthread_mutex_t
+#define __NEED_pthread_cond_t
+#define __NEED_pthread_rwlock_t
+#define __NEED_pthread_barrier_t
+#define __NEED_pthread_spinlock_t
+#define __NEED_pthread_key_t
+#define __NEED_pthread_once_t
+#define __NEED_size_t
+
+#include <sched.h>
+#include <time.h>
+
+#include <bits/alltypes.h>
+
+#define PTHREAD_CREATE_JOINABLE 0
+#define PTHREAD_CREATE_DETACHED 1
+
+#define PTHREAD_MUTEX_NORMAL 0
+#define PTHREAD_MUTEX_DEFAULT 0
+#define PTHREAD_MUTEX_RECURSIVE 1
+#define PTHREAD_MUTEX_ERRORCHECK 2
+
+#define PTHREAD_MUTEX_STALLED 0
+#define PTHREAD_MUTEX_ROBUST 1
+
+#define PTHREAD_PRIO_NONE 0
+#define PTHREAD_PRIO_INHERIT 1
+#define PTHREAD_PRIO_PROTECT 2
+
+#define PTHREAD_INHERIT_SCHED 0
+#define PTHREAD_EXPLICIT_SCHED 1
+
+#define PTHREAD_SCOPE_SYSTEM 0
+#define PTHREAD_SCOPE_PROCESS 1
+
+#define PTHREAD_PROCESS_PRIVATE 0
+
+#define PTHREAD_MUTEX_INITIALIZER \
+ {}
+#define PTHREAD_RWLOCK_INITIALIZER \
+ {}
+#define PTHREAD_COND_INITIALIZER \
+ {}
+#define PTHREAD_ONCE_INIT 0
+
+#define PTHREAD_CANCEL_ENABLE 0
+#define PTHREAD_CANCEL_DISABLE 1
+#define PTHREAD_CANCEL_MASKED 2
+
+#define PTHREAD_CANCEL_DEFERRED 0
+#define PTHREAD_CANCEL_ASYNCHRONOUS 1
+
+#define PTHREAD_CANCELED ((void*)-1)
+
+#define PTHREAD_BARRIER_SERIAL_THREAD (-1)
+
+int pthread_create(pthread_t* __restrict, const pthread_attr_t* __restrict, void* (*)(void*),
+ void* __restrict);
+int pthread_detach(pthread_t);
+_Noreturn void pthread_exit(void*);
+int pthread_join(pthread_t, void**);
+
+pthread_t pthread_self(void);
+
+int pthread_equal(pthread_t, pthread_t);
+#ifndef __cplusplus
+#define pthread_equal(x, y) ((x) == (y))
+#endif
+
+int pthread_setcancelstate(int, int*);
+int pthread_setcanceltype(int, int*);
+void pthread_testcancel(void);
+int pthread_cancel(pthread_t);
+
+int pthread_once(pthread_once_t*, void (*)(void));
+
+int pthread_mutex_init(pthread_mutex_t* __restrict, const pthread_mutexattr_t* __restrict);
+int pthread_mutex_lock(pthread_mutex_t*);
+int pthread_mutex_unlock(pthread_mutex_t*);
+int pthread_mutex_trylock(pthread_mutex_t*);
+int pthread_mutex_timedlock(pthread_mutex_t* __restrict, const struct timespec* __restrict);
+int pthread_mutex_destroy(pthread_mutex_t*);
+int pthread_mutex_consistent(pthread_mutex_t*);
+
+int pthread_mutex_getprioceiling(const pthread_mutex_t* __restrict, int* __restrict);
+int pthread_mutex_setprioceiling(pthread_mutex_t* __restrict, int, int* __restrict);
+
+int pthread_cond_init(pthread_cond_t* __restrict, const pthread_condattr_t* __restrict);
+int pthread_cond_destroy(pthread_cond_t*);
+int pthread_cond_wait(pthread_cond_t* __restrict, pthread_mutex_t* __restrict);
+int pthread_cond_timedwait(pthread_cond_t* __restrict, pthread_mutex_t* __restrict,
+ const struct timespec* __restrict);
+int pthread_cond_broadcast(pthread_cond_t*);
+int pthread_cond_signal(pthread_cond_t*);
+
+int pthread_rwlock_init(pthread_rwlock_t* __restrict, const pthread_rwlockattr_t* __restrict);
+int pthread_rwlock_destroy(pthread_rwlock_t*);
+int pthread_rwlock_rdlock(pthread_rwlock_t*);
+int pthread_rwlock_tryrdlock(pthread_rwlock_t*);
+int pthread_rwlock_timedrdlock(pthread_rwlock_t* __restrict, const struct timespec* __restrict);
+int pthread_rwlock_wrlock(pthread_rwlock_t*);
+int pthread_rwlock_trywrlock(pthread_rwlock_t*);
+int pthread_rwlock_timedwrlock(pthread_rwlock_t* __restrict, const struct timespec* __restrict);
+int pthread_rwlock_unlock(pthread_rwlock_t*);
+
+int pthread_spin_init(pthread_spinlock_t*, int);
+int pthread_spin_destroy(pthread_spinlock_t*);
+int pthread_spin_lock(pthread_spinlock_t*);
+int pthread_spin_trylock(pthread_spinlock_t*);
+int pthread_spin_unlock(pthread_spinlock_t*);
+
+int pthread_barrier_init(pthread_barrier_t* __restrict, const pthread_barrierattr_t* __restrict,
+ unsigned);
+int pthread_barrier_destroy(pthread_barrier_t*);
+int pthread_barrier_wait(pthread_barrier_t*);
+
+int pthread_key_create(pthread_key_t*, void (*)(void*));
+int pthread_key_delete(pthread_key_t);
+void* pthread_getspecific(pthread_key_t);
+int pthread_setspecific(pthread_key_t, const void*);
+
+int pthread_attr_init(pthread_attr_t*);
+int pthread_attr_destroy(pthread_attr_t*);
+
+int pthread_attr_getguardsize(const pthread_attr_t* __restrict, size_t* __restrict);
+int pthread_attr_setguardsize(pthread_attr_t*, size_t);
+int pthread_attr_getstacksize(const pthread_attr_t* __restrict, size_t* __restrict);
+int pthread_attr_setstacksize(pthread_attr_t*, size_t);
+int pthread_attr_getdetachstate(const pthread_attr_t*, int*);
+int pthread_attr_setdetachstate(pthread_attr_t*, int);
+int pthread_attr_getstack(const pthread_attr_t* __restrict, void** __restrict, size_t* __restrict);
+int pthread_attr_setstack(pthread_attr_t*, void*, size_t) __attribute__((__deprecated__(
+ "pthread_attr_setstack is not available in Fuchsia; perhaps pthread_attr_setstacksize and/or "
+ "pthread_attr_setguardsize is sufficient for your needs?")));
+int pthread_attr_getschedparam(const pthread_attr_t* __restrict, struct sched_param* __restrict);
+int pthread_attr_setschedparam(pthread_attr_t* __restrict, const struct sched_param* __restrict);
+
+int pthread_mutexattr_destroy(pthread_mutexattr_t*);
+int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t* __restrict, int* __restrict);
+int pthread_mutexattr_getprotocol(const pthread_mutexattr_t* __restrict, int* __restrict);
+int pthread_mutexattr_getrobust(const pthread_mutexattr_t* __restrict, int* __restrict);
+int pthread_mutexattr_gettype(const pthread_mutexattr_t* __restrict, int* __restrict);
+int pthread_mutexattr_init(pthread_mutexattr_t*);
+int pthread_mutexattr_setprioceiling(pthread_mutexattr_t*, int);
+int pthread_mutexattr_setprotocol(pthread_mutexattr_t*, int);
+int pthread_mutexattr_setrobust(pthread_mutexattr_t*, int);
+int pthread_mutexattr_settype(pthread_mutexattr_t*, int);
+
+int pthread_condattr_init(pthread_condattr_t*);
+int pthread_condattr_destroy(pthread_condattr_t*);
+int pthread_condattr_setclock(pthread_condattr_t*, clockid_t);
+int pthread_condattr_getclock(const pthread_condattr_t* __restrict, clockid_t* __restrict);
+
+int pthread_rwlockattr_init(pthread_rwlockattr_t*);
+int pthread_rwlockattr_destroy(pthread_rwlockattr_t*);
+
+int pthread_barrierattr_destroy(pthread_barrierattr_t*);
+int pthread_barrierattr_init(pthread_barrierattr_t*);
+
+int pthread_atfork(void (*)(void), void (*)(void), void (*)(void));
+
+int pthread_getconcurrency(void);
+int pthread_setconcurrency(int);
+
+int pthread_getcpuclockid(pthread_t, clockid_t*);
+
+#define pthread_cleanup_push(f, x)
+#define pthread_cleanup_pop(r)
+
+#ifdef _GNU_SOURCE
+struct cpu_set_t;
+int pthread_getaffinity_np(pthread_t, size_t, struct cpu_set_t*);
+int pthread_setaffinity_np(pthread_t, size_t, const struct cpu_set_t*);
+int pthread_getattr_np(pthread_t, pthread_attr_t*);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_PTHREAD_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/pwd.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/pwd.h
new file mode 100644
index 0000000..213eefa
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/pwd.h
@@ -0,0 +1,48 @@
+#ifndef SYSROOT_PWD_H_
+#define SYSROOT_PWD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+#define __NEED_uid_t
+#define __NEED_gid_t
+
+#ifdef _GNU_SOURCE
+#define __NEED_FILE
+#endif
+
+#include <bits/alltypes.h>
+
+struct passwd {
+ char* pw_name;
+ char* pw_passwd;
+ uid_t pw_uid;
+ gid_t pw_gid;
+ char* pw_gecos;
+ char* pw_dir;
+ char* pw_shell;
+};
+
+void setpwent(void);
+void endpwent(void);
+struct passwd* getpwent(void);
+
+struct passwd* getpwuid(uid_t);
+struct passwd* getpwnam(const char*);
+int getpwuid_r(uid_t, struct passwd*, char*, size_t, struct passwd**);
+int getpwnam_r(const char*, struct passwd*, char*, size_t, struct passwd**);
+
+#ifdef _GNU_SOURCE
+struct passwd* fgetpwent(FILE*);
+int putpwent(const struct passwd*, FILE*);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_PWD_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/regex.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/regex.h
new file mode 100644
index 0000000..53fac22
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/regex.h
@@ -0,0 +1,62 @@
+#ifndef SYSROOT_REGEX_H_
+#define SYSROOT_REGEX_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_regoff_t
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+typedef struct re_pattern_buffer {
+ size_t re_nsub;
+ void *__opaque, *__padding[4];
+ size_t __nsub2;
+ char __padding2;
+} regex_t;
+
+typedef struct {
+ regoff_t rm_so;
+ regoff_t rm_eo;
+} regmatch_t;
+
+#define REG_EXTENDED 1
+#define REG_ICASE 2
+#define REG_NEWLINE 4
+#define REG_NOSUB 8
+
+#define REG_NOTBOL 1
+#define REG_NOTEOL 2
+
+#define REG_OK 0
+#define REG_NOMATCH 1
+#define REG_BADPAT 2
+#define REG_ECOLLATE 3
+#define REG_ECTYPE 4
+#define REG_EESCAPE 5
+#define REG_ESUBREG 6
+#define REG_EBRACK 7
+#define REG_EPAREN 8
+#define REG_EBRACE 9
+#define REG_BADBR 10
+#define REG_ERANGE 11
+#define REG_ESPACE 12
+#define REG_BADRPT 13
+
+#define REG_ENOSYS -1
+
+int regcomp(regex_t* __restrict, const char* __restrict, int);
+int regexec(const regex_t* __restrict, const char* __restrict, size_t, regmatch_t* __restrict, int);
+void regfree(regex_t*);
+
+size_t regerror(int, const regex_t* __restrict, char* __restrict, size_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_REGEX_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/resolv.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/resolv.h
new file mode 100644
index 0000000..a90e0e8
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/resolv.h
@@ -0,0 +1,143 @@
+#ifndef SYSROOT_RESOLV_H_
+#define SYSROOT_RESOLV_H_
+
+#include <arpa/nameser.h>
+#include <netinet/in.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAXNS 3
+#define MAXDFLSRCH 3
+#define MAXDNSRCH 6
+#define LOCALDOMAINPARTS 2
+
+#define RES_TIMEOUT 5
+#define MAXRESOLVSORT 10
+#define RES_MAXNDOTS 15
+#define RES_MAXRETRANS 30
+#define RES_MAXRETRY 5
+#define RES_DFLRETRY 2
+#define RES_MAXTIME 65535
+
+/* unused; purely for broken apps */
+typedef struct __res_state {
+ int retrans;
+ int retry;
+ unsigned long options;
+ int nscount;
+ struct sockaddr_in nsaddr_list[MAXNS];
+#define nsaddr nsaddr_list[0]
+ unsigned short id;
+ char* dnsrch[MAXDNSRCH + 1];
+ char defdname[256];
+ unsigned long pfcode;
+ unsigned ndots : 4;
+ unsigned nsort : 4;
+ unsigned ipv6_unavail : 1;
+ unsigned unused : 23;
+ struct {
+ struct in_addr addr;
+ uint32_t mask;
+ } sort_list[MAXRESOLVSORT];
+ void* qhook;
+ void* rhook;
+ int res_h_errno;
+ int _vcsock;
+ unsigned _flags;
+ union {
+ char pad[52];
+ struct {
+ uint16_t nscount;
+ uint16_t nsmap[MAXNS];
+ int nssocks[MAXNS];
+ uint16_t nscount6;
+ uint16_t nsinit;
+ struct sockaddr_in6* nsaddrs[MAXNS];
+ unsigned int _initstamp[2];
+ } _ext;
+ } _u;
+} * res_state;
+
+#define __RES 19991006
+
+#ifndef _PATH_RESCONF
+#define _PATH_RESCONF "/etc/resolv.conf"
+#endif
+
+struct res_sym {
+ int number;
+ char* name;
+ char* humanname;
+};
+
+#define RES_F_VC 0x00000001
+#define RES_F_CONN 0x00000002
+#define RES_F_EDNS0ERR 0x00000004
+
+#define RES_EXHAUSTIVE 0x00000001
+
+#define RES_INIT 0x00000001
+#define RES_DEBUG 0x00000002
+#define RES_AAONLY 0x00000004
+#define RES_USEVC 0x00000008
+#define RES_PRIMARY 0x00000010
+#define RES_IGNTC 0x00000020
+#define RES_RECURSE 0x00000040
+#define RES_DEFNAMES 0x00000080
+#define RES_STAYOPEN 0x00000100
+#define RES_DNSRCH 0x00000200
+#define RES_INSECURE1 0x00000400
+#define RES_INSECURE2 0x00000800
+#define RES_NOALIASES 0x00001000
+#define RES_USE_INET6 0x00002000
+#define RES_ROTATE 0x00004000
+#define RES_NOCHECKNAME 0x00008000
+#define RES_KEEPTSIG 0x00010000
+#define RES_BLAST 0x00020000
+#define RES_USEBSTRING 0x00040000
+#define RES_NOIP6DOTINT 0x00080000
+#define RES_USE_EDNS0 0x00100000
+#define RES_SNGLKUP 0x00200000
+#define RES_SNGLKUPREOP 0x00400000
+#define RES_USE_DNSSEC 0x00800000
+
+#define RES_DEFAULT (RES_RECURSE | RES_DEFNAMES | RES_DNSRCH | RES_NOIP6DOTINT)
+
+#define RES_PRF_STATS 0x00000001
+#define RES_PRF_UPDATE 0x00000002
+#define RES_PRF_CLASS 0x00000004
+#define RES_PRF_CMD 0x00000008
+#define RES_PRF_QUES 0x00000010
+#define RES_PRF_ANS 0x00000020
+#define RES_PRF_AUTH 0x00000040
+#define RES_PRF_ADD 0x00000080
+#define RES_PRF_HEAD1 0x00000100
+#define RES_PRF_HEAD2 0x00000200
+#define RES_PRF_TTLID 0x00000400
+#define RES_PRF_HEADX 0x00000800
+#define RES_PRF_QUERY 0x00001000
+#define RES_PRF_REPLY 0x00002000
+#define RES_PRF_INIT 0x00004000
+
+struct __res_state* __res_state(void);
+#define _res (*__res_state())
+
+int res_init(void);
+int res_query(const char*, int, int, unsigned char*, int);
+int res_querydomain(const char*, const char*, int, int, unsigned char*, int);
+int res_search(const char*, int, int, unsigned char*, int);
+int res_mkquery(int, const char*, int, int, const unsigned char*, int, const unsigned char*,
+ unsigned char*, int);
+int res_send(const unsigned char*, int, unsigned char*, int);
+int dn_comp(const char*, unsigned char*, int, unsigned char**, unsigned char**);
+int dn_expand(const unsigned char*, const unsigned char*, const unsigned char*, char*, int);
+int dn_skipname(const unsigned char*, const unsigned char*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_RESOLV_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sched.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sched.h
new file mode 100644
index 0000000..ac06166
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sched.h
@@ -0,0 +1,110 @@
+#ifndef SYSROOT_SCHED_H_
+#define SYSROOT_SCHED_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_struct_timespec
+#define __NEED_pid_t
+#define __NEED_time_t
+
+#ifdef _GNU_SOURCE
+#define __NEED_size_t
+#endif
+
+#include <bits/alltypes.h>
+
+struct sched_param {
+ int sched_priority;
+ int sched_ss_low_priority;
+ struct timespec sched_ss_repl_period;
+ struct timespec sched_ss_init_budget;
+ int sched_ss_max_repl;
+};
+
+int sched_get_priority_max(int);
+int sched_get_priority_min(int);
+int sched_getparam(pid_t, struct sched_param*);
+int sched_getscheduler(pid_t);
+int sched_rr_get_interval(pid_t, struct timespec*);
+int sched_setparam(pid_t, const struct sched_param*);
+int sched_setscheduler(pid_t, int, const struct sched_param*);
+int sched_yield(void);
+
+#define SCHED_OTHER 0
+#define SCHED_FIFO 1
+#define SCHED_RR 2
+#define SCHED_BATCH 3
+#define SCHED_IDLE 5
+#define SCHED_DEADLINE 6
+#define SCHED_RESET_ON_FORK 0x40000000
+
+#ifdef _GNU_SOURCE
+void* memcpy(void* __restrict, const void* __restrict, size_t);
+int memcmp(const void*, const void*, size_t);
+void* calloc(size_t, size_t);
+void free(void*);
+
+typedef struct cpu_set_t {
+ unsigned long __bits[128 / sizeof(long)];
+} cpu_set_t;
+int __sched_cpucount(size_t, const cpu_set_t*);
+int sched_getcpu(void);
+int sched_getaffinity(pid_t, size_t, cpu_set_t*);
+int sched_setaffinity(pid_t, size_t, const cpu_set_t*);
+
+#define __CPU_op_S(i, size, set, op) \
+ ((i) / 8U >= (size) \
+ ? 0 \
+ : ((set)->__bits[(i) / 8 / sizeof(long)] op(1UL << ((i) % (8 * sizeof(long))))))
+
+#define CPU_SET_S(i, size, set) __CPU_op_S(i, size, set, |=)
+#define CPU_CLR_S(i, size, set) __CPU_op_S(i, size, set, &= ~)
+#define CPU_ISSET_S(i, size, set) __CPU_op_S(i, size, set, &)
+
+#define __CPU_op_func_S(func, op) \
+ static __inline void __CPU_##func##_S(size_t __size, cpu_set_t* __dest, const cpu_set_t* __src1, \
+ const cpu_set_t* __src2) { \
+ size_t __i; \
+ for (__i = 0; __i < __size / sizeof(long); __i++) \
+ __dest->__bits[__i] = __src1->__bits[__i] op __src2->__bits[__i]; \
+ }
+
+__CPU_op_func_S(AND, &) __CPU_op_func_S(OR, |) __CPU_op_func_S(XOR, ^)
+
+#define CPU_AND_S(a, b, c, d) __CPU_AND_S(a, b, c, d)
+#define CPU_OR_S(a, b, c, d) __CPU_OR_S(a, b, c, d)
+#define CPU_XOR_S(a, b, c, d) __CPU_XOR_S(a, b, c, d)
+
+#define CPU_COUNT_S(size, set) __sched_cpucount(size, set)
+#define CPU_ZERO_S(size, set) memset(set, 0, size)
+#define CPU_EQUAL_S(size, set1, set2) (!memcmp(set1, set2, size))
+
+#define CPU_ALLOC_SIZE(n) \
+ (sizeof(long) * ((n) / (8 * sizeof(long)) + \
+ ((n) % (8 * sizeof(long)) + 8 * sizeof(long) - 1) / (8 * sizeof(long))))
+#define CPU_ALLOC(n) ((cpu_set_t*)calloc(1, CPU_ALLOC_SIZE(n)))
+#define CPU_FREE(set) free(set)
+
+#define CPU_SETSIZE 128
+
+#define CPU_SET(i, set) CPU_SET_S(i, sizeof(cpu_set_t), set)
+#define CPU_CLR(i, set) CPU_CLR_S(i, sizeof(cpu_set_t), set)
+#define CPU_ISSET(i, set) CPU_ISSET_S(i, sizeof(cpu_set_t), set)
+#define CPU_AND(d, s1, s2) CPU_AND_S(sizeof(cpu_set_t), d, s1, s2)
+#define CPU_OR(d, s1, s2) CPU_OR_S(sizeof(cpu_set_t), d, s1, s2)
+#define CPU_XOR(d, s1, s2) CPU_XOR_S(sizeof(cpu_set_t), d, s1, s2)
+#define CPU_COUNT(set) CPU_COUNT_S(sizeof(cpu_set_t), set)
+#define CPU_ZERO(set) CPU_ZERO_S(sizeof(cpu_set_t), set)
+#define CPU_EQUAL(s1, s2) CPU_EQUAL_S(sizeof(cpu_set_t), s1, s2)
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SCHED_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/search.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/search.h
new file mode 100644
index 0000000..5348eab
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/search.h
@@ -0,0 +1,61 @@
+#ifndef SYSROOT_SEARCH_H_
+#define SYSROOT_SEARCH_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+#include <bits/alltypes.h>
+
+typedef enum { FIND, ENTER } ACTION;
+typedef enum { preorder, postorder, endorder, leaf } VISIT;
+
+typedef struct entry {
+ char* key;
+ void* data;
+} ENTRY;
+
+int hcreate(size_t);
+void hdestroy(void);
+ENTRY* hsearch(ENTRY, ACTION);
+
+#ifdef _GNU_SOURCE
+struct hsearch_data {
+ struct __tab* __tab;
+ unsigned int __unused1;
+ unsigned int __unused2;
+};
+
+int hcreate_r(size_t, struct hsearch_data*);
+void hdestroy_r(struct hsearch_data*);
+int hsearch_r(ENTRY, ACTION, ENTRY**, struct hsearch_data*);
+#endif
+
+void insque(void*, void*);
+void remque(void*);
+
+void* lsearch(const void*, void*, size_t*, size_t, int (*)(const void*, const void*));
+void* lfind(const void*, const void*, size_t*, size_t, int (*)(const void*, const void*));
+
+void* tdelete(const void* __restrict, void** __restrict, int (*)(const void*, const void*));
+void* tfind(const void*, void* const*, int (*)(const void*, const void*));
+void* tsearch(const void*, void**, int (*)(const void*, const void*));
+void twalk(const void*, void (*)(const void*, VISIT, int));
+
+#ifdef _GNU_SOURCE
+struct qelem {
+ struct qelem *q_forw, *q_back;
+ char q_data[1];
+};
+
+void tdestroy(void*, void (*)(void*));
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SEARCH_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/semaphore.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/semaphore.h
new file mode 100644
index 0000000..d9e996e
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/semaphore.h
@@ -0,0 +1,34 @@
+#ifndef SYSROOT_SEMAPHORE_H_
+#define SYSROOT_SEMAPHORE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_sem_t
+#define __NEED_time_t
+#define __NEED_struct_timespec
+#include <fcntl.h>
+
+#include <bits/alltypes.h>
+
+#define SEM_FAILED ((sem_t*)0)
+
+int sem_close(sem_t*);
+int sem_destroy(sem_t*);
+int sem_getvalue(sem_t* __restrict, int* __restrict);
+int sem_init(sem_t*, int, unsigned);
+sem_t* sem_open(const char*, int, ...);
+int sem_post(sem_t*);
+int sem_timedwait(sem_t* __restrict, const struct timespec* __restrict);
+int sem_trywait(sem_t*);
+int sem_unlink(const char*);
+int sem_wait(sem_t*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SEMAPHORE_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/setjmp.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/setjmp.h
new file mode 100644
index 0000000..65971b7
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/setjmp.h
@@ -0,0 +1,39 @@
+#ifndef SYSROOT_SETJMP_H_
+#define SYSROOT_SETJMP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <bits/setjmp.h>
+
+typedef struct __jmp_buf_tag {
+ __jmp_buf __jb;
+ unsigned long __fl;
+ unsigned long __ss[128 / sizeof(long)];
+} jmp_buf[1];
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+typedef jmp_buf sigjmp_buf;
+int sigsetjmp(sigjmp_buf, int);
+_Noreturn void siglongjmp(sigjmp_buf, int);
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+int _setjmp(jmp_buf);
+_Noreturn void _longjmp(jmp_buf, int);
+#endif
+
+int setjmp(jmp_buf);
+_Noreturn void longjmp(jmp_buf, int);
+
+#define setjmp setjmp
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SETJMP_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/signal.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/signal.h
new file mode 100644
index 0000000..594cf80
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/signal.h
@@ -0,0 +1,263 @@
+#ifndef SYSROOT_SIGNAL_H_
+#define SYSROOT_SIGNAL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#ifdef _GNU_SOURCE
+#define __ucontext ucontext
+#endif
+
+#define __NEED_size_t
+#define __NEED_pid_t
+#define __NEED_uid_t
+#define __NEED_struct_timespec
+#define __NEED_pthread_t
+#define __NEED_pthread_attr_t
+#define __NEED_time_t
+#define __NEED_clock_t
+#define __NEED_sigset_t
+
+#include <bits/alltypes.h>
+
+#define SIG_BLOCK 0
+#define SIG_UNBLOCK 1
+#define SIG_SETMASK 2
+
+#define SI_ASYNCNL (-60)
+#define SI_TKILL (-6)
+#define SI_SIGIO (-5)
+#define SI_ASYNCIO (-4)
+#define SI_MESGQ (-3)
+#define SI_TIMER (-2)
+#define SI_QUEUE (-1)
+#define SI_USER 0
+#define SI_KERNEL 128
+
+typedef struct sigaltstack stack_t;
+
+#endif
+
+#include <bits/signal.h>
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#define SIG_HOLD ((void (*)(int))2)
+
+#define FPE_INTDIV 1
+#define FPE_INTOVF 2
+#define FPE_FLTDIV 3
+#define FPE_FLTOVF 4
+#define FPE_FLTUND 5
+#define FPE_FLTRES 6
+#define FPE_FLTINV 7
+#define FPE_FLTSUB 8
+
+#define ILL_ILLOPC 1
+#define ILL_ILLOPN 2
+#define ILL_ILLADR 3
+#define ILL_ILLTRP 4
+#define ILL_PRVOPC 5
+#define ILL_PRVREG 6
+#define ILL_COPROC 7
+#define ILL_BADSTK 8
+
+#define SEGV_MAPERR 1
+#define SEGV_ACCERR 2
+#define SEGV_BNDERR 3
+
+#define BUS_ADRALN 1
+#define BUS_ADRERR 2
+#define BUS_OBJERR 3
+#define BUS_MCEERR_AR 4
+#define BUS_MCEERR_AO 5
+
+#define CLD_EXITED 1
+#define CLD_KILLED 2
+#define CLD_DUMPED 3
+#define CLD_TRAPPED 4
+#define CLD_STOPPED 5
+#define CLD_CONTINUED 6
+
+union sigval {
+ int sival_int;
+ void* sival_ptr;
+};
+
+typedef struct {
+#ifdef __SI_SWAP_ERRNO_CODE
+ int si_signo, si_code, si_errno;
+#else
+ int si_signo, si_errno, si_code;
+#endif
+ union {
+ char __pad[128 - 2 * sizeof(int) - sizeof(long)];
+ struct {
+ union {
+ struct {
+ pid_t si_pid;
+ uid_t si_uid;
+ } __piduid;
+ struct {
+ int si_timerid;
+ int si_overrun;
+ } __timer;
+ } __first;
+ union {
+ union sigval si_value;
+ struct {
+ int si_status;
+ clock_t si_utime, si_stime;
+ } __sigchld;
+ } __second;
+ } __si_common;
+ struct {
+ void* si_addr;
+ short si_addr_lsb;
+ struct {
+ void* si_lower;
+ void* si_upper;
+ } __addr_bnd;
+ } __sigfault;
+ struct {
+ long si_band;
+ int si_fd;
+ } __sigpoll;
+ struct {
+ void* si_call_addr;
+ int si_syscall;
+ unsigned si_arch;
+ } __sigsys;
+ } __si_fields;
+} siginfo_t;
+#define si_pid __si_fields.__si_common.__first.__piduid.si_pid
+#define si_uid __si_fields.__si_common.__first.__piduid.si_uid
+#define si_status __si_fields.__si_common.__second.__sigchld.si_status
+#define si_utime __si_fields.__si_common.__second.__sigchld.si_utime
+#define si_stime __si_fields.__si_common.__second.__sigchld.si_stime
+#define si_value __si_fields.__si_common.__second.si_value
+#define si_addr __si_fields.__sigfault.si_addr
+#define si_addr_lsb __si_fields.__sigfault.si_addr_lsb
+#define si_lower __si_fields.__sigfault.__addr_bnd.si_lower
+#define si_upper __si_fields.__sigfault.__addr_bnd.si_upper
+#define si_band __si_fields.__sigpoll.si_band
+#define si_fd __si_fields.__sigpoll.si_fd
+#define si_timerid __si_fields.__si_common.__first.__timer.si_timerid
+#define si_overrun __si_fields.__si_common.__first.__timer.si_overrun
+#define si_ptr si_value.sival_ptr
+#define si_int si_value.sival_int
+#define si_call_addr __si_fields.__sigsys.si_call_addr
+#define si_syscall __si_fields.__sigsys.si_syscall
+#define si_arch __si_fields.__sigsys.si_arch
+
+struct sigaction {
+ union {
+ void (*sa_handler)(int);
+ void (*sa_sigaction)(int, siginfo_t*, void*);
+ } __sa_handler;
+ sigset_t sa_mask;
+ int sa_flags;
+ void (*sa_restorer)(void);
+};
+#define sa_handler __sa_handler.sa_handler
+#define sa_sigaction __sa_handler.sa_sigaction
+
+struct sigevent {
+ union sigval sigev_value;
+ int sigev_signo;
+ int sigev_notify;
+ void (*sigev_notify_function)(union sigval);
+ pthread_attr_t* sigev_notify_attributes;
+ char __pad[56 - 3 * sizeof(long)];
+};
+
+#define SIGEV_SIGNAL 0
+#define SIGEV_NONE 1
+#define SIGEV_THREAD 2
+
+int __libc_current_sigrtmin(void);
+int __libc_current_sigrtmax(void);
+
+#define SIGRTMIN (__libc_current_sigrtmin())
+#define SIGRTMAX (__libc_current_sigrtmax())
+
+int kill(pid_t, int);
+
+int sigemptyset(sigset_t*);
+int sigfillset(sigset_t*);
+int sigaddset(sigset_t*, int);
+int sigdelset(sigset_t*, int);
+int sigismember(const sigset_t*, int);
+
+int sigprocmask(int, const sigset_t* __restrict, sigset_t* __restrict);
+int sigsuspend(const sigset_t*);
+int sigaction(int, const struct sigaction* __restrict, struct sigaction* __restrict);
+int sigpending(sigset_t*);
+int sigwait(const sigset_t* __restrict, int* __restrict);
+int sigwaitinfo(const sigset_t* __restrict, siginfo_t* __restrict);
+int sigtimedwait(const sigset_t* __restrict, siginfo_t* __restrict,
+ const struct timespec* __restrict);
+int sigqueue(pid_t, int, const union sigval);
+
+int pthread_sigmask(int, const sigset_t* __restrict, sigset_t* __restrict);
+int pthread_kill(pthread_t, int);
+
+void psiginfo(const siginfo_t*, const char*);
+void psignal(int, const char*);
+
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+int killpg(pid_t, int);
+int sigaltstack(const stack_t* __restrict, stack_t* __restrict);
+int siginterrupt(int, int);
+int sigpause(int);
+#define TRAP_BRKPT 1
+#define TRAP_TRACE 2
+#define POLL_IN 1
+#define POLL_OUT 2
+#define POLL_MSG 3
+#define POLL_ERR 4
+#define POLL_PRI 5
+#define POLL_HUP 6
+#define SS_ONSTACK 1
+#define SS_DISABLE 2
+#endif
+
+#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+#define NSIG _NSIG
+typedef void (*sig_t)(int);
+#endif
+
+#ifdef _GNU_SOURCE
+typedef void (*sighandler_t)(int);
+void (*bsd_signal(int, void (*)(int)))(int);
+int sigisemptyset(const sigset_t*);
+int sigorset(sigset_t*, const sigset_t*, const sigset_t*);
+int sigandset(sigset_t*, const sigset_t*, const sigset_t*);
+
+#define SA_NOMASK SA_NODEFER
+#define SA_ONESHOT SA_RESETHAND
+#endif
+
+#define SIG_ERR ((void (*)(int)) - 1)
+#define SIG_DFL ((void (*)(int))0)
+#define SIG_IGN ((void (*)(int))1)
+
+typedef int sig_atomic_t;
+
+void (*signal(int, void (*)(int)))(int);
+int raise(int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SIGNAL_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/spawn.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/spawn.h
new file mode 100644
index 0000000..1c70bb2
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/spawn.h
@@ -0,0 +1,79 @@
+#ifndef SYSROOT_SPAWN_H_
+#define SYSROOT_SPAWN_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_mode_t
+#define __NEED_pid_t
+#define __NEED_sigset_t
+
+#include <bits/alltypes.h>
+
+struct sched_param;
+
+#define POSIX_SPAWN_RESETIDS 1
+#define POSIX_SPAWN_SETPGROUP 2
+#define POSIX_SPAWN_SETSIGDEF 4
+#define POSIX_SPAWN_SETSIGMASK 8
+#define POSIX_SPAWN_SETSCHEDPARAM 16
+#define POSIX_SPAWN_SETSCHEDULER 32
+
+typedef struct {
+ int __flags;
+ pid_t __pgrp;
+ sigset_t __def, __mask;
+ int __prio, __pol, __pad[16];
+} posix_spawnattr_t;
+
+typedef struct {
+ int __pad0[2];
+ void* __actions;
+ int __pad[16];
+} posix_spawn_file_actions_t;
+
+int posix_spawn(pid_t* __restrict, const char* __restrict, const posix_spawn_file_actions_t*,
+ const posix_spawnattr_t* __restrict, char* const* __restrict,
+ char* const* __restrict);
+int posix_spawnp(pid_t* __restrict, const char* __restrict, const posix_spawn_file_actions_t*,
+ const posix_spawnattr_t* __restrict, char* const* __restrict,
+ char* const* __restrict);
+
+int posix_spawnattr_init(posix_spawnattr_t*);
+int posix_spawnattr_destroy(posix_spawnattr_t*);
+
+int posix_spawnattr_setflags(posix_spawnattr_t*, short);
+int posix_spawnattr_getflags(const posix_spawnattr_t* __restrict, short* __restrict);
+
+int posix_spawnattr_setpgroup(posix_spawnattr_t*, pid_t);
+int posix_spawnattr_getpgroup(const posix_spawnattr_t* __restrict, pid_t* __restrict);
+
+int posix_spawnattr_setsigmask(posix_spawnattr_t* __restrict, const sigset_t* __restrict);
+int posix_spawnattr_getsigmask(const posix_spawnattr_t* __restrict, sigset_t* __restrict);
+
+int posix_spawnattr_setsigdefault(posix_spawnattr_t* __restrict, const sigset_t* __restrict);
+int posix_spawnattr_getsigdefault(const posix_spawnattr_t* __restrict, sigset_t* __restrict);
+
+int posix_spawnattr_setschedparam(posix_spawnattr_t* __restrict,
+ const struct sched_param* __restrict);
+int posix_spawnattr_getschedparam(const posix_spawnattr_t* __restrict,
+ struct sched_param* __restrict);
+int posix_spawnattr_setschedpolicy(posix_spawnattr_t*, int);
+int posix_spawnattr_getschedpolicy(const posix_spawnattr_t* __restrict, int* __restrict);
+
+int posix_spawn_file_actions_init(posix_spawn_file_actions_t*);
+int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t*);
+
+int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t* __restrict, int,
+ const char* __restrict, int, mode_t);
+int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t*, int);
+int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t*, int, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SPAWN_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/stdio.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/stdio.h
new file mode 100644
index 0000000..c08aba0
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/stdio.h
@@ -0,0 +1,185 @@
+#ifndef SYSROOT_STDIO_H_
+#define SYSROOT_STDIO_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __printflike(__fmt, __varargs) __attribute__((__format__(__printf__, __fmt, __varargs)))
+#define __scanflike(__fmt, __varargs) __attribute__((__format__(__scanf__, __fmt, __varargs)))
+
+#define __NEED_FILE
+#define __NEED___isoc_va_list
+#define __NEED_size_t
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __NEED_ssize_t
+#define __NEED_off_t
+#define __NEED_va_list
+#endif
+
+#include <bits/alltypes.h>
+#include <bits/null.h>
+
+#undef EOF
+#define EOF (-1)
+
+#undef SEEK_SET
+#undef SEEK_CUR
+#undef SEEK_END
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
+#define _IOFBF 0
+#define _IOLBF 1
+#define _IONBF 2
+
+#define BUFSIZ 1024
+#define FILENAME_MAX 4096
+#define FOPEN_MAX 1000
+#define TMP_MAX 10000
+#define L_tmpnam 20
+
+typedef union _G_fpos64_t {
+ char __opaque[16];
+ double __align;
+} fpos_t;
+
+extern FILE* const stdin;
+extern FILE* const stdout;
+extern FILE* const stderr;
+
+#define stdin (stdin)
+#define stdout (stdout)
+#define stderr (stderr)
+
+FILE* fopen(const char* __restrict, const char* __restrict);
+FILE* freopen(const char* __restrict, const char* __restrict, FILE* __restrict);
+int fclose(FILE*);
+
+int remove(const char*);
+int rename(const char*, const char*);
+
+int feof(FILE*);
+int ferror(FILE*);
+int fflush(FILE*);
+void clearerr(FILE*);
+
+int fseek(FILE*, long, int);
+long ftell(FILE*);
+void rewind(FILE*);
+
+int fgetpos(FILE* __restrict, fpos_t* __restrict);
+int fsetpos(FILE*, const fpos_t*);
+
+size_t fread(void* __restrict, size_t, size_t, FILE* __restrict);
+size_t fwrite(const void* __restrict, size_t, size_t, FILE* __restrict);
+
+int fgetc(FILE*);
+int getc(FILE*);
+int getchar(void);
+int ungetc(int, FILE*);
+
+int fputc(int, FILE*);
+int putc(int, FILE*);
+int putchar(int);
+
+char* fgets(char* __restrict, int, FILE* __restrict);
+#if __STDC_VERSION__ < 201112L
+char* gets(char*);
+#endif
+
+int fputs(const char* __restrict, FILE* __restrict);
+int puts(const char*);
+
+int printf(const char* __restrict, ...) __printflike(1, 2);
+int fprintf(FILE* __restrict, const char* __restrict, ...) __printflike(2, 3);
+int sprintf(char* __restrict, const char* __restrict, ...) __printflike(2, 3);
+int snprintf(char* __restrict, size_t, const char* __restrict, ...) __printflike(3, 4);
+
+int vprintf(const char* __restrict, __isoc_va_list) __printflike(1, 0);
+int vfprintf(FILE* __restrict, const char* __restrict, __isoc_va_list) __printflike(2, 0);
+int vsprintf(char* __restrict, const char* __restrict, __isoc_va_list) __printflike(2, 0);
+int vsnprintf(char* __restrict, size_t, const char* __restrict, __isoc_va_list) __printflike(3, 0);
+
+int scanf(const char* __restrict, ...) __scanflike(1, 2);
+int fscanf(FILE* __restrict, const char* __restrict, ...) __scanflike(2, 3);
+int sscanf(const char* __restrict, const char* __restrict, ...) __scanflike(2, 3);
+int vscanf(const char* __restrict, __isoc_va_list) __scanflike(1, 0);
+int vfscanf(FILE* __restrict, const char* __restrict, __isoc_va_list) __scanflike(2, 0);
+int vsscanf(const char* __restrict, const char* __restrict, __isoc_va_list) __scanflike(2, 0);
+
+void perror(const char*);
+
+int setvbuf(FILE* __restrict, char* __restrict, int, size_t);
+void setbuf(FILE* __restrict, char* __restrict);
+
+char* tmpnam(char*);
+FILE* tmpfile(void);
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+FILE* fmemopen(void* __restrict, size_t, const char* __restrict);
+FILE* open_memstream(char**, size_t*);
+FILE* fdopen(int, const char*);
+FILE* popen(const char*, const char*);
+int pclose(FILE*);
+int fileno(FILE*);
+int fseeko(FILE*, off_t, int);
+off_t ftello(FILE*);
+int dprintf(int, const char* __restrict, ...) __printflike(2, 3);
+int vdprintf(int, const char* __restrict, __isoc_va_list) __printflike(2, 0);
+void flockfile(FILE*);
+int ftrylockfile(FILE*);
+void funlockfile(FILE*);
+int getc_unlocked(FILE*);
+int getchar_unlocked(void);
+int putc_unlocked(int, FILE*);
+int putchar_unlocked(int);
+ssize_t getdelim(char** __restrict, size_t* __restrict, int, FILE* __restrict);
+ssize_t getline(char** __restrict, size_t* __restrict, FILE* __restrict);
+int renameat(int, const char*, int, const char*);
+char* ctermid(char*);
+#define L_ctermid 20
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define P_tmpdir "/tmp"
+char* tempnam(const char*, const char*);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define L_cuserid 20
+char* cuserid(char*);
+void setlinebuf(FILE*);
+void setbuffer(FILE*, char*, size_t);
+int fgetc_unlocked(FILE*);
+int fputc_unlocked(int, FILE*);
+int fflush_unlocked(FILE*);
+size_t fread_unlocked(void*, size_t, size_t, FILE*);
+size_t fwrite_unlocked(const void*, size_t, size_t, FILE*);
+void clearerr_unlocked(FILE*);
+int feof_unlocked(FILE*);
+int ferror_unlocked(FILE*);
+int fileno_unlocked(FILE*);
+int getw(FILE*);
+int putw(int, FILE*);
+char* fgetln(FILE*, size_t*);
+int asprintf(char**, const char*, ...) __printflike(2, 3);
+int vasprintf(char**, const char*, __isoc_va_list) __printflike(2, 0);
+#endif
+
+#ifdef _GNU_SOURCE
+char* fgets_unlocked(char*, int, FILE*);
+int fputs_unlocked(const char*, FILE*);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_STDIO_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/stdlib.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/stdlib.h
new file mode 100644
index 0000000..862c83f
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/stdlib.h
@@ -0,0 +1,157 @@
+#ifndef SYSROOT_STDLIB_H_
+#define SYSROOT_STDLIB_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <bits/null.h>
+
+#define __NEED_size_t
+#define __NEED_wchar_t
+
+#include <bits/alltypes.h>
+
+int atoi(const char*);
+long atol(const char*);
+long long atoll(const char*);
+double atof(const char*);
+
+float strtof(const char* __restrict, char** __restrict);
+double strtod(const char* __restrict, char** __restrict);
+long double strtold(const char* __restrict, char** __restrict);
+
+long strtol(const char* __restrict, char** __restrict, int);
+unsigned long strtoul(const char* __restrict, char** __restrict, int);
+long long strtoll(const char* __restrict, char** __restrict, int);
+unsigned long long strtoull(const char* __restrict, char** __restrict, int);
+
+int rand(void);
+void srand(unsigned);
+
+void* malloc(size_t);
+void* calloc(size_t, size_t);
+void* realloc(void*, size_t);
+void free(void*);
+void* aligned_alloc(size_t alignment, size_t size);
+
+_Noreturn void abort(void);
+int atexit(void (*)(void));
+_Noreturn void exit(int);
+_Noreturn void _Exit(int);
+int at_quick_exit(void (*)(void));
+_Noreturn void quick_exit(int);
+
+char* getenv(const char*);
+
+int system(const char*);
+
+void* bsearch(const void*, const void*, size_t, size_t, int (*)(const void*, const void*));
+void qsort(void*, size_t, size_t, int (*)(const void*, const void*));
+
+int abs(int);
+long labs(long);
+long long llabs(long long);
+
+typedef struct {
+ int quot, rem;
+} div_t;
+typedef struct {
+ long quot, rem;
+} ldiv_t;
+typedef struct {
+ long long quot, rem;
+} lldiv_t;
+
+div_t div(int, int);
+ldiv_t ldiv(long, long);
+lldiv_t lldiv(long long, long long);
+
+int mblen(const char*, size_t);
+int mbtowc(wchar_t* __restrict, const char* __restrict, size_t);
+int wctomb(char*, wchar_t);
+size_t mbstowcs(wchar_t* __restrict, const char* __restrict, size_t);
+size_t wcstombs(char* __restrict, const wchar_t* __restrict, size_t);
+
+#define EXIT_FAILURE 1
+#define EXIT_SUCCESS 0
+
+size_t __ctype_get_mb_cur_max(void);
+#define MB_CUR_MAX (__ctype_get_mb_cur_max())
+
+#define RAND_MAX (0x7fffffff)
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#define WNOHANG 1
+#define WUNTRACED 2
+
+#define WEXITSTATUS(s) (((s)&0xff00) >> 8)
+#define WTERMSIG(s) ((s)&0x7f)
+#define WSTOPSIG(s) WEXITSTATUS(s)
+#define WIFEXITED(s) (!WTERMSIG(s))
+#define WIFSTOPPED(s) ((short)((((s)&0xffff) * 0x10001) >> 8) > 0x7f00)
+#define WIFSIGNALED(s) (((s)&0xffff) - 1U < 0xffu)
+
+int posix_memalign(void**, size_t, size_t);
+int setenv(const char*, const char*, int);
+int unsetenv(const char*);
+int mkstemp(char*);
+int mkostemp(char*, int);
+char* mkdtemp(char*);
+int getsubopt(char**, char* const*, char**);
+int rand_r(unsigned*);
+
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+char* realpath(const char* __restrict, char* __restrict);
+long int random(void);
+void srandom(unsigned int);
+char* initstate(unsigned int, char*, size_t);
+char* setstate(char*);
+int putenv(char*);
+int posix_openpt(int);
+int grantpt(int);
+int unlockpt(int);
+char* ptsname(int);
+long a64l(const char*);
+void setkey(const char*);
+double drand48(void);
+double erand48(unsigned short[3]);
+long int lrand48(void);
+long int nrand48(unsigned short[3]);
+long mrand48(void);
+long jrand48(unsigned short[3]);
+void srand48(long);
+unsigned short* seed48(unsigned short[3]);
+void lcong48(unsigned short[7]);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#include <alloca.h>
+char* mktemp(char*);
+int mkstemps(char*, int);
+int mkostemps(char*, int, int);
+void* valloc(size_t);
+void* memalign(size_t, size_t);
+int clearenv(void);
+#define WCOREDUMP(s) ((s)&0x80)
+#define WIFCONTINUED(s) ((s) == 0xffff)
+#endif
+
+#ifdef _GNU_SOURCE
+int ptsname_r(int, char*, size_t);
+char* ecvt(double, int, int*, int*);
+char* fcvt(double, int, int*, int*);
+char* gcvt(double, int, char*);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_STDLIB_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/string.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/string.h
new file mode 100644
index 0000000..0265b57
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/string.h
@@ -0,0 +1,90 @@
+#ifndef SYSROOT_STRING_H_
+#define SYSROOT_STRING_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <bits/null.h>
+
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+void* memcpy(void* __restrict, const void* __restrict, size_t);
+void* memmove(void*, const void*, size_t);
+void* memset(void*, int, size_t);
+int memcmp(const void*, const void*, size_t);
+void* memchr(const void*, int, size_t);
+
+char* strcpy(char* __restrict, const char* __restrict);
+char* strncpy(char* __restrict, const char* __restrict, size_t);
+
+char* strcat(char* __restrict, const char* __restrict);
+char* strncat(char* __restrict, const char* __restrict, size_t);
+
+int strcmp(const char*, const char*);
+int strncmp(const char*, const char*, size_t);
+
+int strcoll(const char*, const char*);
+size_t strxfrm(char* __restrict, const char* __restrict, size_t);
+
+char* strchr(const char*, int);
+char* strrchr(const char*, int);
+
+size_t strcspn(const char*, const char*);
+size_t strspn(const char*, const char*);
+char* strpbrk(const char*, const char*);
+char* strstr(const char*, const char*);
+char* strtok(char* __restrict, const char* __restrict);
+
+size_t strlen(const char*);
+
+char* strerror(int);
+
+#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+#include <strings.h>
+#endif
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+char* strtok_r(char* __restrict, const char* __restrict, char** __restrict);
+int strerror_r(int, char*, size_t);
+char* stpcpy(char* __restrict, const char* __restrict);
+char* stpncpy(char* __restrict, const char* __restrict, size_t);
+size_t strnlen(const char*, size_t);
+char* strdup(const char*);
+char* strndup(const char*, size_t);
+char* strsignal(int);
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+void* memccpy(void* __restrict, const void* __restrict, int, size_t);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+char* strsep(char**, const char*);
+size_t strlcat(char*, const char*, size_t);
+size_t strlcpy(char*, const char*, size_t);
+#endif
+
+#ifdef _GNU_SOURCE
+#define strdupa(x) strcpy(alloca(strlen(x) + 1), x)
+int strverscmp(const char*, const char*);
+char* strchrnul(const char*, int);
+char* strcasestr(const char*, const char*);
+void* memmem(const void*, size_t, const void*, size_t);
+void* memrchr(const void*, int, size_t);
+void* mempcpy(void*, const void*, size_t);
+#ifndef __cplusplus
+char* basename(char*);
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_STRING_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/strings.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/strings.h
new file mode 100644
index 0000000..eb703d1
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/strings.h
@@ -0,0 +1,38 @@
+#ifndef SYSROOT_STRINGS_H_
+#define SYSROOT_STRINGS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_size_t
+#define __NEED_locale_t
+#include <bits/alltypes.h>
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_POSIX_SOURCE) || \
+ (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE + 0 < 200809L) || \
+ (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE + 0 < 700)
+int bcmp(const void*, const void*, size_t);
+void bcopy(const void*, void*, size_t);
+void bzero(void*, size_t);
+char* index(const char*, int);
+char* rindex(const char*, int);
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+int ffs(int);
+int ffsl(long);
+int ffsll(long long);
+#endif
+
+int strcasecmp(const char*, const char*);
+int strncasecmp(const char*, const char*, size_t);
+
+int strcasecmp_l(const char*, const char*, locale_t);
+int strncasecmp_l(const char*, const char*, size_t, locale_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_STRINGS_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/stropts.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/stropts.h
new file mode 100644
index 0000000..92eb968
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/stropts.h
@@ -0,0 +1,139 @@
+#ifndef SYSROOT_STROPTS_H_
+#define SYSROOT_STROPTS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __SID ('S' << 8)
+
+#define I_NREAD (__SID | 1)
+#define I_PUSH (__SID | 2)
+#define I_POP (__SID | 3)
+#define I_LOOK (__SID | 4)
+#define I_FLUSH (__SID | 5)
+#define I_SRDOPT (__SID | 6)
+#define I_GRDOPT (__SID | 7)
+#define I_STR (__SID | 8)
+#define I_SETSIG (__SID | 9)
+#define I_GETSIG (__SID | 10)
+#define I_FIND (__SID | 11)
+#define I_LINK (__SID | 12)
+#define I_UNLINK (__SID | 13)
+#define I_PEEK (__SID | 15)
+#define I_FDINSERT (__SID | 16)
+#define I_SENDFD (__SID | 17)
+#define I_RECVFD (__SID | 14)
+#define I_SWROPT (__SID | 19)
+#define I_GWROPT (__SID | 20)
+#define I_LIST (__SID | 21)
+#define I_PLINK (__SID | 22)
+#define I_PUNLINK (__SID | 23)
+#define I_FLUSHBAND (__SID | 28)
+#define I_CKBAND (__SID | 29)
+#define I_GETBAND (__SID | 30)
+#define I_ATMARK (__SID | 31)
+#define I_SETCLTIME (__SID | 32)
+#define I_GETCLTIME (__SID | 33)
+#define I_CANPUT (__SID | 34)
+
+#define FMNAMESZ 8
+
+#define FLUSHR 0x01
+#define FLUSHW 0x02
+#define FLUSHRW 0x03
+#define FLUSHBAND 0x04
+
+#define S_INPUT 0x0001
+#define S_HIPRI 0x0002
+#define S_OUTPUT 0x0004
+#define S_MSG 0x0008
+#define S_ERROR 0x0010
+#define S_HANGUP 0x0020
+#define S_RDNORM 0x0040
+#define S_WRNORM S_OUTPUT
+#define S_RDBAND 0x0080
+#define S_WRBAND 0x0100
+#define S_BANDURG 0x0200
+
+#define RS_HIPRI 0x01
+
+#define RNORM 0x0000
+#define RMSGD 0x0001
+#define RMSGN 0x0002
+#define RPROTDAT 0x0004
+#define RPROTDIS 0x0008
+#define RPROTNORM 0x0010
+#define RPROTMASK 0x001C
+
+#define SNDZERO 0x001
+#define SNDPIPE 0x002
+
+#define ANYMARK 0x01
+#define LASTMARK 0x02
+
+#define MUXID_ALL (-1)
+
+#define MSG_HIPRI 0x01
+#define MSG_ANY 0x02
+#define MSG_BAND 0x04
+
+#define MORECTL 1
+#define MOREDATA 2
+
+struct bandinfo {
+ unsigned char bi_pri;
+ int bi_flag;
+};
+
+struct strbuf {
+ int maxlen;
+ int len;
+ char* buf;
+};
+
+struct strpeek {
+ struct strbuf ctlbuf;
+ struct strbuf databuf;
+ unsigned flags;
+};
+
+struct strfdinsert {
+ struct strbuf ctlbuf;
+ struct strbuf databuf;
+ unsigned flags;
+ int fildes;
+ int offset;
+};
+
+struct strioctl {
+ int ic_cmd;
+ int ic_timout;
+ int ic_len;
+ char* ic_dp;
+};
+
+struct strrecvfd {
+ int fd;
+ int uid;
+ int gid;
+ char __fill[8];
+};
+
+struct str_mlist {
+ char l_name[FMNAMESZ + 1];
+};
+
+struct str_list {
+ int sl_nmods;
+ struct str_mlist* sl_modlist;
+};
+
+int isastream(int);
+int ioctl(int, int, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_STROPTS_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/acct.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/acct.h
new file mode 100644
index 0000000..8561ad0
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/acct.h
@@ -0,0 +1,72 @@
+#ifndef SYSROOT_SYS_ACCT_H_
+#define SYSROOT_SYS_ACCT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <endian.h>
+#include <features.h>
+#include <stdint.h>
+#include <time.h>
+
+#define ACCT_COMM 16
+
+typedef uint16_t comp_t;
+
+struct acct {
+ char ac_flag;
+ uint16_t ac_uid;
+ uint16_t ac_gid;
+ uint16_t ac_tty;
+ uint32_t ac_btime;
+ comp_t ac_utime;
+ comp_t ac_stime;
+ comp_t ac_etime;
+ comp_t ac_mem;
+ comp_t ac_io;
+ comp_t ac_rw;
+ comp_t ac_minflt;
+ comp_t ac_majflt;
+ comp_t ac_swaps;
+ uint32_t ac_exitcode;
+ char ac_comm[ACCT_COMM + 1];
+ char ac_pad[10];
+};
+
+struct acct_v3 {
+ char ac_flag;
+ char ac_version;
+ uint16_t ac_tty;
+ uint32_t ac_exitcode;
+ uint32_t ac_uid;
+ uint32_t ac_gid;
+ uint32_t ac_pid;
+ uint32_t ac_ppid;
+ uint32_t ac_btime;
+ float ac_etime;
+ comp_t ac_utime;
+ comp_t ac_stime;
+ comp_t ac_mem;
+ comp_t ac_io;
+ comp_t ac_rw;
+ comp_t ac_minflt;
+ comp_t ac_majflt;
+ comp_t ac_swaps;
+ char ac_comm[ACCT_COMM];
+};
+
+#define AFORK 1
+#define ASU 2
+#define ACORE 8
+#define AXSIG 16
+#define ACCT_BYTEORDER (128 * (__BYTE_ORDER == __BIG_ENDIAN))
+#define AHZ 100
+
+int acct(const char*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_ACCT_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/auxv.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/auxv.h
new file mode 100644
index 0000000..61ddea0
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/auxv.h
@@ -0,0 +1,16 @@
+#ifndef SYSROOT_SYS_AUXV_H_
+#define SYSROOT_SYS_AUXV_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <elf.h>
+
+unsigned long getauxval(unsigned long);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_AUXV_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/dir.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/dir.h
new file mode 100644
index 0000000..9ba1c79
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/dir.h
@@ -0,0 +1,2 @@
+#include <dirent.h>
+#define direct dirent
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/errno.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/errno.h
new file mode 100644
index 0000000..35a3e5a
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/errno.h
@@ -0,0 +1,2 @@
+#warning redirecting incorrect #include <sys/errno.h> to <errno.h>
+#include <errno.h>
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/eventfd.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/eventfd.h
new file mode 100644
index 0000000..4259bac
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/eventfd.h
@@ -0,0 +1,25 @@
+#ifndef SYSROOT_SYS_EVENTFD_H_
+#define SYSROOT_SYS_EVENTFD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <fcntl.h>
+#include <stdint.h>
+
+typedef uint64_t eventfd_t;
+
+#define EFD_SEMAPHORE 1
+#define EFD_CLOEXEC O_CLOEXEC
+#define EFD_NONBLOCK O_NONBLOCK
+
+int eventfd(unsigned int, int);
+int eventfd_read(int, eventfd_t*);
+int eventfd_write(int, eventfd_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_EVENTFD_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/fcntl.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/fcntl.h
new file mode 100644
index 0000000..3dd928e
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/fcntl.h
@@ -0,0 +1,2 @@
+#warning redirecting incorrect #include <sys/fcntl.h> to <fcntl.h>
+#include <fcntl.h>
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/file.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/file.h
new file mode 100644
index 0000000..fe17290
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/file.h
@@ -0,0 +1,23 @@
+#ifndef SYSROOT_SYS_FILE_H_
+#define SYSROOT_SYS_FILE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LOCK_SH 1
+#define LOCK_EX 2
+#define LOCK_NB 4
+#define LOCK_UN 8
+
+#define L_SET 0
+#define L_INCR 1
+#define L_XTND 2
+
+int flock(int, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_FILE_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/fsuid.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/fsuid.h
new file mode 100644
index 0000000..a9f654c
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/fsuid.h
@@ -0,0 +1,20 @@
+#ifndef SYSROOT_SYS_FSUID_H_
+#define SYSROOT_SYS_FSUID_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_uid_t
+#define __NEED_gid_t
+
+#include <bits/alltypes.h>
+
+int setfsuid(uid_t);
+int setfsgid(gid_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_FSUID_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/io.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/io.h
new file mode 100644
index 0000000..89617e5
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/io.h
@@ -0,0 +1,19 @@
+#ifndef SYSROOT_SYS_IO_H_
+#define SYSROOT_SYS_IO_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <bits/io.h>
+
+int iopl(int);
+int ioperm(unsigned long, unsigned long, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_IO_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/ioctl.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/ioctl.h
new file mode 100644
index 0000000..ad22a3b
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/ioctl.h
@@ -0,0 +1,16 @@
+#ifndef SYSROOT_SYS_IOCTL_H_
+#define SYSROOT_SYS_IOCTL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <bits/ioctl.h>
+
+int ioctl(int, int, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_IOCTL_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/ipc.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/ipc.h
new file mode 100644
index 0000000..5d019f4
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/ipc.h
@@ -0,0 +1,44 @@
+#ifndef SYSROOT_SYS_IPC_H_
+#define SYSROOT_SYS_IPC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_uid_t
+#define __NEED_gid_t
+#define __NEED_mode_t
+#define __NEED_key_t
+
+#include <bits/alltypes.h>
+
+#define __ipc_perm_key __key
+#define __ipc_perm_seq __seq
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __key key
+#define __seq seq
+#endif
+
+#include <bits/ipc.h>
+
+#define IPC_CREAT 01000
+#define IPC_EXCL 02000
+#define IPC_NOWAIT 04000
+
+#define IPC_RMID 0
+#define IPC_SET 1
+#define IPC_STAT 2
+#define IPC_INFO 3
+
+#define IPC_PRIVATE ((key_t)0)
+
+key_t ftok(const char*, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_IPC_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/klog.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/klog.h
new file mode 100644
index 0000000..b182302
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/klog.h
@@ -0,0 +1,14 @@
+#ifndef SYSROOT_SYS_KLOG_H_
+#define SYSROOT_SYS_KLOG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int klogctl(int, char*, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_KLOG_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/mman.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/mman.h
new file mode 100644
index 0000000..7a913ae
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/mman.h
@@ -0,0 +1,102 @@
+#ifndef SYSROOT_SYS_MMAN_H_
+#define SYSROOT_SYS_MMAN_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_mode_t
+#define __NEED_size_t
+#define __NEED_off_t
+
+#include <bits/alltypes.h>
+
+#define MAP_FAILED ((void*)-1)
+
+#define MAP_SHARED 0x01
+#define MAP_PRIVATE 0x02
+#define MAP_TYPE 0x0f
+#define MAP_FIXED 0x10
+#define MAP_ANON 0x20
+#define MAP_ANONYMOUS MAP_ANON
+#define MAP_NORESERVE 0x4000
+#define MAP_GROWSDOWN 0x0100
+#define MAP_DENYWRITE 0x0800
+#define MAP_EXECUTABLE 0x1000
+#define MAP_LOCKED 0x2000
+#define MAP_POPULATE 0x8000
+#define MAP_NONBLOCK 0x10000
+#define MAP_STACK 0x20000
+#define MAP_HUGETLB 0x40000
+#define MAP_JIT 0x80000
+#define MAP_FILE 0
+
+#define PROT_NONE 0
+#define PROT_READ 1
+#define PROT_WRITE 2
+#define PROT_EXEC 4
+#define PROT_GROWSDOWN 0x01000000
+#define PROT_GROWSUP 0x02000000
+
+#define MS_ASYNC 1
+#define MS_INVALIDATE 2
+#define MS_SYNC 4
+
+#define MCL_CURRENT 1
+#define MCL_FUTURE 2
+#define MCL_ONFAULT 4
+
+#define POSIX_MADV_NORMAL 0
+#define POSIX_MADV_RANDOM 1
+#define POSIX_MADV_SEQUENTIAL 2
+#define POSIX_MADV_WILLNEED 3
+#define POSIX_MADV_DONTNEED 4
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define MADV_NORMAL 0
+#define MADV_RANDOM 1
+#define MADV_SEQUENTIAL 2
+#define MADV_WILLNEED 3
+#define MADV_DONTNEED 4
+#define MADV_FREE 8
+#define MADV_REMOVE 9
+#define MADV_DONTFORK 10
+#define MADV_DOFORK 11
+#define MADV_MERGEABLE 12
+#define MADV_UNMERGEABLE 13
+#define MADV_HUGEPAGE 14
+#define MADV_NOHUGEPAGE 15
+#define MADV_DONTDUMP 16
+#define MADV_DODUMP 17
+#define MADV_HWPOISON 100
+#define MADV_SOFT_OFFLINE 101
+#endif
+
+void* mmap(void*, size_t, int, int, int, off_t);
+int munmap(void*, size_t);
+
+int mprotect(void*, size_t, int);
+int msync(void*, size_t, int);
+
+int posix_madvise(void*, size_t, int);
+
+int mlock(const void*, size_t);
+int munlock(const void*, size_t);
+int mlockall(int);
+int munlockall(void);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define MLOCK_ONFAULT 0x01
+int madvise(void*, size_t, int);
+#endif
+
+int shm_open(const char*, int, mode_t);
+int shm_unlink(const char*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_MMAN_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/mount.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/mount.h
new file mode 100644
index 0000000..53181ea
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/mount.h
@@ -0,0 +1,73 @@
+#ifndef SYSROOT_SYS_MOUNT_H_
+#define SYSROOT_SYS_MOUNT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/ioctl.h>
+
+#define BLKROSET _IO(0x12, 93)
+#define BLKROGET _IO(0x12, 94)
+#define BLKRRPART _IO(0x12, 95)
+#define BLKGETSIZE _IO(0x12, 96)
+#define BLKFLSBUF _IO(0x12, 97)
+#define BLKRASET _IO(0x12, 98)
+#define BLKRAGET _IO(0x12, 99)
+#define BLKFRASET _IO(0x12, 100)
+#define BLKFRAGET _IO(0x12, 101)
+#define BLKSECTSET _IO(0x12, 102)
+#define BLKSECTGET _IO(0x12, 103)
+#define BLKSSZGET _IO(0x12, 104)
+#define BLKBSZGET _IOR(0x12, 112, size_t)
+#define BLKBSZSET _IOW(0x12, 113, size_t)
+#define BLKGETSIZE64 _IOR(0x12, 114, size_t)
+
+#define MS_RDONLY 1
+#define MS_NOSUID 2
+#define MS_NODEV 4
+#define MS_NOEXEC 8
+#define MS_SYNCHRONOUS 16
+#define MS_REMOUNT 32
+#define MS_MANDLOCK 64
+#define MS_DIRSYNC 128
+#define MS_NOATIME 1024
+#define MS_NODIRATIME 2048
+#define MS_BIND 4096
+#define MS_MOVE 8192
+#define MS_REC 16384
+#define MS_SILENT 32768
+#define MS_POSIXACL (1 << 16)
+#define MS_UNBINDABLE (1 << 17)
+#define MS_PRIVATE (1 << 18)
+#define MS_SLAVE (1 << 19)
+#define MS_SHARED (1 << 20)
+#define MS_RELATIME (1 << 21)
+#define MS_KERNMOUNT (1 << 22)
+#define MS_I_VERSION (1 << 23)
+#define MS_STRICTATIME (1 << 24)
+#define MS_LAZYTIME (1 << 25)
+#define MS_NOSEC (1 << 28)
+#define MS_BORN (1 << 29)
+#define MS_ACTIVE (1 << 30)
+#define MS_NOUSER (1U << 31)
+
+#define MS_RMT_MASK (MS_RDONLY | MS_SYNCHRONOUS | MS_MANDLOCK | MS_I_VERSION | MS_LAZYTIME)
+
+#define MS_MGC_VAL 0xc0ed0000
+#define MS_MGC_MSK 0xffff0000
+
+#define MNT_FORCE 1
+#define MNT_DETACH 2
+#define MNT_EXPIRE 4
+#define UMOUNT_NOFOLLOW 8
+
+int mount(const char*, const char*, const char*, unsigned long, const void*);
+int umount(const char*);
+int umount2(const char*, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_MOUNT_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/msg.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/msg.h
new file mode 100644
index 0000000..be0114b
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/msg.h
@@ -0,0 +1,52 @@
+#ifndef SYSROOT_SYS_MSG_H_
+#define SYSROOT_SYS_MSG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/ipc.h>
+
+#define __NEED_pid_t
+#define __NEED_key_t
+#define __NEED_time_t
+#define __NEED_size_t
+#define __NEED_ssize_t
+
+#include <bits/alltypes.h>
+
+typedef unsigned long msgqnum_t;
+typedef unsigned long msglen_t;
+
+#include <bits/msg.h>
+
+#define __msg_cbytes msg_cbytes
+
+#define MSG_NOERROR 010000
+#define MSG_EXCEPT 020000
+
+#define MSG_STAT 11
+#define MSG_INFO 12
+
+struct msginfo {
+ int msgpool, msgmap, msgmax, msgmnb, msgmni, msgssz, msgtql;
+ unsigned short msgseg;
+};
+
+int msgctl(int, int, struct msqid_ds*);
+int msgget(key_t, int);
+ssize_t msgrcv(int, void*, size_t, long, int);
+int msgsnd(int, const void*, size_t, int);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+struct msgbuf {
+ long mtype;
+ char mtext[1];
+};
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_MSG_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/mtio.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/mtio.h
new file mode 100644
index 0000000..3d9f753
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/mtio.h
@@ -0,0 +1,183 @@
+#ifndef SYSROOT_SYS_MTIO_H_
+#define SYSROOT_SYS_MTIO_H_
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+
+struct mtop {
+ short mt_op;
+ int mt_count;
+};
+
+#define _IOT_mtop _IOT(_IOTS(short), 1, _IOTS(int), 1, 0, 0)
+#define _IOT_mtget _IOT(_IOTS(long), 7, 0, 0, 0, 0)
+#define _IOT_mtpos _IOT_SIMPLE(long)
+#define _IOT_mtconfiginfo _IOT(_IOTS(long), 2, _IOTS(short), 3, _IOTS(long), 1)
+
+#define MTRESET 0
+#define MTFSF 1
+#define MTBSF 2
+#define MTFSR 3
+#define MTBSR 4
+#define MTWEOF 5
+#define MTREW 6
+#define MTOFFL 7
+#define MTNOP 8
+#define MTRETEN 9
+#define MTBSFM 10
+#define MTFSFM 11
+#define MTEOM 12
+#define MTERASE 13
+#define MTRAS1 14
+#define MTRAS2 15
+#define MTRAS3 16
+#define MTSETBLK 20
+#define MTSETDENSITY 21
+#define MTSEEK 22
+#define MTTELL 23
+#define MTSETDRVBUFFER 24
+#define MTFSS 25
+#define MTBSS 26
+#define MTWSM 27
+#define MTLOCK 28
+#define MTUNLOCK 29
+#define MTLOAD 30
+#define MTUNLOAD 31
+#define MTCOMPRESSION 32
+#define MTSETPART 33
+#define MTMKPART 34
+
+struct mtget {
+ long mt_type;
+ long mt_resid;
+ long mt_dsreg;
+ long mt_gstat;
+ long mt_erreg;
+ int mt_fileno;
+ int mt_blkno;
+};
+
+#define MT_ISUNKNOWN 0x01
+#define MT_ISQIC02 0x02
+#define MT_ISWT5150 0x03
+#define MT_ISARCHIVE_5945L2 0x04
+#define MT_ISCMSJ500 0x05
+#define MT_ISTDC3610 0x06
+#define MT_ISARCHIVE_VP60I 0x07
+#define MT_ISARCHIVE_2150L 0x08
+#define MT_ISARCHIVE_2060L 0x09
+#define MT_ISARCHIVESC499 0x0A
+#define MT_ISQIC02_ALL_FEATURES 0x0F
+#define MT_ISWT5099EEN24 0x11
+#define MT_ISTEAC_MT2ST 0x12
+#define MT_ISEVEREX_FT40A 0x32
+#define MT_ISDDS1 0x51
+#define MT_ISDDS2 0x52
+#define MT_ISSCSI1 0x71
+#define MT_ISSCSI2 0x72
+#define MT_ISFTAPE_UNKNOWN 0x800000
+#define MT_ISFTAPE_FLAG 0x800000
+
+struct mt_tape_info {
+ long t_type;
+ char* t_name;
+};
+
+#define MT_TAPE_INFO \
+ { \
+ {MT_ISUNKNOWN, "Unknown type of tape device"}, {MT_ISQIC02, "Generic QIC-02 tape streamer"}, \
+ {MT_ISWT5150, "Wangtek 5150, QIC-150"}, {MT_ISARCHIVE_5945L2, "Archive 5945L-2"}, \
+ {MT_ISCMSJ500, "CMS Jumbo 500"}, {MT_ISTDC3610, "Tandberg TDC 3610, QIC-24"}, \
+ {MT_ISARCHIVE_VP60I, "Archive VP60i, QIC-02"}, \
+ {MT_ISARCHIVE_2150L, "Archive Viper 2150L"}, {MT_ISARCHIVE_2060L, "Archive Viper 2060L"}, \
+ {MT_ISARCHIVESC499, "Archive SC-499 QIC-36 controller"}, \
+ {MT_ISQIC02_ALL_FEATURES, "Generic QIC-02 tape, all features"}, \
+ {MT_ISWT5099EEN24, "Wangtek 5099-een24, 60MB"}, \
+ {MT_ISTEAC_MT2ST, "Teac MT-2ST 155mb data cassette drive"}, \
+ {MT_ISEVEREX_FT40A, "Everex FT40A, QIC-40"}, {MT_ISSCSI1, "Generic SCSI-1 tape"}, \
+ {MT_ISSCSI2, "Generic SCSI-2 tape"}, { \
+ 0, 0 \
+ } \
+ }
+
+struct mtpos {
+ long mt_blkno;
+};
+
+struct mtconfiginfo {
+ long mt_type;
+ long ifc_type;
+ unsigned short irqnr;
+ unsigned short dmanr;
+ unsigned short port;
+ unsigned long debug;
+ unsigned have_dens : 1;
+ unsigned have_bsf : 1;
+ unsigned have_fsr : 1;
+ unsigned have_bsr : 1;
+ unsigned have_eod : 1;
+ unsigned have_seek : 1;
+ unsigned have_tell : 1;
+ unsigned have_ras1 : 1;
+ unsigned have_ras2 : 1;
+ unsigned have_ras3 : 1;
+ unsigned have_qfa : 1;
+ unsigned pad1 : 5;
+ char reserved[10];
+};
+
+#define MTIOCTOP _IOW('m', 1, struct mtop)
+#define MTIOCGET _IOR('m', 2, struct mtget)
+#define MTIOCPOS _IOR('m', 3, struct mtpos)
+
+#define MTIOCGETCONFIG _IOR('m', 4, struct mtconfiginfo)
+#define MTIOCSETCONFIG _IOW('m', 5, struct mtconfiginfo)
+
+#define GMT_EOF(x) ((x)&0x80000000)
+#define GMT_BOT(x) ((x)&0x40000000)
+#define GMT_EOT(x) ((x)&0x20000000)
+#define GMT_SM(x) ((x)&0x10000000)
+#define GMT_EOD(x) ((x)&0x08000000)
+#define GMT_WR_PROT(x) ((x)&0x04000000)
+#define GMT_ONLINE(x) ((x)&0x01000000)
+#define GMT_D_6250(x) ((x)&0x00800000)
+#define GMT_D_1600(x) ((x)&0x00400000)
+#define GMT_D_800(x) ((x)&0x00200000)
+#define GMT_DR_OPEN(x) ((x)&0x00040000)
+#define GMT_IM_REP_EN(x) ((x)&0x00010000)
+
+#define MT_ST_BLKSIZE_SHIFT 0
+#define MT_ST_BLKSIZE_MASK 0xffffff
+#define MT_ST_DENSITY_SHIFT 24
+#define MT_ST_DENSITY_MASK 0xff000000
+#define MT_ST_SOFTERR_SHIFT 0
+#define MT_ST_SOFTERR_MASK 0xffff
+#define MT_ST_OPTIONS 0xf0000000
+#define MT_ST_BOOLEANS 0x10000000
+#define MT_ST_SETBOOLEANS 0x30000000
+#define MT_ST_CLEARBOOLEANS 0x40000000
+#define MT_ST_WRITE_THRESHOLD 0x20000000
+#define MT_ST_DEF_BLKSIZE 0x50000000
+#define MT_ST_DEF_OPTIONS 0x60000000
+#define MT_ST_BUFFER_WRITES 0x1
+#define MT_ST_ASYNC_WRITES 0x2
+#define MT_ST_READ_AHEAD 0x4
+#define MT_ST_DEBUGGING 0x8
+#define MT_ST_TWO_FM 0x10
+#define MT_ST_FAST_MTEOM 0x20
+#define MT_ST_AUTO_LOCK 0x40
+#define MT_ST_DEF_WRITES 0x80
+#define MT_ST_CAN_BSR 0x100
+#define MT_ST_NO_BLKLIMS 0x200
+#define MT_ST_CAN_PARTITIONS 0x400
+#define MT_ST_SCSI2LOGICAL 0x800
+#define MT_ST_CLEAR_DEFAULT 0xfffff
+#define MT_ST_DEF_DENSITY (MT_ST_DEF_OPTIONS | 0x100000)
+#define MT_ST_DEF_COMPRESSION (MT_ST_DEF_OPTIONS | 0x200000)
+#define MT_ST_DEF_DRVBUFFER (MT_ST_DEF_OPTIONS | 0x300000)
+#define MT_ST_HPLOADER_OFFSET 10000
+#ifndef DEFTAPE
+#define DEFTAPE "/dev/tape"
+#endif
+
+#endif // SYSROOT_SYS_MTIO_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/param.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/param.h
new file mode 100644
index 0000000..301bba7
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/param.h
@@ -0,0 +1,34 @@
+#ifndef SYSROOT_SYS_PARAM_H_
+#define SYSROOT_SYS_PARAM_H_
+
+#define MAXSYMLINKS 20
+#define MAXHOSTNAMELEN 64
+#define MAXNAMLEN 255
+#define MAXPATHLEN 4096
+#define NBBY 8
+#define NGROUPS 32
+#define CANBSIZE 255
+#define NOFILE 256
+#define NCARGS 131072
+#define DEV_BSIZE 512
+#define NOGROUP (-1)
+
+#undef MIN
+#undef MAX
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+
+#define __bitop(x, i, o) ((x)[(i) / 8] o(1 << (i) % 8))
+#define setbit(x, i) __bitop(x, i, |=)
+#define clrbit(x, i) __bitop(x, i, &= ~)
+#define isset(x, i) __bitop(x, i, &)
+#define isclr(x, i) !isset(x, i)
+
+#define howmany(n, d) (((n) + ((d)-1)) / (d))
+#define roundup(n, d) (howmany(n, d) * (d))
+#define powerof2(n) !(((n)-1) & (n))
+
+#include <endian.h>
+#include <limits.h>
+
+#endif // SYSROOT_SYS_PARAM_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/personality.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/personality.h
new file mode 100644
index 0000000..b32d1eb
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/personality.h
@@ -0,0 +1,47 @@
+#ifndef SYSROOT_SYS_PERSONALITY_H_
+#define SYSROOT_SYS_PERSONALITY_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ADDR_NO_RANDOMIZE 0x0040000
+#define MMAP_PAGE_ZERO 0x0100000
+#define ADDR_COMPAT_LAYOUT 0x0200000
+#define READ_IMPLIES_EXEC 0x0400000
+#define ADDR_LIMIT_32BIT 0x0800000
+#define SHORT_INODE 0x1000000
+#define WHOLE_SECONDS 0x2000000
+#define STICKY_TIMEOUTS 0x4000000
+#define ADDR_LIMIT_3GB 0x8000000
+
+#define PER_LINUX 0
+#define PER_LINUX_32BIT ADDR_LIMIT_32BIT
+#define PER_SVR4 (1 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO)
+#define PER_SVR3 (2 | STICKY_TIMEOUTS | SHORT_INODE)
+#define PER_SCOSVR3 (3 | STICKY_TIMEOUTS | WHOLE_SECONDS | SHORT_INODE)
+#define PER_OSR5 (3 | STICKY_TIMEOUTS | WHOLE_SECONDS)
+#define PER_WYSEV386 (4 | STICKY_TIMEOUTS | SHORT_INODE)
+#define PER_ISCR4 (5 | STICKY_TIMEOUTS)
+#define PER_BSD 6
+#define PER_SUNOS (6 | STICKY_TIMEOUTS)
+#define PER_XENIX (7 | STICKY_TIMEOUTS | SHORT_INODE)
+#define PER_LINUX32 8
+#define PER_LINUX32_3GB (8 | ADDR_LIMIT_3GB)
+#define PER_IRIX32 (9 | STICKY_TIMEOUTS)
+#define PER_IRIXN32 (0xa | STICKY_TIMEOUTS)
+#define PER_IRIX64 (0x0b | STICKY_TIMEOUTS)
+#define PER_RISCOS 0xc
+#define PER_SOLARIS (0xd | STICKY_TIMEOUTS)
+#define PER_UW7 (0xe | STICKY_TIMEOUTS | MMAP_PAGE_ZERO)
+#define PER_OSF4 0xf
+#define PER_HPUX 0x10
+#define PER_MASK 0xff
+
+int personality(unsigned long);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_PERSONALITY_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/poll.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/poll.h
new file mode 100644
index 0000000..9917040
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/poll.h
@@ -0,0 +1,2 @@
+#warning redirecting incorrect #include <sys/poll.h> to <poll.h>
+#include <poll.h>
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/quota.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/quota.h
new file mode 100644
index 0000000..aec5dc9
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/quota.h
@@ -0,0 +1,102 @@
+#ifndef SYSROOT_SYS_QUOTA_H_
+#define SYSROOT_SYS_QUOTA_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#define _LINUX_QUOTA_VERSION 2
+
+#define dbtob(num) ((num) << 10)
+#define btodb(num) ((num) >> 10)
+#define fs_to_dq_blocks(num, blksize) (((num) * (blksize)) / 1024)
+
+#define MAX_IQ_TIME 604800
+#define MAX_DQ_TIME 604800
+
+#define MAXQUOTAS 2
+#define USRQUOTA 0
+#define GRPQUOTA 1
+
+#define INITQFNAMES {"user", "group", "undefined"};
+
+#define QUOTAFILENAME "quota"
+#define QUOTAGROUP "staff"
+
+#define NR_DQHASH 43
+#define NR_DQUOTS 256
+
+#define SUBCMDMASK 0x00ff
+#define SUBCMDSHIFT 8
+#define QCMD(cmd, type) (((cmd) << SUBCMDSHIFT) | ((type)&SUBCMDMASK))
+
+#define Q_SYNC 0x800001
+#define Q_QUOTAON 0x800002
+#define Q_QUOTAOFF 0x800003
+#define Q_GETFMT 0x800004
+#define Q_GETINFO 0x800005
+#define Q_SETINFO 0x800006
+#define Q_GETQUOTA 0x800007
+#define Q_SETQUOTA 0x800008
+
+#define QFMT_VFS_OLD 1
+#define QFMT_VFS_V0 2
+#define QFMT_OCFS2 3
+#define QFMT_VFS_V1 4
+
+#define QIF_BLIMITS 1
+#define QIF_SPACE 2
+#define QIF_ILIMITS 4
+#define QIF_INODES 8
+#define QIF_BTIME 16
+#define QIF_ITIME 32
+#define QIF_LIMITS (QIF_BLIMITS | QIF_ILIMITS)
+#define QIF_USAGE (QIF_SPACE | QIF_INODES)
+#define QIF_TIMES (QIF_BTIME | QIF_ITIME)
+#define QIF_ALL (QIF_LIMITS | QIF_USAGE | QIF_TIMES)
+
+struct dqblk {
+ uint64_t dqb_bhardlimit;
+ uint64_t dqb_bsoftlimit;
+ uint64_t dqb_curspace;
+ uint64_t dqb_ihardlimit;
+ uint64_t dqb_isoftlimit;
+ uint64_t dqb_curinodes;
+ uint64_t dqb_btime;
+ uint64_t dqb_itime;
+ uint32_t dqb_valid;
+};
+
+#define dq_bhardlimit dq_dqb.dqb_bhardlimit
+#define dq_bsoftlimit dq_dqb.dqb_bsoftlimit
+#define dq_curspace dq_dqb.dqb_curspace
+#define dq_valid dq_dqb.dqb_valid
+#define dq_ihardlimit dq_dqb.dqb_ihardlimit
+#define dq_isoftlimit dq_dqb.dqb_isoftlimit
+#define dq_curinodes dq_dqb.dqb_curinodes
+#define dq_btime dq_dqb.dqb_btime
+#define dq_itime dq_dqb.dqb_itime
+
+#define dqoff(UID) ((long long)(UID) * sizeof(struct dqblk))
+
+#define IIF_BGRACE 1
+#define IIF_IGRACE 2
+#define IIF_FLAGS 4
+#define IIF_ALL (IIF_BGRACE | IIF_IGRACE | IIF_FLAGS)
+
+struct dqinfo {
+ uint64_t dqi_bgrace;
+ uint64_t dqi_igrace;
+ uint32_t dqi_flags;
+ uint32_t dqi_valid;
+};
+
+int quotactl(int, const char*, int, char*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_QUOTA_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/random.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/random.h
new file mode 100644
index 0000000..258201d
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/random.h
@@ -0,0 +1,16 @@
+#ifndef SYSROOT_SYS_RANDOM_H_
+#define SYSROOT_SYS_RANDOM_H_
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int getentropy(void* buffer, size_t length) __attribute__((__warn_unused_result__));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_RANDOM_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/reboot.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/reboot.h
new file mode 100644
index 0000000..a83629c
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/reboot.h
@@ -0,0 +1,22 @@
+#ifndef SYSROOT_SYS_REBOOT_H_
+#define SYSROOT_SYS_REBOOT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RB_AUTOBOOT 0x01234567
+#define RB_HALT_SYSTEM 0xcdef0123
+#define RB_ENABLE_CAD 0x89abcdef
+#define RB_DISABLE_CAD 0
+#define RB_POWER_OFF 0x4321fedc
+#define RB_SW_SUSPEND 0xd000fce2
+#define RB_KEXEC 0x45584543
+
+int reboot(int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_REBOOT_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/reg.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/reg.h
new file mode 100644
index 0000000..0f37ffe
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/reg.h
@@ -0,0 +1,9 @@
+#ifndef SYSROOT_SYS_REG_H_
+#define SYSROOT_SYS_REG_H_
+
+#include <limits.h>
+#include <unistd.h>
+
+#include <bits/reg.h>
+
+#endif // SYSROOT_SYS_REG_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/select.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/select.h
new file mode 100644
index 0000000..5d4fd7d
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/select.h
@@ -0,0 +1,54 @@
+#ifndef SYSROOT_SYS_SELECT_H_
+#define SYSROOT_SYS_SELECT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+#define __NEED_time_t
+#define __NEED_suseconds_t
+#define __NEED_struct_timeval
+#define __NEED_struct_timespec
+#define __NEED_sigset_t
+
+#include <bits/alltypes.h>
+
+#define FD_SETSIZE 1024
+
+typedef unsigned long fd_mask;
+
+typedef struct {
+ unsigned long fds_bits[FD_SETSIZE / 8 / sizeof(long)];
+} fd_set;
+
+#define FD_ZERO(s) \
+ do { \
+ int __i; \
+ unsigned long* __b = (s)->fds_bits; \
+ for (__i = sizeof(fd_set) / sizeof(long); __i; __i--) \
+ *__b++ = 0; \
+ } while (0)
+#define FD_SET(d, s) \
+ ((s)->fds_bits[(d) / (8 * sizeof(long))] |= (1UL << ((d) % (8 * sizeof(long)))))
+#define FD_CLR(d, s) \
+ ((s)->fds_bits[(d) / (8 * sizeof(long))] &= ~(1UL << ((d) % (8 * sizeof(long)))))
+#define FD_ISSET(d, s) \
+ !!((s)->fds_bits[(d) / (8 * sizeof(long))] & (1UL << ((d) % (8 * sizeof(long)))))
+
+int select(int, fd_set* __restrict, fd_set* __restrict, fd_set* __restrict,
+ struct timeval* __restrict);
+int pselect(int, fd_set* __restrict, fd_set* __restrict, fd_set* __restrict,
+ const struct timespec* __restrict, const sigset_t* __restrict);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define NFDBITS (8 * (int)sizeof(long))
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_SELECT_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/sem.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/sem.h
new file mode 100644
index 0000000..a4330af
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/sem.h
@@ -0,0 +1,69 @@
+#ifndef SYSROOT_SYS_SEM_H_
+#define SYSROOT_SYS_SEM_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+#define __NEED_pid_t
+#define __NEED_time_t
+#ifdef _GNU_SOURCE
+#define __NEED_struct_timespec
+#endif
+#include <sys/ipc.h>
+
+#include <bits/alltypes.h>
+
+#define SEM_UNDO 0x1000
+#define GETPID 11
+#define GETVAL 12
+#define GETALL 13
+#define GETNCNT 14
+#define GETZCNT 15
+#define SETVAL 16
+#define SETALL 17
+
+#include <endian.h>
+
+#include <bits/sem.h>
+
+#define _SEM_SEMUN_UNDEFINED 1
+
+#define SEM_STAT 18
+#define SEM_INFO 19
+
+struct seminfo {
+ int semmap;
+ int semmni;
+ int semmns;
+ int semmnu;
+ int semmsl;
+ int semopm;
+ int semume;
+ int semusz;
+ int semvzx;
+ int semaem;
+};
+
+struct sembuf {
+ unsigned short sem_num;
+ short sem_op;
+ short sem_flg;
+};
+
+int semctl(int, int, int, ...);
+int semget(key_t, int, int);
+int semop(int, struct sembuf*, size_t);
+
+#ifdef _GNU_SOURCE
+int semtimedop(int, struct sembuf*, size_t, const struct timespec*);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_SEM_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/shm.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/shm.h
new file mode 100644
index 0000000..55b4389
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/shm.h
@@ -0,0 +1,54 @@
+#ifndef SYSROOT_SYS_SHM_H_
+#define SYSROOT_SYS_SHM_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_time_t
+#define __NEED_size_t
+#define __NEED_pid_t
+
+#include <sys/ipc.h>
+
+#include <bits/alltypes.h>
+
+#ifdef _GNU_SOURCE
+#define __used_ids used_ids
+#define __swap_attempts swap_attempts
+#define __swap_successes swap_successes
+#endif
+
+#include <bits/shm.h>
+
+#define SHM_R 0400
+#define SHM_W 0200
+
+#define SHM_RDONLY 010000
+#define SHM_RND 020000
+#define SHM_REMAP 040000
+#define SHM_EXEC 0100000
+
+#define SHM_LOCK 11
+#define SHM_UNLOCK 12
+#define SHM_STAT 13
+#define SHM_INFO 14
+#define SHM_DEST 01000
+#define SHM_LOCKED 02000
+#define SHM_HUGETLB 04000
+#define SHM_NORESERVE 010000
+
+typedef unsigned long shmatt_t;
+
+void* shmat(int, const void*, int);
+int shmctl(int, int, struct shmid_ds*);
+int shmdt(const void*);
+int shmget(key_t, size_t, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_SHM_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/signal.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/signal.h
new file mode 100644
index 0000000..45bdcc6
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/signal.h
@@ -0,0 +1,2 @@
+#warning redirecting incorrect #include <sys/signal.h> to <signal.h>
+#include <signal.h>
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/signalfd.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/signalfd.h
new file mode 100644
index 0000000..46a5489
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/signalfd.h
@@ -0,0 +1,45 @@
+#ifndef SYSROOT_SYS_SIGNALFD_H_
+#define SYSROOT_SYS_SIGNALFD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <fcntl.h>
+#include <stdint.h>
+
+#define __NEED_sigset_t
+
+#include <bits/alltypes.h>
+
+#define SFD_CLOEXEC O_CLOEXEC
+#define SFD_NONBLOCK O_NONBLOCK
+
+int signalfd(int, const sigset_t*, int);
+
+struct signalfd_siginfo {
+ uint32_t ssi_signo;
+ int32_t ssi_errno;
+ int32_t ssi_code;
+ uint32_t ssi_pid;
+ uint32_t ssi_uid;
+ int32_t ssi_fd;
+ uint32_t ssi_tid;
+ uint32_t ssi_band;
+ uint32_t ssi_overrun;
+ uint32_t ssi_trapno;
+ int32_t ssi_status;
+ int32_t ssi_int;
+ uint64_t ssi_ptr;
+ uint64_t ssi_utime;
+ uint64_t ssi_stime;
+ uint64_t ssi_addr;
+ uint16_t ssi_addr_lsb;
+ uint8_t pad[128 - 12 * 4 - 4 * 8 - 2];
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_SIGNALFD_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/socket.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/socket.h
new file mode 100644
index 0000000..7f68e6e
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/socket.h
@@ -0,0 +1,322 @@
+#ifndef SYSROOT_SYS_SOCKET_H_
+#define SYSROOT_SYS_SOCKET_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_socklen_t
+#define __NEED_sa_family_t
+#define __NEED_size_t
+#define __NEED_ssize_t
+#define __NEED_uid_t
+#define __NEED_pid_t
+#define __NEED_gid_t
+#define __NEED_struct_iovec
+
+#include <bits/alltypes.h>
+#include <bits/socket.h>
+
+#ifdef _GNU_SOURCE
+struct ucred {
+ pid_t pid;
+ uid_t uid;
+ gid_t gid;
+};
+
+struct mmsghdr {
+ struct msghdr msg_hdr;
+ unsigned int msg_len;
+};
+
+struct timespec;
+
+int sendmmsg(int, struct mmsghdr*, unsigned int, unsigned int);
+int recvmmsg(int, struct mmsghdr*, unsigned int, unsigned int, struct timespec*);
+#endif
+
+struct linger {
+ int l_onoff;
+ int l_linger;
+};
+
+#define SHUT_RD 0
+#define SHUT_WR 1
+#define SHUT_RDWR 2
+
+#ifndef SOCK_STREAM
+#define SOCK_STREAM 1
+#define SOCK_DGRAM 2
+#endif
+
+#define SOCK_RAW 3
+#define SOCK_RDM 4
+#define SOCK_SEQPACKET 5
+#define SOCK_DCCP 6
+#define SOCK_PACKET 10
+
+#ifndef SOCK_CLOEXEC
+#define SOCK_CLOEXEC 02000000
+#define SOCK_NONBLOCK 04000
+#endif
+
+#define PF_UNSPEC 0
+#define PF_LOCAL 1
+#define PF_UNIX PF_LOCAL
+#define PF_FILE PF_LOCAL
+#define PF_INET 2
+#define PF_AX25 3
+#define PF_IPX 4
+#define PF_APPLETALK 5
+#define PF_NETROM 6
+#define PF_BRIDGE 7
+#define PF_ATMPVC 8
+#define PF_X25 9
+#define PF_INET6 10
+#define PF_ROSE 11
+#define PF_DECnet 12
+#define PF_NETBEUI 13
+#define PF_SECURITY 14
+#define PF_KEY 15
+#define PF_NETLINK 16
+#define PF_ROUTE PF_NETLINK
+#define PF_PACKET 17
+#define PF_ASH 18
+#define PF_ECONET 19
+#define PF_ATMSVC 20
+#define PF_RDS 21
+#define PF_SNA 22
+#define PF_IRDA 23
+#define PF_PPPOX 24
+#define PF_WANPIPE 25
+#define PF_LLC 26
+#define PF_IB 27
+#define PF_MPLS 28
+#define PF_TIPC 30
+#define PF_BLUETOOTH 31
+#define PF_IUCV 32
+#define PF_RXRPC 33
+#define PF_ISDN 34
+#define PF_PHONET 35
+#define PF_IEEE802154 36
+#define PF_CAIF 37
+#define PF_ALG 38
+#define PF_NFC 39
+#define PF_VSOCK 40
+#define PF_MAX 41
+
+#define AF_UNSPEC PF_UNSPEC
+#define AF_LOCAL PF_LOCAL
+#define AF_UNIX AF_LOCAL
+#define AF_FILE AF_LOCAL
+#define AF_INET PF_INET
+#define AF_AX25 PF_AX25
+#define AF_IPX PF_IPX
+#define AF_APPLETALK PF_APPLETALK
+#define AF_NETROM PF_NETROM
+#define AF_BRIDGE PF_BRIDGE
+#define AF_ATMPVC PF_ATMPVC
+#define AF_X25 PF_X25
+#define AF_INET6 PF_INET6
+#define AF_ROSE PF_ROSE
+#define AF_DECnet PF_DECnet
+#define AF_NETBEUI PF_NETBEUI
+#define AF_SECURITY PF_SECURITY
+#define AF_KEY PF_KEY
+#define AF_NETLINK PF_NETLINK
+#define AF_ROUTE PF_ROUTE
+#define AF_PACKET PF_PACKET
+#define AF_ASH PF_ASH
+#define AF_ECONET PF_ECONET
+#define AF_ATMSVC PF_ATMSVC
+#define AF_RDS PF_RDS
+#define AF_SNA PF_SNA
+#define AF_IRDA PF_IRDA
+#define AF_PPPOX PF_PPPOX
+#define AF_WANPIPE PF_WANPIPE
+#define AF_LLC PF_LLC
+#define AF_IB PF_IB
+#define AF_MPLS PF_MPLS
+#define AF_TIPC PF_TIPC
+#define AF_BLUETOOTH PF_BLUETOOTH
+#define AF_IUCV PF_IUCV
+#define AF_RXRPC PF_RXRPC
+#define AF_ISDN PF_ISDN
+#define AF_PHONET PF_PHONET
+#define AF_IEEE802154 PF_IEEE802154
+#define AF_CAIF PF_CAIF
+#define AF_ALG PF_ALG
+#define AF_NFC PF_NFC
+#define AF_VSOCK PF_VSOCK
+#define AF_MAX PF_MAX
+
+#ifndef SO_DEBUG
+#define SO_DEBUG 1
+#define SO_REUSEADDR 2
+#define SO_TYPE 3
+#define SO_ERROR 4
+#define SO_DONTROUTE 5
+#define SO_BROADCAST 6
+#define SO_SNDBUF 7
+#define SO_RCVBUF 8
+#define SO_KEEPALIVE 9
+#define SO_OOBINLINE 10
+#define SO_NO_CHECK 11
+#define SO_PRIORITY 12
+#define SO_LINGER 13
+#define SO_BSDCOMPAT 14
+#define SO_REUSEPORT 15
+#define SO_PASSCRED 16
+#define SO_PEERCRED 17
+#define SO_RCVLOWAT 18
+#define SO_SNDLOWAT 19
+#define SO_RCVTIMEO 20
+#define SO_SNDTIMEO 21
+#define SO_ACCEPTCONN 30
+#define SO_SNDBUFFORCE 32
+#define SO_RCVBUFFORCE 33
+#define SO_PROTOCOL 38
+#define SO_DOMAIN 39
+#endif
+
+#define SO_SECURITY_AUTHENTICATION 22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT 23
+#define SO_SECURITY_ENCRYPTION_NETWORK 24
+
+#define SO_BINDTODEVICE 25
+
+#define SO_ATTACH_FILTER 26
+#define SO_DETACH_FILTER 27
+#define SO_GET_FILTER SO_ATTACH_FILTER
+
+#define SO_PEERNAME 28
+#define SO_TIMESTAMP 29
+#define SCM_TIMESTAMP SO_TIMESTAMP
+
+#define SO_PEERSEC 31
+#define SO_PASSSEC 34
+#define SO_TIMESTAMPNS 35
+#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+#define SO_MARK 36
+#define SO_TIMESTAMPING 37
+#define SCM_TIMESTAMPING SO_TIMESTAMPING
+#define SO_RXQ_OVFL 40
+#define SO_WIFI_STATUS 41
+#define SCM_WIFI_STATUS SO_WIFI_STATUS
+#define SO_PEEK_OFF 42
+#define SO_NOFCS 43
+#define SO_LOCK_FILTER 44
+#define SO_SELECT_ERR_QUEUE 45
+#define SO_BUSY_POLL 46
+#define SO_MAX_PACING_RATE 47
+#define SO_BPF_EXTENSIONS 48
+#define SO_INCOMING_CPU 49
+#define SO_ATTACH_BPF 50
+#define SO_DETACH_BPF SO_DETACH_FILTER
+#define SO_ATTACH_REUSEPORT_CBPF 51
+#define SO_ATTACH_REUSEPORT_EBPF 52
+
+#ifndef SOL_SOCKET
+#define SOL_SOCKET 1
+#endif
+
+#define SOL_IP 0
+#define SOL_IPV6 41
+#define SOL_ICMPV6 58
+
+#define SOL_RAW 255
+#define SOL_DECNET 261
+#define SOL_X25 262
+#define SOL_PACKET 263
+#define SOL_ATM 264
+#define SOL_AAL 265
+#define SOL_IRDA 266
+
+#define SOMAXCONN 128
+
+#define MSG_OOB 0x0001
+#define MSG_PEEK 0x0002
+#define MSG_DONTROUTE 0x0004
+#define MSG_CTRUNC 0x0008
+#define MSG_PROXY 0x0010
+#define MSG_TRUNC 0x0020
+#define MSG_DONTWAIT 0x0040
+#define MSG_EOR 0x0080
+#define MSG_WAITALL 0x0100
+#define MSG_FIN 0x0200
+#define MSG_SYN 0x0400
+#define MSG_CONFIRM 0x0800
+#define MSG_RST 0x1000
+#define MSG_ERRQUEUE 0x2000
+#define MSG_MORE 0x8000
+#define MSG_WAITFORONE 0x10000
+#define MSG_FASTOPEN 0x20000000
+#define MSG_CMSG_CLOEXEC 0x40000000
+
+#define __CMSG_LEN(cmsg) (((cmsg)->cmsg_len + sizeof(long) - 1) & ~(long)(sizeof(long) - 1))
+#define __CMSG_NEXT(cmsg) ((unsigned char*)(cmsg) + __CMSG_LEN(cmsg))
+#define __MHDR_END(mhdr) ((unsigned char*)(mhdr)->msg_control + (mhdr)->msg_controllen)
+
+#define CMSG_DATA(cmsg) ((unsigned char*)(((struct cmsghdr*)(cmsg)) + 1))
+#define CMSG_NXTHDR(mhdr, cmsg) \
+ ((cmsg)->cmsg_len < sizeof(struct cmsghdr) \
+ ? (struct cmsghdr*)0 \
+ : (__CMSG_NEXT(cmsg) + sizeof(struct cmsghdr) >= __MHDR_END(mhdr) \
+ ? (struct cmsghdr*)0 \
+ : ((struct cmsghdr*)__CMSG_NEXT(cmsg))))
+#define CMSG_FIRSTHDR(mhdr) \
+ ((size_t)(mhdr)->msg_controllen >= sizeof(struct cmsghdr) ? (struct cmsghdr*)(mhdr)->msg_control \
+ : (struct cmsghdr*)0)
+
+#define CMSG_ALIGN(len) (((len) + sizeof(size_t) - 1) & (size_t) ~(sizeof(size_t) - 1))
+#define CMSG_SPACE(len) (CMSG_ALIGN(len) + CMSG_ALIGN(sizeof(struct cmsghdr)))
+#define CMSG_LEN(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + (len))
+
+#define SCM_RIGHTS 0x01
+#define SCM_CREDENTIALS 0x02
+
+struct sockaddr {
+ sa_family_t sa_family;
+ char sa_data[14];
+};
+
+struct sockaddr_storage {
+ sa_family_t ss_family;
+ unsigned long __ss_align;
+ char __ss_padding[128 - 2 * sizeof(unsigned long)];
+};
+
+int socket(int, int, int);
+int socketpair(int, int, int, int[2]);
+
+int shutdown(int, int);
+
+int bind(int, const struct sockaddr*, socklen_t);
+int connect(int, const struct sockaddr*, socklen_t);
+int listen(int, int);
+int accept(int, struct sockaddr* __restrict, socklen_t* __restrict);
+int accept4(int, struct sockaddr* __restrict, socklen_t* __restrict, int);
+
+int getsockname(int, struct sockaddr* __restrict, socklen_t* __restrict);
+int getpeername(int, struct sockaddr* __restrict, socklen_t* __restrict);
+
+ssize_t send(int, const void*, size_t, int);
+ssize_t recv(int, void*, size_t, int);
+ssize_t sendto(int, const void*, size_t, int, const struct sockaddr*, socklen_t);
+ssize_t recvfrom(int, void* __restrict, size_t, int, struct sockaddr* __restrict,
+ socklen_t* __restrict);
+ssize_t sendmsg(int, const struct msghdr*, int);
+ssize_t recvmsg(int, struct msghdr*, int);
+
+int getsockopt(int, int, int, void* __restrict, socklen_t* __restrict);
+int setsockopt(int, int, int, const void*, socklen_t);
+
+int sockatmark(int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_SOCKET_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/stat.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/stat.h
new file mode 100644
index 0000000..d58e26c
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/stat.h
@@ -0,0 +1,102 @@
+#ifndef SYSROOT_SYS_STAT_H_
+#define SYSROOT_SYS_STAT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_dev_t
+#define __NEED_ino_t
+#define __NEED_mode_t
+#define __NEED_nlink_t
+#define __NEED_uid_t
+#define __NEED_gid_t
+#define __NEED_off_t
+#define __NEED_time_t
+#define __NEED_blksize_t
+#define __NEED_blkcnt_t
+#define __NEED_struct_timespec
+
+#include <bits/alltypes.h>
+#include <bits/stat.h>
+
+#define st_atime st_atim.tv_sec
+#define st_mtime st_mtim.tv_sec
+#define st_ctime st_ctim.tv_sec
+
+#define S_IFMT 0170000
+
+#define S_IFDIR 0040000
+#define S_IFCHR 0020000
+#define S_IFBLK 0060000
+#define S_IFREG 0100000
+#define S_IFIFO 0010000
+#define S_IFLNK 0120000
+#define S_IFSOCK 0140000
+
+#define S_TYPEISMQ(buf) 0
+#define S_TYPEISSEM(buf) 0
+#define S_TYPEISSHM(buf) 0
+#define S_TYPEISTMO(buf) 0
+
+#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
+#define S_ISCHR(mode) (((mode)&S_IFMT) == S_IFCHR)
+#define S_ISBLK(mode) (((mode)&S_IFMT) == S_IFBLK)
+#define S_ISREG(mode) (((mode)&S_IFMT) == S_IFREG)
+#define S_ISFIFO(mode) (((mode)&S_IFMT) == S_IFIFO)
+#define S_ISLNK(mode) (((mode)&S_IFMT) == S_IFLNK)
+#define S_ISSOCK(mode) (((mode)&S_IFMT) == S_IFSOCK)
+
+#ifndef S_IRUSR
+#define S_ISUID 04000
+#define S_ISGID 02000
+#define S_ISVTX 01000
+#define S_IRUSR 0400
+#define S_IWUSR 0200
+#define S_IXUSR 0100
+#define S_IRWXU 0700
+#define S_IRGRP 0040
+#define S_IWGRP 0020
+#define S_IXGRP 0010
+#define S_IRWXG 0070
+#define S_IROTH 0004
+#define S_IWOTH 0002
+#define S_IXOTH 0001
+#define S_IRWXO 0007
+#endif
+
+#define UTIME_NOW 0x3fffffff
+#define UTIME_OMIT 0x3ffffffe
+
+int stat(const char* __restrict, struct stat* __restrict);
+int fstat(int, struct stat*);
+int lstat(const char* __restrict, struct stat* __restrict);
+int fstatat(int, const char* __restrict, struct stat* __restrict, int);
+int chmod(const char*, mode_t);
+int fchmod(int, mode_t);
+int fchmodat(int, const char*, mode_t, int);
+mode_t umask(mode_t);
+int mkdir(const char*, mode_t);
+int mknod(const char*, mode_t, dev_t);
+int mkfifo(const char*, mode_t);
+int mkdirat(int, const char*, mode_t);
+int mknodat(int, const char*, mode_t, dev_t);
+int mkfifoat(int, const char*, mode_t);
+
+int futimens(int, const struct timespec[2]);
+int utimensat(int, const char*, const struct timespec[2], int);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+int lchmod(const char*, mode_t);
+#define S_IREAD S_IRUSR
+#define S_IWRITE S_IWUSR
+#define S_IEXEC S_IXUSR
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_STAT_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/statfs.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/statfs.h
new file mode 100644
index 0000000..1459181
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/statfs.h
@@ -0,0 +1,24 @@
+#ifndef SYSROOT_SYS_STATFS_H_
+#define SYSROOT_SYS_STATFS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <sys/statvfs.h>
+
+typedef struct __fsid_t {
+ int __val[2];
+} fsid_t;
+
+#include <bits/statfs.h>
+
+int statfs(const char*, struct statfs*);
+int fstatfs(int, struct statfs*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_STATFS_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/statvfs.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/statvfs.h
new file mode 100644
index 0000000..0423246
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/statvfs.h
@@ -0,0 +1,50 @@
+#ifndef SYSROOT_SYS_STATVFS_H_
+#define SYSROOT_SYS_STATVFS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_fsblkcnt_t
+#define __NEED_fsfilcnt_t
+#include <endian.h>
+
+#include <bits/alltypes.h>
+
+struct statvfs {
+ unsigned long f_bsize, f_frsize;
+ fsblkcnt_t f_blocks, f_bfree, f_bavail;
+ fsfilcnt_t f_files, f_ffree, f_favail;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned long f_fsid;
+ unsigned : 8 * (2 * sizeof(int) - sizeof(long));
+#else
+ unsigned : 8 * (2 * sizeof(int) - sizeof(long));
+ unsigned long f_fsid;
+#endif
+ unsigned long f_flag, f_namemax;
+ int __reserved[6];
+};
+
+int statvfs(const char* __restrict, struct statvfs* __restrict);
+int fstatvfs(int, struct statvfs*);
+
+#define ST_RDONLY 1
+#define ST_NOSUID 2
+#define ST_NODEV 4
+#define ST_NOEXEC 8
+#define ST_SYNCHRONOUS 16
+#define ST_MANDLOCK 64
+#define ST_WRITE 128
+#define ST_APPEND 256
+#define ST_IMMUTABLE 512
+#define ST_NOATIME 1024
+#define ST_NODIRATIME 2048
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_STATVFS_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/stropts.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/stropts.h
new file mode 100644
index 0000000..5b5bc02
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/stropts.h
@@ -0,0 +1 @@
+#include <stropts.h>
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/swap.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/swap.h
new file mode 100644
index 0000000..6420606
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/swap.h
@@ -0,0 +1,20 @@
+#ifndef SYSROOT_SYS_SWAP_H_
+#define SYSROOT_SYS_SWAP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SWAP_FLAG_PREFER 0x8000
+#define SWAP_FLAG_PRIO_MASK 0x7fff
+#define SWAP_FLAG_PRIO_SHIFT 0
+#define SWAP_FLAG_DISCARD 0x10000
+
+int swapon(const char*, int);
+int swapoff(const char*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_SWAP_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/syslog.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/syslog.h
new file mode 100644
index 0000000..7761ece
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/syslog.h
@@ -0,0 +1 @@
+#include <syslog.h>
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/termios.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/termios.h
new file mode 100644
index 0000000..f5f751f
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/termios.h
@@ -0,0 +1,2 @@
+#warning redirecting incorrect #include <sys/termios.h> to <termios.h>
+#include <termios.h>
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/time.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/time.h
new file mode 100644
index 0000000..a9476c7
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/time.h
@@ -0,0 +1,65 @@
+#ifndef SYSROOT_SYS_TIME_H_
+#define SYSROOT_SYS_TIME_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <sys/select.h>
+
+int gettimeofday(struct timeval* __restrict, void* __restrict);
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#define ITIMER_REAL 0
+#define ITIMER_VIRTUAL 1
+#define ITIMER_PROF 2
+
+struct itimerval {
+ struct timeval it_interval;
+ struct timeval it_value;
+};
+
+int getitimer(int, struct itimerval*);
+int setitimer(int, const struct itimerval* __restrict, struct itimerval* __restrict);
+int utimes(const char*, const struct timeval[2]);
+
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+struct timezone {
+ int tz_minuteswest;
+ int tz_dsttime;
+};
+int futimes(int, const struct timeval[2]);
+int futimesat(int, const char*, const struct timeval[2]);
+int lutimes(const char*, const struct timeval[2]);
+int settimeofday(const struct timeval*, const struct timezone*);
+int adjtime(const struct timeval*, struct timeval*);
+#define timerisset(t) ((t)->tv_sec || (t)->tv_usec)
+#define timerclear(t) ((t)->tv_sec = (t)->tv_usec = 0)
+#define timercmp(s, t, op) \
+ ((s)->tv_sec == (t)->tv_sec ? (s)->tv_usec op(t)->tv_usec : (s)->tv_sec op(t)->tv_sec)
+#define timeradd(s, t, a) \
+ (void)((a)->tv_sec = (s)->tv_sec + (t)->tv_sec, \
+ ((a)->tv_usec = (s)->tv_usec + (t)->tv_usec) >= 1000000 && \
+ ((a)->tv_usec -= 1000000, (a)->tv_sec++))
+#define timersub(s, t, a) \
+ (void)((a)->tv_sec = (s)->tv_sec - (t)->tv_sec, \
+ ((a)->tv_usec = (s)->tv_usec - (t)->tv_usec) < 0 && \
+ ((a)->tv_usec += 1000000, (a)->tv_sec--))
+#endif
+
+#if defined(_GNU_SOURCE)
+#define TIMEVAL_TO_TIMESPEC(tv, ts) \
+ ((ts)->tv_sec = (tv)->tv_sec, (ts)->tv_nsec = (tv)->tv_usec * 1000, (void)0)
+#define TIMESPEC_TO_TIMEVAL(tv, ts) \
+ ((tv)->tv_sec = (ts)->tv_sec, (tv)->tv_usec = (ts)->tv_nsec / 1000, (void)0)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_TIME_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/timeb.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/timeb.h
new file mode 100644
index 0000000..bbb7e34
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/timeb.h
@@ -0,0 +1,24 @@
+#ifndef SYSROOT_SYS_TIMEB_H_
+#define SYSROOT_SYS_TIMEB_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_time_t
+
+#include <bits/alltypes.h>
+
+struct timeb {
+ time_t time;
+ unsigned short millitm;
+ short timezone, dstflag;
+};
+
+int ftime(struct timeb*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_TIMEB_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/timerfd.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/timerfd.h
new file mode 100644
index 0000000..499a938
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/timerfd.h
@@ -0,0 +1,26 @@
+#ifndef SYSROOT_SYS_TIMERFD_H_
+#define SYSROOT_SYS_TIMERFD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <fcntl.h>
+#include <time.h>
+
+#define TFD_NONBLOCK O_NONBLOCK
+#define TFD_CLOEXEC O_CLOEXEC
+
+#define TFD_TIMER_ABSTIME 1
+
+struct itimerspec;
+
+int timerfd_create(int, int);
+int timerfd_settime(int, int, const struct itimerspec*, struct itimerspec*);
+int timerfd_gettime(int, struct itimerspec*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_TIMERFD_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/times.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/times.h
new file mode 100644
index 0000000..ec5d3d6
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/times.h
@@ -0,0 +1,24 @@
+#ifndef SYSROOT_SYS_TIMES_H_
+#define SYSROOT_SYS_TIMES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_clock_t
+#include <bits/alltypes.h>
+
+struct tms {
+ clock_t tms_utime;
+ clock_t tms_stime;
+ clock_t tms_cutime;
+ clock_t tms_cstime;
+};
+
+clock_t times(struct tms*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_TIMES_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/timex.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/timex.h
new file mode 100644
index 0000000..9981c93
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/timex.h
@@ -0,0 +1,99 @@
+#ifndef SYSROOT_SYS_TIMEX_H_
+#define SYSROOT_SYS_TIMEX_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_clockid_t
+
+#include <sys/time.h>
+
+#include <bits/alltypes.h>
+
+struct ntptimeval {
+ struct timeval time;
+ long maxerror, esterror;
+};
+
+struct timex {
+ unsigned modes;
+ long offset, freq, maxerror, esterror;
+ int status;
+ long constant, precision, tolerance;
+ struct timeval time;
+ long tick, ppsfreq, jitter;
+ int shift;
+ long stabil, jitcnt, calcnt, errcnt, stbcnt;
+ int tai;
+ int __padding[11];
+};
+
+#define ADJ_OFFSET 0x0001
+#define ADJ_FREQUENCY 0x0002
+#define ADJ_MAXERROR 0x0004
+#define ADJ_ESTERROR 0x0008
+#define ADJ_STATUS 0x0010
+#define ADJ_TIMECONST 0x0020
+#define ADJ_TAI 0x0080
+#define ADJ_SETOFFSET 0x0100
+#define ADJ_MICRO 0x1000
+#define ADJ_NANO 0x2000
+#define ADJ_TICK 0x4000
+#define ADJ_OFFSET_SINGLESHOT 0x8001
+#define ADJ_OFFSET_SS_READ 0xa001
+
+#define MOD_OFFSET ADJ_OFFSET
+#define MOD_FREQUENCY ADJ_FREQUENCY
+#define MOD_MAXERROR ADJ_MAXERROR
+#define MOD_ESTERROR ADJ_ESTERROR
+#define MOD_STATUS ADJ_STATUS
+#define MOD_TIMECONST ADJ_TIMECONST
+#define MOD_CLKB ADJ_TICK
+#define MOD_CLKA ADJ_OFFSET_SINGLESHOT
+#define MOD_TAI ADJ_TAI
+#define MOD_MICRO ADJ_MICRO
+#define MOD_NANO ADJ_NANO
+
+#define STA_PLL 0x0001
+#define STA_PPSFREQ 0x0002
+#define STA_PPSTIME 0x0004
+#define STA_FLL 0x0008
+
+#define STA_INS 0x0010
+#define STA_DEL 0x0020
+#define STA_UNSYNC 0x0040
+#define STA_FREQHOLD 0x0080
+
+#define STA_PPSSIGNAL 0x0100
+#define STA_PPSJITTER 0x0200
+#define STA_PPSWANDER 0x0400
+#define STA_PPSERROR 0x0800
+
+#define STA_CLOCKERR 0x1000
+#define STA_NANO 0x2000
+#define STA_MODE 0x4000
+#define STA_CLK 0x8000
+
+#define STA_RONLY \
+ (STA_PPSSIGNAL | STA_PPSJITTER | STA_PPSWANDER | STA_PPSERROR | STA_CLOCKERR | STA_NANO | \
+ STA_MODE | STA_CLK)
+
+#define TIME_OK 0
+#define TIME_INS 1
+#define TIME_DEL 2
+#define TIME_OOP 3
+#define TIME_WAIT 4
+#define TIME_ERROR 5
+#define TIME_BAD TIME_ERROR
+
+#define MAXTC 6
+
+int adjtimex(struct timex*);
+int clock_adjtime(clockid_t, struct timex*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_TIMEX_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/ttydefaults.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/ttydefaults.h
new file mode 100644
index 0000000..e4994fe
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/ttydefaults.h
@@ -0,0 +1,39 @@
+#ifndef SYSROOT_SYS_TTYDEFAULTS_H_
+#define SYSROOT_SYS_TTYDEFAULTS_H_
+
+#define TTYDEF_IFLAG (BRKINT | ISTRIP | ICRNL | IMAXBEL | IXON | IXANY)
+#define TTYDEF_OFLAG (OPOST | ONLCR | XTABS)
+#define TTYDEF_LFLAG (ECHO | ICANON | ISIG | IEXTEN | ECHOE | ECHOKE | ECHOCTL)
+#define TTYDEF_CFLAG (CREAD | CS7 | PARENB | HUPCL)
+#define TTYDEF_SPEED (B9600)
+#define CTRL(x) (x & 037)
+#define CEOF CTRL('d')
+
+#ifdef _POSIX_VDISABLE
+#define CEOL _POSIX_VDISABLE
+#define CSTATUS _POSIX_VDISABLE
+#else
+#define CEOL '\0'
+#define CSTATUS '\0'
+#endif
+
+#define CERASE 0177
+#define CINTR CTRL('c')
+#define CKILL CTRL('u')
+#define CMIN 1
+#define CQUIT 034
+#define CSUSP CTRL('z')
+#define CTIME 0
+#define CDSUSP CTRL('y')
+#define CSTART CTRL('q')
+#define CSTOP CTRL('s')
+#define CLNEXT CTRL('v')
+#define CDISCARD CTRL('o')
+#define CWERASE CTRL('w')
+#define CREPRINT CTRL('r')
+#define CEOT CEOF
+#define CBRK CEOL
+#define CRPRNT CREPRINT
+#define CFLUSH CDISCARD
+
+#endif // SYSROOT_SYS_TTYDEFAULTS_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/types.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/types.h
new file mode 100644
index 0000000..ea195a0
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/types.h
@@ -0,0 +1,76 @@
+#ifndef SYSROOT_SYS_TYPES_H_
+#define SYSROOT_SYS_TYPES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_ino_t
+#define __NEED_dev_t
+#define __NEED_uid_t
+#define __NEED_gid_t
+#define __NEED_mode_t
+#define __NEED_nlink_t
+#define __NEED_off_t
+#define __NEED_pid_t
+#define __NEED_size_t
+#define __NEED_ssize_t
+#define __NEED_time_t
+#define __NEED_timer_t
+#define __NEED_clockid_t
+
+#define __NEED_blkcnt_t
+#define __NEED_fsblkcnt_t
+#define __NEED_fsfilcnt_t
+
+#define __NEED_id_t
+#define __NEED_key_t
+#define __NEED_clock_t
+#define __NEED_suseconds_t
+#define __NEED_blksize_t
+
+#define __NEED_pthread_t
+#define __NEED_pthread_attr_t
+#define __NEED_pthread_mutexattr_t
+#define __NEED_pthread_condattr_t
+#define __NEED_pthread_rwlockattr_t
+#define __NEED_pthread_barrierattr_t
+#define __NEED_pthread_mutex_t
+#define __NEED_pthread_cond_t
+#define __NEED_pthread_rwlock_t
+#define __NEED_pthread_barrier_t
+#define __NEED_pthread_spinlock_t
+#define __NEED_pthread_key_t
+#define __NEED_pthread_once_t
+#define __NEED_useconds_t
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#include <stdint.h>
+#define __NEED_u_int64_t
+#define __NEED_register_t
+#endif
+
+#include <bits/alltypes.h>
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+typedef unsigned char u_int8_t;
+typedef unsigned short u_int16_t;
+typedef unsigned u_int32_t;
+typedef char* caddr_t;
+typedef unsigned char u_char;
+typedef unsigned short u_short, ushort;
+typedef unsigned u_int, uint;
+typedef unsigned long u_long, ulong;
+typedef long long quad_t;
+typedef unsigned long long u_quad_t;
+#include <endian.h>
+#include <sys/select.h>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_TYPES_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/ucontext.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/ucontext.h
new file mode 100644
index 0000000..5fdbd63
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/ucontext.h
@@ -0,0 +1 @@
+#include <ucontext.h>
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/uio.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/uio.h
new file mode 100644
index 0000000..4762083
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/uio.h
@@ -0,0 +1,34 @@
+#ifndef SYSROOT_SYS_UIO_H_
+#define SYSROOT_SYS_UIO_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+#define __NEED_ssize_t
+#define __NEED_struct_iovec
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __NEED_off_t
+#endif
+
+#include <bits/alltypes.h>
+
+#define UIO_MAXIOV 1024
+
+ssize_t readv(int, const struct iovec*, int);
+ssize_t writev(int, const struct iovec*, int);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+ssize_t preadv(int, const struct iovec*, int, off_t);
+ssize_t pwritev(int, const struct iovec*, int, off_t);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_UIO_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/un.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/un.h
new file mode 100644
index 0000000..425c801
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/un.h
@@ -0,0 +1,31 @@
+#ifndef SYSROOT_SYS_UN_H_
+#define SYSROOT_SYS_UN_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_sa_family_t
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __NEED_size_t
+#endif
+
+#include <bits/alltypes.h>
+
+struct sockaddr_un {
+ sa_family_t sun_family;
+ char sun_path[108];
+};
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+size_t strlen(const char*);
+#define SUN_LEN(s) (2 + strlen((s)->sun_path))
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_UN_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/utsname.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/utsname.h
new file mode 100644
index 0000000..5d5fee1
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/utsname.h
@@ -0,0 +1,30 @@
+#ifndef SYSROOT_SYS_UTSNAME_H_
+#define SYSROOT_SYS_UTSNAME_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <limits.h>
+
+struct utsname {
+ char sysname[65];
+ char nodename[HOST_NAME_MAX + 1];
+ char release[65];
+ char version[65];
+ char machine[65];
+#ifdef _GNU_SOURCE
+ char domainname[65];
+#else
+ char __domainname[65];
+#endif
+};
+
+int uname(struct utsname*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_UTSNAME_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/vfs.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/vfs.h
new file mode 100644
index 0000000..a899db2
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/vfs.h
@@ -0,0 +1 @@
+#include <sys/statfs.h>
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/wait.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/wait.h
new file mode 100644
index 0000000..3b33520
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sys/wait.h
@@ -0,0 +1,46 @@
+#ifndef SYSROOT_SYS_WAIT_H_
+#define SYSROOT_SYS_WAIT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_pid_t
+#define __NEED_id_t
+#include <bits/alltypes.h>
+
+typedef enum { P_ALL = 0, P_PID = 1, P_PGID = 2 } idtype_t;
+
+pid_t wait(int*);
+pid_t waitpid(pid_t, int*, int);
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#include <signal.h>
+int waitid(idtype_t, id_t, siginfo_t*, int);
+#endif
+
+#define WNOHANG 1
+#define WUNTRACED 2
+
+#define WSTOPPED 2
+#define WEXITED 4
+#define WCONTINUED 8
+#define WNOWAIT 0x1000000
+
+#define WEXITSTATUS(s) (((s)&0xff00) >> 8)
+#define WTERMSIG(s) ((s)&0x7f)
+#define WSTOPSIG(s) WEXITSTATUS(s)
+#define WCOREDUMP(s) ((s)&0x80)
+#define WIFEXITED(s) (!WTERMSIG(s))
+#define WIFSTOPPED(s) ((short)((((s)&0xffff) * 0x10001) >> 8) > 0x7f00)
+#define WIFSIGNALED(s) (((s)&0xffff) - 1U < 0xffu)
+#define WIFCONTINUED(s) ((s) == 0xffff)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYS_WAIT_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/sysexits.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sysexits.h
new file mode 100644
index 0000000..ca2782d
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/sysexits.h
@@ -0,0 +1,23 @@
+#ifndef SYSROOT_SYSEXITS_H_
+#define SYSROOT_SYSEXITS_H_
+
+#define EX_OK 0
+#define EX__BASE 64
+#define EX_USAGE 64
+#define EX_DATAERR 65
+#define EX_NOINPUT 66
+#define EX_NOUSER 67
+#define EX_NOHOST 68
+#define EX_UNAVAILABLE 69
+#define EX_SOFTWARE 70
+#define EX_OSERR 71
+#define EX_OSFILE 72
+#define EX_CANTCREAT 73
+#define EX_IOERR 74
+#define EX_TEMPFAIL 75
+#define EX_PROTOCOL 76
+#define EX_NOPERM 77
+#define EX_CONFIG 78
+#define EX__MAX 78
+
+#endif // SYSROOT_SYSEXITS_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/syslog.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/syslog.h
new file mode 100644
index 0000000..dcb09e3
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/syslog.h
@@ -0,0 +1,121 @@
+#ifndef SYSROOT_SYSLOG_H_
+#define SYSROOT_SYSLOG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define LOG_EMERG 0
+#define LOG_ALERT 1
+#define LOG_CRIT 2
+#define LOG_ERR 3
+#define LOG_WARNING 4
+#define LOG_NOTICE 5
+#define LOG_INFO 6
+#define LOG_DEBUG 7
+
+#define LOG_PRIMASK 7
+#define LOG_PRI(p) ((p)&LOG_PRIMASK)
+#define LOG_MAKEPRI(f, p) (((f) << 3) | (p))
+
+#define LOG_MASK(p) (1 << (p))
+#define LOG_UPTO(p) ((1 << ((p) + 1)) - 1)
+
+#define LOG_KERN (0 << 3)
+#define LOG_USER (1 << 3)
+#define LOG_MAIL (2 << 3)
+#define LOG_DAEMON (3 << 3)
+#define LOG_AUTH (4 << 3)
+#define LOG_SYSLOG (5 << 3)
+#define LOG_LPR (6 << 3)
+#define LOG_NEWS (7 << 3)
+#define LOG_UUCP (8 << 3)
+#define LOG_CRON (9 << 3)
+#define LOG_AUTHPRIV (10 << 3)
+#define LOG_FTP (11 << 3)
+
+#define LOG_LOCAL0 (16 << 3)
+#define LOG_LOCAL1 (17 << 3)
+#define LOG_LOCAL2 (18 << 3)
+#define LOG_LOCAL3 (19 << 3)
+#define LOG_LOCAL4 (20 << 3)
+#define LOG_LOCAL5 (21 << 3)
+#define LOG_LOCAL6 (22 << 3)
+#define LOG_LOCAL7 (23 << 3)
+
+#define LOG_NFACILITIES 24
+#define LOG_FACMASK 0x3f8
+#define LOG_FAC(p) (((p)&LOG_FACMASK) >> 3)
+
+#define LOG_PID 0x01
+#define LOG_CONS 0x02
+#define LOG_ODELAY 0x04
+#define LOG_NDELAY 0x08
+#define LOG_NOWAIT 0x10
+#define LOG_PERROR 0x20
+
+void closelog(void);
+void openlog(const char*, int, int);
+int setlogmask(int);
+void syslog(int, const char*, ...);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define _PATH_LOG "/dev/log"
+#define __NEED_va_list
+#include <bits/alltypes.h>
+void vsyslog(int, const char*, va_list);
+#if defined(SYSLOG_NAMES)
+#define INTERNAL_NOPRI 0x10
+#define INTERNAL_MARK (LOG_NFACILITIES << 3)
+typedef struct {
+ char* c_name;
+ int c_val;
+} CODE;
+#define prioritynames \
+ ((CODE*)(const CODE[]){{"alert", LOG_ALERT}, \
+ {"crit", LOG_CRIT}, \
+ {"debug", LOG_DEBUG}, \
+ {"emerg", LOG_EMERG}, \
+ {"err", LOG_ERR}, \
+ {"error", LOG_ERR}, \
+ {"info", LOG_INFO}, \
+ {"none", INTERNAL_NOPRI}, \
+ {"notice", LOG_NOTICE}, \
+ {"panic", LOG_EMERG}, \
+ {"warn", LOG_WARNING}, \
+ {"warning", LOG_WARNING}, \
+ {0, -1}})
+#define facilitynames \
+ ((CODE*)(const CODE[]){{"auth", LOG_AUTH}, \
+ {"authpriv", LOG_AUTHPRIV}, \
+ {"cron", LOG_CRON}, \
+ {"daemon", LOG_DAEMON}, \
+ {"ftp", LOG_FTP}, \
+ {"kern", LOG_KERN}, \
+ {"lpr", LOG_LPR}, \
+ {"mail", LOG_MAIL}, \
+ {"mark", INTERNAL_MARK}, \
+ {"news", LOG_NEWS}, \
+ {"security", LOG_AUTH}, \
+ {"syslog", LOG_SYSLOG}, \
+ {"user", LOG_USER}, \
+ {"uucp", LOG_UUCP}, \
+ {"local0", LOG_LOCAL0}, \
+ {"local1", LOG_LOCAL1}, \
+ {"local2", LOG_LOCAL2}, \
+ {"local3", LOG_LOCAL3}, \
+ {"local4", LOG_LOCAL4}, \
+ {"local5", LOG_LOCAL5}, \
+ {"local6", LOG_LOCAL6}, \
+ {"local7", LOG_LOCAL7}, \
+ {0, -1}})
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_SYSLOG_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/tar.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/tar.h
new file mode 100644
index 0000000..2dcb983
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/tar.h
@@ -0,0 +1,33 @@
+#ifndef SYSROOT_TAR_H_
+#define SYSROOT_TAR_H_
+
+#define TSUID 04000
+#define TSGID 02000
+#define TSVTX 01000
+#define TUREAD 00400
+#define TUWRITE 00200
+#define TUEXEC 00100
+#define TGREAD 00040
+#define TGWRITE 00020
+#define TGEXEC 00010
+#define TOREAD 00004
+#define TOWRITE 00002
+#define TOEXEC 00001
+
+#define REGTYPE '0'
+#define AREGTYPE '\0'
+#define LNKTYPE '1'
+#define SYMTYPE '2'
+#define CHRTYPE '3'
+#define BLKTYPE '4'
+#define DIRTYPE '5'
+#define FIFOTYPE '6'
+#define CONTTYPE '7'
+
+#define TMAGIC "ustar"
+#define TMAGLEN 6
+
+#define TVERSION "00"
+#define TVERSLEN 2
+
+#endif // SYSROOT_TAR_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/termios.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/termios.h
new file mode 100644
index 0000000..4ccfe13
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/termios.h
@@ -0,0 +1,46 @@
+#ifndef SYSROOT_TERMIOS_H_
+#define SYSROOT_TERMIOS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_pid_t
+
+#include <bits/alltypes.h>
+
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+typedef unsigned int tcflag_t;
+
+#define NCCS 32
+
+#include <bits/termios.h>
+
+speed_t cfgetospeed(const struct termios*);
+speed_t cfgetispeed(const struct termios*);
+int cfsetospeed(struct termios*, speed_t);
+int cfsetispeed(struct termios*, speed_t);
+
+int tcgetattr(int, struct termios*);
+int tcsetattr(int, int, const struct termios*);
+
+int tcsendbreak(int, int);
+int tcdrain(int);
+int tcflush(int, int);
+int tcflow(int, int);
+
+pid_t tcgetsid(int);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+void cfmakeraw(struct termios*);
+int cfsetspeed(struct termios*, speed_t);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_TERMIOS_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/threads.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/threads.h
new file mode 100644
index 0000000..480a6f7
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/threads.h
@@ -0,0 +1,108 @@
+#ifndef SYSROOT_THREADS_H_
+#define SYSROOT_THREADS_H_
+
+#include <features.h>
+#include <time.h>
+
+#ifdef __cplusplus
+extern "C" {
+typedef unsigned long thrd_t;
+#else
+typedef struct __pthread* thrd_t;
+#define thread_local _Thread_local
+#endif
+
+typedef unsigned tss_t;
+typedef int (*thrd_start_t)(void*);
+typedef void (*tss_dtor_t)(void*);
+
+#define __NEED_cnd_t
+#define __NEED_mtx_t
+#define __NEED_once_flag
+
+#include <bits/alltypes.h>
+
+#define TSS_DTOR_ITERATIONS 4
+
+enum {
+ thrd_success = 0,
+ thrd_busy = 1,
+ thrd_error = 2,
+ thrd_nomem = 3,
+ thrd_timedout = 4,
+};
+
+// These are bitfield values; initialize with e.g. (mtx_plain|mtx_timed).
+// mtx_recursive is not implemented.
+enum {
+ mtx_plain = 0,
+ mtx_recursive = 1,
+ mtx_timed = 2,
+};
+
+#ifdef _ALL_SOURCE
+#define MTX_INIT \
+ {}
+#define CND_INIT \
+ {}
+#endif
+
+#define ONCE_FLAG_INIT 0
+
+int thrd_create(thrd_t*, thrd_start_t, void*);
+#ifdef _ALL_SOURCE
+// |name| is silently truncated to a maximum of ZX_MAX_NAME_LEN-1 characters.
+int thrd_create_with_name(thrd_t*, thrd_start_t, void*, const char* name);
+#endif
+_Noreturn void thrd_exit(int);
+
+int thrd_detach(thrd_t);
+int thrd_join(thrd_t, int*);
+
+int thrd_sleep(const struct timespec*, struct timespec*);
+void thrd_yield(void);
+
+thrd_t thrd_current(void);
+int thrd_equal(thrd_t, thrd_t);
+#ifndef __cplusplus
+#define thrd_equal(A, B) ((A) == (B))
+#endif
+
+void call_once(once_flag*, void (*)(void));
+
+int mtx_init(mtx_t*, int);
+void mtx_destroy(mtx_t*);
+
+int mtx_lock(mtx_t* __m)
+#ifdef __clang__
+ __attribute__((__acquire_capability__(__m)))
+#endif
+ ;
+int mtx_timedlock(mtx_t* __restrict, const struct timespec* __restrict);
+int mtx_trylock(mtx_t*);
+int mtx_unlock(mtx_t* __m)
+#ifdef __clang__
+ __attribute__((__release_capability__(__m)))
+#endif
+ ;
+
+int cnd_init(cnd_t*);
+void cnd_destroy(cnd_t*);
+
+int cnd_broadcast(cnd_t*);
+int cnd_signal(cnd_t*);
+
+int cnd_timedwait(cnd_t* __restrict, mtx_t* __restrict, const struct timespec* __restrict);
+int cnd_wait(cnd_t*, mtx_t*);
+
+int tss_create(tss_t*, tss_dtor_t);
+void tss_delete(tss_t key);
+
+int tss_set(tss_t, void*);
+void* tss_get(tss_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_THREADS_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/time.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/time.h
new file mode 100644
index 0000000..b81da45
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/time.h
@@ -0,0 +1,124 @@
+#ifndef SYSROOT_TIME_H_
+#define SYSROOT_TIME_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <bits/null.h>
+
+#define __NEED_size_t
+#define __NEED_time_t
+#define __NEED_clock_t
+#define __NEED_struct_timespec
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __NEED_clockid_t
+#define __NEED_timer_t
+#define __NEED_pid_t
+#endif
+
+#include <bits/alltypes.h>
+
+#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+#define __tm_gmtoff tm_gmtoff
+#define __tm_zone tm_zone
+#endif
+
+struct tm {
+ int tm_sec;
+ int tm_min;
+ int tm_hour;
+ int tm_mday;
+ int tm_mon;
+ int tm_year;
+ int tm_wday;
+ int tm_yday;
+ int tm_isdst;
+ long __tm_gmtoff;
+ const char* __tm_zone;
+};
+
+clock_t clock(void);
+time_t time(time_t*);
+double difftime(time_t, time_t);
+time_t mktime(struct tm*);
+size_t strftime(char* __restrict, size_t, const char* __restrict, const struct tm* __restrict);
+struct tm* gmtime(const time_t*);
+struct tm* localtime(const time_t*);
+char* asctime(const struct tm*);
+char* ctime(const time_t*);
+int timespec_get(struct timespec*, int);
+
+#define CLOCKS_PER_SEC 1000000L
+
+#define TIME_UTC 1
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+struct tm* gmtime_r(const time_t* __restrict, struct tm* __restrict);
+struct tm* localtime_r(const time_t* __restrict, struct tm* __restrict);
+char* asctime_r(const struct tm* __restrict, char* __restrict);
+char* ctime_r(const time_t*, char*);
+
+void tzset(void);
+
+struct itimerspec {
+ struct timespec it_interval;
+ struct timespec it_value;
+};
+
+#define CLOCK_REALTIME 0
+#define CLOCK_MONOTONIC 1
+#define CLOCK_PROCESS_CPUTIME_ID 2
+#define CLOCK_THREAD_CPUTIME_ID 3
+#define CLOCK_MONOTONIC_RAW 4
+#define CLOCK_REALTIME_COARSE 5
+#define CLOCK_MONOTONIC_COARSE 6
+#define CLOCK_BOOTTIME 7
+#define CLOCK_REALTIME_ALARM 8
+#define CLOCK_BOOTTIME_ALARM 9
+#define CLOCK_SGI_CYCLE 10
+#define CLOCK_TAI 11
+
+#define TIMER_ABSTIME 1
+
+int nanosleep(const struct timespec*, struct timespec*);
+int clock_getres(clockid_t, struct timespec*);
+int clock_gettime(clockid_t, struct timespec*);
+int clock_settime(clockid_t, const struct timespec*);
+int clock_nanosleep(clockid_t, int, const struct timespec*, struct timespec*);
+int clock_getcpuclockid(pid_t, clockid_t*);
+
+struct sigevent;
+int timer_create(clockid_t, struct sigevent* __restrict, timer_t* __restrict);
+int timer_delete(timer_t);
+int timer_settime(timer_t, int, const struct itimerspec* __restrict, struct itimerspec* __restrict);
+int timer_gettime(timer_t, struct itimerspec*);
+int timer_getoverrun(timer_t);
+
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+char* strptime(const char* __restrict, const char* __restrict, struct tm* __restrict);
+extern int daylight;
+extern long timezone;
+extern char* tzname[2];
+extern int getdate_err;
+struct tm* getdate(const char*);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+int stime(const time_t*);
+time_t timegm(struct tm*);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_TIME_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/uchar.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/uchar.h
new file mode 100644
index 0000000..79cda7c
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/uchar.h
@@ -0,0 +1,28 @@
+#ifndef SYSROOT_UCHAR_H_
+#define SYSROOT_UCHAR_H_
+
+#ifdef __cplusplus
+extern "C" {
+#else
+typedef unsigned short char16_t;
+typedef unsigned char32_t;
+#endif
+
+#define __NEED_mbstate_t
+#define __NEED_size_t
+
+#include <features.h>
+
+#include <bits/alltypes.h>
+
+size_t c16rtomb(char* __restrict, char16_t, mbstate_t* __restrict);
+size_t mbrtoc16(char16_t* __restrict, const char* __restrict, size_t, mbstate_t* __restrict);
+
+size_t c32rtomb(char* __restrict, char32_t, mbstate_t* __restrict);
+size_t mbrtoc32(char32_t* __restrict, const char* __restrict, size_t, mbstate_t* __restrict);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_UCHAR_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/ucontext.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/ucontext.h
new file mode 100644
index 0000000..ccd910f
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/ucontext.h
@@ -0,0 +1,26 @@
+#ifndef SYSROOT_UCONTEXT_H_
+#define SYSROOT_UCONTEXT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <signal.h>
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define NGREG (sizeof(gregset_t) / sizeof(greg_t))
+#endif
+
+struct __ucontext;
+
+int getcontext(struct __ucontext*);
+void makecontext(struct __ucontext*, void (*)(void), int, ...);
+int setcontext(const struct __ucontext*);
+int swapcontext(struct __ucontext*, const struct __ucontext*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_UCONTEXT_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/unistd.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/unistd.h
new file mode 100644
index 0000000..e400030
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/unistd.h
@@ -0,0 +1,436 @@
+#ifndef SYSROOT_UNISTD_H_
+#define SYSROOT_UNISTD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <bits/null.h>
+
+#define STDIN_FILENO 0
+#define STDOUT_FILENO 1
+#define STDERR_FILENO 2
+
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
+#define __NEED_size_t
+#define __NEED_ssize_t
+#define __NEED_uid_t
+#define __NEED_gid_t
+#define __NEED_off_t
+#define __NEED_pid_t
+#define __NEED_intptr_t
+#define __NEED_useconds_t
+
+#include <bits/alltypes.h>
+
+int pipe(int[2]);
+int pipe2(int[2], int);
+int close(int);
+int posix_close(int, int);
+int dup(int);
+int dup2(int, int);
+int dup3(int, int, int);
+off_t lseek(int, off_t, int);
+int fsync(int);
+int fdatasync(int);
+
+ssize_t read(int, void*, size_t);
+ssize_t write(int, const void*, size_t);
+ssize_t pread(int, void*, size_t, off_t);
+ssize_t pwrite(int, const void*, size_t, off_t);
+
+int chown(const char*, uid_t, gid_t);
+int fchown(int, uid_t, gid_t);
+int lchown(const char*, uid_t, gid_t);
+int fchownat(int, const char*, uid_t, gid_t, int);
+
+int link(const char*, const char*);
+int linkat(int, const char*, int, const char*, int);
+int symlink(const char*, const char*);
+int symlinkat(const char*, int, const char*);
+ssize_t readlink(const char* __restrict, char* __restrict, size_t);
+ssize_t readlinkat(int, const char* __restrict, char* __restrict, size_t);
+int unlink(const char*);
+int unlinkat(int, const char*, int);
+int rmdir(const char*);
+int truncate(const char*, off_t);
+int ftruncate(int, off_t);
+
+#define F_OK 0
+#define R_OK 4
+#define W_OK 2
+#define X_OK 1
+
+int access(const char*, int);
+int faccessat(int, const char*, int, int);
+
+int chdir(const char*);
+char* getcwd(char*, size_t);
+
+unsigned alarm(unsigned);
+unsigned sleep(unsigned);
+int pause(void);
+
+pid_t fork(void);
+int execve(const char*, char* const[], char* const[]);
+int execv(const char*, char* const[]);
+int execle(const char*, const char*, ...);
+int execl(const char*, const char*, ...);
+int execvp(const char*, char* const[]);
+int execlp(const char*, const char*, ...);
+int fexecve(int, char* const[], char* const[]);
+_Noreturn void _exit(int);
+
+pid_t getpid(void);
+pid_t getppid(void);
+pid_t getpgrp(void);
+pid_t getpgid(pid_t);
+int setpgid(pid_t, pid_t);
+pid_t setsid(void);
+pid_t getsid(pid_t);
+char* ttyname(int);
+int ttyname_r(int, char*, size_t);
+int isatty(int);
+pid_t tcgetpgrp(int);
+int tcsetpgrp(int, pid_t);
+
+uid_t getuid(void);
+uid_t geteuid(void);
+gid_t getgid(void);
+gid_t getegid(void);
+int getgroups(int, gid_t[]);
+int setuid(uid_t);
+int setreuid(uid_t, uid_t);
+int seteuid(uid_t);
+int setgid(gid_t);
+int setregid(gid_t, gid_t);
+int setegid(gid_t);
+
+char* getlogin(void);
+int getlogin_r(char*, size_t);
+int gethostname(char*, size_t);
+char* ctermid(char*);
+
+int getopt(int, char* const[], const char*);
+extern char* optarg;
+extern int optind, opterr, optopt;
+
+long pathconf(const char*, int);
+long fpathconf(int, int);
+long sysconf(int);
+size_t confstr(int, char*, size_t);
+
+#define F_ULOCK 0
+#define F_LOCK 1
+#define F_TLOCK 2
+#define F_TEST 3
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+int lockf(int, int, off_t);
+long gethostid(void);
+void sync(void);
+int syncfs(int);
+pid_t setpgrp(void);
+void swab(const void* __restrict, void* __restrict, ssize_t);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || \
+ (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE + 0 < 700)
+int usleep(unsigned);
+unsigned ualarm(unsigned, unsigned);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define L_SET 0
+#define L_INCR 1
+#define L_XTND 2
+int vhangup(void);
+int getpagesize(void);
+int getdtablesize(void);
+int sethostname(const char*, size_t);
+int getdomainname(char*, size_t);
+int setdomainname(const char*, size_t);
+int setgroups(size_t, const gid_t*);
+char* getpass(const char*);
+int acct(const char*);
+int execvpe(const char*, char* const[], char* const[]);
+int issetugid(void);
+#endif
+
+#ifdef _GNU_SOURCE
+extern char** environ;
+int setresuid(uid_t, uid_t, uid_t);
+int setresgid(gid_t, gid_t, gid_t);
+int getresuid(uid_t*, uid_t*, uid_t*);
+int getresgid(gid_t*, gid_t*, gid_t*);
+char* get_current_dir_name(void);
+int euidaccess(const char*, int);
+int eaccess(const char*, int);
+#endif
+
+#define POSIX_CLOSE_RESTART 0
+
+#define _XOPEN_VERSION 700
+#define _XOPEN_UNIX 1
+#define _XOPEN_ENH_I18N 1
+
+#define _POSIX_VERSION 200809L
+#define _POSIX2_VERSION _POSIX_VERSION
+
+#define _POSIX_ADVISORY_INFO _POSIX_VERSION
+#define _POSIX_CHOWN_RESTRICTED 1
+#define _POSIX_IPV6 _POSIX_VERSION
+#define _POSIX_JOB_CONTROL 1
+#define _POSIX_MAPPED_FILES _POSIX_VERSION
+#define _POSIX_MEMLOCK _POSIX_VERSION
+#define _POSIX_MEMLOCK_RANGE _POSIX_VERSION
+#define _POSIX_MEMORY_PROTECTION _POSIX_VERSION
+#define _POSIX_MESSAGE_PASSING _POSIX_VERSION
+#define _POSIX_FSYNC _POSIX_VERSION
+#define _POSIX_NO_TRUNC 1
+#define _POSIX_RAW_SOCKETS _POSIX_VERSION
+#define _POSIX_REALTIME_SIGNALS _POSIX_VERSION
+#define _POSIX_REGEXP 1
+#define _POSIX_SAVED_IDS 1
+#define _POSIX_SHELL 1
+#define _POSIX_SPAWN _POSIX_VERSION
+#define _POSIX_VDISABLE 0
+
+#define _POSIX_THREADS _POSIX_VERSION
+#define _POSIX_THREAD_PROCESS_SHARED _POSIX_VERSION
+#define _POSIX_THREAD_SAFE_FUNCTIONS _POSIX_VERSION
+#define _POSIX_THREAD_ATTR_STACKADDR _POSIX_VERSION
+#define _POSIX_THREAD_ATTR_STACKSIZE _POSIX_VERSION
+/* #define _POSIX_THREAD_PRIORITY_SCHEDULING -1 */
+#define _POSIX_THREAD_CPUTIME _POSIX_VERSION
+#define _POSIX_TIMERS _POSIX_VERSION
+#define _POSIX_TIMEOUTS _POSIX_VERSION
+#define _POSIX_MONOTONIC_CLOCK _POSIX_VERSION
+#define _POSIX_CPUTIME _POSIX_VERSION
+#define _POSIX_CLOCK_SELECTION _POSIX_VERSION
+#define _POSIX_BARRIERS _POSIX_VERSION
+#define _POSIX_SPIN_LOCKS _POSIX_VERSION
+#define _POSIX_READER_WRITER_LOCKS _POSIX_VERSION
+#define _POSIX_ASYNCHRONOUS_IO _POSIX_VERSION
+#define _POSIX_SEMAPHORES _POSIX_VERSION
+#define _POSIX_SHARED_MEMORY_OBJECTS _POSIX_VERSION
+
+#define _POSIX2_C_BIND _POSIX_VERSION
+
+#include <bits/posix.h>
+
+#define _PC_LINK_MAX 0
+#define _PC_MAX_CANON 1
+#define _PC_MAX_INPUT 2
+#define _PC_NAME_MAX 3
+#define _PC_PATH_MAX 4
+#define _PC_PIPE_BUF 5
+#define _PC_CHOWN_RESTRICTED 6
+#define _PC_NO_TRUNC 7
+#define _PC_VDISABLE 8
+#define _PC_SYNC_IO 9
+#define _PC_ASYNC_IO 10
+#define _PC_PRIO_IO 11
+#define _PC_SOCK_MAXBUF 12
+#define _PC_FILESIZEBITS 13
+#define _PC_REC_INCR_XFER_SIZE 14
+#define _PC_REC_MAX_XFER_SIZE 15
+#define _PC_REC_MIN_XFER_SIZE 16
+#define _PC_REC_XFER_ALIGN 17
+#define _PC_ALLOC_SIZE_MIN 18
+#define _PC_SYMLINK_MAX 19
+#define _PC_2_SYMLINKS 20
+
+#define _SC_ARG_MAX 0
+#define _SC_CHILD_MAX 1
+#define _SC_CLK_TCK 2
+#define _SC_NGROUPS_MAX 3
+#define _SC_OPEN_MAX 4
+#define _SC_STREAM_MAX 5
+#define _SC_TZNAME_MAX 6
+#define _SC_JOB_CONTROL 7
+#define _SC_SAVED_IDS 8
+#define _SC_REALTIME_SIGNALS 9
+#define _SC_PRIORITY_SCHEDULING 10
+#define _SC_TIMERS 11
+#define _SC_ASYNCHRONOUS_IO 12
+#define _SC_PRIORITIZED_IO 13
+#define _SC_SYNCHRONIZED_IO 14
+#define _SC_FSYNC 15
+#define _SC_MAPPED_FILES 16
+#define _SC_MEMLOCK 17
+#define _SC_MEMLOCK_RANGE 18
+#define _SC_MEMORY_PROTECTION 19
+#define _SC_MESSAGE_PASSING 20
+#define _SC_SEMAPHORES 21
+#define _SC_SHARED_MEMORY_OBJECTS 22
+#define _SC_AIO_LISTIO_MAX 23
+#define _SC_AIO_MAX 24
+#define _SC_AIO_PRIO_DELTA_MAX 25
+#define _SC_DELAYTIMER_MAX 26
+#define _SC_MQ_OPEN_MAX 27
+#define _SC_MQ_PRIO_MAX 28
+#define _SC_VERSION 29
+#define _SC_PAGE_SIZE 30
+#define _SC_PAGESIZE 30 /* !! */
+#define _SC_RTSIG_MAX 31
+#define _SC_SEM_NSEMS_MAX 32
+#define _SC_SEM_VALUE_MAX 33
+#define _SC_SIGQUEUE_MAX 34
+#define _SC_TIMER_MAX 35
+#define _SC_BC_BASE_MAX 36
+#define _SC_BC_DIM_MAX 37
+#define _SC_BC_SCALE_MAX 38
+#define _SC_BC_STRING_MAX 39
+#define _SC_COLL_WEIGHTS_MAX 40
+#define _SC_EXPR_NEST_MAX 42
+#define _SC_LINE_MAX 43
+#define _SC_RE_DUP_MAX 44
+#define _SC_2_VERSION 46
+#define _SC_2_C_BIND 47
+#define _SC_2_C_DEV 48
+#define _SC_2_FORT_DEV 49
+#define _SC_2_FORT_RUN 50
+#define _SC_2_SW_DEV 51
+#define _SC_2_LOCALEDEF 52
+#define _SC_UIO_MAXIOV 60 /* !! */
+#define _SC_IOV_MAX 60
+#define _SC_THREADS 67
+#define _SC_THREAD_SAFE_FUNCTIONS 68
+#define _SC_GETGR_R_SIZE_MAX 69
+#define _SC_GETPW_R_SIZE_MAX 70
+#define _SC_LOGIN_NAME_MAX 71
+#define _SC_TTY_NAME_MAX 72
+#define _SC_THREAD_DESTRUCTOR_ITERATIONS 73
+#define _SC_THREAD_KEYS_MAX 74
+#define _SC_THREAD_STACK_MIN 75
+#define _SC_THREAD_THREADS_MAX 76
+#define _SC_THREAD_ATTR_STACKADDR 77
+#define _SC_THREAD_ATTR_STACKSIZE 78
+#define _SC_THREAD_PRIORITY_SCHEDULING 79
+#define _SC_THREAD_PRIO_INHERIT 80
+#define _SC_THREAD_PRIO_PROTECT 81
+#define _SC_THREAD_PROCESS_SHARED 82
+#define _SC_NPROCESSORS_CONF 83
+#define _SC_NPROCESSORS_ONLN 84
+#define _SC_PHYS_PAGES 85
+#define _SC_AVPHYS_PAGES 86
+#define _SC_ATEXIT_MAX 87
+#define _SC_PASS_MAX 88
+#define _SC_XOPEN_VERSION 89
+#define _SC_XOPEN_XCU_VERSION 90
+#define _SC_XOPEN_UNIX 91
+#define _SC_XOPEN_CRYPT 92
+#define _SC_XOPEN_ENH_I18N 93
+#define _SC_XOPEN_SHM 94
+#define _SC_2_CHAR_TERM 95
+#define _SC_2_UPE 97
+#define _SC_XOPEN_XPG2 98
+#define _SC_XOPEN_XPG3 99
+#define _SC_XOPEN_XPG4 100
+#define _SC_NZERO 109
+#define _SC_XBS5_ILP32_OFF32 125
+#define _SC_XBS5_ILP32_OFFBIG 126
+#define _SC_XBS5_LP64_OFF64 127
+#define _SC_XBS5_LPBIG_OFFBIG 128
+#define _SC_XOPEN_LEGACY 129
+#define _SC_XOPEN_REALTIME 130
+#define _SC_XOPEN_REALTIME_THREADS 131
+#define _SC_ADVISORY_INFO 132
+#define _SC_BARRIERS 133
+#define _SC_CLOCK_SELECTION 137
+#define _SC_CPUTIME 138
+#define _SC_THREAD_CPUTIME 139
+#define _SC_MONOTONIC_CLOCK 149
+#define _SC_READER_WRITER_LOCKS 153
+#define _SC_SPIN_LOCKS 154
+#define _SC_REGEXP 155
+#define _SC_SHELL 157
+#define _SC_SPAWN 159
+#define _SC_SPORADIC_SERVER 160
+#define _SC_THREAD_SPORADIC_SERVER 161
+#define _SC_TIMEOUTS 164
+#define _SC_TYPED_MEMORY_OBJECTS 165
+#define _SC_2_PBS 168
+#define _SC_2_PBS_ACCOUNTING 169
+#define _SC_2_PBS_LOCATE 170
+#define _SC_2_PBS_MESSAGE 171
+#define _SC_2_PBS_TRACK 172
+#define _SC_SYMLOOP_MAX 173
+#define _SC_STREAMS 174
+#define _SC_2_PBS_CHECKPOINT 175
+#define _SC_V6_ILP32_OFF32 176
+#define _SC_V6_ILP32_OFFBIG 177
+#define _SC_V6_LP64_OFF64 178
+#define _SC_V6_LPBIG_OFFBIG 179
+#define _SC_HOST_NAME_MAX 180
+#define _SC_TRACE 181
+#define _SC_TRACE_EVENT_FILTER 182
+#define _SC_TRACE_INHERIT 183
+#define _SC_TRACE_LOG 184
+
+#define _SC_IPV6 235
+#define _SC_RAW_SOCKETS 236
+#define _SC_V7_ILP32_OFF32 237
+#define _SC_V7_ILP32_OFFBIG 238
+#define _SC_V7_LP64_OFF64 239
+#define _SC_V7_LPBIG_OFFBIG 240
+#define _SC_SS_REPL_MAX 241
+#define _SC_TRACE_EVENT_NAME_MAX 242
+#define _SC_TRACE_NAME_MAX 243
+#define _SC_TRACE_SYS_MAX 244
+#define _SC_TRACE_USER_EVENT_MAX 245
+#define _SC_XOPEN_STREAMS 246
+#define _SC_THREAD_ROBUST_PRIO_INHERIT 247
+#define _SC_THREAD_ROBUST_PRIO_PROTECT 248
+
+#define _CS_PATH 0
+#define _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS 1
+#define _CS_GNU_LIBC_VERSION 2
+#define _CS_GNU_LIBPTHREAD_VERSION 3
+#define _CS_POSIX_V5_WIDTH_RESTRICTED_ENVS 4
+#define _CS_POSIX_V7_WIDTH_RESTRICTED_ENVS 5
+
+#define _CS_POSIX_V6_ILP32_OFF32_CFLAGS 1116
+#define _CS_POSIX_V6_ILP32_OFF32_LDFLAGS 1117
+#define _CS_POSIX_V6_ILP32_OFF32_LIBS 1118
+#define _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS 1119
+#define _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS 1120
+#define _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS 1121
+#define _CS_POSIX_V6_ILP32_OFFBIG_LIBS 1122
+#define _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS 1123
+#define _CS_POSIX_V6_LP64_OFF64_CFLAGS 1124
+#define _CS_POSIX_V6_LP64_OFF64_LDFLAGS 1125
+#define _CS_POSIX_V6_LP64_OFF64_LIBS 1126
+#define _CS_POSIX_V6_LP64_OFF64_LINTFLAGS 1127
+#define _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS 1128
+#define _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS 1129
+#define _CS_POSIX_V6_LPBIG_OFFBIG_LIBS 1130
+#define _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS 1131
+#define _CS_POSIX_V7_ILP32_OFF32_CFLAGS 1132
+#define _CS_POSIX_V7_ILP32_OFF32_LDFLAGS 1133
+#define _CS_POSIX_V7_ILP32_OFF32_LIBS 1134
+#define _CS_POSIX_V7_ILP32_OFF32_LINTFLAGS 1135
+#define _CS_POSIX_V7_ILP32_OFFBIG_CFLAGS 1136
+#define _CS_POSIX_V7_ILP32_OFFBIG_LDFLAGS 1137
+#define _CS_POSIX_V7_ILP32_OFFBIG_LIBS 1138
+#define _CS_POSIX_V7_ILP32_OFFBIG_LINTFLAGS 1139
+#define _CS_POSIX_V7_LP64_OFF64_CFLAGS 1140
+#define _CS_POSIX_V7_LP64_OFF64_LDFLAGS 1141
+#define _CS_POSIX_V7_LP64_OFF64_LIBS 1142
+#define _CS_POSIX_V7_LP64_OFF64_LINTFLAGS 1143
+#define _CS_POSIX_V7_LPBIG_OFFBIG_CFLAGS 1144
+#define _CS_POSIX_V7_LPBIG_OFFBIG_LDFLAGS 1145
+#define _CS_POSIX_V7_LPBIG_OFFBIG_LIBS 1146
+#define _CS_POSIX_V7_LPBIG_OFFBIG_LINTFLAGS 1147
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_UNISTD_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/utime.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/utime.h
new file mode 100644
index 0000000..b4368aa
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/utime.h
@@ -0,0 +1,23 @@
+#ifndef SYSROOT_UTIME_H_
+#define SYSROOT_UTIME_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_time_t
+
+#include <bits/alltypes.h>
+
+struct utimbuf {
+ time_t actime;
+ time_t modtime;
+};
+
+int utime(const char*, const struct utimbuf*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_UTIME_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/values.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/values.h
new file mode 100644
index 0000000..0862584
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/values.h
@@ -0,0 +1,39 @@
+#ifndef SYSROOT_VALUES_H_
+#define SYSROOT_VALUES_H_
+
+#include <limits.h>
+
+#define CHARBITS (sizeof(char) * 8)
+#define SHORTBITS (sizeof(short) * 8)
+#define INTBITS (sizeof(int) * 8)
+#define LONGBITS (sizeof(long) * 8)
+#define PTRBITS (sizeof(char*) * 8)
+#define DOUBLEBITS (sizeof(double) * 8)
+#define FLOATBITS (sizeof(float) * 8)
+
+#define MINSHORT SHRT_MIN
+#define MININT INT_MIN
+#define MINLONG LONG_MIN
+
+#define MAXSHORT SHRT_MAX
+#define MAXINT INT_MAX
+#define MAXLONG LONG_MAX
+
+#define HIBITS MINSHORT
+#define HIBITL MINLONG
+
+#include <float.h>
+
+#define MAXDOUBLE DBL_MAX
+#undef MAXFLOAT
+#define MAXFLOAT FLT_MAX
+#define MINDOUBLE DBL_MIN
+#define MINFLOAT FLT_MIN
+#define DMINEXP DBL_MIN_EXP
+#define FMINEXP FLT_MIN_EXP
+#define DMAXEXP DBL_MAX_EXP
+#define FMAXEXP FLT_MAX_EXP
+
+#define BITSPERBYTE CHAR_BIT
+
+#endif // SYSROOT_VALUES_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/wait.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/wait.h
new file mode 100644
index 0000000..98396e2
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/wait.h
@@ -0,0 +1,2 @@
+#warning redirecting incorrect #include <wait.h> to <sys/wait.h>
+#include <sys/wait.h>
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/wchar.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/wchar.h
new file mode 100644
index 0000000..aaa7e9e
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/wchar.h
@@ -0,0 +1,185 @@
+#ifndef SYSROOT_WCHAR_H_
+#define SYSROOT_WCHAR_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <bits/null.h>
+
+#define __NEED_FILE
+#define __NEED___isoc_va_list
+#define __NEED_size_t
+#define __NEED_wchar_t
+#define __NEED_wint_t
+#define __NEED_mbstate_t
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __NEED_va_list
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __NEED_wctype_t
+#endif
+
+#include <bits/alltypes.h>
+
+#ifndef WCHAR_MAX
+#define WCHAR_MAX __WCHAR_MAX__
+#endif
+
+#ifndef WCHAR_MIN
+#if defined(__WCHAR_MIN__)
+#define WCHAR_MIN __WCHAR_MIN__
+#else // defined(__WCHAR_MIN__)
+#if defined(__WCHAR_UNSIGNED__)
+#define WCHAR_MIN (L'\0' + 0)
+#else
+#define WCHAR_MIN (-WCHAR_MAX - 1)
+#endif // defined (__WCHAR_UNSIGNED)
+#endif // defined(__WCHAR_MIN__)
+#endif
+
+#undef WEOF
+#define WEOF 0xffffffffU
+
+wchar_t* wcscpy(wchar_t* __restrict, const wchar_t* __restrict);
+wchar_t* wcsncpy(wchar_t* __restrict, const wchar_t* __restrict, size_t);
+
+wchar_t* wcscat(wchar_t* __restrict, const wchar_t* __restrict);
+wchar_t* wcsncat(wchar_t* __restrict, const wchar_t* __restrict, size_t);
+
+int wcscmp(const wchar_t*, const wchar_t*);
+int wcsncmp(const wchar_t*, const wchar_t*, size_t);
+
+int wcscoll(const wchar_t*, const wchar_t*);
+size_t wcsxfrm(wchar_t* __restrict, const wchar_t* __restrict, size_t n);
+
+wchar_t* wcschr(const wchar_t*, wchar_t);
+wchar_t* wcsrchr(const wchar_t*, wchar_t);
+
+size_t wcscspn(const wchar_t*, const wchar_t*);
+size_t wcsspn(const wchar_t*, const wchar_t*);
+wchar_t* wcspbrk(const wchar_t*, const wchar_t*);
+
+wchar_t* wcstok(wchar_t* __restrict, const wchar_t* __restrict, wchar_t** __restrict);
+
+size_t wcslen(const wchar_t*);
+
+wchar_t* wcsstr(const wchar_t* __restrict, const wchar_t* __restrict);
+wchar_t* wcswcs(const wchar_t*, const wchar_t*);
+
+wchar_t* wmemchr(const wchar_t*, wchar_t, size_t);
+int wmemcmp(const wchar_t*, const wchar_t*, size_t);
+wchar_t* wmemcpy(wchar_t* __restrict, const wchar_t* __restrict, size_t);
+wchar_t* wmemmove(wchar_t*, const wchar_t*, size_t);
+wchar_t* wmemset(wchar_t*, wchar_t, size_t);
+
+wint_t btowc(int);
+int wctob(wint_t);
+
+int mbsinit(const mbstate_t*);
+size_t mbrtowc(wchar_t* __restrict, const char* __restrict, size_t, mbstate_t* __restrict);
+size_t wcrtomb(char* __restrict, wchar_t, mbstate_t* __restrict);
+
+size_t mbrlen(const char* __restrict, size_t, mbstate_t* __restrict);
+
+size_t mbsrtowcs(wchar_t* __restrict, const char** __restrict, size_t, mbstate_t* __restrict);
+size_t wcsrtombs(char* __restrict, const wchar_t** __restrict, size_t, mbstate_t* __restrict);
+
+float wcstof(const wchar_t* __restrict, wchar_t** __restrict);
+double wcstod(const wchar_t* __restrict, wchar_t** __restrict);
+long double wcstold(const wchar_t* __restrict, wchar_t** __restrict);
+
+long wcstol(const wchar_t* __restrict, wchar_t** __restrict, int);
+unsigned long wcstoul(const wchar_t* __restrict, wchar_t** __restrict, int);
+
+long long wcstoll(const wchar_t* __restrict, wchar_t** __restrict, int);
+unsigned long long wcstoull(const wchar_t* __restrict, wchar_t** __restrict, int);
+
+int fwide(FILE*, int);
+
+int wprintf(const wchar_t* __restrict, ...);
+int fwprintf(FILE* __restrict, const wchar_t* __restrict, ...);
+int swprintf(wchar_t* __restrict, size_t, const wchar_t* __restrict, ...);
+
+int vwprintf(const wchar_t* __restrict, __isoc_va_list);
+int vfwprintf(FILE* __restrict, const wchar_t* __restrict, __isoc_va_list);
+int vswprintf(wchar_t* __restrict, size_t, const wchar_t* __restrict, __isoc_va_list);
+
+int wscanf(const wchar_t* __restrict, ...);
+int fwscanf(FILE* __restrict, const wchar_t* __restrict, ...);
+int swscanf(const wchar_t* __restrict, const wchar_t* __restrict, ...);
+
+int vwscanf(const wchar_t* __restrict, __isoc_va_list);
+int vfwscanf(FILE* __restrict, const wchar_t* __restrict, __isoc_va_list);
+int vswscanf(const wchar_t* __restrict, const wchar_t* __restrict, __isoc_va_list);
+
+wint_t fgetwc(FILE*);
+wint_t getwc(FILE*);
+wint_t getwchar(void);
+
+wint_t fputwc(wchar_t, FILE*);
+wint_t putwc(wchar_t, FILE*);
+wint_t putwchar(wchar_t);
+
+wchar_t* fgetws(wchar_t* __restrict, int, FILE* __restrict);
+int fputws(const wchar_t* __restrict, FILE* __restrict);
+
+wint_t ungetwc(wint_t, FILE*);
+
+struct tm;
+size_t wcsftime(wchar_t* __restrict, size_t, const wchar_t* __restrict,
+ const struct tm* __restrict);
+
+#undef iswdigit
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+FILE* open_wmemstream(wchar_t**, size_t*);
+size_t mbsnrtowcs(wchar_t* __restrict, const char** __restrict, size_t, size_t,
+ mbstate_t* __restrict);
+size_t wcsnrtombs(char* __restrict, const wchar_t** __restrict, size_t, size_t,
+ mbstate_t* __restrict);
+wchar_t* wcsdup(const wchar_t*);
+size_t wcsnlen(const wchar_t*, size_t);
+wchar_t* wcpcpy(wchar_t* __restrict, const wchar_t* __restrict);
+wchar_t* wcpncpy(wchar_t* __restrict, const wchar_t* __restrict, size_t);
+int wcscasecmp(const wchar_t*, const wchar_t*);
+int wcsncasecmp(const wchar_t*, const wchar_t*, size_t);
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+int wcwidth(wchar_t);
+int wcswidth(const wchar_t*, size_t);
+int iswalnum(wint_t);
+int iswalpha(wint_t);
+int iswblank(wint_t);
+int iswcntrl(wint_t);
+int iswdigit(wint_t);
+int iswgraph(wint_t);
+int iswlower(wint_t);
+int iswprint(wint_t);
+int iswpunct(wint_t);
+int iswspace(wint_t);
+int iswupper(wint_t);
+int iswxdigit(wint_t);
+int iswctype(wint_t, wctype_t);
+wint_t towlower(wint_t);
+wint_t towupper(wint_t);
+wctype_t wctype(const char*);
+
+#ifndef __cplusplus
+#undef iswdigit
+#define iswdigit(a) (0 ? iswdigit(a) : ((unsigned)(a) - '0') < 10)
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_WCHAR_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/wctype.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/wctype.h
new file mode 100644
index 0000000..5a04bb8
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/wctype.h
@@ -0,0 +1,60 @@
+#ifndef SYSROOT_WCTYPE_H_
+#define SYSROOT_WCTYPE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_wint_t
+#define __NEED_wctype_t
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __NEED_locale_t
+#endif
+
+#include <bits/alltypes.h>
+
+typedef const int* wctrans_t;
+
+#undef WEOF
+#define WEOF 0xffffffffU
+
+#undef iswdigit
+
+int iswalnum(wint_t);
+int iswalpha(wint_t);
+int iswblank(wint_t);
+int iswcntrl(wint_t);
+int iswdigit(wint_t);
+int iswgraph(wint_t);
+int iswlower(wint_t);
+int iswprint(wint_t);
+int iswpunct(wint_t);
+int iswspace(wint_t);
+int iswupper(wint_t);
+int iswxdigit(wint_t);
+int iswctype(wint_t, wctype_t);
+wint_t towctrans(wint_t, wctrans_t);
+wint_t towlower(wint_t);
+wint_t towupper(wint_t);
+wctrans_t wctrans(const char*);
+wctype_t wctype(const char*);
+
+#ifndef __cplusplus
+#undef iswdigit
+#define iswdigit(a) (0 ? iswdigit(a) : ((unsigned)(a) - '0') < 10)
+#endif
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+ defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_WCTYPE_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/wordexp.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/wordexp.h
new file mode 100644
index 0000000..dd6caa0
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/wordexp.h
@@ -0,0 +1,41 @@
+#ifndef SYSROOT_WORDEXP_H_
+#define SYSROOT_WORDEXP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+#define WRDE_DOOFFS 1
+#define WRDE_APPEND 2
+#define WRDE_NOCMD 4
+#define WRDE_REUSE 8
+#define WRDE_SHOWERR 16
+#define WRDE_UNDEF 32
+
+typedef struct {
+ size_t we_wordc;
+ char** we_wordv;
+ size_t we_offs;
+} wordexp_t;
+
+#define WRDE_NOSYS -1
+#define WRDE_NOSPACE 1
+#define WRDE_BADCHAR 2
+#define WRDE_BADVAL 3
+#define WRDE_CMDSUB 4
+#define WRDE_SYNTAX 5
+
+int wordexp(const char* __restrict, wordexp_t* __restrict, int);
+void wordfree(wordexp_t*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SYSROOT_WORDEXP_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/assert.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/assert.h
new file mode 100644
index 0000000..d53115d
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/assert.h
@@ -0,0 +1,101 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_ASSERT_
+#define SYSROOT_ZIRCON_ASSERT_
+
+// For a description of which asserts are enabled at which debug levels, see the documentation for
+// GN build argument |assert_level|.
+
+#ifdef _KERNEL
+#include <assert.h>
+#define ZX_PANIC(args...) PANIC(args)
+#define ZX_ASSERT(args...) ASSERT(args)
+#define ZX_ASSERT_MSG(args...) ASSERT_MSG(args)
+#define ZX_DEBUG_ASSERT(args...) DEBUG_ASSERT(args)
+#define ZX_DEBUG_ASSERT_MSG(args...) DEBUG_ASSERT_MSG(args)
+#define ZX_DEBUG_ASSERT_COND(args...) DEBUG_ASSERT_COND(args)
+#define ZX_DEBUG_ASSERT_MSG_COND(args...) DEBUG_ASSERT_MSG_COND(args)
+#define ZX_DEBUG_ASSERT_IMPLEMENTED DEBUG_ASSERT_IMPLEMENTED
+
+#else // #ifdef _KERNEL
+
+#include <zircon/compiler.h>
+
+__BEGIN_CDECLS
+void __zx_panic(const char* format, ...) __NO_RETURN __PRINTFLIKE(1, 2);
+__END_CDECLS
+
+#define ZX_PANIC(fmt, ...) __zx_panic((fmt), ##__VA_ARGS__)
+
+// Assert that |x| is true, else panic.
+//
+// ZX_ASSERT is always enabled and |x| will be evaluated regardless of any build arguments.
+#define ZX_ASSERT(x) \
+ do { \
+ if (unlikely(!(x))) { \
+ ZX_PANIC("ASSERT FAILED at (%s:%d): %s\n", __FILE__, __LINE__, #x); \
+ } \
+ } while (0)
+
+// Assert that |x| is true, else panic with the given message.
+//
+// ZX_ASSERT_MSG is always enabled and |x| will be evaluated regardless of any build arguments.
+#define ZX_ASSERT_MSG(x, msg, msgargs...) \
+ do { \
+ if (unlikely(!(x))) { \
+ ZX_PANIC("ASSERT FAILED at (%s:%d): %s\n" msg "\n", __FILE__, __LINE__, #x, ##msgargs); \
+ } \
+ } while (0)
+
+// Conditionally implement ZX_DEBUG_ASSERT based on ZX_ASSERT_LEVEL.
+#ifdef ZX_ASSERT_LEVEL
+
+// ZX_DEBUG_ASSERT_IMPLEMENTED is intended to be used to conditionalize code that is logically part
+// of a debug assert. It's useful for performing complex consistency checks that are difficult to
+// work into a ZX_DEBUG_ASSERT statement.
+#define ZX_DEBUG_ASSERT_IMPLEMENTED (ZX_ASSERT_LEVEL > 1)
+#else
+#define ZX_DEBUG_ASSERT_IMPLEMENTED 0
+#endif
+
+// Assert that |x| is true, else panic.
+//
+// Depending on build arguments, ZX_DEBUG_ASSERT may or may not be enabled. When disabled, |x| will
+// not be evaluated.
+#define ZX_DEBUG_ASSERT(x) \
+ do { \
+ if (ZX_DEBUG_ASSERT_IMPLEMENTED && unlikely(!(x))) { \
+ ZX_PANIC("DEBUG ASSERT FAILED at (%s:%d): %s\n", __FILE__, __LINE__, #x); \
+ } \
+ } while (0)
+
+// Assert that |x| is true, else panic with the given message.
+//
+// Depending on build arguments, ZX_DEBUG_ASSERT_MSG may or may not be enabled. When disabled, |x|
+// will not be evaluated.
+#define ZX_DEBUG_ASSERT_MSG(x, msg, msgargs...) \
+ do { \
+ if (ZX_DEBUG_ASSERT_IMPLEMENTED && unlikely(!(x))) { \
+ ZX_PANIC("DEBUG ASSERT FAILED at (%s:%d): %s\n" msg "\n", __FILE__, __LINE__, #x, \
+ ##msgargs); \
+ } \
+ } while (0)
+
+// implement _COND versions of ZX_DEBUG_ASSERT which only emit the body if
+// ZX_DEBUG_ASSERT_IMPLEMENTED is set
+#if ZX_DEBUG_ASSERT_IMPLEMENTED
+#define ZX_DEBUG_ASSERT_COND(x) ZX_DEBUG_ASSERT(x)
+#define ZX_DEBUG_ASSERT_MSG_COND(x, msg, msgargs...) ZX_DEBUG_ASSERT_MSG(x, msg, msgargs)
+#else
+#define ZX_DEBUG_ASSERT_COND(x) \
+ do { \
+ } while (0)
+#define ZX_DEBUG_ASSERT_MSG_COND(x, msg, msgargs...) \
+ do { \
+ } while (0)
+#endif
+#endif // #ifdef _KERNEL
+
+#endif // SYSROOT_ZIRCON_ASSERT_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/boot/driver-config.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/boot/driver-config.h
new file mode 100644
index 0000000..8565ba6
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/boot/driver-config.h
@@ -0,0 +1,170 @@
+// Copyright 2018 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.
+
+#ifndef SYSROOT_ZIRCON_BOOT_DRIVER_CONFIG_H_
+#define SYSROOT_ZIRCON_BOOT_DRIVER_CONFIG_H_
+
+#include <stdint.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+// ZBI_TYPE_KERNEL_DRIVER item types (for zbi_header_t.extra)
+#define KDRV_ARM_PSCI 0x49435350 // 'PSCI'
+#define KDRV_ARM_GIC_V2 0x32434947 // 'GIC2'
+#define KDRV_ARM_GIC_V3 0x33434947 // 'GIC3'
+#define KDRV_ARM_GENERIC_TIMER 0x4D495441 // 'ATIM'
+#define KDRV_PL011_UART 0x55304C50 // 'PL0U'
+#define KDRV_AMLOGIC_UART 0x554C4D41 // 'AMLU'
+#define KDRV_NXP_IMX_UART 0x55584D49 // 'IMXU'
+#define KDRV_MT8167_UART 0x5538544D // 'MT8U'
+#define KDRV_HISILICON_POWER 0x4F505348 // 'HSPO'
+#define KDRV_AMLOGIC_HDCP 0x484C4D41 // 'AMLH'
+#define KDRV_MSM_UART 0x554D534D // 'MSMU'
+#define KDRV_MSM_POWER 1347244877 // 'MSMP'
+#define KDRV_DW8250_UART 0x44573855 // 'DW8U'
+#define KDRV_AS370_POWER 0x50303733 // '370P'
+#define KDRV_AMLOGIC_RNG 0x484C4D52 // 'AMLR'
+#define KDRV_GENERIC_32BIT_WATCHDOG 0x32334457 // 'WD32'
+#define KDRV_I8250_PIO_UART 0x30353238 // '8250'
+#define KDRV_I8250_MMIO_UART 0x4d353238 // '825M'
+
+// Kernel driver struct that can be used for simple drivers.
+// Used by KDRV_PL011_UART, KDRV_AMLOGIC_UART, KDRV_NXP_IMX_UART,
+// and KDRV_I8250_MMIO_UART.
+typedef struct {
+ uint64_t mmio_phys;
+ uint32_t irq;
+} dcfg_simple_t;
+
+// Used by KDRV_I8250_PIO_UART.
+typedef struct {
+ uint16_t base;
+ uint32_t irq;
+} dcfg_simple_pio_t;
+
+// for KDRV_MT8167_UART
+typedef struct {
+ uint64_t soc_mmio_phys;
+ uint64_t uart_mmio_phys;
+ uint32_t irq;
+} dcfg_soc_uart_t;
+
+// for KDRV_ARM_PSCI
+typedef struct {
+ bool use_hvc;
+ uint64_t shutdown_args[3];
+ uint64_t reboot_args[3];
+ uint64_t reboot_bootloader_args[3];
+ uint64_t reboot_recovery_args[3];
+} dcfg_arm_psci_driver_t;
+
+typedef struct {
+ uint64_t soc_imem_phys;
+ uint64_t soc_imem_offset;
+} dcfg_msm_power_driver_t;
+
+// for KDRV_ARM_GIC_V2
+typedef struct {
+ uint64_t mmio_phys;
+ uint64_t msi_frame_phys;
+ uint64_t gicd_offset;
+ uint64_t gicc_offset;
+ uint64_t gich_offset;
+ uint64_t gicv_offset;
+ uint32_t ipi_base;
+ bool optional;
+ bool use_msi;
+} dcfg_arm_gicv2_driver_t;
+
+// for KDRV_ARM_GIC_V3
+typedef struct {
+ uint64_t mmio_phys;
+ uint64_t gicd_offset;
+ uint64_t gicr_offset;
+ uint64_t gicr_stride;
+ uint64_t mx8_gpr_phys;
+ uint32_t ipi_base;
+ bool optional;
+} dcfg_arm_gicv3_driver_t;
+
+// for KDRV_ARM_GENERIC_TIMER
+typedef struct {
+ uint32_t irq_phys;
+ uint32_t irq_virt;
+ uint32_t irq_sphys;
+ uint32_t freq_override;
+} dcfg_arm_generic_timer_driver_t;
+
+// for KDRV_HISILICON_POWER
+typedef struct {
+ uint64_t sctrl_phys;
+ uint64_t pmu_phys;
+} dcfg_hisilicon_power_driver_t;
+
+// for KDRV_AMLOGIC_HDCP
+typedef struct {
+ uint64_t preset_phys;
+ uint64_t hiu_phys;
+ uint64_t hdmitx_phys;
+} dcfg_amlogic_hdcp_driver_t;
+
+// for KDRV_AMLOGIC_RNG
+typedef struct {
+ uint64_t rng_data_phys;
+ uint64_t rng_status_phys;
+ uint64_t rng_refresh_interval_usec;
+} dcfg_amlogic_rng_driver_t;
+
+// Defines a register write action for a generic kernel watchdog driver. An
+// action consists of the following steps.
+//
+// 1) Read from the register located a physical address |addr|
+// 2) Clear all of the bits in the value which was read using the |clr_mask|
+// 3) Set all of the bits in the value using the |set_mask|
+// 4) Write this value back to the address located at addr.
+//
+typedef struct {
+ uint64_t addr;
+ uint32_t clr_mask;
+ uint32_t set_mask;
+} dcfg_generic_32bit_watchdog_action_t;
+
+#define KDRV_GENERIC_32BIT_WATCHDOG_FLAG_ENABLED ((uint32_t)0x00000001)
+#define KDRV_GENERIC_32BIT_WATCHDOG_MIN_PERIOD ZX_MSEC(1)
+
+// Definitions of actions which may be taken by a generic 32 bit watchdog timer
+// kernel driver which may be passed by a bootloader. Field definitions are as
+// follows.
+//
+// |pet_action|
+// The address and masks needed to "pet" (aka, dismiss) a hardware watchdog timer.
+//
+// |enable_action|
+// The address and masks needed to enable a hardware watchdog timer. If enable
+// is an unsupported operation, the addr of the |enable_action| shall be zero.
+//
+// |disable_action|
+// The address and masks needed to disable a hardware watchdog timer. If
+// disable is an unsupported operation, the addr of the |disable_action| shall
+// be zero.
+//
+// |watchdog_period_nsec|
+// The period of the watchdog timer given in nanoseconds. When enabled, the
+// watchdog timer driver must pet the watch dog at least this often. The value
+// must be at least 1 mSec, typically much larger (on the order of a second or
+// two)
+//
+// |flags|
+// Storage for additional flags. Currently, only one flag is defined,
+// "FLAG_ENABLED". When this flag is set, it indicates that the watchdog timer
+// was left enabled by the bootloader at startup.
+typedef struct {
+ dcfg_generic_32bit_watchdog_action_t pet_action;
+ dcfg_generic_32bit_watchdog_action_t enable_action;
+ dcfg_generic_32bit_watchdog_action_t disable_action;
+ zx_duration_t watchdog_period_nsec;
+ uint32_t flags;
+} dcfg_generic_32bit_watchdog_t;
+
+#endif // SYSROOT_ZIRCON_BOOT_DRIVER_CONFIG_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/boot/e820.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/boot/e820.h
new file mode 100644
index 0000000..f0f98f0
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/boot/e820.h
@@ -0,0 +1,23 @@
+// Copyright 2017 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.
+
+#ifndef SYSROOT_ZIRCON_BOOT_E820_H_
+#define SYSROOT_ZIRCON_BOOT_E820_H_
+
+#include <stdint.h>
+#include <zircon/compiler.h>
+
+#define E820_RAM 1
+#define E820_RESERVED 2
+#define E820_ACPI 3
+#define E820_NVS 4
+#define E820_UNUSABLE 5
+
+typedef struct e820entry {
+ uint64_t addr;
+ uint64_t size;
+ uint32_t type;
+} __PACKED e820entry_t;
+
+#endif // SYSROOT_ZIRCON_BOOT_E820_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/boot/image.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/boot/image.h
new file mode 100644
index 0000000..1e23a25
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/boot/image.h
@@ -0,0 +1,636 @@
+// Copyright 2018 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.
+
+#ifndef SYSROOT_ZIRCON_BOOT_IMAGE_H_
+#define SYSROOT_ZIRCON_BOOT_IMAGE_H_
+
+// This file contains assembly code that cannot be clang formatted.
+// clang-format off
+
+#ifndef __ASSEMBLER__
+#include <stdint.h>
+#endif
+
+// Zircon Boot Image format (ZBI).
+//
+// A Zircon Boot Image consists of a container header followed by boot
+// items. Each boot item has a header (zbi_header_t) and then a payload of
+// zbi_header_t.length bytes, which can be any size. The zbi_header_t.type
+// field indicates how to interpret the payload. Many types specify an
+// additional type-specific header that begins a variable-sized payload.
+// zbi_header_t.length does not include the zbi_header_t itself, but does
+// include any type-specific headers as part of the payload. All fields in
+// all header formats are little-endian.
+//
+// Padding bytes appear after each item as needed to align the payload size
+// up to a ZBI_ALIGNMENT (8-byte) boundary. This padding is not reflected
+// in the zbi_header_t.length value.
+//
+// A "complete" ZBI can be booted by a Zircon-compatible boot loader.
+// It contains one ZBI_TYPE_KERNEL_{ARCH} boot item that must come first,
+// followed by any number of additional boot items, which must include
+// exactly one ZBI_TYPE_STORAGE_BOOTFS item.
+//
+// A partial ZBI cannot be booted, and is only used during the build process.
+// It contains one or more boot items and can be combined with other ZBIs to
+// make a complete ZBI.
+
+// All items begin at an 8-byte aligned offset into the image.
+#ifdef __ASSEMBLER__
+#define ZBI_ALIGNMENT (8)
+#else
+#define ZBI_ALIGNMENT (8u)
+#endif
+
+// Round n up to the next 8 byte boundary
+#ifndef __ASSEMBLER__
+#ifdef __cplusplus
+constexpr
+#endif
+static inline uint32_t ZBI_ALIGN(uint32_t n) {
+ return ((n + ZBI_ALIGNMENT - 1) & -ZBI_ALIGNMENT);
+}
+#endif
+
+// LSW of sha256("bootdata")
+#define ZBI_CONTAINER_MAGIC (0x868cf7e6)
+
+// LSW of sha256("bootitem")
+#define ZBI_ITEM_MAGIC (0xb5781729)
+
+// This flag is always required.
+#define ZBI_FLAG_VERSION (0x00010000)
+
+// ZBI items with the CRC32 flag must have a valid crc32.
+// Otherwise their crc32 field must contain ZBI_ITEM_NO_CRC32
+#define ZBI_FLAG_CRC32 (0x00020000)
+
+// Value for zbi_header_t.crc32 when ZBI_FLAG_CRC32 is not set.
+#define ZBI_ITEM_NO_CRC32 (0x4a87e8d6)
+
+#ifndef __ASSEMBLER__
+// Each header must be 8-byte aligned. The length field specifies the
+// actual payload length and does not include the size of padding.
+typedef struct {
+ // ZBI_TYPE_* constant, see below.
+ uint32_t type;
+
+ // Size of the payload immediately following this header. This
+ // does not include the header itself nor any alignment padding
+ // after the payload.
+ uint32_t length;
+
+ // Type-specific extra data. Each type specifies the use of this
+ // field; see below. When not explicitly specified, it should be zero.
+ uint32_t extra;
+
+ // Flags for this item. This must always include ZBI_FLAG_VERSION.
+ // It should contain ZBI_FLAG_CRC32 for any item where it's feasible
+ // to compute the CRC32 at build time. Other flags are specific to
+ // each type; see below.
+ uint32_t flags;
+
+ // For future expansion. Set to 0.
+ uint32_t reserved0;
+ uint32_t reserved1;
+
+ // Must be ZBI_ITEM_MAGIC.
+ uint32_t magic;
+
+ // Must be the CRC32 of payload if ZBI_FLAG_CRC32 is set,
+ // otherwise must be ZBI_ITEM_NO_CRC32.
+ uint32_t crc32;
+} zbi_header_t;
+#endif
+
+// Be sure to add new types to ZBI_ALL_TYPES.
+#define ZBI_ALL_TYPES(macro) \
+ macro(ZBI_TYPE_CONTAINER, "CONTAINER", ".bin") \
+ macro(ZBI_TYPE_KERNEL_X64, "KERNEL_X64", ".bin") \
+ macro(ZBI_TYPE_KERNEL_ARM64, "KERNEL_ARM64", ".bin") \
+ macro(ZBI_TYPE_DISCARD, "DISCARD", ".bin") \
+ macro(ZBI_TYPE_STORAGE_RAMDISK, "RAMDISK", ".bin") \
+ macro(ZBI_TYPE_STORAGE_BOOTFS, "BOOTFS", ".bin") \
+ macro(ZBI_TYPE_STORAGE_BOOTFS_FACTORY, "BOOTFS_FACTORY", ".bin") \
+ macro(ZBI_TYPE_CMDLINE, "CMDLINE", ".txt") \
+ macro(ZBI_TYPE_CRASHLOG, "CRASHLOG", ".bin") \
+ macro(ZBI_TYPE_NVRAM, "NVRAM", ".bin") \
+ macro(ZBI_TYPE_PLATFORM_ID, "PLATFORM_ID", ".bin") \
+ macro(ZBI_TYPE_CPU_CONFIG, "CPU_CONFIG", ".bin") /* Deprecated */ \
+ macro(ZBI_TYPE_CPU_TOPOLOGY, "CPU_TOPOLOGY", ".bin") \
+ macro(ZBI_TYPE_MEM_CONFIG, "MEM_CONFIG", ".bin") \
+ macro(ZBI_TYPE_KERNEL_DRIVER, "KERNEL_DRIVER", ".bin") \
+ macro(ZBI_TYPE_ACPI_RSDP, "ACPI_RSDP", ".bin") \
+ macro(ZBI_TYPE_SMBIOS, "SMBIOS", ".bin") \
+ macro(ZBI_TYPE_EFI_MEMORY_MAP, "EFI_MEMORY_MAP", ".bin") \
+ macro(ZBI_TYPE_EFI_SYSTEM_TABLE, "EFI_SYSTEM_TABLE", ".bin") \
+ macro(ZBI_TYPE_E820_TABLE, "E820_TABLE", ".bin") \
+ macro(ZBI_TYPE_FRAMEBUFFER, "FRAMEBUFFER", ".bin") \
+ macro(ZBI_TYPE_DRV_MAC_ADDRESS, "DRV_MAC_ADDRESS", ".bin") \
+ macro(ZBI_TYPE_DRV_PARTITION_MAP, "DRV_PARTITION_MAP", ".bin") \
+ macro(ZBI_TYPE_DRV_BOARD_PRIVATE, "DRV_BOARD_PRIVATE", ".bin") \
+ macro(ZBI_TYPE_DRV_BOARD_INFO, "DRV_BOARD_INFO", ".bin") \
+ macro(ZBI_TYPE_IMAGE_ARGS, "IMAGE_ARGS", ".txt") \
+ macro(ZBI_TYPE_BOOT_VERSION, "BOOT_VERSION", ".bin") \
+ macro(ZBI_TYPE_HW_REBOOT_REASON, "HW_REBOOT_REASON", ".bin")
+
+// Each ZBI starts with a container header.
+// length: Total size of the image after this header.
+// This includes all item headers, payloads, and padding.
+// It does not include the container header itself.
+// Must be a multiple of ZBI_ALIGNMENT.
+// extra: Must be ZBI_CONTAINER_MAGIC.
+// flags: Must be ZBI_FLAG_VERSION and no other flags.
+#define ZBI_TYPE_CONTAINER (0x544f4f42) // BOOT
+
+// Define a container header in assembly code. The symbol name is defined
+// as a local label; use .global symbol to make it global. The length
+// argument can use assembly label arithmetic like any immediate operand.
+#ifdef __ASSEMBLER__
+#define ZBI_CONTAINER_HEADER(symbol, length) \
+ .balign ZBI_ALIGNMENT; \
+ symbol: \
+ .int ZBI_TYPE_CONTAINER; \
+ .int (length); \
+ .int ZBI_CONTAINER_MAGIC; \
+ .int ZBI_FLAG_VERSION; \
+ .int 0; \
+ .int 0; \
+ .int ZBI_ITEM_MAGIC; \
+ .int ZBI_ITEM_NO_CRC32; \
+ .size symbol, . - symbol; \
+ .type symbol, %object
+#else
+#define ZBI_CONTAINER_HEADER(length) { \
+ ZBI_TYPE_CONTAINER, \
+ (length), \
+ ZBI_CONTAINER_MAGIC, \
+ ZBI_FLAG_VERSION, \
+ 0, \
+ 0, \
+ ZBI_ITEM_MAGIC, \
+ ZBI_ITEM_NO_CRC32, \
+}
+#endif
+
+
+// The kernel image. In a complete ZBI this item must always be first,
+// immediately after the ZBI_TYPE_CONTAINER header. The contiguous memory
+// image of the kernel is formed from the ZBI_TYPE_CONTAINER header, the
+// ZBI_TYPE_KERNEL_{ARCH} header, and the payload.
+//
+// The boot loader loads the whole image starting with the container header
+// through to the end of the kernel item's payload into contiguous physical
+// memory. It then constructs a partial ZBI elsewhere in memory, which has
+// a ZBI_TYPE_CONTAINER header of its own followed by all the other items
+// that were in the booted ZBI plus other items synthesized by the boot
+// loader to describe the machine. This partial ZBI must be placed at an
+// address (where the container header is found) that is aligned to the
+// machine's page size. The precise protocol for transferring control to
+// the kernel's entry point varies by machine.
+//
+// On all machines, the kernel requires some amount of scratch memory to be
+// available immediately after the kernel image at boot. It needs this
+// space for early setup work before it has a chance to read any memory-map
+// information from the boot loader. The `reserve_memory_size` field tells
+// the boot loader how much space after the kernel's load image it must
+// leave available for the kernel's use. The boot loader must place its
+// constructed ZBI or other reserved areas at least this many bytes after
+// the kernel image.
+//
+// x86-64
+//
+// The kernel assumes it was loaded at a fixed physical address of
+// 0x100000 (1MB). zbi_kernel_t.entry is the absolute physical address
+// of the PC location where the kernel will start.
+// TODO(SEC-31): Perhaps this will change??
+// The processor is in 64-bit mode with direct virtual to physical
+// mapping covering the physical memory where the kernel and
+// bootloader-constructed ZBI were loaded.
+// The %rsi register holds the physical address of the
+// bootloader-constructed ZBI.
+// All other registers are unspecified.
+//
+// ARM64
+//
+// zbi_kernel_t.entry is an offset from the beginning of the image
+// (i.e., the ZBI_TYPE_CONTAINER header before the ZBI_TYPE_KERNEL_ARM64
+// header) to the PC location in the image where the kernel will
+// start. The processor is in physical address mode at EL1 or
+// above. The kernel image and the bootloader-constructed ZBI each
+// can be loaded anywhere in physical memory. The x0 register
+// holds the physical address of the bootloader-constructed ZBI.
+// All other registers are unspecified.
+//
+#define ZBI_TYPE_KERNEL_PREFIX (0x004e524b) // KRN\0
+#define ZBI_TYPE_KERNEL_MASK (0x00FFFFFF)
+#define ZBI_TYPE_KERNEL_X64 (0x4c4e524b) // KRNL
+#define ZBI_TYPE_KERNEL_ARM64 (0x384e524b) // KRN8
+#define ZBI_IS_KERNEL_BOOTITEM(x) (((x) & ZBI_TYPE_KERNEL_MASK) == \
+ ZBI_TYPE_KERNEL_PREFIX)
+
+#ifndef __ASSEMBLER__
+typedef struct {
+ // Entry-point address. The interpretation of this differs by machine.
+ uint64_t entry;
+ // Minimum amount (in bytes) of scratch memory that the kernel requires
+ // immediately after its load image.
+ uint64_t reserve_memory_size;
+} zbi_kernel_t;
+
+// The whole contiguous image loaded into memory by the boot loader.
+typedef struct {
+ zbi_header_t hdr_file;
+ zbi_header_t hdr_kernel;
+ zbi_kernel_t data_kernel;
+ uint8_t contents[/*hdr_kernel.length - sizeof(zbi_kernel_t)*/];
+ // data_kernel.reserve_memory_size bytes in memory are free after contents.
+} zircon_kernel_t;
+#endif
+
+
+// A discarded item that should just be ignored. This is used for an
+// item that was already processed and should be ignored by whatever
+// stage is now looking at the ZBI. An earlier stage already "consumed"
+// this information, but avoided copying data around to remove it from
+// the ZBI item stream.
+#define ZBI_TYPE_DISCARD (0x50494b53) // SKIP
+
+
+// ZBI_TYPE_STORAGE_* types represent an image that might otherwise
+// appear on some block storage device, i.e. a RAM disk of some sort.
+// All zbi_header_t fields have the same meanings for all these types.
+// The interpretation of the payload (after possible decompression) is
+// indicated by the specific zbi_header_t.type value.
+//
+// **Note:** The ZBI_TYPE_STORAGE_* types are not a long-term stable ABI.
+// - Items of these types are always packed for a specific version of the
+// kernel and userland boot services, often in the same build that compiles
+// the kernel.
+// - These item types are **not** expected to be synthesized or
+// examined by boot loaders.
+// - New versions of the `zbi` tool will usually retain the ability to
+// read old formats and non-default switches to write old formats, for
+// diagnostic use.
+//
+// The zbi_header_t.extra field always gives the exact size of the
+// original, uncompressed payload. That equals zbi_header_t.length when
+// the payload is not compressed. If ZBI_FLAG_STORAGE_COMPRESSED is set in
+// zbi_header_t.flags, then the payload is compressed.
+//
+// **Note:** Magic-number and header bytes at the start of the compressed
+// payload indicate the compression algorithm and parameters. The set of
+// compression formats is not a long-term stable ABI.
+// - Zircon [userboot](../../../../docs/userboot.md) and core services
+// do the decompression. A given kernel build's `userboot` will usually
+// only support one particular compression format.
+// - The `zbi` tool will usually retain the ability to compress and
+// decompress for old formats, and can be used to convert between formats.
+#define ZBI_FLAG_STORAGE_COMPRESSED (0x00000001)
+
+// A virtual disk image. This is meant to be treated as if it were a
+// storage device. The payload (after decompression) is the contents of
+// the storage device, in whatever format that might be.
+#define ZBI_TYPE_STORAGE_RAMDISK (0x4b534452) // RDSK
+
+// The /boot filesystem in BOOTFS format, specified in <zircon/boot/bootfs.h>.
+// A complete ZBI must have exactly one ZBI_TYPE_STORAGE_BOOTFS item.
+// Zircon [userboot](../../../../docs/userboot.md) handles the contents
+// of this filesystem.
+#define ZBI_TYPE_STORAGE_BOOTFS (0x42534642) // BFSB
+
+// Device-specific factory data, stored in BOOTFS format, specified below.
+#define ZBI_TYPE_STORAGE_BOOTFS_FACTORY (0x46534642) // BFSF
+
+// The remaining types are used to communicate information from the boot
+// loader to the kernel. Usually these are synthesized in memory by the
+// boot loader, but they can also be included in a ZBI along with the
+// kernel and BOOTFS. Some boot loaders may set the zbi_header_t flags
+// and crc32 fields to zero, though setting them to ZBI_FLAG_VERSION and
+// ZBI_ITEM_NO_CRC32 is specified. The kernel doesn't check.
+
+
+// A kernel command line fragment, a NUL-terminated UTF-8 string.
+// Multiple ZBI_TYPE_CMDLINE items can appear. They are treated as if
+// concatenated with ' ' between each item, in the order they appear:
+// first items in the complete ZBI containing the kernel; then items in
+// the ZBI synthesized by the boot loader. The kernel interprets the
+// [whole command line](../../../../docs/kernel_cmdline.md).
+#define ZBI_TYPE_CMDLINE (0x4c444d43) // CMDL
+
+// The crash log from the previous boot, a UTF-8 string.
+#define ZBI_TYPE_CRASHLOG (0x4d4f4f42) // BOOM
+
+// Physical memory region that will persist across warm boots.
+// zbi_nvram_t gives the physical base address and length in bytes.
+#define ZBI_TYPE_NVRAM (0x4c4c564e) // NVLL
+// This reflects a typo we need to support for a while.
+#define ZBI_TYPE_NVRAM_DEPRECATED (0x4c4c5643) // CVLL
+#ifndef __ASSEMBLER__
+typedef struct {
+ uint64_t base;
+ uint64_t length;
+} zbi_nvram_t;
+#endif
+
+#define ZBI_BOARD_NAME_LEN 32
+
+// Platform ID Information.
+#define ZBI_TYPE_PLATFORM_ID (0x44494C50) // PLID
+#ifndef __ASSEMBLER__
+typedef struct {
+ uint32_t vid;
+ uint32_t pid;
+ char board_name[ZBI_BOARD_NAME_LEN];
+} zbi_platform_id_t;
+#endif
+
+#define ZBI_TYPE_DRV_BOARD_INFO (0x4953426D) // mBSI
+// Board-specific information.
+#ifndef __ASSEMBLER__
+typedef struct {
+ uint32_t revision;
+} zbi_board_info_t;
+#endif
+
+// CPU configuration, a zbi_cpu_config_t header followed by one or more
+// zbi_cpu_cluster_t entries. zbi_header_t.length must equal
+// zbi_cpu_config_t.cluster_count * sizeof(zbi_cpu_cluster_t).
+#define ZBI_TYPE_CPU_CONFIG (0x43555043) // CPUC
+#ifndef __ASSEMBLER__
+typedef struct {
+ // Number of CPU cores in the cluster.
+ uint32_t cpu_count;
+
+ // Reserved for future use. Set to 0.
+ uint32_t type;
+ uint32_t flags;
+ uint32_t reserved;
+} zbi_cpu_cluster_t;
+
+typedef struct {
+ // Number of zbi_cpu_cluster_t entries following this header.
+ uint32_t cluster_count;
+
+ // Reserved for future use. Set to 0.
+ uint32_t reserved[3];
+
+ // cluster_count entries follow.
+ zbi_cpu_cluster_t clusters[];
+} zbi_cpu_config_t;
+#endif
+
+#define ZBI_TYPE_CPU_TOPOLOGY (0x544F504F) // TOPO
+
+#ifndef __ASSEMBLER__
+
+#define ZBI_MAX_SMT 4
+
+// These are Used in the flags field of zbi_topology_processor_t.
+
+// This is the processor that boots the system and the last to be shutdown.
+#define ZBI_TOPOLOGY_PROCESSOR_PRIMARY 0b1
+
+// This is the processor that handles all interrupts, some architectures will
+// not have one.
+#define ZBI_TOPOLOGY_PROCESSOR_INTERRUPT 0b10
+
+#define ZBI_TOPOLOGY_NO_PARENT 0xFFFF
+
+typedef enum {
+ ZBI_TOPOLOGY_ARCH_UNDEFINED = 0, // Intended primarily for testing.
+ ZBI_TOPOLOGY_ARCH_X86 = 1,
+ ZBI_TOPOLOGY_ARCH_ARM = 2,
+} zbi_topology_architecture_t;
+
+typedef struct {
+ // Cluster ids for each level, one being closest to the cpu.
+ // These map to aff1, aff2, and aff3 values in the ARM registers.
+ uint8_t cluster_1_id;
+ uint8_t cluster_2_id;
+ uint8_t cluster_3_id;
+
+ // Id of the cpu inside of the bottom-most cluster, aff0 value.
+ uint8_t cpu_id;
+
+ // The GIC interface number for this processor.
+ // In GIC v3+ this is not necessary as the processors are addressed by their
+ // affinity routing (all cluster ids followed by cpu_id).
+ uint8_t gic_id;
+} zbi_topology_arm_info_t;
+
+typedef struct {
+ // Indexes here correspond to the logical_ids index for the thread.
+ uint32_t apic_ids[ZBI_MAX_SMT];
+ uint32_t apic_id_count;
+} zbi_topology_x86_info_t;
+
+typedef struct {
+ uint16_t logical_ids[ZBI_MAX_SMT];
+ uint8_t logical_id_count;
+
+ uint16_t flags;
+
+ // Should be one of zbi_topology_arm_info_t.
+ // If UNDEFINED then nothing will be set in arch_info.
+ uint8_t architecture;
+ union {
+ zbi_topology_arm_info_t arm;
+ zbi_topology_x86_info_t x86;
+ } architecture_info;
+
+} zbi_topology_processor_t;
+
+typedef struct {
+ // Relative performance level of this processor in the system, with 0
+ // representing the lowest performance.
+ // For example on a two cluster ARM big.LITTLE system 0 would be the little
+ // cores and 1 would represent the big cores.
+ uint8_t performance_class;
+} zbi_topology_cluster_t;
+
+typedef struct {
+ // Starting and ending memory addresses of this numa region.
+ uint64_t start_address;
+ uint64_t end_address;
+} zbi_topology_numa_region_t;
+
+typedef enum {
+ ZBI_TOPOLOGY_ENTITY_UNDEFINED = 0, // Unused default.
+ ZBI_TOPOLOGY_ENTITY_PROCESSOR = 1,
+ ZBI_TOPOLOGY_ENTITY_CLUSTER = 2,
+ ZBI_TOPOLOGY_ENTITY_CACHE = 3,
+ ZBI_TOPOLOGY_ENTITY_DIE = 4,
+ ZBI_TOPOLOGY_ENTITY_SOCKET = 5,
+ ZBI_TOPOLOGY_ENTITY_POWER_PLANE = 6,
+ ZBI_TOPOLOGY_ENTITY_NUMA_REGION = 7,
+} zbi_topology_entity_type_t;
+
+typedef struct {
+ // Should be one of zbi_topology_entity_type_t.
+ uint8_t entity_type;
+ uint16_t parent_index;
+ union {
+ zbi_topology_processor_t processor;
+ zbi_topology_cluster_t cluster;
+ zbi_topology_numa_region_t numa_region;
+ } entity;
+} zbi_topology_node_t;
+
+#endif
+
+// Memory configuration, one or more zbi_mem_range_t entries.
+// zbi_header_t.length is sizeof(zbi_mem_range_t) times the number of entries.
+#define ZBI_TYPE_MEM_CONFIG (0x434D454D) // MEMC
+#ifndef __ASSEMBLER__
+typedef struct {
+ uint64_t paddr;
+ uint64_t length;
+ uint32_t type;
+ uint32_t reserved;
+} zbi_mem_range_t;
+#endif
+#define ZBI_MEM_RANGE_RAM (1)
+#define ZBI_MEM_RANGE_PERIPHERAL (2)
+#define ZBI_MEM_RANGE_RESERVED (3)
+
+// Kernel driver configuration. The zbi_header_t.extra field gives a
+// KDRV_* type that determines the payload format.
+// See [driver-config.h](<zircon/boot/driver-config.h>) for details.
+#define ZBI_TYPE_KERNEL_DRIVER (0x5652444B) // KDRV
+
+// ACPI Root Table Pointer, a uint64_t physical address.
+#define ZBI_TYPE_ACPI_RSDP (0x50445352) // RSDP
+
+// SMBIOS entry point, a uint64_t physical address.
+#define ZBI_TYPE_SMBIOS (0x49424d53) // SMBI
+
+// EFI memory map, a uint64_t entry size followed by a sequence of
+// EFI memory descriptors aligned on that entry size.
+#define ZBI_TYPE_EFI_MEMORY_MAP (0x4d494645) // EFIM
+
+// EFI system table, a uint64_t physical address.
+#define ZBI_TYPE_EFI_SYSTEM_TABLE (0x53494645) // EFIS
+
+// E820 memory table, an array of e820entry_t.
+#define ZBI_TYPE_E820_TABLE (0x30323845) // E820
+
+/* EFI Variable for Crash Log */
+#define ZIRCON_VENDOR_GUID \
+ {0x82305eb2, 0xd39e, 0x4575, {0xa0, 0xc8, 0x6c, 0x20, 0x72, 0xd0, 0x84, 0x4c}}
+#define ZIRCON_CRASHLOG_EFIVAR \
+ { 'c', 'r', 'a', 's', 'h', 'l', 'o', 'g', 0 }
+#define ZIRCON_CRASHLOG_EFIATTR \
+ (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS)
+
+// Framebuffer parameters, a zbi_swfb_t entry.
+#define ZBI_TYPE_FRAMEBUFFER (0x42465753) // SWFB
+
+// The image arguments, data is a trivial text format of one "key=value" per line
+// with leading whitespace stripped and "#" comment lines and blank lines ignored.
+// It is processed by bootsvc and parsed args are shared to others via Arguments service.
+// TODO: the format can be streamlined after the /config/devmgr compat support is removed.
+#define ZBI_TYPE_IMAGE_ARGS (0x47524149) // IARG
+
+// A copy of the boot version stored within the sysconfig
+// partition
+#define ZBI_TYPE_BOOT_VERSION (0x53525642) // BVRS
+
+#ifndef __ASSEMBLER__
+typedef struct {
+ // Physical memory address.
+ uint64_t base;
+
+ // Pixel layout and format.
+ // See [../pixelformat.h](<zircon/pixelformat.h>).
+ uint32_t width;
+ uint32_t height;
+ uint32_t stride;
+ uint32_t format;
+} zbi_swfb_t;
+#endif
+
+
+// ZBI_TYPE_DRV_* types (LSB is 'm') contain driver metadata.
+#define ZBI_TYPE_DRV_METADATA(type) (((type) & 0xFF) == 0x6D) // 'm'
+
+// MAC address for Ethernet, Wifi, Bluetooth, etc. zbi_header_t.extra
+// is a board-specific index to specify which device the MAC address
+// applies to. zbi_header_t.length gives the size in bytes, which
+// varies depending on the type of address appropriate for the device.
+#define ZBI_TYPE_DRV_MAC_ADDRESS (0x43414D6D) // mMAC
+
+// A partition map for a storage device, a zbi_partition_map_t header
+// followed by one or more zbi_partition_t entries. zbi_header_t.extra
+// is a board-specific index to specify which device this applies to.
+#define ZBI_TYPE_DRV_PARTITION_MAP (0x5452506D) // mPRT
+#define ZBI_PARTITION_NAME_LEN (32)
+#define ZBI_PARTITION_GUID_LEN (16)
+
+// Private information for the board driver.
+#define ZBI_TYPE_DRV_BOARD_PRIVATE (0x524F426D) // mBOR
+
+#ifndef __ASSEMBLER__
+typedef struct {
+ // GUID specifying the format and use of data stored in the partition.
+ uint8_t type_guid[ZBI_PARTITION_GUID_LEN];
+
+ // GUID unique to this partition.
+ uint8_t uniq_guid[ZBI_PARTITION_GUID_LEN];
+
+ // First and last block occupied by this partition.
+ uint64_t first_block;
+ uint64_t last_block;
+
+ // Reserved for future use. Set to 0.
+ uint64_t flags;
+
+ char name[ZBI_PARTITION_NAME_LEN];
+} zbi_partition_t;
+
+typedef struct {
+ // Total blocks used on the device.
+ uint64_t block_count;
+ // Size of each block in bytes.
+ uint64_t block_size;
+
+ // Number of partitions in the map.
+ uint32_t partition_count;
+
+ // Reserved for future use.
+ uint32_t reserved;
+
+ // Device GUID.
+ uint8_t guid[ZBI_PARTITION_GUID_LEN];
+
+ // partition_count partition entries follow.
+ zbi_partition_t partitions[];
+} zbi_partition_map_t;
+#endif
+
+
+#define ZBI_TYPE_HW_REBOOT_REASON (0x42525748) // HWRB
+
+#define ZBI_HW_REBOOT_UNDEFINED ((uint32_t)0)
+#define ZBI_HW_REBOOT_COLD ((uint32_t)1)
+#define ZBI_HW_REBOOT_WARM ((uint32_t)2)
+#define ZBI_HW_REBOOT_BROWNOUT ((uint32_t)3)
+#define ZBI_HW_REBOOT_WATCHDOG ((uint32_t)4)
+
+#ifndef __ASSEMBLER__
+#ifndef __cplusplus
+typedef uint32_t zbi_hw_reboot_reason_t;
+#else
+enum class ZbiHwRebootReason : uint32_t {
+ Undefined = ZBI_HW_REBOOT_UNDEFINED,
+ Cold = ZBI_HW_REBOOT_COLD,
+ Warm = ZBI_HW_REBOOT_WARM,
+ Brownout = ZBI_HW_REBOOT_BROWNOUT,
+ Watchdog = ZBI_HW_REBOOT_WATCHDOG,
+};
+using zbi_hw_reboot_reason_t = ZbiHwRebootReason;
+#endif // __cplusplus
+#endif // __ASSEMBLER__
+
+#endif // SYSROOT_ZIRCON_BOOT_IMAGE_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/boot/multiboot.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/boot/multiboot.h
new file mode 100644
index 0000000..85cf0a6
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/boot/multiboot.h
@@ -0,0 +1,114 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Copyright (c) 2009 Corey Tabaka
+
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SYSROOT_ZIRCON_MULTIBOOT_H_
+#define SYSROOT_ZIRCON_MULTIBOOT_H_
+
+/* magic number for multiboot header */
+#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
+
+// Flags for multiboot header:
+// 0x00000002: Boot loader should provide memory map.
+// 0x00010000: *_addr fields in multiboot_header_t are used.
+#define MULTIBOOT_HEADER_FLAGS 0x00010002
+
+/* magic number passed by multiboot-compliant boot loaders */
+#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+/* multiboot header */
+typedef struct multiboot_header {
+ uint32_t magic;
+ uint32_t flags;
+ uint32_t checksum;
+ uint32_t header_addr;
+ uint32_t load_addr;
+ uint32_t load_end_addr;
+ uint32_t bss_end_addr;
+ uint32_t entry_addr;
+} multiboot_header_t;
+
+/* symbol table for a.out */
+typedef struct aout_symbol_table {
+ uint32_t tabsize;
+ uint32_t strsize;
+ uint32_t addr;
+ uint32_t reserved;
+} aout_symbol_table_t;
+
+/* section header table for ELF */
+typedef struct elf_section_header_table {
+ uint32_t num;
+ uint32_t size;
+ uint32_t addr;
+ uint32_t shndx;
+} elf_section_header_table_t;
+
+/* multiboot info */
+typedef struct multiboot_info {
+ uint32_t flags;
+ uint32_t mem_lower;
+ uint32_t mem_upper;
+ uint32_t boot_device;
+ uint32_t cmdline;
+ uint32_t mods_count;
+ uint32_t mods_addr;
+ union {
+ aout_symbol_table_t aout_sym;
+ elf_section_header_table_t elf_sec;
+ } u;
+ uint32_t mmap_length;
+ uint32_t mmap_addr;
+ uint32_t drives_length;
+ uint32_t drives_addr;
+ uint32_t config_table;
+ uint32_t boot_loader_name;
+ uint32_t apm_table;
+} multiboot_info_t;
+
+#define MB_INFO_MEM_SIZE 0x001
+#define MB_INFO_BOOT_DEV 0x002
+#define MB_INFO_CMD_LINE 0x004
+#define MB_INFO_MODS 0x008
+#define MB_INFO_SYMS 0x010
+#define MB_INFO_SHDR 0x020
+#define MB_INFO_MMAP 0x040
+#define MB_INFO_DRIVES 0x080
+#define MB_INFO_CONFIG 0x100
+#define MB_INFO_BOOT_LOADER 0x200
+#define MB_INFO_APM_TABLE 0x400
+#define MB_INFO_VBE 0x800
+
+/* module structure */
+typedef struct module {
+ uint32_t mod_start;
+ uint32_t mod_end;
+ uint32_t string;
+ uint32_t reserved;
+} module_t;
+
+/* memory map - be careful that the offset 0 is base_addr_low without size */
+typedef struct memory_map {
+ uint32_t size;
+ uint32_t base_addr_low;
+ uint32_t base_addr_high;
+ uint32_t length_low;
+ uint32_t length_high;
+ uint32_t type;
+} memory_map_t;
+
+/* memory map entry types */
+#define MB_MMAP_TYPE_AVAILABLE 0x01
+#define MB_MMAP_TYPE_RESERVED 0x02
+#define MB_MMAP_TYPE_ACPI_RECLAIM 0x03
+#define MB_MMAP_TYPE_ACPI_NVS 0x04
+
+#endif
+
+#endif // SYSROOT_ZIRCON_BOOT_MULTIBOOT_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/boot/netboot.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/boot/netboot.h
new file mode 100644
index 0000000..edbfd53
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/boot/netboot.h
@@ -0,0 +1,150 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_BOOT_NETBOOT_H_
+#define SYSROOT_ZIRCON_BOOT_NETBOOT_H_
+
+#include <stddef.h>
+#include <stdint.h>
+#include <zircon/types.h>
+
+// clang-format off
+
+#define BOOTLOADER_VERSION "0.7.22"
+
+#define NB_MAGIC 0xAA774217
+#define NB_DEBUGLOG_MAGIC 0xAEAE1123
+
+#define NB_SERVER_PORT 33330
+#define NB_ADVERT_PORT 33331
+#define NB_CMD_PORT_START 33332
+#define NB_CMD_PORT_END 33339
+#define NB_TFTP_OUTGOING_PORT 33340
+#define NB_TFTP_INCOMING_PORT 33341
+
+
+#define NB_COMMAND 1 // arg=0, data=command
+#define NB_SEND_FILE 2 // arg=size, data=filename
+#define NB_DATA 3 // arg=offset, data=data
+#define NB_BOOT 4 // arg=0
+#define NB_QUERY 5 // arg=0, data=hostname (or "*")
+#define NB_SHELL_CMD 6 // arg=0, data=command string
+#define NB_OPEN 7 // arg=O_RDONLY|O_WRONLY, data=filename
+#define NB_READ 8 // arg=blocknum
+#define NB_WRITE 9 // arg=blocknum, data=data
+#define NB_CLOSE 10 // arg=0
+#define NB_LAST_DATA 11 // arg=offset, data=data
+#define NB_REBOOT 12 // arg=0
+#define NB_GET_ADVERT 13 // arg=0
+
+#define NB_ACK 0 // arg=0 or -err, NB_READ: data=data
+#define NB_FILE_RECEIVED 0x70000001 // arg=size
+
+#define NB_ADVERTISE 0x77777777
+
+#define NB_ERROR 0x80000000
+#define NB_ERROR_BAD_CMD 0x80000001
+#define NB_ERROR_BAD_PARAM 0x80000002
+#define NB_ERROR_TOO_LARGE 0x80000003
+#define NB_ERROR_BAD_FILE 0x80000004
+
+#define NB_VERSION_1_0 0x0001000
+#define NB_VERSION_1_1 0x0001010
+#define NB_VERSION_1_2 0x0001020
+#define NB_VERSION_1_3 0x0001030
+#define NB_VERSION_CURRENT NB_VERSION_1_3
+
+#define NB_FILENAME_PREFIX "<<netboot>>"
+#define NB_KERNEL_FILENAME NB_FILENAME_PREFIX "kernel.bin"
+#define NB_RAMDISK_FILENAME NB_FILENAME_PREFIX "ramdisk.bin"
+#define NB_CMDLINE_FILENAME NB_FILENAME_PREFIX "cmdline"
+
+#define NB_IMAGE_PREFIX "<<image>>"
+#define NB_FVM_HOST_FILENAME "sparse.fvm"
+#define NB_FVM_FILENAME NB_IMAGE_PREFIX NB_FVM_HOST_FILENAME
+#define NB_BOOTLOADER_HOST_FILENAME "bootloader.img"
+#define NB_BOOTLOADER_FILENAME NB_IMAGE_PREFIX NB_BOOTLOADER_HOST_FILENAME
+// Firmware images are slightly different, as they have an optional type suffix:
+// firmware_ <- type = "" (the default)
+// firmware_foo <- type = "foo"
+#define NB_FIRMWARE_HOST_FILENAME_PREFIX "firmware_"
+#define NB_FIRMWARE_FILENAME_PREFIX NB_IMAGE_PREFIX NB_FIRMWARE_HOST_FILENAME_PREFIX
+#define NB_ZIRCONA_HOST_FILENAME "zircona.img"
+#define NB_ZIRCONA_FILENAME NB_IMAGE_PREFIX NB_ZIRCONA_HOST_FILENAME
+#define NB_ZIRCONB_HOST_FILENAME "zirconb.img"
+#define NB_ZIRCONB_FILENAME NB_IMAGE_PREFIX NB_ZIRCONB_HOST_FILENAME
+#define NB_ZIRCONR_HOST_FILENAME "zirconr.img"
+#define NB_ZIRCONR_FILENAME NB_IMAGE_PREFIX NB_ZIRCONR_HOST_FILENAME
+#define NB_VBMETAA_HOST_FILENAME "vbmetaa.img"
+#define NB_VBMETAA_FILENAME NB_IMAGE_PREFIX NB_VBMETAA_HOST_FILENAME
+#define NB_VBMETAB_HOST_FILENAME "vbmetab.img"
+#define NB_VBMETAB_FILENAME NB_IMAGE_PREFIX NB_VBMETAB_HOST_FILENAME
+#define NB_VBMETAR_HOST_FILENAME "vbmetar.img"
+#define NB_VBMETAR_FILENAME NB_IMAGE_PREFIX NB_VBMETAR_HOST_FILENAME
+#define NB_SSHAUTH_HOST_FILENAME "authorized_keys"
+#define NB_SSHAUTH_FILENAME NB_IMAGE_PREFIX NB_SSHAUTH_HOST_FILENAME
+#define NB_BOARD_NAME_HOST_FILENAME "board_name"
+#define NB_BOARD_NAME_FILENAME NB_IMAGE_PREFIX NB_BOARD_NAME_HOST_FILENAME
+#define NB_BOARD_REVISION_HOST_FILENAME "board_revision"
+#define NB_BOARD_REVISION_FILENAME NB_IMAGE_PREFIX NB_BOARD_REVISION_HOST_FILENAME
+#define NB_BOARD_INFO_HOST_FILENAME "board_info"
+#define NB_BOARD_INFO_FILENAME NB_IMAGE_PREFIX NB_BOARD_INFO_HOST_FILENAME
+#define NB_INIT_PARTITION_TABLES_HOST_FILENAME "init_partition_tables"
+#define NB_INIT_PARTITION_TABLES_FILENAME NB_IMAGE_PREFIX NB_INIT_PARTITION_TABLES_HOST_FILENAME
+#define NB_WIPE_PARTITION_TABLES_HOST_FILENAME "wipe_partition_tables"
+#define NB_WIPE_PARTITION_TABLES_FILENAME NB_IMAGE_PREFIX NB_WIPE_PARTITION_TABLES_HOST_FILENAME
+
+// Should match paver FIDL definition.
+// Length does not include the '\0' terminator, so when allocating a character
+// buffer to hold the type use (NB_FIRMWARE_TYPE_MAX_LENGTH + 1).
+#define NB_FIRMWARE_TYPE_MAX_LENGTH 256
+
+typedef struct board_info {
+ char board_name[ZX_MAX_NAME_LEN];
+ uint32_t board_revision;
+ uint8_t mac_address[8];
+} board_info_t;
+
+typedef struct modify_partition_table_info {
+ // Path of block device to initialize or wipe.
+ char block_device_path[ZX_MAX_NAME_LEN + 1];
+} modify_partition_table_info_t;
+
+typedef struct nbmsg_t {
+ uint32_t magic;
+ uint32_t cookie;
+ uint32_t cmd;
+ uint32_t arg;
+ uint8_t data[0];
+} nbmsg;
+
+typedef struct nbfile_t {
+ uint8_t* data;
+ size_t size; // max size of buffer
+ size_t offset; // write pointer
+} nbfile;
+
+int netboot_init(const char* nodename);
+const char* netboot_nodename(void);
+int netboot_poll(void);
+void netboot_close(void);
+
+// Ask for a buffer suitable to put the file /name/ in
+// Return NULL to indicate /name/ is not wanted.
+nbfile* netboot_get_buffer(const char* name, size_t size);
+
+#define DEBUGLOG_PORT 33337
+#define DEBUGLOG_ACK_PORT 33338
+
+#define MAX_LOG_DATA 1216
+#define MAX_NODENAME_LENGTH 64
+
+typedef struct logpacket {
+ uint32_t magic;
+ uint32_t seqno;
+ char nodename[MAX_NODENAME_LENGTH];
+ char data[MAX_LOG_DATA];
+} logpacket_t;
+
+#endif // SYSROOT_ZIRCON_BOOT_NETBOOT_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/boot/sysconfig.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/boot/sysconfig.h
new file mode 100644
index 0000000..1f7d49b
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/boot/sysconfig.h
@@ -0,0 +1,29 @@
+// Copyright 2018 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.
+
+#ifndef SYSROOT_ZIRCON_BOOT_SYSCONFIG_H_
+#define SYSROOT_ZIRCON_BOOT_SYSCONFIG_H_
+
+// Zircon sysconfig partition format
+//
+// The sysconfig partition consists of four kvstore sections, each 32K in size.
+// The sections are:
+//
+// version-a: System configuration used when booting from Zircon-A.
+//
+// version-b: System configuration used when booting from Zircon-B.
+//
+// boot-default: Default bootloader configuration.
+//
+// boot-oneshot: Bootloader configuration for one-time use.
+// If present, this overrides boot-default, and the bootloader
+// deletes this section after use.
+
+#define ZX_SYSCONFIG_KVSTORE_SIZE 32768
+#define ZX_SYSCONFIG_VERSION_A_OFFSET (0 * ZX_SYSCONFIG_KVSTORE_SIZE)
+#define ZX_SYSCONFIG_VERSION_B_OFFSET (1 * ZX_SYSCONFIG_KVSTORE_SIZE)
+#define ZX_SYSCONFIG_BOOT_DEFAULT_OFFSET (2 * ZX_SYSCONFIG_KVSTORE_SIZE)
+#define ZX_SYSCONFIG_BOOT_ONESHOT_OFFSET (3 * ZX_SYSCONFIG_KVSTORE_SIZE)
+
+#endif // SYSROOT_ZIRCON_BOOT_SYSCONFIG_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/compiler.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/compiler.h
new file mode 100644
index 0000000..ce2bcea
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/compiler.h
@@ -0,0 +1,191 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_COMPILER_H_
+#define SYSROOT_ZIRCON_COMPILER_H_
+
+#ifndef __has_feature
+#define __has_feature(x) 0
+#endif
+
+#ifndef __has_cpp_attribute
+#define __has_cpp_attribute(x) 0
+#endif
+
+#ifndef __ASSEMBLER__
+
+#if !defined(__GNUC__) && !defined(__clang__)
+#error "Unrecognized compiler!"
+#endif
+
+#define likely(x) __builtin_expect(!!(x), 1)
+#define unlikely(x) __builtin_expect(!!(x), 0)
+#define __UNUSED __attribute__((__unused__))
+#define __USED __attribute__((__used__))
+#define __PACKED __attribute__((packed))
+#define __ALIGNED(x) __attribute__((aligned(x)))
+#define __PRINTFLIKE(__fmt, __varargs) __attribute__((__format__(__printf__, __fmt, __varargs)))
+#define __SCANFLIKE(__fmt, __varargs) __attribute__((__format__(__scanf__, __fmt, __varargs)))
+#define __SECTION(x) __attribute__((__section__(x)))
+#define __PURE __attribute__((__pure__))
+#define __CONST __attribute__((__const__))
+#define __NO_RETURN __attribute__((__noreturn__))
+#define __MALLOC __attribute__((__malloc__))
+#define __WEAK __attribute__((__weak__))
+#define __GNU_INLINE __attribute__((__gnu_inline__))
+#define __GET_CALLER(x) __builtin_return_address(0)
+#define __GET_FRAME(x) __builtin_frame_address(0)
+#define __NAKED __attribute__((__naked__))
+#define __ISCONSTANT(x) __builtin_constant_p(x)
+#define __NO_INLINE __attribute__((__noinline__))
+#define __SRAM __NO_INLINE __SECTION(".sram.text")
+#define __CONSTRUCTOR __attribute__((__constructor__))
+#define __DESTRUCTOR __attribute__((__destructor__))
+#define __RESTRICT __restrict
+
+#ifndef __clang__
+#define __LEAF_FN __attribute__((__leaf__))
+#define __OPTIMIZE(x) __attribute__((__optimize__(x)))
+#define __EXTERNALLY_VISIBLE __attribute__((__externally_visible__))
+#define __NO_SAFESTACK
+#define __THREAD_ANNOTATION(x)
+#else
+#define __LEAF_FN
+#define __OPTIMIZE(x)
+#define __EXTERNALLY_VISIBLE
+// The thread safety annotations are frequently used with C++ standard library
+// types in userspace, so only enable the annotations if we know that the C++
+// standard library types are annotated or if we're in kernel code.
+#if defined(_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS) || defined(_KERNEL)
+#define __THREAD_ANNOTATION(x) __attribute__((x))
+#else
+#define __THREAD_ANNOTATION(x)
+#endif // _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
+#define __NO_SAFESTACK __attribute__((__no_sanitize__("safe-stack", "shadow-call-stack")))
+#endif
+
+#define __ALWAYS_INLINE __attribute__((__always_inline__))
+#define __MAY_ALIAS __attribute__((__may_alias__))
+#define __NONNULL(x) __attribute__((__nonnull__ x))
+#define __WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
+#define __UNREACHABLE __builtin_unreachable()
+#define __WEAK_ALIAS(x) __attribute__((__weak__, __alias__(x)))
+#define __ALIAS(x) __attribute__((__alias__(x)))
+#define __EXPORT __attribute__((__visibility__("default")))
+#define __LOCAL __attribute__((__visibility__("hidden")))
+#define __THREAD __thread
+#define __offsetof(type, field) __builtin_offsetof(type, field)
+
+// Only define __NO_UNIQUE_ADDRESS for C++, since it doesn't make sense in C.
+#ifdef __cplusplus
+#if __has_cpp_attribute(no_unique_address)
+#define __NO_UNIQUE_ADDRESS [[no_unique_address]]
+#else
+#define __NO_UNIQUE_ADDRESS
+#endif
+#endif // ifdef __cplusplus
+
+#if defined(__cplusplus) && __cplusplus >= 201703L
+#define __FALLTHROUGH [[fallthrough]]
+#elif defined(__cplusplus) && defined(__clang__)
+#define __FALLTHROUGH [[clang::fallthrough]]
+// The GNU style attribute is supported by Clang for C code, but __GNUC__ for
+// clang right now is 4.
+#elif __GNUC__ >= 7 || (!defined(__cplusplus) && defined(__clang__))
+#define __FALLTHROUGH __attribute__((__fallthrough__))
+#else
+#define __FALLTHROUGH \
+ do { \
+ } while (0)
+#endif
+
+// C++17 onwards supports [[nodiscard]] on a constructor, warning if
+// a temporary object is created without a name. Such objects would be
+// immediately destroyed again, while the user's expectation might be
+// that it would last the scope.
+//
+// We could ideally just use [[nodiscard]] (or __WARN_UNUSED_RESULT)
+// directly, except GCC < 10.0 has a bug preventing it from being used
+// on constructors. __WARN_UNUSED_CONSTRUCTOR allows us to tag
+// constructors in supported compilers, and is simply ignored in older
+// compilers.
+#if defined(__cplusplus)
+// Clang and GCC versions >= 10.0 support [[nodiscard]] on constructors.
+#if __cplusplus >= 201703L && (defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 10)))
+#define __WARN_UNUSED_CONSTRUCTOR [[nodiscard]]
+#else
+#define __WARN_UNUSED_CONSTRUCTOR
+#endif
+#endif
+
+// Publicly exposed thread annotation macros. These have a long and ugly name to
+// minimize the chance of collision with consumers of Zircon's public headers.
+#define __TA_CAPABILITY(x) __THREAD_ANNOTATION(__capability__(x))
+#define __TA_GUARDED(x) __THREAD_ANNOTATION(__guarded_by__(x))
+#define __TA_ACQUIRE(...) __THREAD_ANNOTATION(__acquire_capability__(__VA_ARGS__))
+#define __TA_ACQUIRE_SHARED(...) __THREAD_ANNOTATION(__acquire_shared_capability__(__VA_ARGS__))
+#define __TA_TRY_ACQUIRE(...) __THREAD_ANNOTATION(__try_acquire_capability__(__VA_ARGS__))
+#define __TA_ACQUIRED_BEFORE(...) __THREAD_ANNOTATION(__acquired_before__(__VA_ARGS__))
+#define __TA_ACQUIRED_AFTER(...) __THREAD_ANNOTATION(__acquired_after__(__VA_ARGS__))
+#define __TA_RELEASE(...) __THREAD_ANNOTATION(__release_capability__(__VA_ARGS__))
+#define __TA_RELEASE_SHARED(...) __THREAD_ANNOTATION(__release_shared_capability__(__VA_ARGS__))
+#define __TA_REQUIRES(...) __THREAD_ANNOTATION(__requires_capability__(__VA_ARGS__))
+#define __TA_REQUIRES_SHARED(...) __THREAD_ANNOTATION(__requires_shared_capability__(__VA_ARGS__))
+#define __TA_EXCLUDES(...) __THREAD_ANNOTATION(__locks_excluded__(__VA_ARGS__))
+#define __TA_ASSERT(...) __THREAD_ANNOTATION(__assert_capability__(__VA_ARGS__))
+#define __TA_ASSERT_SHARED(...) __THREAD_ANNOTATION(__assert_shared_capability__(__VA_ARGS__))
+#define __TA_RETURN_CAPABILITY(x) __THREAD_ANNOTATION(__lock_returned__(x))
+#define __TA_SCOPED_CAPABILITY __THREAD_ANNOTATION(__scoped_lockable__)
+#define __TA_NO_THREAD_SAFETY_ANALYSIS __THREAD_ANNOTATION(__no_thread_safety_analysis__)
+
+#endif // ifndef __ASSEMBLER__
+
+#if !defined(__DEPRECATE)
+#define __DEPRECATE __attribute__((__deprecated__))
+#endif
+
+/* TODO: add type check */
+#if !defined(countof)
+#define countof(a) (sizeof(a) / sizeof((a)[0]))
+#endif
+
+/* CPP header guards */
+#ifdef __cplusplus
+#define __BEGIN_CDECLS extern "C" {
+#define __END_CDECLS }
+#else
+#define __BEGIN_CDECLS
+#define __END_CDECLS
+#endif
+
+// constexpr annotation for use in static inlines usable in both C and C++
+#ifdef __cplusplus
+#define __CONSTEXPR constexpr
+#else
+#define __CONSTEXPR
+#endif
+
+#define add_overflow(a, b, c) __builtin_add_overflow(a, b, c)
+#define sub_overflow(a, b, c) __builtin_sub_overflow(a, b, c)
+#define mul_overflow(a, b, c) __builtin_mul_overflow(a, b, c)
+
+// A workaround to help static analyzer identify assertion failures
+#if defined(__clang__)
+#define __ANALYZER_CREATE_SINK __attribute__((analyzer_noreturn))
+#else
+#define __ANALYZER_CREATE_SINK // no-op
+#endif
+
+// Lifetime analysis
+#ifndef __OWNER
+#ifdef __clang__
+#define __OWNER(x) [[gsl::Owner(x)]]
+#define __POINTER(x) [[gsl::Pointer(x)]]
+#else
+#define __OWNER(x)
+#define __POINTER(x)
+#endif
+#endif
+
+#endif // SYSROOT_ZIRCON_COMPILER_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/device/audio.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/device/audio.h
new file mode 100644
index 0000000..47da2d2
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/device/audio.h
@@ -0,0 +1,460 @@
+// Copyright 2017 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.
+
+#ifndef SYSROOT_ZIRCON_DEVICE_AUDIO_H_
+#define SYSROOT_ZIRCON_DEVICE_AUDIO_H_
+
+#include <sys/types.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+#include <cassert>
+#include <cstdio>
+
+// When communicating with an Audio driver using zx_channel_call, do not use
+// the AUDIO_INVALID_TRANSACTION_ID as your message's transaction ID. It is
+// reserved for async notifications sent from the driver to the application.
+#define AUDIO_INVALID_TRANSACTION_ID ((zx_txid_t)0)
+
+__BEGIN_CDECLS
+
+typedef uint32_t audio_cmd_t;
+
+// Commands sent on the stream channel
+#define AUDIO_STREAM_CMD_GET_FORMATS ((audio_cmd_t)0x1000)
+#define AUDIO_STREAM_CMD_SET_FORMAT ((audio_cmd_t)0x1001)
+#define AUDIO_STREAM_CMD_GET_GAIN ((audio_cmd_t)0x1002)
+#define AUDIO_STREAM_CMD_SET_GAIN ((audio_cmd_t)0x1003)
+#define AUDIO_STREAM_CMD_PLUG_DETECT ((audio_cmd_t)0x1004)
+#define AUDIO_STREAM_CMD_GET_UNIQUE_ID ((audio_cmd_t)0x1005)
+#define AUDIO_STREAM_CMD_GET_STRING ((audio_cmd_t)0x1006)
+#define AUDIO_STREAM_CMD_GET_CLOCK_DOMAIN ((audio_cmd_t)0x1007)
+
+// Async notifications sent on the stream channel.
+#define AUDIO_STREAM_PLUG_DETECT_NOTIFY ((audio_cmd_t)0x2000)
+
+// Commands sent on the ring buffer channel
+#define AUDIO_RB_CMD_GET_FIFO_DEPTH ((audio_cmd_t)0x3000)
+#define AUDIO_RB_CMD_GET_BUFFER ((audio_cmd_t)0x3001)
+#define AUDIO_RB_CMD_START ((audio_cmd_t)0x3002)
+#define AUDIO_RB_CMD_STOP ((audio_cmd_t)0x3003)
+
+// Async notifications sent on the ring buffer channel.
+#define AUDIO_RB_POSITION_NOTIFY ((audio_cmd_t)0x4000)
+
+// Flags used to modify commands.
+// The NO_ACK flag can be used with the SET_GAIN and PLUG_DETECT commands.
+#define AUDIO_FLAG_NO_ACK ((audio_cmd_t)0x80000000)
+
+typedef struct audio_cmd_hdr {
+ zx_txid_t transaction_id;
+ audio_cmd_t cmd;
+} audio_cmd_hdr_t;
+
+static_assert(sizeof(audio_cmd_hdr_t) == 8,
+ "audio_cmd_hdr_t should be 8 bytes! "
+ "If sizeof(zx_txid_t has changed from 4 to 8, "
+ "consider repacking the structs in audio.h");
+
+// audio_sample_format_t
+//
+// Bitfield which describes audio sample format as they reside in memory.
+//
+typedef uint32_t audio_sample_format_t;
+#define AUDIO_SAMPLE_FORMAT_BITSTREAM ((audio_sample_format_t)(1u << 0))
+#define AUDIO_SAMPLE_FORMAT_8BIT ((audio_sample_format_t)(1u << 1))
+#define AUDIO_SAMPLE_FORMAT_16BIT ((audio_sample_format_t)(1u << 2))
+#define AUDIO_SAMPLE_FORMAT_20BIT_PACKED ((audio_sample_format_t)(1u << 4))
+#define AUDIO_SAMPLE_FORMAT_24BIT_PACKED ((audio_sample_format_t)(1u << 5))
+#define AUDIO_SAMPLE_FORMAT_20BIT_IN32 ((audio_sample_format_t)(1u << 6))
+#define AUDIO_SAMPLE_FORMAT_24BIT_IN32 ((audio_sample_format_t)(1u << 7))
+#define AUDIO_SAMPLE_FORMAT_32BIT ((audio_sample_format_t)(1u << 8))
+#define AUDIO_SAMPLE_FORMAT_32BIT_FLOAT ((audio_sample_format_t)(1u << 9))
+#define AUDIO_SAMPLE_FORMAT_FLAG_UNSIGNED ((audio_sample_format_t)(1u << 30))
+#define AUDIO_SAMPLE_FORMAT_FLAG_INVERT_ENDIAN ((audio_sample_format_t)(1u << 31))
+#define AUDIO_SAMPLE_FORMAT_FLAG_MASK \
+ ((audio_sample_format_t)(AUDIO_SAMPLE_FORMAT_FLAG_UNSIGNED | \
+ AUDIO_SAMPLE_FORMAT_FLAG_INVERT_ENDIAN))
+
+// audio_stream_format_range_t
+//
+// A structure used along with the AUDIO_STREAM_CMD_GET_FORMATS command in order
+// to describe the formats supported by an audio stream.
+#define ASF_RANGE_FLAG_FPS_CONTINUOUS ((uint16_t)(1u << 0))
+#define ASF_RANGE_FLAG_FPS_48000_FAMILY ((uint16_t)(1u << 1))
+#define ASF_RANGE_FLAG_FPS_44100_FAMILY ((uint16_t)(1u << 2))
+typedef struct audio_stream_format_range {
+ audio_sample_format_t sample_formats;
+ uint32_t min_frames_per_second;
+ uint32_t max_frames_per_second;
+ uint8_t min_channels;
+ uint8_t max_channels;
+ uint16_t flags;
+} __PACKED audio_stream_format_range_t;
+
+static_assert(sizeof(audio_stream_format_range_t) == 16,
+ "audio_stream_format_range_t should be 16 bytes!");
+
+// audio_set_gain_flags_t
+//
+// Flags used by the AUDIO_STREAM_CMD_SET_GAIN message.
+//
+typedef uint32_t audio_set_gain_flags_t;
+#define AUDIO_SGF_MUTE_VALID \
+ ((audio_set_gain_flags_t)0x1) // Whether or not the mute flag is valid.
+#define AUDIO_SGF_AGC_VALID ((audio_set_gain_flags_t)0x2) // Whether or not the agc flag is valid.
+#define AUDIO_SGF_GAIN_VALID \
+ ((audio_set_gain_flags_t)0x4) // Whether or not the gain float is valid.
+#define AUDIO_SGF_MUTE ((audio_set_gain_flags_t)0x40000000) // Whether or not to mute the stream.
+#define AUDIO_SGF_AGC \
+ ((audio_set_gain_flags_t)0x80000000) // Whether or not enable AGC for the stream.
+
+// audio_pd_flags_t
+//
+// Flags used by AUDIO_STREAM_CMD_PLUG_DETECT commands to enable or disable
+// asynchronous plug detect notifications.
+//
+typedef uint32_t audio_pd_flags_t;
+#define AUDIO_PDF_NONE ((audio_pd_flags_t)0)
+#define AUDIO_PDF_ENABLE_NOTIFICATIONS ((audio_pd_flags_t)0x40000000)
+#define AUDIO_PDF_DISABLE_NOTIFICATIONS ((audio_pd_flags_t)0x80000000)
+
+// audio_pd_notify_flags_t
+//
+// Flags used by responses to the AUDIO_STREAM_CMD_PLUG_DETECT
+// message, and by AUDIO_STREAM_PLUG_DETECT_NOTIFY messages.
+//
+typedef uint32_t audio_pd_notify_flags_t;
+#define AUDIO_PDNF_HARDWIRED \
+ ((audio_pd_notify_flags_t)0x1) // Stream is hardwired (will always be plugged in)
+#define AUDIO_PDNF_CAN_NOTIFY \
+ ((audio_pd_notify_flags_t)0x2) // Stream is able to notify of plug state changes.
+#define AUDIO_PDNF_PLUGGED ((audio_pd_notify_flags_t)0x80000000) // Stream is currently plugged in.
+
+// AUDIO_STREAM_CMD_GET_FORMATS
+//
+// Must not be used with the NO_ACK flag.
+#define AUDIO_STREAM_CMD_GET_FORMATS_MAX_RANGES_PER_RESPONSE (15u)
+typedef struct audio_stream_cmd_get_formats_req {
+ audio_cmd_hdr_t hdr;
+} audio_stream_cmd_get_formats_req_t;
+
+// TODO(johngro) : Figure out if zx_txid_t is ever going to go up to 8 bytes or
+// not. If it is, just remove the _pad field below. If not, either keep it as
+// a _pad field, or repurpose it for some flags of some form. Right now, we use
+// it to make sure that format_ranges is aligned to a 16 byte boundary.
+typedef struct audio_stream_cmd_get_formats_resp {
+ audio_cmd_hdr_t hdr;
+ uint32_t _pad;
+ uint16_t format_range_count;
+ uint16_t first_format_range_ndx;
+ audio_stream_format_range_t format_ranges[AUDIO_STREAM_CMD_GET_FORMATS_MAX_RANGES_PER_RESPONSE];
+} audio_stream_cmd_get_formats_resp_t;
+
+static_assert(sizeof(audio_stream_cmd_get_formats_resp_t) == 256,
+ "audio_stream_cmd_get_formats_resp_t must be 256 bytes");
+
+// AUDIO_STREAM_CMD_SET_FORMAT
+//
+// Must not be used with the NO_ACK flag.
+typedef struct audio_stream_cmd_set_format_req {
+ audio_cmd_hdr_t hdr;
+ uint32_t frames_per_second;
+ audio_sample_format_t sample_format;
+ uint16_t channels;
+} audio_stream_cmd_set_format_req_t;
+
+typedef struct audio_stream_cmd_set_format_resp {
+ audio_cmd_hdr_t hdr;
+ zx_status_t result;
+ uint64_t external_delay_nsec;
+
+ // Note: Upon success, a channel used to control the audio buffer will also
+ // be returned.
+} audio_stream_cmd_set_format_resp_t;
+
+// AUDIO_STREAM_CMD_GET_GAIN
+//
+// Request that a gain notification be sent with the current details of the
+// streams current gain settings as well as gain setting capabilities.
+//
+// Must not be used with the NO_ACK flag.
+typedef struct audio_stream_cmd_get_gain_req {
+ audio_cmd_hdr_t hdr;
+} audio_stream_cmd_get_gain_req_t;
+
+typedef struct audio_stream_cmd_get_gain_resp {
+ // TODO(johngro) : Is there value in exposing the gain step to the level
+ // above the lowest level stream interface, or should we have all drivers
+ // behave as if they have continuous control at all times?
+ audio_cmd_hdr_t hdr;
+
+ bool cur_mute; // True if the stream is currently muted.
+ bool cur_agc; // True if the stream has AGC currently enabled.
+ float cur_gain; // The current setting gain of the stream in dB
+
+ bool can_mute; // True if the stream is capable of muting
+ bool can_agc; // True if the stream has support for AGC
+ float min_gain; // The minimum valid gain setting, in dB
+ float max_gain; // The maximum valid gain setting, in dB
+ float gain_step; // The smallest valid gain increment, counted from the minimum gain.
+} audio_stream_cmd_get_gain_resp_t;
+
+// AUDIO_STREAM_CMD_SET_GAIN
+//
+// Request that a stream change its gain settings to most closely match those
+// requested. Gain values for Valid requests will be rounded to the nearest
+// gain step. For example, if a stream can control its gain on the range from
+// -60.0 to 0.0 dB, a request to set the gain to -33.3 dB will result in a gain
+// of -33.5 being applied.
+//
+// Gain change requests outside of the capabilities of the stream's
+// amplifier will be rejected with a result of ZX_ERR_INVALID_ARGS. Using the
+// previous example, requests for gains of -65.0 or +3dB would be rejected.
+// Similarly, If an amplifier is capable of gain control but cannot mute, a
+// request to mute will be rejected.
+//
+// TODO(johngro) : Is this the correct behavior? Should we just apply sensible
+// limits instead? IOW - If the user requests a gain of -1000 dB, should we
+// just set the gain to -60dB? Likewise, if they request mute but the amplifier
+// has no hard mute feature, should we just set the gain to the minimum
+// permitted gain?
+//
+// May be used with the NO_ACK flag.
+typedef struct audio_stream_cmd_set_gain_req {
+ audio_cmd_hdr_t hdr;
+ audio_set_gain_flags_t flags;
+ float gain;
+} audio_stream_cmd_set_gain_req_t;
+
+typedef struct audio_stream_cmd_set_gain_resp {
+ audio_cmd_hdr_t hdr;
+ zx_status_t result;
+ // The current gain settings observed immediately after processing the set
+ // gain request.
+ bool cur_mute;
+ bool cur_agc;
+ float cur_gain;
+} audio_stream_cmd_set_gain_resp_t;
+
+// AUDIO_STREAM_CMD_PLUG_DETECT
+//
+// Trigger a plug detect operation and/or enable/disable asynchronous plug
+// detect notifications.
+//
+// May be used with the NO_ACK flag.
+typedef struct audio_stream_cmd_plug_detect_req {
+ audio_cmd_hdr_t hdr;
+ audio_pd_flags_t flags; // Options used to enable or disable notifications
+} audio_stream_cmd_plug_detect_req_t;
+
+typedef struct audio_stream_cmd_plug_detect_resp {
+ audio_cmd_hdr_t hdr;
+ audio_pd_notify_flags_t flags; // The current plug state and capabilities
+ zx_time_t plug_state_time; // The time of the plug state last change.
+} audio_stream_cmd_plug_detect_resp_t;
+
+// AUDIO_STREAM_PLUG_DETECT_NOTIFY
+//
+// Message asynchronously in response to a plug state change to clients who have
+// registered for plug state notifications.
+//
+// Note: Solicited and unsolicited plug detect messages currently use the same
+// structure and contain the same information. The difference between the two
+// is that Solicited messages, use AUDIO_STREAM_CMD_PLUG_DETECT as the value of
+// the `cmd` field of their header and the transaction ID of the request sent by
+// the client. Unsolicited messages use AUDIO_STREAM_PLUG_DETECT_NOTIFY as the
+// value value of the `cmd` field of their header, and
+// AUDIO_INVALID_TRANSACTION_ID for their transaction ID.
+typedef audio_stream_cmd_plug_detect_resp_t audio_stream_plug_detect_notify_t;
+
+// AUDIO_STREAM_CMD_GET_UNIQUE_ID
+//
+// Fetch a globally unique, but persistent ID for the stream.
+//
+// Drivers should make every effort to return as unique an identifier as
+// possible for each stream that they publish. This ID must not change between
+// boots. When available, using a globally unique device serial number is
+// strongly encouraged. Other possible sources of unique-ness include a
+// driver's physical connection path, driver binding information, manufacturer
+// calibration data, and so on.
+//
+// Note: a small number of hardcoded unique ID has been provided for built-in
+// devices. Platform drivers for systems with hardwired audio devices may use
+// these unique IDs as appropriate to signal which audio streams represent the
+// built-in devices for the system. Drivers for hot-pluggable audio devices
+// should *never* use these identifiers.
+//
+// Even given this, higher level code should *not* depend on these identifiers
+// being perfectly unique, and should be prepared to take steps to de-dupe
+// identifiers when needed.
+typedef struct audio_stream_cmd_get_unique_id_req {
+ audio_cmd_hdr_t hdr;
+} audio_stream_cmd_get_unique_id_req_t;
+
+typedef struct audio_stream_unique_id {
+ uint8_t data[16];
+} audio_stream_unique_id_t;
+
+#define AUDIO_STREAM_UNIQUE_ID_BUILTIN_SPEAKERS \
+ { \
+ .data = { 0x01, 0x00 } \
+ }
+#define AUDIO_STREAM_UNIQUE_ID_BUILTIN_HEADPHONE_JACK \
+ { \
+ .data = { 0x02, 0x00 } \
+ }
+#define AUDIO_STREAM_UNIQUE_ID_BUILTIN_MICROPHONE \
+ { \
+ .data = { 0x03, 0x00 } \
+ }
+#define AUDIO_STREAM_UNIQUE_ID_BUILTIN_HEADSET_JACK \
+ { \
+ .data = { 0x04, 0x00 } \
+ }
+
+typedef struct audio_stream_cmd_get_unique_id_resp {
+ audio_cmd_hdr_t hdr;
+ audio_stream_unique_id_t unique_id;
+} audio_stream_cmd_get_unique_id_resp_t;
+
+// AUDIO_STREAM_CMD_GET_STRING
+//
+// Fetch the specified string from a device's static string table. Strings
+// returned by the device driver...
+//
+// ++ Must be encoded using UTF8
+// ++ May contain embedded NULLs
+// ++ May not be NULL terminated
+//
+// Drivers are encouraged to NULL terminate all of their strings whenever
+// possible, but are not required to do so if the response buffer is too small.
+//
+typedef uint32_t audio_stream_string_id_t;
+#define AUDIO_STREAM_STR_ID_MANUFACTURER ((audio_stream_string_id_t)0x80000000)
+#define AUDIO_STREAM_STR_ID_PRODUCT ((audio_stream_string_id_t)0x80000001)
+
+typedef struct audio_stream_cmd_get_string_req {
+ audio_cmd_hdr_t hdr;
+ audio_stream_string_id_t id;
+} audio_stream_cmd_get_string_req_t;
+
+typedef struct audio_stream_cmd_get_string_resp {
+ audio_cmd_hdr_t hdr;
+ zx_status_t result;
+ audio_stream_string_id_t id;
+ uint32_t strlen;
+ uint8_t str[256 - sizeof(audio_cmd_hdr_t) - (3 * sizeof(uint32_t))];
+} audio_stream_cmd_get_string_resp_t;
+
+static_assert(sizeof(audio_stream_cmd_get_string_resp_t) == 256,
+ "audio_stream_cmd_get_string_resp_t must be exactly 256 bytes");
+
+// AUDIO_STREAM_CMD_GET_CLOCK_DOMAIN
+//
+// Fetch the hardware clock domain for this device.
+// On products containing audio devices that are not locked to the local system clock, the board
+// driver will provide a clock tree entry to the audio driver at driver startup time. From that,
+// the audio driver can extract the clock domain and provide it to the sender, upon receiving this
+// command. This domain value is all that the sender needs, in order to locate controls for that
+// clock domain in the clock tree and trim that clock domain's rate.
+// On products containing audio devices that are locked to the local system monotonic clock, a clock
+// domain value of 0 should be returned.
+//
+// Must not be used with the NO_ACK flag.
+typedef struct audio_stream_cmd_get_clock_domain_req {
+ audio_cmd_hdr_t hdr;
+} audio_stream_cmd_get_clock_domain_req_t;
+
+typedef struct audio_stream_cmd_get_clock_domain_resp {
+ audio_cmd_hdr_t hdr;
+ int32_t clock_domain;
+} audio_stream_cmd_get_clock_domain_resp_t;
+
+//
+// Ring-buffer commands
+//
+
+// AUDIO_RB_CMD_GET_FIFO_DEPTH
+//
+// TODO(johngro) : Is calling this "FIFO" depth appropriate? Should it be some
+// direction neutral form of something like "max-read-ahead-amount" or something
+// instead?
+//
+// Must not be used with the NO_ACK flag.
+typedef struct audio_rb_cmd_get_fifo_depth_req {
+ audio_cmd_hdr_t hdr;
+} audio_rb_cmd_get_fifo_depth_req_t;
+
+typedef struct audio_rb_cmd_get_fifo_depth_resp {
+ audio_cmd_hdr_t hdr;
+ zx_status_t result;
+
+ // A representation (in bytes) of how far ahead audio hardware may read
+ // into the stream (in the case of output) or may hold onto audio before
+ // writing it to memory (in the case of input).
+ uint32_t fifo_depth;
+} audio_rb_cmd_get_fifo_depth_resp_t;
+
+// AUDIO_RB_CMD_GET_BUFFER
+typedef struct audio_rb_cmd_get_buffer_req {
+ audio_cmd_hdr_t hdr;
+
+ uint32_t min_ring_buffer_frames;
+ uint32_t notifications_per_ring;
+} audio_rb_cmd_get_buffer_req_t;
+
+typedef struct audio_rb_cmd_get_buffer_resp {
+ audio_cmd_hdr_t hdr;
+ zx_status_t result;
+ uint32_t num_ring_buffer_frames;
+
+ // NOTE: If result == ZX_OK, a VMO handle representing the ring buffer to
+ // be used will be returned as well. Clients may map this buffer with
+ // read-write permissions in the case of an output stream, or read-only
+ // permissions in the case of an input stream. The size of the VMO
+ // indicates where the wrap point of the ring (in bytes) is located in the
+ // VMO. This size *must* always be an integral number of audio frames.
+ //
+ // TODO(johngro) : Should we provide some indication of whether or not this
+ // memory is being used directly for HW DMA and may need explicit cache
+ // flushing/invalidation?
+} audio_rb_cmd_get_buffer_resp_t;
+
+// AUDIO_RB_CMD_START
+typedef struct audio_rb_cmd_start_req {
+ audio_cmd_hdr_t hdr;
+} audio_rb_cmd_start_req_t;
+
+typedef struct audio_rb_cmd_start_resp {
+ audio_cmd_hdr_t hdr;
+ zx_status_t result;
+ uint64_t start_time;
+} audio_rb_cmd_start_resp_t;
+
+// AUDIO_RB_CMD_STOP
+typedef struct audio_rb_cmd_stop_req {
+ audio_cmd_hdr_t hdr;
+} audio_rb_cmd_stop_req_t;
+
+typedef struct audio_rb_cmd_stop_resp {
+ audio_cmd_hdr_t hdr;
+ zx_status_t result;
+} audio_rb_cmd_stop_resp_t;
+
+// AUDIO_RB_POSITION_NOTIFY
+typedef struct audio_rb_position_notify {
+ audio_cmd_hdr_t hdr;
+
+ // The time, per system monotonic clock, of the below byte position.
+ zx_time_t monotonic_time;
+
+ // The current position (in bytes) of the driver/hardware's read (output) or
+ // write (input) pointer in the ring buffer.
+ uint32_t ring_buffer_pos;
+} audio_rb_position_notify_t;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_DEVICE_AUDIO_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/dlfcn.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/dlfcn.h
new file mode 100644
index 0000000..f37e9be
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/dlfcn.h
@@ -0,0 +1,35 @@
+// Copyright 2018 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.
+
+#ifndef SYSROOT_ZIRCON_DLFCN_H_
+#define SYSROOT_ZIRCON_DLFCN_H_
+
+#include <dlfcn.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// Loads a dynamic shared object stored in |vmo|.
+// Acts identically to dlopen, but acts on a vmo
+// instead of a file path.
+//
+// Does not take ownership of the input vmo.
+void* dlopen_vmo(zx_handle_t vmo, int mode);
+
+// Replace the handle to the "loader service" used to map names
+// to VM objects for dlopen et al. This takes ownership of the
+// given handle, and gives the caller ownership of the old handle
+// in the return value.
+zx_handle_t dl_set_loader_service(zx_handle_t new_svc);
+
+// Ask the active "loader service" (if there is one), to return
+// a new connection. Not all loader services need support this.
+// On success, a channel handle to the new connection is returned
+// via out.
+zx_status_t dl_clone_loader_service(zx_handle_t* out);
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_DLFCN_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/driver/binding.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/driver/binding.h
new file mode 100644
index 0000000..82f513e
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/driver/binding.h
@@ -0,0 +1,310 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_DRIVER_BINDING_H_
+#define SYSROOT_ZIRCON_DRIVER_BINDING_H_
+
+#include <assert.h>
+#include <stdalign.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <zircon/compiler.h>
+
+__BEGIN_CDECLS
+
+// COAABBBB VVVVVVVV Condition Opcode paramA paramB Value
+
+#define OP_ABORT 0x0 // if (cond) return no-match
+#define OP_MATCH 0x1 // if (cond) return match
+#define OP_GOTO 0x2 // if (cond) advance to next LABEL(paramA)
+#define OP_LABEL 0x5 // no-op, labels line with paramA
+
+#define COND_AL 0x0 // true
+#define COND_EQ 0x1 // bind(paramB) == Value
+#define COND_NE 0x2 // bind(paramB) != Value
+#define COND_GT 0x3 // bind(paramB) > Value
+#define COND_LT 0x4 // bind(paramB) < Value
+#define COND_GE 0x5 // bind(paramB) >= Value
+#define COND_LE 0x6 // bind(paramB) <= Value
+
+// branches are forward-only
+// branches always go to the first matching LABEL
+// branches that cannot find a matching LABEL are treated as ABORTs
+// there is an implied unconditional ABORT after the last instruction
+// flags are initially zero, may be set/cleared with SET/CLEAR
+// flags may be tested by comparison against BIND_FLAGS
+
+#define BINDINST(c, o, a, b, v) \
+ { (((c)&0xF) << 28) | (((o)&0xF) << 24) | (((a)&0xFF) << 16) | ((b)&0xFFFF), (v), 0 /* debug */ }
+
+#define BINDINST_CC(n) ((n) >> 28)
+#define BINDINST_OP(n) (((n) >> 24) & 0xF)
+#define BINDINST_PA(n) (((n) >> 16) & 0xFF)
+#define BINDINST_PB(n) ((n)&0xFFFF)
+
+#define BI_ABORT() BINDINST(COND_AL, OP_ABORT, 0, 0, 0)
+#define BI_MATCH() BINDINST(COND_AL, OP_MATCH, 0, 0, 0)
+#define BI_GOTO(n) BINDINST(COND_AL, OP_GOTO, n, 0, 0)
+#define BI_LABEL(n) BINDINST(COND_AL, OP_LABEL, n, 0, 0)
+
+#define BI_ABORT_IF(c, b, v) BINDINST(COND_##c, OP_ABORT, 0, b, v)
+#define BI_MATCH_IF(c, b, v) BINDINST(COND_##c, OP_MATCH, 0, b, v)
+#define BI_GOTO_IF(c, b, v, n) BINDINST(COND_##c, OP_GOTO, n, b, v)
+
+// for drivers that only want to be bound on user request
+#define BI_ABORT_IF_AUTOBIND BI_ABORT_IF(NE, BIND_AUTOBIND, 0)
+
+// global binding variables at 0x00XX
+#define BIND_FLAGS 0x0000 // value of the flags register
+#define BIND_PROTOCOL 0x0001 // primary protocol of the device
+#define BIND_AUTOBIND 0x0002 // if this is an automated bind/load
+
+// pci binding variables at 0x01XX
+#define BIND_PCI_VID 0x0100
+#define BIND_PCI_DID 0x0101
+#define BIND_PCI_CLASS 0x0102
+#define BIND_PCI_SUBCLASS 0x0103
+#define BIND_PCI_INTERFACE 0x0104
+#define BIND_PCI_REVISION 0x0105
+
+// usb binding variables at 0x02XX
+// these are used for both ZX_PROTOCOL_USB and ZX_PROTOCOL_USB_FUNCTION
+#define BIND_USB_VID 0x0200
+#define BIND_USB_PID 0x0201
+#define BIND_USB_CLASS 0x0202
+#define BIND_USB_SUBCLASS 0x0203
+#define BIND_USB_PROTOCOL 0x0204
+
+// Platform bus binding variables at 0x03XX
+#define BIND_PLATFORM_DEV_VID 0x0300
+#define BIND_PLATFORM_DEV_PID 0x0301
+#define BIND_PLATFORM_DEV_DID 0x0302
+#define BIND_PLATFORM_PROTO 0x0303
+
+// ACPI binding variables at 0x04XX
+// The _HID is a 7- or 8-byte string. Because a bind property is 32-bit, use 2
+// properties to bind using the _HID. They are encoded in big endian order for
+// human readability. In the case of 7-byte _HID's, the 8th-byte shall be 0.
+#define BIND_ACPI_HID_0_3 0x0400 // char 0-3
+#define BIND_ACPI_HID_4_7 0x0401 // char 4-7
+// The _CID may be a valid HID value or a bus-specific string. The ACPI bus
+// driver only publishes those that are valid HID values.
+#define BIND_ACPI_CID_0_3 0x0402 // char 0-3
+#define BIND_ACPI_CID_4_7 0x0403 // char 4-7
+
+// Intel HDA Codec binding variables at 0x05XX
+#define BIND_IHDA_CODEC_VID 0x0500
+#define BIND_IHDA_CODEC_DID 0x0501
+#define BIND_IHDA_CODEC_MAJOR_REV 0x0502
+#define BIND_IHDA_CODEC_MINOR_REV 0x0503
+#define BIND_IHDA_CODEC_VENDOR_REV 0x0504
+#define BIND_IHDA_CODEC_VENDOR_STEP 0x0505
+
+// Serial binding variables at 0x06XX
+#define BIND_SERIAL_CLASS 0x0600
+#define BIND_SERIAL_VID 0x0601
+#define BIND_SERIAL_PID 0x0602
+
+// NAND binding variables at 0x07XX
+#define BIND_NAND_CLASS 0x0700
+
+// Bluetooth binding variables at 0x08XX
+#define BIND_BT_GATT_SVC_UUID16 0x0800
+// 128-bit UUID is split across 4 32-bit unsigned ints
+#define BIND_BT_GATT_SVC_UUID128_1 0x0801
+#define BIND_BT_GATT_SVC_UUID128_2 0x0802
+#define BIND_BT_GATT_SVC_UUID128_3 0x0803
+#define BIND_BT_GATT_SVC_UUID128_4 0x0804
+
+// SDIO binding variables at 0x09XX
+#define BIND_SDIO_VID 0x0900
+#define BIND_SDIO_PID 0x0901
+#define BIND_SDIO_FUNCTION 0x0902
+
+// I2C binding variables at 0x0A0X
+#define BIND_I2C_CLASS 0x0A00
+#define BIND_I2C_BUS_ID 0x0A01
+#define BIND_I2C_ADDRESS 0x0A02
+
+// GPIO binding variables at 0x0A1X
+#define BIND_GPIO_PIN 0x0A10
+
+// POWER binding variables at 0x0A2X
+#define BIND_POWER_DOMAIN 0x0A20
+#define BIND_POWER_DOMAIN_COMPOSITE 0x0A21
+
+// POWER binding variables at 0x0A3X
+#define BIND_CLOCK_ID 0x0A30
+
+// SPI binding variables at 0x0A4X
+#define BIND_SPI_CLASS 0x0A40
+#define BIND_SPI_BUS_ID 0x0A41
+#define BIND_SPI_CHIP_SELECT 0x0A42
+
+// PWM binding variables at 0x0A5X
+#define BIND_PWM_ID 0x0A50
+
+// Init Step binding variables at 0x0A6X
+#define BIND_INIT_STEP 0x0A60
+
+// Fuchsia-defined topological path properties are at 0x0B00 through 0x0B7F.
+// Vendor-defined topological path properties are at 0x0B80 to 0x0BFF.
+// For vendor properties, it is recommended that a vendor ID be included
+// and checked via some other property.
+#define BIND_TOPO_START 0x0B00
+#define BIND_TOPO_PCI 0x0B00
+#define BIND_TOPO_I2C 0x0B01
+#define BIND_TOPO_SPI 0x0B02
+#define BIND_TOPO_VENDOR_START 0x0B80
+#define BIND_TOPO_VENDOR_END 0x0BFF
+#define BIND_TOPO_END 0x0BFF
+
+#define BIND_TOPO_PCI_PACK(bus, dev, func) (((bus) << 8) | (dev << 3) | (func))
+#define BIND_TOPO_PCI_UNPACK_BUS(topo) (((topo) >> 8) & 0xff)
+#define BIND_TOPO_PCI_UNPACK_DEVICE(topo) (((topo) >> 3) & 0x1f)
+#define BIND_TOPO_PCI_UNPACK_FUNCTION(topo) ((topo)&0x7)
+
+#define BIND_TOPO_I2C_PACK(addr) ((addr))
+#define BIND_TOPO_I2C_UNPACK(topo) ((topo))
+
+#define BIND_TOPO_SPI_PACK(bus, chip_select) (((bus) << 8) | (chip_select))
+#define BIND_TOPO_SPI_UNPACK_BUS_ID(topo) (((topo) >> 8) && 0xff)
+#define BIND_TOPO_SPI_UNPACK_CHIP_SELECT(topo) ((topo)&0xff)
+
+typedef struct zx_bind_inst {
+ uint32_t op;
+ uint32_t arg;
+ uint32_t debug;
+} zx_bind_inst_t;
+
+typedef struct zx_device_prop {
+ uint16_t id;
+ uint16_t reserved;
+ uint32_t value;
+} zx_device_prop_t;
+
+// simple example
+#if 0
+zx_bind_inst_t i915_binding[] = {
+ BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_PCI),
+ BI_ABORT_IF(NE, BIND_PCI_VID, 0x8086),
+ BI_MATCH_IF(EQ, BIND_PCI_DID, 0x1616), // broadwell
+ BI_MATCH_IF(EQ, BIND_PCI_DID, 0x1916), // skylake
+ BI_ABORT(),
+};
+#endif
+
+#define ZIRCON_NOTE_NAME "Zircon"
+#define ZIRCON_NOTE_DRIVER 0x31565244 // DRV1
+
+typedef struct {
+ // Elf64_Nhdr fields:
+ uint32_t namesz;
+ uint32_t descsz;
+ uint32_t type;
+ // ELF note name. namesz is the exact size of the name (including '\0'),
+ // but the storage size is always rounded up to a multiple of 4 bytes.
+ char name[(sizeof(ZIRCON_NOTE_NAME) + 3) & -4];
+} zircon_driver_note_header_t;
+
+#define ZIRCON_DRIVER_NOTE_HEADER_INIT(object) \
+ { \
+ /* .namesz = */ sizeof(ZIRCON_NOTE_NAME), \
+ /* .descsz = */ (sizeof(object) - sizeof(zircon_driver_note_header_t)), \
+ /* .type = */ ZIRCON_NOTE_DRIVER, /* .name = */ ZIRCON_NOTE_NAME, \
+ }
+
+typedef struct {
+ // See flag bits below.
+ uint32_t flags;
+
+ // Driver Metadata
+ uint32_t bindcount;
+ uint32_t reserved0;
+ char name[32];
+ char vendor[16];
+ char version[16];
+
+ // Driver Bind Program follows
+} zircon_driver_note_payload_t;
+
+// Flag bits in the driver note:
+
+// Driver is built with `-fsanitize=address` and can only be loaded into a
+// devhost that supports the ASan runtime.
+#define ZIRCON_DRIVER_NOTE_FLAG_ASAN (1u << 0)
+
+#define ZIRCON_DRIVER_NOTE_PAYLOAD_INIT(Driver, VendorName, Version, BindCount) \
+ { \
+ /* .flags = */ ZIRCON_DRIVER_NOTE_FLAGS, /* .bindcount = */ (BindCount), /* .reserved0 = */ 0, \
+ /* .name = */ #Driver, /* .vendor = */ VendorName, /* .version = */ Version, \
+ }
+
+#define ZIRCON_DRIVER_NOTE_FLAGS \
+ (__has_feature(address_sanitizer) ? ZIRCON_DRIVER_NOTE_FLAG_ASAN : 0)
+
+typedef struct {
+ zircon_driver_note_header_t header;
+ zircon_driver_note_payload_t payload;
+} zircon_driver_note_t;
+
+static_assert(offsetof(zircon_driver_note_t, payload) == sizeof(zircon_driver_note_header_t),
+ "alignment snafu?");
+
+// Without this, ASan will add redzone padding after the object, which
+// would make it invalid ELF note format.
+#if __has_feature(address_sanitizer)
+#define ZIRCON_DRIVER_NOTE_ASAN __attribute__((no_sanitize("address")))
+#else
+#define ZIRCON_DRIVER_NOTE_ASAN
+#endif
+
+// GCC has a quirk about how '__attribute__((visibility("default")))'
+// (__EXPORT here) works for const variables in C++. The attribute has no
+// effect when used on the definition of a const variable, and GCC gives a
+// warning/error about that. The attribute must appear on the "extern"
+// declaration of the variable instead.
+
+// We explicitly align the note to 4 bytes. That's its natural alignment
+// anyway, but the compilers sometimes like to over-align as an
+// optimization while other tools sometimes like to complain if SHT_NOTE
+// sections are over-aligned (since this could result in padding being
+// inserted that makes it violate the ELF note format). Standard C11
+// doesn't permit alignas(...) on a type but we could use __ALIGNED(4) on
+// all the types (i.e. GNU __attribute__ syntax instead of C11 syntax).
+// But the alignment of the types is not actually the issue: it's the
+// compiler deciding to over-align the individual object regardless of its
+// type's alignment, so we have to explicitly set the alignment of the
+// object to defeat any compiler default over-alignment.
+
+#define ZIRCON_DRIVER_BEGIN(Driver, Ops, VendorName, Version, BindCount) \
+ const zx_driver_ops_t* __zircon_driver_ops__ __EXPORT = &(Ops); \
+ zx_driver_rec_t __zircon_driver_rec__ __EXPORT = { \
+ /* .ops = */ &(Ops), /* .driver = */ NULL, \
+ /* .log_flags = */ 7, /* DDK_LOG_ERROR | DDK_LOG_WARN | DDK_LOG_INFO */ \
+ }; \
+ extern const struct zircon_driver_note __zircon_driver_note__ __EXPORT; \
+ alignas(4) __SECTION(".note.zircon.driver." #Driver) \
+ ZIRCON_DRIVER_NOTE_ASAN const struct zircon_driver_note { \
+ zircon_driver_note_t note; \
+ zx_bind_inst_t binding[BindCount]; \
+ } __zircon_driver_note__ = { \
+ /* .note = */ { \
+ ZIRCON_DRIVER_NOTE_HEADER_INIT(__zircon_driver_note__), \
+ ZIRCON_DRIVER_NOTE_PAYLOAD_INIT(Driver, VendorName, Version, BindCount), \
+ }, \
+ /* .binding = */ {
+#define ZIRCON_DRIVER_END(Driver) \
+ } \
+ } \
+ ;
+
+// TODO: if we moved the Ops from the BEGIN() to END() macro we
+// could add a zircon_driver_note_t* to the zx_driver_rec_t,
+// define it in END(), and have only one symbol to dlsym()
+// when loading drivers
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_DRIVER_BINDING_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/errors.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/errors.h
new file mode 100644
index 0000000..4e0da7d
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/errors.h
@@ -0,0 +1,233 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_ERRORS_H_
+#define SYSROOT_ZIRCON_ERRORS_H_
+
+// Zircon statuses are signed 32 bit integers. The space of values is
+// divided as follows:
+// - The zero value is for the OK status.
+// - Negative values are defined by the system, in this file.
+// - Positive values are reserved for protocol-specific error values,
+// and will never be defined by the system.
+
+#define ZX_OK (0)
+
+// ======= Internal failures =======
+// ZX_ERR_INTERNAL: The system encountered an otherwise unspecified error
+// while performing the operation.
+#define ZX_ERR_INTERNAL (-1)
+
+// ZX_ERR_NOT_SUPPORTED: The operation is not implemented, supported,
+// or enabled.
+#define ZX_ERR_NOT_SUPPORTED (-2)
+
+// ZX_ERR_NO_RESOURCES: The system was not able to allocate some resource
+// needed for the operation.
+#define ZX_ERR_NO_RESOURCES (-3)
+
+// ZX_ERR_NO_MEMORY: The system was not able to allocate memory needed
+// for the operation.
+#define ZX_ERR_NO_MEMORY (-4)
+
+// -5 used to be ZX_ERR_CALL_FAILED.
+
+// ZX_ERR_INTERNAL_INTR_RETRY: The system call was interrupted, but should be
+// retried. This should not be seen outside of the VDSO.
+#define ZX_ERR_INTERNAL_INTR_RETRY (-6)
+
+// ======= Parameter errors =======
+// ZX_ERR_INVALID_ARGS: an argument is invalid, ex. null pointer
+#define ZX_ERR_INVALID_ARGS (-10)
+
+// ZX_ERR_BAD_HANDLE: A specified handle value does not refer to a handle.
+#define ZX_ERR_BAD_HANDLE (-11)
+
+// ZX_ERR_WRONG_TYPE: The subject of the operation is the wrong type to
+// perform the operation.
+// Example: Attempting a message_read on a thread handle.
+#define ZX_ERR_WRONG_TYPE (-12)
+
+// ZX_ERR_BAD_SYSCALL: The specified syscall number is invalid.
+#define ZX_ERR_BAD_SYSCALL (-13)
+
+// ZX_ERR_OUT_OF_RANGE: An argument is outside the valid range for this
+// operation.
+#define ZX_ERR_OUT_OF_RANGE (-14)
+
+// ZX_ERR_BUFFER_TOO_SMALL: A caller provided buffer is too small for
+// this operation.
+#define ZX_ERR_BUFFER_TOO_SMALL (-15)
+
+// ======= Precondition or state errors =======
+// ZX_ERR_BAD_STATE: operation failed because the current state of the
+// object does not allow it, or a precondition of the operation is
+// not satisfied
+#define ZX_ERR_BAD_STATE (-20)
+
+// ZX_ERR_TIMED_OUT: The time limit for the operation elapsed before
+// the operation completed.
+#define ZX_ERR_TIMED_OUT (-21)
+
+// ZX_ERR_SHOULD_WAIT: The operation cannot be performed currently but
+// potentially could succeed if the caller waits for a prerequisite
+// to be satisfied, for example waiting for a handle to be readable
+// or writable.
+// Example: Attempting to read from a channel that has no
+// messages waiting but has an open remote will return ZX_ERR_SHOULD_WAIT.
+// Attempting to read from a channel that has no messages waiting
+// and has a closed remote end will return ZX_ERR_PEER_CLOSED.
+#define ZX_ERR_SHOULD_WAIT (-22)
+
+// ZX_ERR_CANCELED: The in-progress operation (e.g. a wait) has been
+// canceled.
+#define ZX_ERR_CANCELED (-23)
+
+// ZX_ERR_PEER_CLOSED: The operation failed because the remote end of the
+// subject of the operation was closed.
+#define ZX_ERR_PEER_CLOSED (-24)
+
+// ZX_ERR_NOT_FOUND: The requested entity is not found.
+#define ZX_ERR_NOT_FOUND (-25)
+
+// ZX_ERR_ALREADY_EXISTS: An object with the specified identifier
+// already exists.
+// Example: Attempting to create a file when a file already exists
+// with that name.
+#define ZX_ERR_ALREADY_EXISTS (-26)
+
+// ZX_ERR_ALREADY_BOUND: The operation failed because the named entity
+// is already owned or controlled by another entity. The operation
+// could succeed later if the current owner releases the entity.
+#define ZX_ERR_ALREADY_BOUND (-27)
+
+// ZX_ERR_UNAVAILABLE: The subject of the operation is currently unable
+// to perform the operation.
+// Note: This is used when there's no direct way for the caller to
+// observe when the subject will be able to perform the operation
+// and should thus retry.
+#define ZX_ERR_UNAVAILABLE (-28)
+
+// ======= Permission check errors =======
+// ZX_ERR_ACCESS_DENIED: The caller did not have permission to perform
+// the specified operation.
+#define ZX_ERR_ACCESS_DENIED (-30)
+
+// ======= Input-output errors =======
+// ZX_ERR_IO: Otherwise unspecified error occurred during I/O.
+#define ZX_ERR_IO (-40)
+
+// ZX_ERR_REFUSED: The entity the I/O operation is being performed on
+// rejected the operation.
+// Example: an I2C device NAK'ing a transaction or a disk controller
+// rejecting an invalid command, or a stalled USB endpoint.
+#define ZX_ERR_IO_REFUSED (-41)
+
+// ZX_ERR_IO_DATA_INTEGRITY: The data in the operation failed an integrity
+// check and is possibly corrupted.
+// Example: CRC or Parity error.
+#define ZX_ERR_IO_DATA_INTEGRITY (-42)
+
+// ZX_ERR_IO_DATA_LOSS: The data in the operation is currently unavailable
+// and may be permanently lost.
+// Example: A disk block is irrecoverably damaged.
+#define ZX_ERR_IO_DATA_LOSS (-43)
+
+// ZX_ERR_IO_NOT_PRESENT: The device is no longer available (has been
+// unplugged from the system, powered down, or the driver has been
+// unloaded)
+#define ZX_ERR_IO_NOT_PRESENT (-44)
+
+// ZX_ERR_IO_OVERRUN: More data was received from the device than expected.
+// Example: a USB "babble" error due to a device sending more data than
+// the host queued to receive.
+#define ZX_ERR_IO_OVERRUN (-45)
+
+// ZX_ERR_IO_MISSED_DEADLINE: An operation did not complete within the required timeframe.
+// Example: A USB isochronous transfer that failed to complete due to an overrun or underrun.
+#define ZX_ERR_IO_MISSED_DEADLINE (-46)
+
+// ZX_ERR_IO_INVALID: The data in the operation is invalid parameter or is out of range.
+// Example: A USB transfer that failed to complete with TRB Error
+#define ZX_ERR_IO_INVALID (-47)
+
+// ======== Filesystem Errors ========
+// ZX_ERR_BAD_PATH: Path name is too long.
+#define ZX_ERR_BAD_PATH (-50)
+
+// ZX_ERR_NOT_DIR: Object is not a directory or does not support
+// directory operations.
+// Example: Attempted to open a file as a directory or
+// attempted to do directory operations on a file.
+#define ZX_ERR_NOT_DIR (-51)
+
+// ZX_ERR_NOT_FILE: Object is not a regular file.
+#define ZX_ERR_NOT_FILE (-52)
+
+// ZX_ERR_FILE_BIG: This operation would cause a file to exceed a
+// filesystem-specific size limit
+#define ZX_ERR_FILE_BIG (-53)
+
+// ZX_ERR_NO_SPACE: Filesystem or device space is exhausted.
+#define ZX_ERR_NO_SPACE (-54)
+
+// ZX_ERR_NOT_EMPTY: Directory is not empty.
+#define ZX_ERR_NOT_EMPTY (-55)
+
+// ======== Flow Control ========
+// These are not errors, as such, and will never be returned
+// by a syscall or public API. They exist to allow callbacks
+// to request changes in operation.
+//
+// ZX_ERR_STOP: Do not call again.
+// Example: A notification callback will be called on every
+// event until it returns something other than ZX_OK.
+// This status allows differentiation between "stop due to
+// an error" and "stop because the work is done."
+#define ZX_ERR_STOP (-60)
+
+// ZX_ERR_NEXT: Advance to the next item.
+// Example: A notification callback will use this response
+// to indicate it did not "consume" an item passed to it,
+// but by choice, not due to an error condition.
+#define ZX_ERR_NEXT (-61)
+
+// ZX_ERR_ASYNC: Ownership of the item has moved to an asynchronous worker.
+//
+// Unlike ZX_ERR_STOP, which implies that iteration on an object
+// should stop, and ZX_ERR_NEXT, which implies that iteration
+// should continue to the next item, ZX_ERR_ASYNC implies
+// that an asynchronous worker is responsible for continuing iteration.
+//
+// Example: A notification callback will be called on every
+// event, but one event needs to handle some work asynchronously
+// before it can continue. ZX_ERR_ASYNC implies the worker is
+// responsible for resuming iteration once its work has completed.
+#define ZX_ERR_ASYNC (-62)
+
+// ======== Network-related errors ========
+
+// ZX_ERR_PROTOCOL_NOT_SUPPORTED: Specified protocol is not
+// supported.
+#define ZX_ERR_PROTOCOL_NOT_SUPPORTED (-70)
+
+// ZX_ERR_ADDRESS_UNREACHABLE: Host is unreachable.
+#define ZX_ERR_ADDRESS_UNREACHABLE (-71)
+
+// ZX_ERR_ADDRESS_IN_USE: Address is being used by someone else.
+#define ZX_ERR_ADDRESS_IN_USE (-72)
+
+// ZX_ERR_NOT_CONNECTED: Socket is not connected.
+#define ZX_ERR_NOT_CONNECTED (-73)
+
+// ZX_ERR_CONNECTION_REFUSED: Remote peer rejected the connection.
+#define ZX_ERR_CONNECTION_REFUSED (-74)
+
+// ZX_ERR_CONNECTION_RESET: Connection was reset.
+#define ZX_ERR_CONNECTION_RESET (-75)
+
+// ZX_ERR_CONNECTION_ABORTED: Connection was aborted.
+#define ZX_ERR_CONNECTION_ABORTED (-76)
+
+#endif // SYSROOT_ZIRCON_ERRORS_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/exception.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/exception.h
new file mode 100644
index 0000000..bf3843b
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/exception.h
@@ -0,0 +1,19 @@
+// 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.
+
+#pragma once
+
+#include <zircon/syscalls/exception.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+__EXPORT const char* _zx_exception_get_string(zx_excp_type_t exception);
+__EXPORT const char* zx_exception_get_string(zx_excp_type_t exception);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/features.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/features.h
new file mode 100644
index 0000000..d60e724
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/features.h
@@ -0,0 +1,47 @@
+// Copyright 2018 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.
+
+#ifndef SYSROOT_ZIRCON_FEATURES_H_
+#define SYSROOT_ZIRCON_FEATURES_H_
+
+// clang-format off
+
+// types of features that can be retrieved via |zx_system_get_features|
+#define ZX_FEATURE_KIND_CPU ((uint32_t)0)
+#define ZX_FEATURE_KIND_HW_BREAKPOINT_COUNT ((uint32_t)1)
+#define ZX_FEATURE_KIND_HW_WATCHPOINT_COUNT ((uint32_t)2)
+
+// arch-independent CPU features
+#define ZX_HAS_CPU_FEATURES ((uint32_t)(1u << 0))
+
+#if defined(__x86_64__)
+
+// x86-64 CPU features
+// None; use cpuid instead
+
+#elif defined(__aarch64__)
+
+// arm64 CPU features
+#define ZX_ARM64_FEATURE_ISA_FP ((uint32_t)(1u << 1))
+#define ZX_ARM64_FEATURE_ISA_ASIMD ((uint32_t)(1u << 2))
+#define ZX_ARM64_FEATURE_ISA_AES ((uint32_t)(1u << 3))
+#define ZX_ARM64_FEATURE_ISA_PMULL ((uint32_t)(1u << 4))
+#define ZX_ARM64_FEATURE_ISA_SHA1 ((uint32_t)(1u << 5))
+#define ZX_ARM64_FEATURE_ISA_SHA2 ((uint32_t)(1u << 6))
+#define ZX_ARM64_FEATURE_ISA_CRC32 ((uint32_t)(1u << 7))
+#define ZX_ARM64_FEATURE_ISA_ATOMICS ((uint32_t)(1u << 8))
+#define ZX_ARM64_FEATURE_ISA_RDM ((uint32_t)(1u << 9))
+#define ZX_ARM64_FEATURE_ISA_SHA3 ((uint32_t)(1u << 10))
+#define ZX_ARM64_FEATURE_ISA_SM3 ((uint32_t)(1u << 11))
+#define ZX_ARM64_FEATURE_ISA_SM4 ((uint32_t)(1u << 12))
+#define ZX_ARM64_FEATURE_ISA_DP ((uint32_t)(1u << 13))
+#define ZX_ARM64_FEATURE_ISA_DPB ((uint32_t)(1u << 14))
+
+#else
+
+#error what architecture?
+
+#endif
+
+#endif // SYSROOT_ZIRCON_FEATURES_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/fidl.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/fidl.h
new file mode 100644
index 0000000..152843a
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/fidl.h
@@ -0,0 +1,452 @@
+// Copyright 2017 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.
+
+#ifndef SYSROOT_ZIRCON_FIDL_H_
+#define SYSROOT_ZIRCON_FIDL_H_
+
+#include <assert.h> // NOLINT(modernize-deprecated-headers, foobar)
+#include <stdalign.h> // NOLINT(modernize-deprecated-headers)
+#include <stdint.h> // NOLINT(modernize-*)
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// Fidl data types have a representation in a wire format. This wire
+// format is shared by all language bindings, including C11 and C++.
+//
+// The C bindings also define a representation of fidl data types. For
+// a given type, the size and alignment of all parts of the type agree
+// with the wire format's representation. The C representation differs
+// in the representation of pointers to out-of-line allocations. On
+// the wire, allocations are encoded as either present or not. In C,
+// they are actual pointers. The C representation also places any
+// transferred handle types (including requests) inline. The wire
+// format tracks handles separately, just like the underlying channel
+// transport does.
+//
+// Turning the wire format into the C format is called decoding.
+//
+// Turning the C format into the wire format is called encoding.
+//
+// The formats are designed to allow for in-place coding, assuming all
+// out-of-line allocations placed are in traversal order (defined
+// below) with natural alignment.
+
+// Bounds.
+
+// Various fidl types, such as strings and vectors, may be bounded. If
+// no explicit bound is given, then FIDL_MAX_SIZE is implied.
+
+#define FIDL_MAX_SIZE UINT32_MAX
+
+// Out of line allocations.
+
+// The fidl wire format represents potential out-of-line allocations
+// (corresponding to actual pointer types in the C format) as
+// uintptr_t. For allocations that are actually present and that will
+// be patched up with pointers during decoding, the FIDL_ALLOC_PRESENT
+// value is used. For non-present nullable allocations, the
+// FIDL_ALLOC_ABSENT value is used.
+
+#define FIDL_ALLOC_PRESENT ((uintptr_t)UINTPTR_MAX)
+#define FIDL_ALLOC_ABSENT ((uintptr_t)0)
+
+// Out of line allocations are all 8 byte aligned.
+// TODO(fxb/42792): Remove either this FIDL_ALIGN macro or the FidlAlign function in
+// fidl/internal.h.
+#define FIDL_ALIGNMENT ((size_t)8)
+#define FIDL_ALIGN(a) (((a) + 7u) & ~7u)
+#define FIDL_ALIGNDECL alignas(FIDL_ALIGNMENT)
+
+// An opaque struct representing the encoding of a particular fidl
+// type.
+typedef struct fidl_type fidl_type_t;
+
+// Primitive types.
+
+// Both on the wire and once deserialized, primitive fidl types
+// correspond directly to C types. There is no intermediate layer of
+// typedefs. For instance, fidl's float64 is generated as double.
+
+// All primitive types are non-nullable.
+
+// All primitive types are naturally sized and aligned on the wire.
+
+// fidl C Meaning.
+// ---------------------------------------------
+// bool bool A boolean.
+// int8 int8_t An 8 bit signed integer.
+// int16 int16_t A 16 bit signed integer.
+// int32 int32_t A 32 bit signed integer.
+// int64 int64_t A 64 bit signed integer.
+// uint8 uint8_t An 8 bit unsigned integer.
+// uint16 uint16_t A 16 bit unsigned integer.
+// uint32 uint32_t A 32 bit unsigned integer.
+// uint64 uint64_t A 64 bit unsigned integer.
+// float32 float A 32 bit IEEE-754 float.
+// float64 double A 64 bit IEEE-754 float.
+
+// Enums.
+
+// Fidl enums have an undering integer type (one of int8, int16,
+// int32, int64, uint8, uint16, uint32, or uint64). The wire format of
+// an enum and the C format of an enum are the same as the
+// corresponding primitive type.
+
+// String types.
+
+// Fidl strings are variable-length UTF-8 strings. Strings can be
+// nullable (string?) or nonnullable (string); if nullable, the null
+// string is distinct from the empty string. Strings can be bounded to
+// a fixed byte length (e.g. string:40? is a nullable string of at
+// most 40 bytes).
+
+// Strings are not guaranteed to be nul terminated. Strings can
+// contain embedded nuls throughout their length.
+
+// The fidl wire format dictates that strings are valid UTF-8. It is
+// up to clients to provide well-formed UTF-8 and servers to check for
+// it. Message encoding and decoding can, but does not by default,
+// perform this check.
+
+// All deserialized string types are represented by the fidl_string_t
+// structure. This structure consists of a size (in bytes) and a
+// pointer to an out-of-line allocation of uint8_t, guaranteed to be
+// at least as long as the length.
+
+// The bound on a string type is not present in the serialized format,
+// but is checked as part of validation.
+
+typedef struct fidl_string {
+ // Number of UTF-8 code units (bytes), must be 0 if |data| is null.
+ uint64_t size;
+
+ // Pointer to UTF-8 code units (bytes) or null
+ char* data;
+} fidl_string_t;
+
+// When encoded, an absent nullable string is represented as a
+// fidl_string_t with size 0 and FIDL_ALLOC_ABSENT data, with no
+// out-of-line allocation associated with it. A present string
+// (nullable or not) is represented as a fidl_string_t with some size
+// and with data equal to FIDL_ALLOC_PRESENT, which the decoding
+// process replaces with an actual pointer to the next out-of-line
+// allocation.
+
+// All string types:
+
+// fidl C Meaning
+// -----------------------------------------------------------------
+// string fidl_string_t A string of arbitrary length.
+// string? fidl_string_t An optional string of arbitrary length.
+// string:N fidl_string_t A string up to N bytes long.
+// string:N? fidl_string_t An optional string up to N bytes long.
+
+// Arrays.
+
+// On the wire, an array of N objects of type T (array<T, N>) is
+// represented the same as N contiguous Ts. Equivalently, it is
+// represented the same as a nonnullable struct containing N fields
+// all of type T.
+
+// In C, this is just represented as a C array of the corresponding C
+// type.
+
+// Vector types.
+
+// Fidl vectors are variable-length arrays of a given type T. Vectors
+// can be nullable (vector<T>?) or nonnullable (vector<T>); if
+// nullable, the null vector is distinct from the empty
+// vector. Vectors can be bounded to a fixed element length
+// (e.g. vector<T>:40? is a nullable vector of at most 40 Ts).
+
+// All deserialized vector types are represented by the fidl_vector_t
+// structure. This structure consists of a count and a pointer to the
+// bytes.
+
+// The bound on a vector type is not present in the serialized format,
+// but is checked as part of validation.
+
+typedef struct fidl_vector {
+ // Number of elements, must be 0 if |data| is null.
+ uint64_t count;
+
+ // Pointer to element data or null.
+ void* data;
+} fidl_vector_t;
+
+// When encoded, an absent nullable vector is represented as a
+// fidl_vector_t with size 0 and FIDL_ALLOC_ABSENT data, with no
+// out-of-line allocation associated with it. A present vector
+// (nullable or not) is represented as a fidl_vector_t with some size
+// and with data equal to FIDL_ALLOC_PRESENT, which the decoding
+// process replaces with an actual pointer to the next out-of-line
+// allocation.
+
+// All vector types:
+
+// fidl C Meaning
+// --------------------------------------------------------------------------
+// vector<T> fidl_vector_t A vector of T, of arbitrary length.
+// vector<T>? fidl_vector_t An optional vector of T, of arbitrary length.
+// vector<T>:N fidl_vector_t A vector of T, up to N elements.
+// vector<T>:N? fidl_vector_t An optional vector of T, up to N elements.
+
+// Envelope.
+
+// An efficient way to encapsulate uninterpreted FIDL messages.
+// - Stores a variable size uninterpreted payload out-of-line.
+// - Payload may contain an arbitrary number of bytes and handles.
+// - Allows for encapsulation of one FIDL message inside of another.
+// - Building block for extensible structures such as tables & extensible
+// unions.
+
+// When encoded for transfer, |data| indicates presence of content:
+// - FIDL_ALLOC_ABSENT : envelope is null
+// - FIDL_ALLOC_PRESENT : envelope is non-null, |data| is the next out-of-line object
+// When decoded for consumption, |data| is a pointer to content.
+// - nullptr : envelope is null
+// - <valid pointer> : envelope is non-null, |data| is at indicated memory address
+
+typedef struct {
+ // The size of the entire envelope contents, including any additional
+ // out-of-line objects that the envelope may contain. For example, a
+ // vector<string>'s num_bytes for ["hello", "world"] would include the
+ // string contents in the size, not just the outer vector. Always a multiple
+ // of 8; must be zero if envelope is null.
+ uint32_t num_bytes;
+
+ // The number of handles in the envelope, including any additional
+ // out-of-line objects that the envelope contains. Must be zero if envelope is null.
+ uint32_t num_handles;
+
+ // A pointer to the out-of-line envelope data in decoded form, or
+ // FIDL_ALLOC_(ABSENT|PRESENT) in encoded form.
+ union {
+ void* data;
+ uintptr_t presence;
+ };
+} fidl_envelope_t;
+
+// Handle types.
+
+// Handle types are encoded directly. Just like primitive types, there
+// is no fidl-specific handle type. Generated fidl structures simply
+// mention zx_handle_t.
+
+// Handle types are either nullable (handle?), or not (handle); and
+// either explicitly typed (e.g. handle<Channel> or handle<Job>), or
+// not.
+
+// All fidl handle types, regardless of subtype, are represented as
+// zx_handle_t. The encoding tables do know the handle subtypes,
+// however, for clients which wish to perform explicit checking.
+
+// The following are the possible handle subtypes.
+
+// process
+// thread
+// vmo
+// channel
+// event
+// port
+// interrupt
+// iomap
+// pci
+// log
+// socket
+// resource
+// eventpair
+// job
+// vmar
+// fifo
+// hypervisor
+// guest
+// timer
+
+// All handle types are 4 byte sized and aligned on the wire.
+
+// When encoded, absent nullable handles are represented as
+// FIDL_HANDLE_ABSENT. Present handles, whether nullable or not, are
+// represented as FIDL_HANDLE_PRESENT, which the decoding process will
+// overwrite with the next handle value in the channel message.
+
+#define FIDL_HANDLE_ABSENT ((zx_handle_t)ZX_HANDLE_INVALID)
+#define FIDL_HANDLE_PRESENT ((zx_handle_t)UINT32_MAX)
+
+// fidl C Meaning
+// ------------------------------------------------------------------
+// handle zx_handle_t Any valid handle.
+// handle? zx_handle_t Any valid handle, or ZX_HANDLE_INVALID.
+// handle<T> zx_handle_t Any valid T handle.
+// handle<T>? zx_handle_t Any valid T handle, or ZX_HANDLE_INVALID.
+
+// Unions.
+
+// Fidl unions are a tagged sum type. The tag is a 4 bytes. For every
+// union type, the fidl compiler generates an enum representing the
+// different variants of the enum. This is followed, in C and on the
+// wire, by large enough and aligned enough storage for all members of
+// the union.
+
+// Unions may be nullable. Nullable unions are represented as a
+// pointer to an out of line allocation of tag-and-member. As with
+// other out-of-line allocations, ones present on the wire take the
+// value FIDL_ALLOC_PRESENT and those that are not are represented by
+// FIDL_ALLOC_NULL. Nonnullable unions are represented inline as a
+// tag-and-member.
+
+// For each fidl union type, a corresponding C type is generated. They
+// are all structs consisting of a fidl_union_tag_t discriminant,
+// followed by an anonymous union of all the union members.
+
+typedef uint32_t fidl_union_tag_t;
+
+// fidl C Meaning
+// --------------------------------------------------------------------
+// union foo {...} struct union_foo { An inline union.
+// fidl_union_tag_t tag;
+// union {...};
+// }
+//
+// union foo {...}? struct union_foo* A pointer to a
+// union_foo, or else
+// FIDL_ALLOC_ABSENT.
+
+// Tables.
+
+// Tables are 'flexible structs', where all members are optional, and new
+// members can be added, or old members removed while preserving ABI
+// compatibility. Each table member is referenced by ordinal, sequentially
+// assigned from 1 onward, with no gaps. Each member content is stored
+// out-of-line in an envelope, and a table is simply a vector of these envelopes
+// with the requirement that the last envelope must be present in order
+// to guarantee a canonical representation.
+
+typedef struct {
+ fidl_vector_t envelopes;
+} fidl_table_t;
+
+// Extensible unions.
+
+// Extensible unions, or "xunions" (colloquially pronounced "zoo-nions") are
+// similar to unions, except that storage for union members are out-of-line
+// rather than inline. This enables union members to be added and removed while
+// preserving ABI compatibility with the existing xunion definition.
+
+typedef uint64_t fidl_xunion_tag_t;
+
+enum {
+ kFidlXUnionEmptyTag = 0, // The tag representing an empty xunion.
+};
+
+typedef struct {
+ fidl_xunion_tag_t tag;
+ fidl_envelope_t envelope;
+} fidl_xunion_t;
+
+// Messages.
+
+// All fidl messages share a common 16 byte header.
+
+enum {
+ kFidlWireFormatMagicNumberInitial = 1,
+};
+
+typedef struct fidl_message_header {
+ zx_txid_t txid;
+ uint8_t flags[3];
+ // This value indicates the message's wire format. Two sides with different
+ // wire formats are incompatible with each other
+ uint8_t magic_number;
+ uint64_t ordinal;
+} fidl_message_header_t;
+
+// Messages which do not have a response use zero as a special
+// transaction id.
+
+#define FIDL_TXID_NO_RESPONSE 0ul
+
+// A FIDL message.
+typedef struct fidl_msg {
+ // The bytes of the message.
+ //
+ // The bytes of the message might be in the encoded or decoded form.
+ // Functions that take a |fidl_msg_t| as an argument should document whether
+ // the expect encoded or decoded messages.
+ //
+ // See |num_bytes| for the number of bytes in the message.
+ void* bytes;
+
+ // The handles of the message.
+ //
+ // See |num_bytes| for the number of bytes in the message.
+ zx_handle_t* handles;
+
+ // The number of bytes in |bytes|.
+ uint32_t num_bytes;
+
+ // The number of handles in |handles|.
+ uint32_t num_handles;
+} fidl_msg_t;
+
+// An outstanding FIDL transaction.
+typedef struct fidl_txn fidl_txn_t;
+struct fidl_txn {
+ // Replies to the outstanding request and complete the FIDL transaction.
+ //
+ // Pass the |fidl_txn_t| object itself as the first parameter. The |msg|
+ // should already be encoded. This function always consumes any handles
+ // present in |msg|.
+ //
+ // Call |reply| only once for each |txn| object. After |reply| returns, the
+ // |txn| object is considered invalid and might have been freed or reused
+ // for another purpose.
+ zx_status_t (*reply)(fidl_txn_t* txn, const fidl_msg_t* msg);
+};
+
+// An epitaph is a message that a server sends just prior to closing the
+// connection. It provides an indication of why the connection is being closed.
+// Epitaphs are defined in the FIDL wire format specification. Once sent down
+// the wire, the channel should be closed.
+typedef struct fidl_epitaph {
+ FIDL_ALIGNDECL
+
+ // The method ordinal for all epitaphs must be kFidlOrdinalEpitaph
+ fidl_message_header_t hdr;
+
+ // The error associated with this epitaph is stored as a struct{int32} in
+ // the message payload. System errors must be constants of type zx_status_t,
+ // which are all negative. Positive numbers should be used for application
+ // errors. A value of ZX_OK indicates no error.
+ zx_status_t error;
+} fidl_epitaph_t;
+
+// This ordinal value is reserved for Epitaphs.
+enum {
+ kFidlOrdinalEpitaph = 0xFFFFFFFFFFFFFFFF,
+};
+
+// Assumptions.
+
+// Ensure that FIDL_ALIGNMENT is sufficient.
+static_assert(alignof(bool) <= FIDL_ALIGNMENT, "");
+static_assert(alignof(int8_t) <= FIDL_ALIGNMENT, "");
+static_assert(alignof(int16_t) <= FIDL_ALIGNMENT, "");
+static_assert(alignof(int32_t) <= FIDL_ALIGNMENT, "");
+static_assert(alignof(int64_t) <= FIDL_ALIGNMENT, "");
+static_assert(alignof(uint8_t) <= FIDL_ALIGNMENT, "");
+static_assert(alignof(uint16_t) <= FIDL_ALIGNMENT, "");
+static_assert(alignof(uint32_t) <= FIDL_ALIGNMENT, "");
+static_assert(alignof(uint64_t) <= FIDL_ALIGNMENT, "");
+static_assert(alignof(float) <= FIDL_ALIGNMENT, "");
+static_assert(alignof(double) <= FIDL_ALIGNMENT, "");
+static_assert(alignof(void*) <= FIDL_ALIGNMENT, "");
+static_assert(alignof(fidl_union_tag_t) <= FIDL_ALIGNMENT, "");
+static_assert(alignof(fidl_message_header_t) <= FIDL_ALIGNMENT, "");
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_FIDL_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/gpt.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/gpt.h
new file mode 100644
index 0000000..005415c
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/gpt.h
@@ -0,0 +1,300 @@
+// Copyright 2017 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.
+
+#ifndef SYSROOT_ZIRCON_HW_GPT_H_
+#define SYSROOT_ZIRCON_HW_GPT_H_
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <zircon/compiler.h>
+
+#define GPT_MAGIC (0x5452415020494645ull) // 'EFI PART'
+#define GPT_HEADER_SIZE 0x5c
+#define GPT_ENTRY_SIZE 0x80
+#define GPT_GUID_LEN 16
+#define GPT_GUID_STRLEN 37
+#define GPT_NAME_LEN 72
+
+typedef struct gpt_header {
+ uint64_t magic; // Magic number.
+ uint32_t revision; // Revision.
+ uint32_t size; // Size of the header.
+ uint32_t crc32; // Checksum of this header.
+ uint32_t reserved0; // Reserved field.
+ uint64_t current; // Block where this table is stored.
+ uint64_t backup; // Block where other copy of partition table is stored.
+ uint64_t first; // First usable block. Block after primary partition table ends.
+ uint64_t last; // Last usable block. Block before backup partition table starts.
+ uint8_t guid[GPT_GUID_LEN]; // Disk GUID.
+ uint64_t entries; // Starting block where entries for this partition tables are found.
+ // Value equals 2 for primary copy.
+ uint32_t entries_count; // Total number of entries.
+ uint32_t entries_size; // Size of each entry.
+ uint32_t entries_crc; // Checksum of the entire entries array.
+} __PACKED gpt_header_t;
+
+static_assert(GPT_HEADER_SIZE == sizeof(gpt_header_t), "Gpt header size invalid");
+
+typedef struct gpt_entry {
+ uint8_t type[GPT_GUID_LEN];
+ uint8_t guid[GPT_GUID_LEN];
+ uint64_t first;
+ uint64_t last;
+ uint64_t flags;
+ uint8_t name[GPT_NAME_LEN]; // UTF-16 on disk
+} gpt_entry_t;
+
+static_assert(GPT_ENTRY_SIZE == sizeof(gpt_entry_t), "Gpt entry size invalid");
+
+// clang-format off
+#define GUID_EMPTY_STRING "00000000-0000-0000-0000-000000000000"
+#define GUID_EMPTY_VALUE { \
+ 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, \
+ 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 \
+}
+#define GUID_EMPTY_NAME "empty"
+
+#define GUID_EFI_STRING "C12A7328-F81F-11D2-BA4B-00A0C93EC93B"
+#define GUID_EFI_VALUE { \
+ 0x28, 0x73, 0x2a, 0xc1, \
+ 0x1f, 0xf8, \
+ 0xd2, 0x11, \
+ 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b \
+}
+#define GUID_EFI_NAME "efi-system"
+
+// GUID for a system partition
+#define GUID_SYSTEM_STRING "606B000B-B7C7-4653-A7D5-B737332C899D"
+#define GUID_SYSTEM_VALUE { \
+ 0x0b, 0x00, 0x6b, 0x60, \
+ 0xc7, 0xb7, \
+ 0x53, 0x46, \
+ 0xa7, 0xd5, 0xb7, 0x37, 0x33, 0x2c, 0x89, 0x9d \
+}
+#define GUID_SYSTEM_NAME "fuchsia-system"
+
+// GUID for a data partition
+#define GUID_DATA_STRING "08185F0C-892D-428A-A789-DBEEC8F55E6A"
+#define GUID_DATA_VALUE { \
+ 0x0c, 0x5f, 0x18, 0x08, \
+ 0x2d, 0x89, \
+ 0x8a, 0x42, \
+ 0xa7, 0x89, 0xdb, 0xee, 0xc8, 0xf5, 0x5e, 0x6a \
+}
+#define GUID_DATA_NAME "fuchsia-data"
+
+// GUID for a installer partition
+#define GUID_INSTALL_STRING "48435546-4953-2041-494E-5354414C4C52"
+#define GUID_INSTALL_VALUE { \
+ 0x46, 0x55, 0x43, 0x48, \
+ 0x53, 0x49, \
+ 0x41, 0x20, \
+ 0x49, 0x4E, 0x53, 0x54, 0x41, 0x4C, 0x4C, 0x52 \
+}
+#define GUID_INSTALL_NAME "fuchsia-install"
+
+#define GUID_BLOB_STRING "2967380E-134C-4CBB-B6DA-17E7CE1CA45D"
+#define GUID_BLOB_VALUE { \
+ 0x0e, 0x38, 0x67, 0x29, \
+ 0x4c, 0x13, \
+ 0xbb, 0x4c, \
+ 0xb6, 0xda, 0x17, 0xe7, 0xce, 0x1c, 0xa4, 0x5d \
+}
+#define GUID_BLOB_NAME "fuchsia-blob"
+
+#define GUID_FVM_STRING "41D0E340-57E3-954E-8C1E-17ECAC44CFF5"
+#define GUID_FVM_VALUE { \
+ 0x40, 0xe3, 0xd0, 0x41, \
+ 0xe3, 0x57, \
+ 0x4e, 0x95, \
+ 0x8c, 0x1e, 0x17, 0xec, 0xac, 0x44, 0xcf, 0xf5 \
+}
+#define GUID_FVM_NAME "fuchsia-fvm"
+
+#define GUID_ZIRCON_A_STRING "DE30CC86-1F4A-4A31-93C4-66F147D33E05"
+#define GUID_ZIRCON_A_VALUE { \
+ 0x86, 0xcc, 0x30, 0xde, \
+ 0x4a, 0x1f, \
+ 0x31, 0x4a, \
+ 0x93, 0xc4, 0x66, 0xf1, 0x47, 0xd3, 0x3e, 0x05, \
+}
+#define GUID_ZIRCON_A_NAME "zircon-a"
+
+#define GUID_ZIRCON_B_STRING "23CC04DF-C278-4CE7-8471-897D1A4BCDF7"
+#define GUID_ZIRCON_B_VALUE { \
+ 0xdf, 0x04, 0xcc, 0x23, \
+ 0x78, 0xc2, \
+ 0xe7, 0x4c, \
+ 0x84, 0x71, 0x89, 0x7d, 0x1a, 0x4b, 0xcd, 0xf7 \
+}
+#define GUID_ZIRCON_B_NAME "zircon-b"
+
+#define GUID_ZIRCON_R_STRING "A0E5CF57-2DEF-46BE-A80C-A2067C37CD49"
+#define GUID_ZIRCON_R_VALUE { \
+ 0x57, 0xcf, 0xe5, 0xa0, \
+ 0xef, 0x2d, \
+ 0xbe, 0x46, \
+ 0xa8, 0x0c, 0xa2, 0x06, 0x7c, 0x37, 0xcd, 0x49 \
+}
+#define GUID_ZIRCON_R_NAME "zircon-r"
+
+#define GUID_SYS_CONFIG_STRING "4E5E989E-4C86-11E8-A15B-480FCF35F8E6"
+#define GUID_SYS_CONFIG_VALUE { \
+ 0x9e, 0x98, 0x5e, 0x4e, \
+ 0x86, 0x4c, \
+ 0xe8, 0x11, \
+ 0xa1, 0x5b, 0x48, 0x0f, 0xcf, 0x35, 0xf8, 0xe6 \
+}
+#define GUID_SYS_CONFIG_NAME "sys-config"
+
+#define GUID_FACTORY_CONFIG_STRING "5A3A90BE-4C86-11E8-A15B-480FCF35F8E6"
+#define GUID_FACTORY_CONFIG_VALUE { \
+ 0xbe, 0x90, 0x3a, 0x5a, \
+ 0x86, 0x4c, \
+ 0xe8, 0x11, \
+ 0xa1, 0x5b, 0x48, 0x0f, 0xcf, 0x35, 0xf8, 0xe6 \
+}
+#define GUID_FACTORY_CONFIG_NAME "factory"
+
+#define GUID_BOOTLOADER_STRING "5ECE94FE-4C86-11E8-A15B-480FCF35F8E6"
+#define GUID_BOOTLOADER_VALUE { \
+ 0xfe, 0x94, 0xce, 0x5e, \
+ 0x86, 0x4c, \
+ 0xe8, 0x11, \
+ 0xa1, 0x5b, 0x48, 0x0f, 0xcf, 0x35, 0xf8, 0xe6 \
+}
+#define GUID_BOOTLOADER_NAME "bootloader"
+
+#define GUID_TEST_STRING "8B94D043-30BE-4871-9DFA-D69556E8C1F3"
+#define GUID_TEST_VALUE { \
+ 0x43, 0xD0, 0x94, 0x8b, \
+ 0xbe, 0x30, \
+ 0x71, 0x48, \
+ 0x9d, 0xfa, 0xd6, 0x95, 0x56, 0xe8, 0xc1, 0xf3 \
+}
+#define GUID_TEST_NAME "guid-test"
+
+#define GUID_VBMETA_A_STRING "A13B4D9A-EC5F-11E8-97D8-6C3BE52705BF"
+#define GUID_VBMETA_A_VALUE { \
+ 0x9a, 0x4d, 0x3b, 0xa1, \
+ 0x5f, 0xec, \
+ 0xe8, 0x11, \
+ 0x97, 0xd8, 0x6c, 0x3b, 0xe5, 0x27, 0x05, 0xbf \
+}
+#define GUID_VBMETA_A_NAME "vbmeta_a"
+
+#define GUID_VBMETA_B_STRING "A288ABF2-EC5F-11E8-97D8-6C3BE52705BF"
+#define GUID_VBMETA_B_VALUE { \
+ 0xf2, 0xab, 0x88, 0xa2, \
+ 0x5f, 0xec, \
+ 0xe8, 0x11, \
+ 0x97, 0xd8, 0x6c, 0x3b, 0xe5, 0x27, 0x05, 0xbf \
+}
+#define GUID_VBMETA_B_NAME "vbmeta_b"
+
+#define GUID_VBMETA_R_STRING "6A2460C3-CD11-4E8B-80A8-12CCE268ED0A"
+#define GUID_VBMETA_R_VALUE { \
+ 0xc3, 0x60, 0x24, 0x6a, \
+ 0x11, 0xcd, \
+ 0x8b, 0x4e, \
+ 0x80, 0xa8, 0x12, 0xcc, 0xe2, 0x68, 0xed, 0x0a \
+}
+#define GUID_VBMETA_R_NAME "vbmeta_r"
+
+#define GUID_ABR_META_STRING "1D75395D-F2C6-476B-A8B7-45CC1C97B476"
+#define GUID_ABR_META_VALUE { \
+ 0x5d, 0x39, 0x75, 0x1d, \
+ 0xc6, 0xf2, \
+ 0x6b, 0x47, \
+ 0xa8, 0xb7, 0x45, 0xcc, 0x1c, 0x97, 0xb4, 0x76 \
+}
+#define GUID_ABR_META_NAME "misc"
+
+#define GUID_CROS_KERNEL_STRING "FE3A2A5D-4F32-41A7-B725-ACCC3285A309"
+#define GUID_CROS_KERNEL_VALUE { \
+ 0x5d, 0x2a, 0x3a, 0xfe, \
+ 0x32, 0x4f, \
+ 0xa7, 0x41, \
+ 0xb7, 0x25, 0xac, 0xcc, 0x32, 0x85, 0xa3, 0x09 \
+}
+#define GUID_CROS_KERNEL_NAME "cros-kernel"
+
+#define GUID_CROS_ROOTFS_STRING "3CB8E202-3B7E-47DD-8A3C-7FF2A13CFCEC"
+#define GUID_CROS_ROOTFS_VALUE { \
+ 0x02, 0xe2, 0xb8, 0x3C, \
+ 0x7e, 0x3b, \
+ 0xdd, 0x47, \
+ 0x8a, 0x3c, 0x7f, 0xf2, 0xa1, 0x3c, 0xfc, 0xec \
+}
+#define GUID_CROS_ROOTFS_NAME "cros-rootfs"
+
+#define GUID_CROS_RESERVED_STRING "2E0A753D-9E48-43B0-8337-B15192CB1B5E"
+#define GUID_CROS_RESERVED_VALUE { \
+ 0x3d, 0x75, 0x0a, 0x2e, \
+ 0x48, 0x9e, \
+ 0xb0, 0x43, \
+ 0x83, 0x37, 0xb1, 0x51, 0x92, 0xcb, 0x1b, 0x5e \
+}
+#define GUID_CROS_RESERVED_NAME "cros-reserved"
+
+#define GUID_CROS_FIRMWARE_STRING "CAB6E88E-ABF3-4102-A07A-D4BB9BE3C1D3"
+#define GUID_CROS_FIRMWARE_VALUE { \
+ 0x8e, 0xe8, 0xb6, 0xca, \
+ 0xf3, 0xab, \
+ 0x02, 0x41, \
+ 0xa0, 0x7a, 0xd4, 0xbb, 0x9b, 0xe3, 0xc1, 0xd3 \
+}
+#define GUID_CROS_FIRMWARE_NAME "cros-firmware"
+
+#define GUID_CROS_DATA_STRING "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7"
+#define GUID_CROS_DATA_VALUE { \
+ 0xa2, 0xa0, 0xd0, 0xeb, \
+ 0xe5, 0xb9, \
+ 0x33, 0x44, \
+ 0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7 \
+}
+#define GUID_CROS_DATA_NAME "cros-data"
+
+#define GUID_BIOS_STRING "21686148-6449-6E6F-744E-656564454649"
+#define GUID_BIOS_VALUE { \
+ 0x48, 0x61, 0x68, 0x21, \
+ 0x49, 0x64, \
+ 0x6f, 0x6e, \
+ 0x74, 0x4e, 0x65, 0x65, 0x64, 0x45, 0x46, 0x49 \
+}
+#define GUID_BIOS_NAME "bios"
+
+#define GUID_EMMC_BOOT1_STRING "900B0FC5-90CD-4D4F-84F9-9F8ED579DB88"
+#define GUID_EMMC_BOOT1_VALUE { \
+ 0xc5, 0x0f, 0x0b, 0x90, \
+ 0xcd, 0x90, \
+ 0x4f, 0x4d, \
+ 0x84, 0xf9, 0x9f, 0x8e, 0xd5, 0x79, 0xdb, 0x88 \
+}
+#define GUID_EMMC_BOOT1_NAME "emmc-boot1"
+
+#define GUID_EMMC_BOOT2_STRING "B2B2E8D1-7C10-4EBC-A2D0-4614568260AD"
+#define GUID_EMMC_BOOT2_VALUE { \
+ 0xd1, 0xe8, 0xb2, 0xb2, \
+ 0x10, 0x7c, \
+ 0xbc, 0x4e, \
+ 0xa2, 0xd0, 0x46, 0x14, 0x56, 0x82, 0x60, 0xad \
+}
+#define GUID_EMMC_BOOT2_NAME "emmc-boot2"
+
+#define GUID_LINUX_FILESYSTEM_DATA_STRING "0FC63DAF-8483-4772-8E79-3D69D8477DE4"
+#define GUID_LINUX_FILESYSTEM_DATA_VALUE { \
+ 0xaf, 0x3d, 0xc6, 0x0f, \
+ 0x83, 0x84, \
+ 0x72, 0x47, \
+ 0x8e, 0x79, 0x3d, 0x69, 0xd8, 0x47, 0x7d, 0xe4 \
+}
+#define GUID_LINUX_FILESYSTEM_DATA_NAME "linux-filesystem"
+
+// clang-format on
+
+#endif // SYSROOT_ZIRCON_HW_GPT_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/i2c.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/i2c.h
new file mode 100644
index 0000000..e35b6f1
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/i2c.h
@@ -0,0 +1,10 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_HW_I2C_H_
+#define SYSROOT_ZIRCON_HW_I2C_H_
+
+#define I2C_CLASS_HID 1
+
+#endif // SYSROOT_ZIRCON_HW_I2C_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/pci.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/pci.h
new file mode 100644
index 0000000..7de1bca
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/pci.h
@@ -0,0 +1,50 @@
+// Copyright 2018 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.
+
+#ifndef SYSROOT_ZIRCON_HW_PCI_H_
+#define SYSROOT_ZIRCON_HW_PCI_H_
+
+#include <stdint.h>
+#include <zircon/compiler.h>
+
+__BEGIN_CDECLS
+
+// Structure for passing around PCI address information
+typedef struct pci_bdf {
+ uint8_t bus_id;
+ uint8_t device_id;
+ uint8_t function_id;
+} pci_bdf_t;
+
+// TODO(cja): This header is used for the transition of these defines from
+// kernel to userspace, but due to pci_bdf_t some of the kernel includes it.
+// Make sure defines here don't clash with those in pci_common.h by having this
+// guard, but remove it after the transition.
+#ifndef WITH_KERNEL_PCIE
+
+#define PCI_MAX_BUSES (256u)
+#define PCI_MAX_DEVICES_PER_BUS (32u)
+#define PCI_MAX_FUNCTIONS_PER_DEVICE (8u)
+#define PCI_MAX_FUNCTIONS_PER_BUS (PCI_MAX_DEVICES_PER_BUS * PCI_MAX_FUNCTIONS_PER_DEVICE)
+
+#define PCI_STANDARD_CONFIG_HDR_SIZE (64u)
+#define PCI_BASE_CONFIG_SIZE (256u)
+#define PCIE_EXTENDED_CONFIG_SIZE (4096u)
+#define PCIE_ECAM_BYTES_PER_BUS (PCIE_EXTENDED_CONFIG_SIZE * PCI_MAX_FUNCTIONS_PER_BUS)
+
+#define PCI_BAR_REGS_PER_BRIDGE (2u)
+#define PCI_BAR_REGS_PER_DEVICE (6u)
+#define PCI_MAX_BAR_REGS (6u)
+
+#define PCI_MAX_LEGACY_IRQ_PINS (4u)
+#define PCI_MAX_MSI_IRQS (32u)
+#define PCIE_MAX_MSIX_IRQS (2048u)
+
+#define PCI_INVALID_VENDOR_ID (0xFFFF)
+
+#endif // WITH_KERNEL_PCIE
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_HW_PCI_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/usb.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/usb.h
new file mode 100644
index 0000000..8256c2e
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/usb.h
@@ -0,0 +1,281 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_HW_USB_H_
+#define SYSROOT_ZIRCON_HW_USB_H_
+
+// clang-format off
+
+#include <endian.h>
+#include <stdint.h>
+#include <zircon/compiler.h>
+
+__BEGIN_CDECLS
+
+// maximum number of endpoints per device
+#define USB_MAX_EPS 32
+
+/* Request Types */
+#define USB_DIR_OUT (0 << 7)
+#define USB_DIR_IN (1 << 7)
+#define USB_DIR_MASK (1 << 7)
+#define USB_TYPE_STANDARD (0 << 5)
+#define USB_TYPE_CLASS (1 << 5)
+#define USB_TYPE_VENDOR (2 << 5)
+#define USB_TYPE_MASK (3 << 5)
+#define USB_RECIP_DEVICE (0 << 0)
+#define USB_RECIP_INTERFACE (1 << 0)
+#define USB_RECIP_ENDPOINT (2 << 0)
+#define USB_RECIP_OTHER (3 << 0)
+#define USB_RECIP_MASK (0x1f << 0)
+
+/* 1.0 Request Values */
+#define USB_REQ_GET_STATUS 0x00
+#define USB_REQ_CLEAR_FEATURE 0x01
+#define USB_REQ_SET_FEATURE 0x03
+#define USB_REQ_SET_ADDRESS 0x05
+#define USB_REQ_GET_DESCRIPTOR 0x06
+#define USB_REQ_SET_DESCRIPTOR 0x07
+#define USB_REQ_GET_CONFIGURATION 0x08
+#define USB_REQ_SET_CONFIGURATION 0x09
+#define USB_REQ_GET_INTERFACE 0x0A
+#define USB_REQ_SET_INTERFACE 0x0B
+#define USB_REQ_SYNCH_FRAME 0x0C
+
+/* USB device/interface classes */
+#define USB_CLASS_AUDIO 0x01
+#define USB_CLASS_COMM 0x02
+#define USB_CLASS_HID 0x03
+#define USB_CLASS_PHYSICAL 0x05
+#define USB_CLASS_IMAGING 0x06
+#define USB_CLASS_PRINTER 0x07
+#define USB_CLASS_MSC 0x08
+#define USB_CLASS_HUB 0x09
+#define USB_CLASS_CDC 0x0a
+#define USB_CLASS_CCID 0x0b
+#define USB_CLASS_SECURITY 0x0d
+#define USB_CLASS_VIDEO 0x0e
+#define USB_CLASS_HEALTHCARE 0x0f
+#define USB_CLASS_DIAGNOSTIC 0xdc
+#define USB_CLASS_WIRELESS 0xe0
+#define USB_CLASS_MISC 0xef
+#define USB_CLASS_APPLICATION_SPECIFIC 0xfe
+#define USB_CLASS_VENDOR 0xFf
+
+#define USB_SUBCLASS_MSC_SCSI 0x06
+#define USB_PROTOCOL_MSC_BULK_ONLY 0x50
+
+#define USB_SUBCLASS_DFU 0x01
+#define USB_PROTOCOL_DFU 0x02
+
+#define USB_SUBCLASS_VENDOR 0xFF
+#define USB_PROTOCOL_TEST_FTDI 0x01
+#define USB_PROTOCOL_TEST_HID_ONE_ENDPOINT 0x02
+#define USB_PROTOCOL_TEST_HID_TWO_ENDPOINT 0x03
+
+/* Descriptor Types */
+#define USB_DT_DEVICE 0x01
+#define USB_DT_CONFIG 0x02
+#define USB_DT_STRING 0x03
+#define USB_DT_INTERFACE 0x04
+#define USB_DT_ENDPOINT 0x05
+#define USB_DT_DEVICE_QUALIFIER 0x06
+#define USB_DT_OTHER_SPEED_CONFIG 0x07
+#define USB_DT_INTERFACE_POWER 0x08
+#define USB_DT_INTERFACE_ASSOCIATION 0x0b
+#define USB_DT_HID 0x21
+#define USB_DT_HIDREPORT 0x22
+#define USB_DT_HIDPHYSICAL 0x23
+#define USB_DT_CS_INTERFACE 0x24
+#define USB_DT_CS_ENDPOINT 0x25
+#define USB_DT_SS_EP_COMPANION 0x30
+#define USB_DT_SS_ISOCH_EP_COMPANION 0x31
+
+/* USB device feature selectors */
+#define USB_DEVICE_SELF_POWERED 0x00
+#define USB_DEVICE_REMOTE_WAKEUP 0x01
+#define USB_DEVICE_TEST_MODE 0x02
+
+/* Configuration attributes (bmAttributes) */
+#define USB_CONFIGURATION_REMOTE_WAKEUP 0x20
+#define USB_CONFIGURATION_SELF_POWERED 0x40
+#define USB_CONFIGURATION_RESERVED_7 0x80 // This bit must be set
+
+/* Endpoint direction (bEndpointAddress) */
+#define USB_ENDPOINT_IN 0x80
+#define USB_ENDPOINT_OUT 0x00
+#define USB_ENDPOINT_DIR_MASK 0x80
+#define USB_ENDPOINT_NUM_MASK 0x1F
+
+/* Endpoint types (bmAttributes) */
+#define USB_ENDPOINT_CONTROL 0x00
+#define USB_ENDPOINT_ISOCHRONOUS 0x01
+#define USB_ENDPOINT_BULK 0x02
+#define USB_ENDPOINT_INTERRUPT 0x03
+#define USB_ENDPOINT_TYPE_MASK 0x03
+
+/* Endpoint synchronization type (bmAttributes) */
+#define USB_ENDPOINT_NO_SYNCHRONIZATION 0x00
+#define USB_ENDPOINT_ASYNCHRONOUS 0x04
+#define USB_ENDPOINT_ADAPTIVE 0x08
+#define USB_ENDPOINT_SYNCHRONOUS 0x0C
+#define USB_ENDPOINT_SYNCHRONIZATION_MASK 0x0C
+
+/* Endpoint usage type (bmAttributes) */
+#define USB_ENDPOINT_DATA 0x00
+#define USB_ENDPOINT_FEEDBACK 0x10
+#define USB_ENDPOINT_IMPLICIT_FEEDBACK 0x20
+#define USB_ENDPOINT_USAGE_MASK 0x30
+
+#define USB_ENDPOINT_HALT 0x00
+
+// Values in this set match those used in XHCI and other parts of the USB specification
+#define USB_SPEED_UNDEFINED 0
+#define USB_SPEED_FULL 1
+#define USB_SPEED_LOW 2
+#define USB_SPEED_HIGH 3
+#define USB_SPEED_SUPER 4
+typedef uint32_t usb_speed_t;
+
+/* general USB defines */
+typedef struct {
+ uint8_t bmRequestType;
+ uint8_t bRequest;
+ uint16_t wValue;
+ uint16_t wIndex;
+ uint16_t wLength;
+} __attribute__ ((packed)) usb_setup_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+} __attribute__ ((packed)) usb_descriptor_header_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_DEVICE
+ uint16_t bcdUSB;
+ uint8_t bDeviceClass;
+ uint8_t bDeviceSubClass;
+ uint8_t bDeviceProtocol;
+ uint8_t bMaxPacketSize0;
+ uint16_t idVendor;
+ uint16_t idProduct;
+ uint16_t bcdDevice;
+ uint8_t iManufacturer;
+ uint8_t iProduct;
+ uint8_t iSerialNumber;
+ uint8_t bNumConfigurations;
+} __attribute__ ((packed)) usb_device_descriptor_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_CONFIG
+ uint16_t wTotalLength;
+ uint8_t bNumInterfaces;
+ uint8_t bConfigurationValue;
+ uint8_t iConfiguration;
+ uint8_t bmAttributes;
+ uint8_t bMaxPower;
+} __attribute__ ((packed)) usb_configuration_descriptor_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_STRING
+ uint8_t bString[];
+} __attribute__ ((packed)) usb_string_descriptor_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_INTERFACE
+ uint8_t bInterfaceNumber;
+ uint8_t bAlternateSetting;
+ uint8_t bNumEndpoints;
+ uint8_t bInterfaceClass;
+ uint8_t bInterfaceSubClass;
+ uint8_t bInterfaceProtocol;
+ uint8_t iInterface;
+} __attribute__ ((packed)) usb_interface_descriptor_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_ENDPOINT
+ uint8_t bEndpointAddress;
+ uint8_t bmAttributes;
+ uint16_t wMaxPacketSize;
+ uint8_t bInterval;
+} __attribute__ ((packed)) usb_endpoint_descriptor_t;
+#define usb_ep_num(ep) ((ep)->bEndpointAddress & USB_ENDPOINT_NUM_MASK)
+// usb_ep_num2() useful with you have bEndpointAddress outside of a descriptor.
+#define usb_ep_num2(addr) ((addr) & USB_ENDPOINT_NUM_MASK)
+#define usb_ep_direction(ep) ((ep)->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
+#define usb_ep_type(ep) ((ep)->bmAttributes & USB_ENDPOINT_TYPE_MASK)
+#define usb_ep_sync_type(ep) ((ep)->bmAttributes & USB_ENDPOINT_SYNCHRONIZATION_MASK)
+// max packet size is in bits 10..0
+#define usb_ep_max_packet(ep) (le16toh((ep)->wMaxPacketSize) & 0x07FF)
+// for high speed interrupt and isochronous endpoints, additional transactions per microframe
+// are in bits 12..11
+#define usb_ep_add_mf_transactions(ep) ((le16toh((ep)->wMaxPacketSize) >> 11) & 3)
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_DEVICE_QUALIFIER
+ uint16_t bcdUSB;
+ uint8_t bDeviceClass;
+ uint8_t bDeviceSubClass;
+ uint8_t bDeviceProtocol;
+ uint8_t bMaxPacketSize0;
+ uint8_t bNumConfigurations;
+ uint8_t bReserved;
+} __attribute__ ((packed)) usb_device_qualifier_descriptor_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_SS_EP_COMPANION
+ uint8_t bMaxBurst;
+ uint8_t bmAttributes;
+ uint16_t wBytesPerInterval;
+} __attribute__ ((packed)) usb_ss_ep_comp_descriptor_t;
+#define usb_ss_ep_comp_isoc_mult(ep) ((ep)->bmAttributes & 0x3)
+#define usb_ss_ep_comp_isoc_comp(ep) (!!((ep)->bmAttributes & 0x80))
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_SS_ISOCH_EP_COMPANION
+ uint16_t wReserved;
+ uint32_t dwBytesPerInterval;
+} __attribute__ ((packed)) usb_ss_isoch_ep_comp_descriptor_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_INTERFACE_ASSOCIATION
+ uint8_t bFirstInterface;
+ uint8_t bInterfaceCount;
+ uint8_t bFunctionClass;
+ uint8_t bFunctionSubClass;
+ uint8_t bFunctionProtocol;
+ uint8_t iFunction;
+} __attribute__ ((packed)) usb_interface_assoc_descriptor_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_CS_INTERFACE
+ uint8_t bDescriptorSubType;
+} __attribute__ ((packed)) usb_cs_interface_descriptor_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_STRING
+ uint16_t wLangIds[127];
+} __attribute__ ((packed)) usb_langid_desc_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_STRING
+ uint16_t code_points[127];
+} __attribute__ ((packed)) usb_string_desc_t;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_HW_USB_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/usb/audio.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/usb/audio.h
new file mode 100644
index 0000000..4e68f87
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/usb/audio.h
@@ -0,0 +1,527 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_HW_USB_AUDIO_H_
+#define SYSROOT_ZIRCON_HW_USB_AUDIO_H_
+
+// clang-format off
+
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+////////////////////////////////////////////////////
+//
+// General Audio interface constants
+//
+////////////////////////////////////////////////////
+
+// audio interface subclasses
+#define USB_SUBCLASS_AUDIO_CONTROL 0x01
+#define USB_SUBCLASS_AUDIO_STREAMING 0x02
+#define USB_SUBCLASS_MIDI_STREAMING 0x03
+
+// audio class specific descriptor types
+#define USB_AUDIO_CS_DEVICE 0x21
+#define USB_AUDIO_CS_CONFIGURATION 0x22
+#define USB_AUDIO_CS_STRING 0x23
+#define USB_AUDIO_CS_INTERFACE 0x24
+#define USB_AUDIO_CS_ENDPOINT 0x25
+
+////////////////////////////////////////////////////
+//
+// Audio Control interface constants
+//
+////////////////////////////////////////////////////
+
+// audio class specific AC interface descriptor subtypes
+#define USB_AUDIO_AC_HEADER 0x01
+#define USB_AUDIO_AC_INPUT_TERMINAL 0x02
+#define USB_AUDIO_AC_OUTPUT_TERMINAL 0x03
+#define USB_AUDIO_AC_MIXER_UNIT 0x04
+#define USB_AUDIO_AC_SELECTOR_UNIT 0x05
+#define USB_AUDIO_AC_FEATURE_UNIT 0x06
+#define USB_AUDIO_AC_PROCESSING_UNIT 0x07
+#define USB_AUDIO_AC_EXTENSION_UNIT 0x08
+
+// processing unit process types
+#define USB_AUDIO_UP_DOWN_MIX_PROCESS 0x01
+#define USB_AUDIO_DOLBY_PROLOGIC_PROCESS 0x02
+#define USB_AUDIO_3D_STEREO_EXTENDER_PROCESS 0x03
+#define USB_AUDIO_REVERBERATION_PROCESS 0x04
+#define USB_AUDIO_CHORUS_PROCESS 0x05
+#define USB_AUDIO_DYN_RANGE_COMP_PROCESS 0x06
+
+// audio class specific endpoint descriptor subtypes
+#define USB_AUDIO_EP_GENERAL 0x01
+
+// audio class specific request codes
+#define USB_AUDIO_SET_CUR 0x01
+#define USB_AUDIO_GET_CUR 0x81
+#define USB_AUDIO_SET_MIN 0x02
+#define USB_AUDIO_GET_MIN 0x82
+#define USB_AUDIO_SET_MAX 0x03
+#define USB_AUDIO_GET_MAX 0x83
+#define USB_AUDIO_SET_RES 0x04
+#define USB_AUDIO_GET_RES 0x84
+#define USB_AUDIO_SET_MEM 0x05
+#define USB_AUDIO_GET_MEM 0x85
+#define USB_AUDIO_GET_STAT 0xFF
+
+// terminal control selectors
+#define USB_AUDIO_COPY_PROTECT_CONTROL 0x01
+
+// feature unit control selectors
+#define USB_AUDIO_MUTE_CONTROL 0x01
+#define USB_AUDIO_VOLUME_CONTROL 0x02
+#define USB_AUDIO_BASS_CONTROL 0x03
+#define USB_AUDIO_MID_CONTROL 0x04
+#define USB_AUDIO_TREBLE_CONTROL 0x05
+#define USB_AUDIO_GRAPHIC_EQUALIZER_CONTROL 0x06
+#define USB_AUDIO_AUTOMATIC_GAIN_CONTROL 0x07
+#define USB_AUDIO_DELAY_CONTROL 0x08
+#define USB_AUDIO_BASS_BOOST_CONTROL 0x09
+#define USB_AUDIO_LOUDNESS_CONTROL 0x0A
+
+// feature unit control support bitmasks
+#define USB_AUDIO_FU_BMA_MUTE (1u << 0u)
+#define USB_AUDIO_FU_BMA_VOLUME (1u << 1u)
+#define USB_AUDIO_FU_BMA_BASS (1u << 2u)
+#define USB_AUDIO_FU_BMA_MID (1u << 3u)
+#define USB_AUDIO_FU_BMA_TREBLE (1u << 4u)
+#define USB_AUDIO_FU_BMA_GRAPHIC_EQUALIZER (1u << 5u)
+#define USB_AUDIO_FU_BMA_AUTOMATIC_GAIN (1u << 6u)
+#define USB_AUDIO_FU_BMA_DELAY (1u << 7u)
+#define USB_AUDIO_FU_BMA_BASS_BOOST (1u << 8u)
+#define USB_AUDIO_FU_BMA_LOUDNESS (1u << 9u)
+
+// up/down mix processing unit control selectors
+#define USB_AUDIO_UD_ENABLE_CONTROL 0x01
+#define USB_AUDIO_UD_MODE_SELECT_CONTROL 0x02
+#define USB_AUDIO_UD_MODE_SELECT_CONTROL 0x02
+
+// Dolby Prologic processing unit control selectors
+#define USB_AUDIO_DP_ENABLE_CONTROL 0x01
+#define USB_AUDIO_DP_MODE_SELECT_CONTROL 0x02
+
+// 3D stereo extender processing unit control selectors
+#define USB_AUDIO_3D_ENABLE_CONTROL 0x01
+#define USB_AUDIO_SPACIOUSNESS_CONTROL 0x03
+
+// reverberation processing unit control selectors
+#define USB_AUDIO_RV_ENABLE_CONTROL 0x01
+#define USB_AUDIO_REVERB_LEVEL_CONTROL 0x02
+#define USB_AUDIO_REVERB_TIME_CONTROL 0x03
+#define USB_AUDIO_REVERB_FEEDBACK_CONTROL 0x04
+
+// chorus processing unit control selectors
+#define USB_AUDIO_CH_ENABLE_CONTROL 0x01
+#define USB_AUDIO_CHORUS_LEVEL_CONTROL 0x02
+#define USB_AUDIO_CHORUS_RATE_CONTROL 0x03
+#define USB_AUDIO_CHORUS_DEPTH_CONTROL 0x04
+
+// dynamic range compressor processing unit control selectors
+#define USB_AUDIO_DR_ENABLE_CONTROL 0x01
+#define USB_AUDIO_COMPRESSION_RATE_CONTROL 0x02
+#define USB_AUDIO_MAXAMPL_CONTROL 0x03
+#define USB_AUDIO_THRESHOLD_CONTROL 0x04
+#define USB_AUDIO_ATTACK_TIME 0x05
+#define USB_AUDIO_RELEASE_TIME 0x06
+
+// extension unit control selectors
+#define USB_AUDIO_XU_ENABLE_CONTROL 0x01
+
+// endpoint control selectors
+#define USB_AUDIO_SAMPLING_FREQ_CONTROL 0x01
+#define USB_AUDIO_PITCH_CONTROL 0x02
+
+// USB audio terminal types
+#define USB_AUDIO_TERMINAL_USB_UNDEFINED 0x0100
+#define USB_AUDIO_TERMINAL_USB_STREAMING 0x0101
+#define USB_AUDIO_TERMINAL_USB_VENDOR 0x01FF
+#define USB_AUDIO_TERMINAL_INPUT_UNDEFINED 0x0200
+#define USB_AUDIO_TERMINAL_MICROPHONE 0x0201
+#define USB_AUDIO_TERMINAL_DESKTOP_MICROPHONE 0x0202
+#define USB_AUDIO_TERMINAL_PERSONAL_MICROPHONE 0x0203
+#define USB_AUDIO_TERMINAL_OMNI_DIRECTIONAL_MICROPHONE 0x0204
+#define USB_AUDIO_TERMINAL_MICROPHONE_ARRAY 0x0205
+#define USB_AUDIO_TERMINAL_PROCESSING_MICROPHONE_ARRAY 0x0206
+#define USB_AUDIO_TERMINAL_OUTPUT_UNDEFINED 0x0300
+#define USB_AUDIO_TERMINAL_SPEAKER 0x0301
+#define USB_AUDIO_TERMINAL_HEADPHONES 0x0302
+#define USB_AUDIO_TERMINAL_HEAD_MOUNTED_DISPLAY_AUDIO 0x0303
+#define USB_AUDIO_TERMINAL_DESKTOP_SPEAKER 0x0304
+#define USB_AUDIO_TERMINAL_ROOM_SPEAKER 0x0305
+#define USB_AUDIO_TERMINAL_COMMUNICATION_SPEAKER 0x0306
+#define USB_AUDIO_TERMINAL_LOW_FREQ_EFFECTS_SPEAKER 0x0307
+#define USB_AUDIO_TERMINAL_BIDIRECTIONAL_UNDEFINED 0x0400
+#define USB_AUDIO_TERMINAL_HANDSET 0x0401
+#define USB_AUDIO_TERMINAL_HEADSET 0x0402
+#define USB_AUDIO_TERMINAL_SPEAKERPHONE 0x0403
+#define USB_AUDIO_TERMINAL_ECHO_SUPPRESSING_SPEAKERPHONE 0x0404
+#define USB_AUDIO_TERMINAL_ECHO_CANCELING_SPEAKERPHONE 0x0405
+#define USB_AUDIO_TERMINAL_TELEPHONY_UNDEFINED 0x0500
+#define USB_AUDIO_TERMINAL_PHONE_LINE 0x0501
+#define USB_AUDIO_TERMINAL_TELEPHONE 0x0502
+#define USB_AUDIO_TERMINAL_DOWN_LINE_PHONE 0x0503
+#define USB_AUDIO_TERMINAL_EXTERNAL_UNDEFINED 0x0600
+#define USB_AUDIO_TERMINAL_ANALOG_CONNECTOR 0x0601
+#define USB_AUDIO_TERMINAL_DIGITAL_AUDIO_INTERFACE 0x0602
+#define USB_AUDIO_TERMINAL_LINE_CONNECTOR 0x0603
+#define USB_AUDIO_TERMINAL_LEGACY_AUDIO_CONNECTOR 0x0604
+#define USB_AUDIO_TERMINAL_SPDIF_INTERFACE 0x0605
+#define USB_AUDIO_TERMINAL_1394_DA_STREAM 0x0606
+#define USB_AUDIO_TERMINAL_1394_DV_STREAM_SOUNDTRACK 0x0607
+#define USB_AUDIO_TERMINAL_EMBEDDED_UNDEFINED 0x0700
+#define USB_AUDIO_TERMINAL_LEVEL_CALIBRATION_NOISE_SOURCE 0x0701
+#define USB_AUDIO_TERMINAL_EQUALIZATION_NOISE 0x0702
+#define USB_AUDIO_TERMINAL_CD_PLAYER 0x0703
+#define USB_AUDIO_TERMINAL_DAT 0x0704
+#define USB_AUDIO_TERMINAL_DCC 0x0705
+#define USB_AUDIO_TERMINAL_MINI_DISK 0x0706
+#define USB_AUDIO_TERMINAL_ANALOG_TAPE 0x0707
+#define USB_AUDIO_TERMINAL_PHONOGRAPH 0x0708
+#define USB_AUDIO_TERMINAL_VCR_AUDIO 0x0709
+#define USB_AUDIO_TERMINAL_VIDEO_DISK_AUDIO 0x070A
+#define USB_AUDIO_TERMINAL_DVD_AUDIO 0x070B
+#define USB_AUDIO_TERMINAL_TV_TUNER_AUDIO 0x070C
+#define USB_AUDIO_TERMINAL_SATELLITE_RECEIVER_AUDIO 0x070D
+#define USB_AUDIO_TERMINAL_CABLE_TUNER_AUDIO 0x070E
+#define USB_AUDIO_TERMINAL_DSS_AUDIO 0x070F
+#define USB_AUDIO_TERMINAL_RADIO_RECEIVER 0x0710
+#define USB_AUDIO_TERMINAL_RADIO_TRANSMITTER 0x0711
+#define USB_AUDIO_TERMINAL_MULTI_TRACK_RECORDER 0x0712
+#define USB_AUDIO_TERMINAL_SYNTHESIZER 0x0713
+
+////////////////////////////////////////////////////
+//
+// Audio streaming interface constants
+//
+////////////////////////////////////////////////////
+
+// Audio stream class-specific AS interface descriptor subtypes
+#define USB_AUDIO_AS_GENERAL 0x01
+#define USB_AUDIO_AS_FORMAT_TYPE 0x02
+#define USB_AUDIO_AS_FORMAT_SPECIFIC 0x03
+
+// wFormatTag values present in the class specific AS header
+// Defined in Section A.1 of USB Device Class Definition for Audio Data Formats
+#define USB_AUDIO_AS_FT_TYPE_I_UNDEFINED 0x0000
+#define USB_AUDIO_AS_FT_PCM 0x0001
+#define USB_AUDIO_AS_FT_PCM8 0x0002
+#define USB_AUDIO_AS_FT_IEEE_FLOAT 0x0003
+#define USB_AUDIO_AS_FT_ALAW 0x0004
+#define USB_AUDIO_AS_FT_MULAW 0x0005
+#define USB_AUDIO_AS_FT_TYPE_II_UNDEFINED 0x1000
+#define USB_AUDIO_AS_FT_MPEG 0x1001
+#define USB_AUDIO_AS_FT_AC3 0x1002
+#define USB_AUDIO_AS_FT_TYPE_III_UNDEFINED 0x2000
+#define USB_AUDIO_AS_FT_IEC1937_AC3 0x2001
+#define USB_AUDIO_AS_FT_IEC1937_MPEG1_L1 0x2002
+#define USB_AUDIO_AS_FT_IEC1937_MPEG1_L23 0x2003
+#define USB_AUDIO_AS_FT_IEC1937_MPEG2_EXT 0x2004
+#define USB_AUDIO_AS_FT_IEC1937_MPEG2_L1_LS 0x2005
+#define USB_AUDIO_AS_FT_IEC1937_MPEG2_L23_LS 0x2006
+
+// Audio stream class-specific format-specific types
+#define USB_AUDIO_FORMAT_TYPE_UNDEFINED 0x00
+#define USB_AUDIO_FORMAT_TYPE_I 0x01
+#define USB_AUDIO_FORMAT_TYPE_II 0x02
+#define USB_AUDIO_FORMAT_TYPE_III 0x03
+
+////////////////////////////////////////////////////
+//
+// MIDI streaming interface constants
+//
+////////////////////////////////////////////////////
+
+// MIDI class specific MS interface descriptor subtypes
+#define USB_MIDI_MS_HEADER 0x01
+#define USB_MIDI_IN_JACK 0x02
+#define USB_MIDI_OUT_JACK 0x03
+#define USB_MIDI_ELEMENT 0x04
+
+// MIDI class specific MS endpoint descriptor subtypes
+#define USB_MIDI_MS_GENERAL 0x01
+
+// MIDI IN and OUT jack types
+#define USB_MIDI_JACK_EMBEDDED 0x01
+#define USB_MIDI_JACK_INTERNAL 0x02
+
+// MIDI endpoint control selectors
+#define USB_MIDI_ASSOCIATION_CONTROL 0x01
+
+
+// Top level header structure shared by all USB audio descriptors.
+//
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype;
+} __PACKED usb_audio_desc_header;
+
+// Audio Control Interface descriptor definitions
+//
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_AUDIO_AC_HEADER
+ uint16_t bcdADC;
+ uint16_t wTotalLength;
+ uint8_t bInCollection;
+ uint8_t baInterfaceNr[];
+} __PACKED usb_audio_ac_header_desc;
+
+// Common header structure shared by all unit and terminal descriptors found in
+// an Audio Control interface descriptor.
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_AUDIO_AC_.*_(TERMINAL|UNIT)
+ uint8_t bID;
+} __PACKED usb_audio_ac_ut_desc;
+
+// Common header structure shared by all terminal descriptors found in an Audio
+// Control interface descriptor.
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_AUDIO_AC_(INPUT|OUTPUT)_TERMINAL
+ uint8_t bTerminalID;
+ uint16_t wTerminalType;
+ uint8_t bAssocTerminal;
+} __PACKED usb_audio_ac_terminal_desc;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_AUDIO_AC_INPUT_TERMINAL
+ uint8_t bTerminalID;
+ uint16_t wTerminalType;
+ uint8_t bAssocTerminal;
+ uint8_t bNrChannels;
+ uint16_t wChannelConfig;
+ uint8_t iChannelNames;
+ uint8_t iTerminal;
+} __PACKED usb_audio_ac_input_terminal_desc;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_AUDIO_AC_OUTPUT_TERMINAL
+ uint8_t bTerminalID;
+ uint16_t wTerminalType;
+ uint8_t bAssocTerminal;
+ uint8_t bSourceID;
+ uint8_t iTerminal;
+} __PACKED usb_audio_ac_output_terminal_desc;
+
+// Note: Mixer unit descriptors contain two inlined variable length arrays, each
+// with descriptor data following them. They are therefor described using 3
+// structure definitions which are logically concatenated, but separated by the
+// inline arrays.
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_AUDIO_AC_MIXER_UNIT
+ uint8_t bUnitID;
+ uint8_t bNrInPins;
+ uint8_t baSourceID[];
+} __PACKED usb_audio_ac_mixer_unit_desc_0;
+
+typedef struct {
+ uint8_t bNrChannels;
+ uint16_t wChannelConfig;
+ uint8_t iChannelNames;
+ uint8_t bmControls[];
+} __PACKED usb_audio_ac_mixer_unit_desc_1;
+
+typedef struct {
+ uint8_t iMixer;
+} __PACKED usb_audio_ac_mixer_unit_desc_2;
+
+// Note: Selector unit descriptors contain an inlined variable length array with
+// descriptor data following it. They are therefor described using 2 structure
+// definitions which are logically concatenated, but separated by the inline
+// array.
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_AUDIO_AC_SELECTOR_UNIT
+ uint8_t bUnitID;
+ uint8_t bNrInPins;
+ uint8_t baSourceID[];
+} __PACKED usb_audio_ac_selector_unit_desc_0;
+
+typedef struct {
+ uint8_t iSelector;
+} __PACKED usb_audio_ac_selector_unit_desc_1;
+
+// Note: Feature unit descriptors contain an inlined variable length array with
+// descriptor data following it. They are therefor described using 2 structure
+// definitions which are logically concatenated, but separated by the inline
+// array.
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_AUDIO_AC_FEATURE_UNIT
+ uint8_t bUnitID;
+ uint8_t bSourceID;
+ uint8_t bControlSize;
+ uint8_t bmaControls[];
+} __PACKED usb_audio_ac_feature_unit_desc_0;
+
+typedef struct {
+ uint8_t iFeature;
+} __PACKED usb_audio_ac_feature_unit_desc_1;
+
+// Note: Processing unit descriptors contain two inlined variable length arrays,
+// each with descriptor data following them. They are therefor described using
+// 3 structure definitions which are logically concatenated, but separated by
+// the inline arrays.
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_AUDIO_AC_PROCESSING_UNIT
+ uint8_t bUnitID;
+ uint16_t wProcessType;
+ uint8_t bNrInPins;
+ uint8_t baSourceID[];
+} __PACKED usb_audio_ac_processing_unit_desc_0;
+
+typedef struct {
+ uint8_t bNrChannels;
+ uint16_t wChannelConfig;
+ uint8_t iChannelNames;
+ uint8_t bControlSize;
+ uint8_t bmControls[];
+} __PACKED usb_audio_ac_processing_unit_desc_1;
+
+typedef struct {
+ uint8_t iProcessing;
+ // Note: The Process-specific control structure follows this with the
+ // structure type determined by wProcessType
+ // TODO(johngro) : Define the process specific control structures. As of
+ // the 1.0 revision of the USB audio spec, the types to be defined are...
+ //
+ // ** Up/Down-mix
+ // ** Dolby Prologic
+ // ** 3D-Stereo Extender
+ // ** Reverberation
+ // ** Chorus
+ // ** Dynamic Range Compressor
+} __PACKED usb_audio_ac_processing_unit_desc_2;
+
+// Note: Extension unit descriptors contain two inlined variable length arrays,
+// each with descriptor data following them. They are therefor described using
+// 3 structure definitions which are logically concatenated, but separated by
+// the inline arrays.
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_AUDIO_AC_EXTENSION_UNIT
+ uint8_t bUnitID;
+ uint16_t wExtensionCode;
+ uint8_t bNrInPins;
+ uint8_t baSourceID[];
+} __PACKED usb_audio_ac_extension_unit_desc_0;
+
+typedef struct {
+ uint8_t bNrChannels;
+ uint16_t wChannelConfig;
+ uint8_t iChannelNames;
+ uint8_t bControlSize;
+ uint8_t bmControls[];
+} __PACKED usb_audio_ac_extension_unit_desc_1;
+
+typedef struct {
+ uint8_t iExtension;
+} __PACKED usb_audio_ac_extension_unit_desc_2;
+
+// Audio Streaming Interface descriptor definitions
+//
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_AUDIO_AS_GENERAL
+ uint8_t bTerminalLink;
+ uint8_t bDelay;
+ uint16_t wFormatTag;
+} __PACKED usb_audio_as_header_desc;
+
+typedef struct {
+ uint8_t freq[3]; // 24 bit unsigned integer, little-endian
+} __PACKED usb_audio_as_samp_freq;
+
+// Common header used by all format type descriptors
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_AUDIO_AS_FORMAT_TYPE
+ uint8_t bFormatType;
+} __PACKED usb_audio_as_format_type_hdr;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_AUDIO_AS_FORMAT_TYPE
+ uint8_t bFormatType; // USB_AUDIO_FORMAT_TYPE_I
+ uint8_t bNrChannels;
+ uint8_t bSubFrameSize;
+ uint8_t bBitResolution;
+ uint8_t bSamFreqType; // number of sampling frequencies
+ usb_audio_as_samp_freq tSamFreq[]; // list of sampling frequencies (3 bytes each)
+} __PACKED usb_audio_as_format_type_i_desc;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_ENDPOINT
+ uint8_t bDescriptorSubtype; // USB_AUDIO_EP_GENERAL
+ uint8_t bmAttributes;
+ uint8_t bLockDelayUnits;
+ uint16_t wLockDelay;
+} __PACKED usb_audio_as_isoch_ep_desc;
+
+// MIDI Streaming Interface descriptor definitions
+//
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_MIDI_MS_HEADER
+ uint16_t bcdMSC;
+ uint16_t wTotalLength;
+} __PACKED usb_midi_ms_header_desc;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_MIDI_IN_JACK
+ uint8_t bJackType;
+ uint8_t bJackID;
+ uint8_t iJack;
+} __PACKED usb_midi_ms_in_jack_desc;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_MIDI_OUT_JACK
+ uint8_t bJackType;
+ uint8_t bJackID;
+ uint8_t bNrInputPins;
+ uint8_t baSourceID;
+ uint8_t baSourcePin;
+} __PACKED usb_midi_ms_out_jack_desc;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_AUDIO_CS_ENDPOINT
+ uint8_t bDescriptorSubtype; // USB_MIDI_MS_GENERAL
+ uint8_t bNumEmbMIDIJack;
+ uint8_t baAssocJackID[];
+} __PACKED usb_midi_ms_endpoint_desc;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_HW_USB_AUDIO_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/usb/cdc.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/usb/cdc.h
new file mode 100644
index 0000000..67ac8c7
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/usb/cdc.h
@@ -0,0 +1,150 @@
+// Copyright 2017 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.
+
+#ifndef SYSROOT_ZIRCON_HW_USB_CDC_H_
+#define SYSROOT_ZIRCON_HW_USB_CDC_H_
+
+#include <stdint.h>
+
+// clang-format off
+
+#include <zircon/compiler.h>
+
+/* CDC Subclasses for the Communications Interface Class */
+#define USB_CDC_SUBCLASS_DIRECT_LINE 0x01
+#define USB_CDC_SUBCLASS_ABSTRACT 0x02
+#define USB_CDC_SUBCLASS_TELEPHONE 0x03
+#define USB_CDC_SUBCLASS_MULTI_CHANNEL 0x04
+#define USB_CDC_SUBCLASS_CAPI 0x05
+#define USB_CDC_SUBCLASS_ETHERNET 0x06
+#define USB_CDC_SUBCLASS_ATM 0x07
+#define USB_CDC_SUBCLASS_WIRELESS_HANDSET 0x08
+#define USB_CDC_SUBCLASS_DEVICE_MGMT 0x09
+#define USB_CDC_SUBCLASS_MOBILE_DIRECT 0x0A
+#define USB_CDC_SUBCLASS_OBEX 0x0B
+#define USB_CDC_SUBCLASS_ETHERNET_EMU 0x0C
+#define USB_CDC_SUBCLASS_NETWORK_CTRL 0x0D
+
+/* CDC Descriptor SubTypes */
+#define USB_CDC_DST_HEADER 0x00
+#define USB_CDC_DST_CALL_MGMT 0x01
+#define USB_CDC_DST_ABSTRACT_CTRL_MGMT 0x02
+#define USB_CDC_DST_DIRECT_LINE_MGMT 0x03
+#define USB_CDC_DST_TELEPHONE_RINGER 0x04
+#define USB_CDC_DST_TELEPHONE_CALL_REPORTING 0x05
+#define USB_CDC_DST_UNION 0x06
+#define USB_CDC_DST_COUNTRY_SELECTION 0x07
+#define USB_CDC_DST_TELEPHONE_OP_MODES 0x08
+#define USB_CDC_DST_USB_TERMINAL 0x09
+#define USB_CDC_DST_NETWORK_CHANNEL 0x0A
+#define USB_CDC_DST_PROTOCOL_UNIT 0x0B
+#define USB_CDC_DST_EXTENSION_UNIT 0x0C
+#define USB_CDC_DST_MULTI_CHANNEL_MGMT 0x0D
+#define USB_CDC_DST_CAPI_CTRL_MGMT 0x0E
+#define USB_CDC_DST_ETHERNET 0x0F
+#define USB_CDC_DST_ATM_NETWORKING 0x10
+#define USB_CDC_DST_WIRELESS_HANDSET_CTRL 0x11
+#define USB_CDC_DST_MOBILE_DIRECT_LINE 0x12
+#define USB_CDC_DST_MDLM_DETAIL 0x13
+#define USB_CDC_DST_DEVICE_MGMT 0x14
+#define USB_CDC_DST_OBEX 0x15
+#define USB_CDC_DST_COMMAND_SET 0x16
+#define USB_CDC_DST_COMMAND_SET_DETAIL 0x17
+#define USB_CDC_DST_TELEPHONE_CTRL 0x18
+#define USB_CDC_DST_OBEX_SERVICE_ID 0x19
+#define USB_CDC_DST_NCM 0x1A
+
+/* CDC Class-Specific Notification Codes */
+#define USB_CDC_NC_NETWORK_CONNECTION 0x00
+#define USB_CDC_NC_RESPONSE_AVAILABLE 0x01
+#define USB_CDC_NC_SERIAL_STATE 0x20
+#define USB_CDC_NC_CONNECTION_SPEED_CHANGE 0x2A
+
+/* CDC Ethernet Class-Specific Request Codes */
+#define USB_CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40
+#define USB_CDC_SET_ETHERNET_PM_PATTERN_FILTER 0x41
+#define USB_CDC_GET_ETHERNET_PM_PATTERN_FILTER 0x42
+#define USB_CDC_SET_ETHERNET_PACKET_FILTER 0x43
+#define USB_CDC_GET_ETHERNET_STATISTIC 0x44
+
+/* CDC Ethernet Packet Filter Modes Bits */
+#define USB_CDC_PACKET_TYPE_PROMISCUOUS (1 << 0)
+#define USB_CDC_PACKET_TYPE_ALL_MULTICAST (1 << 1)
+#define USB_CDC_PACKET_TYPE_DIRECTED (1 << 2)
+#define USB_CDC_PACKET_TYPE_BROADCAST (1 << 3)
+#define USB_CDC_PACKET_TYPE_MULTICAST (1 << 4)
+
+/* CDC Class-Specific Requests */
+#define USB_CDC_SEND_ENCAPSULATED_COMMAND 0x00
+#define USB_CDC_GET_ENCAPSULATED_RESPONSE 0x01
+
+__BEGIN_CDECLS
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_CS_INTERFACE
+ uint8_t bDescriptorSubType; // USB_CDC_DST_HEADER
+ uint16_t bcdCDC;
+} __attribute__ ((packed)) usb_cs_header_interface_descriptor_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_CS_INTERFACE
+ uint8_t bDescriptorSubType; // USB_CDC_DST_CALL_MGMT
+ uint8_t bmCapabilities;
+ uint8_t bDataInterface;
+} __attribute__ ((packed)) usb_cs_call_mgmt_interface_descriptor_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_CS_INTERFACE
+ uint8_t bDescriptorSubType; // USB_CDC_DST_ABSTRACT_CTRL_MGMT
+ uint8_t bmCapabilities;
+} __attribute__ ((packed)) usb_cs_abstract_ctrl_mgmt_interface_descriptor_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_CS_INTERFACE
+ uint8_t bDescriptorSubType; // USB_CDC_DST_UNION
+ uint8_t bControlInterface;
+ uint8_t bSubordinateInterface[];
+} __attribute__ ((packed)) usb_cs_union_interface_descriptor_t;
+
+// fixed size version of usb_cs_union_interface_descriptor_t
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_CS_INTERFACE
+ uint8_t bDescriptorSubType; // USB_CDC_DST_UNION
+ uint8_t bControlInterface;
+ uint8_t bSubordinateInterface;
+} __attribute__ ((packed)) usb_cs_union_interface_descriptor_1_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DT_CS_INTERFACE
+ uint8_t bDescriptorSubType; // USB_CDC_DST_ETHERNET
+ uint8_t iMACAddress;
+ uint32_t bmEthernetStatistics;
+ uint16_t wMaxSegmentSize;
+ uint16_t wNumberMCFilters;
+ uint8_t bNumberPowerFilters;
+} __attribute__ ((packed)) usb_cs_ethernet_interface_descriptor_t;
+
+typedef struct {
+ uint8_t bmRequestType;
+ uint8_t bNotification;
+ uint16_t wValue;
+ uint16_t wIndex;
+ uint16_t wLength;
+} __attribute__ ((packed)) usb_cdc_notification_t;
+
+typedef struct {
+ usb_cdc_notification_t notification;
+ uint32_t downlink_br;
+ uint32_t uplink_br;
+ } __attribute__ ((packed)) usb_cdc_speed_change_notification_t;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_HW_USB_CDC_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/usb/dfu.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/usb/dfu.h
new file mode 100644
index 0000000..7ca40f0
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/usb/dfu.h
@@ -0,0 +1,82 @@
+// Copyright 2018 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.
+
+#ifndef SYSROOT_ZIRCON_HW_USB_DFU_H_
+#define SYSROOT_ZIRCON_HW_USB_DFU_H_
+
+// clang-format off
+
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// USB DFU Spec, Rev 1.1
+
+// DFU Class-Specific Request Values
+// Table 3.2
+#define USB_DFU_DETACH 0x00
+#define USB_DFU_DNLOAD 0x01
+#define USB_DFU_UPLOAD 0x02
+#define USB_DFU_GET_STATUS 0x03
+#define USB_DFU_CLR_STATUS 0x04
+#define USB_DFU_GET_STATE 0x05
+#define USB_DFU_ABORT 0x06
+
+// DFU Class-Specific Descriptor Types
+// Table 4.1.3
+#define USB_DFU_CS_FUNCTIONAL 0x21
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_DFU_CS_FUNCTIONAL
+ uint8_t bmAttributes;
+ uint16_t wDetachTimeOut;
+ uint16_t wTransferSize;
+ uint16_t bcdDFUVersion;
+} __PACKED usb_dfu_func_desc_t;
+
+// DFU_GET_STATUS Response
+// Section 6.1.2
+typedef struct {
+ uint8_t bStatus;
+ uint8_t bwPollTimeout[3]; // 24 bit unsigned integer
+ uint8_t bState;
+ uint8_t bString;
+} __PACKED usb_dfu_get_status_data_t;
+
+// DFU Device Status Values
+#define USB_DFU_STATUS_OK 0x00
+#define USB_DFU_STATUS_ERR_TARGET 0x01
+#define USB_DFU_STATUS_ERR_FILE 0x02
+#define USB_DFU_STATUS_ERR_WRITE 0x03
+#define USB_DFU_STATUS_ERR_ERASE 0x04
+#define USB_DFU_STATUS_ERR_CHECK_ERASED 0x05
+#define USB_DFU_STATUS_ERR_PROG 0x06
+#define USB_DFU_STATUS_ERR_VERIFY 0x07
+#define USB_DFU_STATUS_ERR_ADDRESS 0x08
+#define USB_DFU_STATUS_ERR_NOT_DONE 0x09
+#define USB_DFU_STATUS_ERR_FIRMWARE 0x0A
+#define USB_DFU_STATUS_ERR_VENDOR 0x0B
+#define USB_DFU_STATUS_ERR_USER 0x0C
+#define USB_DFU_STATUS_ERR_POR 0x0D
+#define USB_DFU_STATUS_ERR_UNKNOWN 0x0E
+#define USB_DFU_STATUS_ERR_STALLED_PKT 0x0F
+
+// DFU Device State Values
+#define USB_DFU_STATE_APP_IDLE 0x00
+#define USB_DFU_STATE_APP_DETACH 0x01
+#define USB_DFU_STATE_DFU_IDLE 0x02
+#define USB_DFU_STATE_DFU_DNLOAD_SYNC 0x03
+#define USB_DFU_STATE_DFU_DNBUSY 0x04
+#define USB_DFU_STATE_DFU_DNLOAD_IDLE 0x05
+#define USB_DFU_STATE_DFU_MANIFEST_SYNC 0x06
+#define USB_DFU_STATE_DFU_MANIFEST 0x07
+#define USB_DFU_STATE_DFU_MANIFEST_WAIT_RESET 0x08
+#define USB_DFU_STATE_DFU_UPLOAD_IDLE 0x09
+#define USB_DFU_STATE_DFU_ERROR 0x0A
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_HW_USB_DFU_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/usb/hid.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/usb/hid.h
new file mode 100644
index 0000000..97dea4e
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/usb/hid.h
@@ -0,0 +1,46 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_HW_USB_HID_H_
+#define SYSROOT_ZIRCON_HW_USB_HID_H_
+
+#include <stdint.h>
+#include <zircon/compiler.h>
+
+__BEGIN_CDECLS
+
+// clang-format off
+
+// HID Request Values.
+#define USB_HID_GET_REPORT 0x01
+#define USB_HID_GET_IDLE 0x02
+#define USB_HID_GET_PROTOCOL 0x03
+#define USB_HID_SET_REPORT 0x09
+#define USB_HID_SET_IDLE 0x0A
+#define USB_HID_SET_PROTOCOL 0x0B
+
+// HID USB protocols
+#define USB_HID_PROTOCOL_KBD 0x01
+#define USB_HID_PROTOCOL_MOUSE 0x02
+#define USB_HID_SUBCLASS_BOOT 0x01
+
+// clang-format on
+
+typedef struct {
+ uint8_t bDescriptorType;
+ uint16_t wDescriptorLength;
+} __attribute__((packed)) usb_hid_descriptor_entry_t;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t bcdHID;
+ uint8_t bCountryCode;
+ uint8_t bNumDescriptors;
+ usb_hid_descriptor_entry_t descriptors[];
+} __attribute__((packed)) usb_hid_descriptor_t;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_HW_USB_HID_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/usb/hub.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/usb/hub.h
new file mode 100644
index 0000000..10ed110
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/usb/hub.h
@@ -0,0 +1,120 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_HW_USB_HUB_H_
+#define SYSROOT_ZIRCON_HW_USB_HUB_H_
+
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+// clang-format off
+
+__BEGIN_CDECLS
+
+// Hub request types
+#define USB_RECIP_HUB (USB_TYPE_CLASS | USB_RECIP_DEVICE)
+#define USB_RECIP_PORT (USB_TYPE_CLASS | USB_RECIP_OTHER)
+
+// Hub requests
+#define USB_HUB_SET_DEPTH 12
+
+// Hub descriptor types
+#define USB_HUB_DESC_TYPE 0x29
+#define USB_HUB_DESC_TYPE_SS 0x2A // for superspeed hubs
+
+// Hub Class Feature Selectors (USB 2.0 spec Table 11.17)
+#define USB_FEATURE_C_HUB_LOCAL_POWER 0
+#define USB_FEATURE_C_HUB_OVER_CURRENT 1
+#define USB_FEATURE_PORT_CONNECTION 0
+#define USB_FEATURE_PORT_ENABLE 1
+#define USB_FEATURE_PORT_SUSPEND 2
+#define USB_FEATURE_PORT_OVER_CURRENT 3
+#define USB_FEATURE_PORT_RESET 4
+#define USB_FEATURE_PORT_LINK_STATE 5
+#define USB_FEATURE_PORT_POWER 8
+#define USB_FEATURE_PORT_LOW_SPEED 9
+#define USB_FEATURE_C_PORT_CONNECTION 16
+#define USB_FEATURE_C_PORT_ENABLE 17
+#define USB_FEATURE_C_PORT_SUSPEND 18
+#define USB_FEATURE_C_PORT_OVER_CURRENT 19
+#define USB_FEATURE_C_PORT_RESET 20
+#define USB_FEATURE_PORT_TEST 21
+#define USB_FEATURE_PORT_INDICATOR 22
+#define USB_FEATURE_PORT_INDICATOR 22
+#define USB_FEATURE_PORT_U1_TIMEOUT 23
+#define USB_FEATURE_PORT_U2_TIMEOUT 24
+#define USB_FEATURE_C_PORT_LINK_STATE 25
+#define USB_FEATURE_C_PORT_CONFIG_ERROR 26
+#define USB_FEATURE_PORT_REMOTE_WAKE_MASK 27
+#define USB_FEATURE_BH_PORT_RESET 28
+#define USB_FEATURE_C_BH_PORT_RESET 29
+#define USB_FEATURE_FORCE_LINKPM_ACCEPT 30
+
+typedef struct {
+ uint8_t bDescLength;
+ uint8_t bDescriptorType;
+ uint8_t bNbrPorts;
+ uint16_t wHubCharacteristics;
+ uint8_t bPowerOn2PwrGood;
+ uint8_t bHubContrCurrent;
+ union {
+ // USB 2.0
+ struct {
+ // variable length depending on number of ports
+ uint8_t DeviceRemovable[4];
+ uint8_t PortPwrCtrlMask[4];
+ } __attribute__ ((packed)) hs;
+ // USB 3.0
+ struct {
+ uint8_t bHubHdrDecLat;
+ uint16_t wHubDelay;
+ uint16_t DeviceRemovable;
+ } __attribute__ ((packed)) ss;
+ } __attribute__ ((packed));
+} __attribute__ ((packed)) usb_hub_descriptor_t;
+
+typedef struct {
+ uint16_t wHubStatus;
+ uint16_t wHubChange;
+} __attribute__ ((packed)) usb_hub_status_t;
+
+// wHubStatus bits
+#define USB_HUB_LOCAL_POWER (1 << 0)
+#define USB_HUB_OVER_CURRENT (1 << 1)
+
+typedef struct {
+ uint16_t wPortStatus;
+ uint16_t wPortChange;
+} __attribute__ ((packed)) usb_port_status_t;
+
+// Port Status bits
+#define USB_PORT_CONNECTION (1 << 0)
+#define USB_PORT_ENABLE (1 << 1)
+#define USB_PORT_SUSPEND (1 << 2) // USB 2.0 only
+#define USB_PORT_OVER_CURRENT (1 << 3)
+#define USB_PORT_RESET (1 << 4)
+#define USB_PORT_POWER (1 << 8) // USB 2.0 only
+#define USB_PORT_LOW_SPEED (1 << 9) // USB 2.0 only
+#define USB_PORT_HIGH_SPEED (1 << 10) // USB 2.0 only
+#define USB_PORT_TEST_MODE (1 << 11) // USB 2.0 only
+#define USB_PORT_INDICATOR_CONTROL (1 << 12) // USB 2.0 only
+
+// Port Status Changed bits
+#define USB_C_PORT_CONNECTION (1 << 0)
+#define USB_C_PORT_ENABLE (1 << 1) // USB 2.0 only
+#define USB_C_PORT_SUSPEND (1 << 2) // USB 2.0 only
+#define USB_C_PORT_OVER_CURRENT (1 << 3)
+#define USB_C_PORT_RESET (1 << 4)
+#define USB_C_BH_PORT_RESET (1 << 5) // USB 3.0 only
+#define USB_C_PORT_LINK_STATE (1 << 6) // USB 3.0 only
+#define USB_C_PORT_CONFIG_ERROR (1 << 7) // USB 3.0 only
+#define USB_C_PORT_POWER (1 << 8) // USB 2.0 only
+#define USB_C_PORT_LOW_SPEED (1 << 9) // USB 2.0 only
+#define USB_C_PORT_HIGH_SPEED (1 << 10) // USB 2.0 only
+#define USB_C_PORT_TEST_MODE (1 << 11) // USB 2.0 only
+#define USB_C_PORT_INDICATOR_CONTROL (1 << 12) // USB 2.0 only
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_HW_USB_HUB_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/usb/ums.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/usb/ums.h
new file mode 100644
index 0000000..6640803
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/usb/ums.h
@@ -0,0 +1,159 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_HW_USB_UMS_H_
+#define SYSROOT_ZIRCON_HW_USB_UMS_H_
+
+// clang-format off
+
+// SCSI commands
+#define UMS_TEST_UNIT_READY 0x00
+#define UMS_REQUEST_SENSE 0x03
+#define UMS_INQUIRY 0x12
+#define UMS_MODE_SELECT6 0x15
+#define UMS_MODE_SENSE6 0x1A
+#define UMS_START_STOP_UNIT 0x1B
+#define UMS_TOGGLE_REMOVABLE 0x1E
+#define UMS_READ_FORMAT_CAPACITIES 0x23
+#define UMS_READ_CAPACITY10 0x25
+#define UMS_READ10 0x28
+#define UMS_WRITE10 0x2A
+#define UMS_SYNCHRONIZE_CACHE 0x35
+#define UMS_MODE_SELECT10 0x55
+#define UMS_MODE_SENSE10 0x5A
+#define UMS_READ16 0x88
+#define UMS_WRITE16 0x8A
+#define UMS_READ_CAPACITY16 0x9E
+#define UMS_READ12 0xA8
+#define UMS_WRITE12 0xAA
+
+// control request values
+#define USB_REQ_RESET 0xFF
+#define USB_REQ_GET_MAX_LUN 0xFE
+
+// error codes for CSW processing
+typedef uint32_t csw_status_t;
+#define CSW_SUCCESS ((csw_status_t)0)
+#define CSW_FAILED ((csw_status_t)1)
+#define CSW_PHASE_ERROR ((csw_status_t)2)
+#define CSW_INVALID ((csw_status_t)3)
+#define CSW_TAG_MISMATCH ((csw_status_t)4)
+
+// signatures in header and status
+#define CBW_SIGNATURE 0x43425355
+#define CSW_SIGNATURE 0x53425355
+
+// transfer lengths
+#define UMS_INQUIRY_TRANSFER_LENGTH 0x24
+#define UMS_REQUEST_SENSE_TRANSFER_LENGTH 0x12
+#define UMS_READ_FORMAT_CAPACITIES_TRANSFER_LENGTH 0xFC
+
+// 6 Byte SCSI command
+// This is big endian
+typedef struct {
+ uint8_t opcode;
+ uint8_t misc;
+ uint16_t lba; // logical block address
+ uint8_t length;
+ uint8_t control;
+} __PACKED scsi_command6_t;
+static_assert(sizeof(scsi_command6_t) == 6, "");
+
+// 10 Byte SCSI command
+// This is big endian
+typedef struct {
+ uint8_t opcode;
+ uint8_t misc;
+ uint32_t lba; // logical block address
+ uint8_t misc2;
+ uint8_t length_hi; // break length into two pieces to avoid odd alignment
+ uint8_t length_lo;
+ uint8_t control;
+} __PACKED scsi_command10_t;
+static_assert(sizeof(scsi_command10_t) == 10, "");
+
+// 12 Byte SCSI command
+// This is big endian
+typedef struct {
+ uint8_t opcode;
+ uint8_t misc;
+ uint32_t lba; // logical block address
+ uint32_t length;
+ uint8_t misc2;
+ uint8_t control;
+} __PACKED scsi_command12_t;
+static_assert(sizeof(scsi_command12_t) == 12, "");
+
+// 16 Byte SCSI command
+// This is big endian
+typedef struct {
+ uint8_t opcode;
+ uint8_t misc;
+ uint64_t lba; // logical block address
+ uint32_t length;
+ uint8_t misc2;
+ uint8_t control;
+} __PACKED scsi_command16_t;
+static_assert(sizeof(scsi_command16_t) == 16, "");
+
+// SCSI Read Capacity 10 payload
+// This is big endian
+typedef struct {
+ uint32_t lba;
+ uint32_t block_length;
+} __PACKED scsi_read_capacity_10_t;
+static_assert(sizeof(scsi_read_capacity_10_t) == 8, "");
+
+// SCSI Read Capacity 16 payload
+// This is big endian
+typedef struct {
+ uint64_t lba;
+ uint32_t block_length;
+ uint8_t ptype_prot_en; // bit 0: PROT_EN, bits 1-3: P_TYPE
+ uint8_t resesrved[19];
+} __PACKED scsi_read_capacity_16_t;
+static_assert(sizeof(scsi_read_capacity_16_t) == 32, "");
+
+// SCSI Mode Sense 6 command
+typedef struct {
+ uint8_t opcode; // UMS_MODE_SENSE6
+ uint8_t disable_block_desc;
+ uint8_t page;
+ uint8_t subpage;
+ uint8_t allocation_length;
+ uint8_t control;
+} __PACKED scsi_mode_sense_6_command_t;
+static_assert(sizeof(scsi_mode_sense_6_command_t) == 6, "");
+
+// SCSI Mode Sense 6 data response
+typedef struct {
+ uint8_t mode_data_length;
+ uint8_t medium_type;
+ uint8_t device_specific_param;
+ uint8_t block_desc_length;
+} __PACKED scsi_mode_sense_6_data_t;
+#define MODE_SENSE_DSP_RO 0x80 // bit 7 of device_specific_param: read-only
+
+// Command Block Wrapper
+typedef struct {
+ uint32_t dCBWSignature; // CBW_SIGNATURE
+ uint32_t dCBWTag;
+ uint32_t dCBWDataTransferLength;
+ uint8_t bmCBWFlags;
+ uint8_t bCBWLUN;
+ uint8_t bCBWCBLength;
+ uint8_t CBWCB[16];
+} __PACKED ums_cbw_t;
+static_assert(sizeof(ums_cbw_t) == 31, "");
+
+// Command Status Wrapper
+typedef struct {
+ uint32_t dCSWSignature; // CSW_SIGNATURE
+ uint32_t dCSWTag;
+ uint32_t dCSWDataResidue;
+ uint8_t bmCSWStatus;
+} __PACKED ums_csw_t;
+static_assert(sizeof(ums_csw_t) == 13, "");
+
+#endif // SYSROOT_ZIRCON_HW_USB_UMS_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/usb/video.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/usb/video.h
new file mode 100644
index 0000000..925b5b6
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/hw/usb/video.h
@@ -0,0 +1,308 @@
+// Copyright 2017 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.
+
+#ifndef SYSROOT_ZIRCON_HW_USB_VIDEO_H_
+#define SYSROOT_ZIRCON_HW_USB_VIDEO_H_
+
+// clang-format off
+
+#include <zircon/compiler.h>
+#include <stdint.h>
+
+__BEGIN_CDECLS;
+
+// video interface subclasses
+#define USB_SUBCLASS_VIDEO_CONTROL 0x01
+#define USB_SUBCLASS_VIDEO_STREAMING 0x02
+#define USB_SUBCLASS_VIDEO_INTERFACE_COLLECTION 0x03
+
+// video class specific descriptor types
+#define USB_VIDEO_CS_DEVICE 0x21
+#define USB_VIDEO_CS_CONFIGURATION 0x22
+#define USB_VIDEO_CS_STRING 0x23
+#define USB_VIDEO_CS_INTERFACE 0x24
+#define USB_VIDEO_CS_ENDPOINT 0x25
+
+// video class specific VC interface descriptor subtypes
+#define USB_VIDEO_VC_HEADER 0x01
+#define USB_VIDEO_VC_INPUT_TERMINAL 0x02
+#define USB_VIDEO_VC_OUTPUT_TERMINAL 0x03
+#define USB_VIDEO_VC_SELECTOR_UNIT 0x04
+#define USB_VIDEO_VC_PROCESSING_UNIT 0x05
+#define USB_VIDEO_VC_EXTENSION_UNIT 0x06
+#define USB_VIDEO_VC_ENCODING_UNIT 0x07
+
+// video class specific VS interface descriptor subtypes
+#define USB_VIDEO_VS_INPUT_HEADER 0x01
+#define USB_VIDEO_VS_OUTPUT_HEADER 0x02
+#define USB_VIDEO_VS_STILL_IMAGE_FRAME 0x03
+#define USB_VIDEO_VS_FORMAT_UNCOMPRESSED 0x04
+#define USB_VIDEO_VS_FRAME_UNCOMPRESSED 0x05
+#define USB_VIDEO_VS_FORMAT_MJPEG 0x06
+#define USB_VIDEO_VS_FRAME_MJPEG 0x07
+#define USB_VIDEO_VS_FORMAT_MPEG2TS 0x0A
+#define USB_VIDEO_VS_FORMAT_DV 0x0C
+#define USB_VIDEO_VS_COLORFORMAT 0x0D
+#define USB_VIDEO_VS_FORMAT_FRAME_BASED 0x10
+#define USB_VIDEO_VS_FRAME_FRAME_BASED 0x11
+#define USB_VIDEO_VS_FORMAT_STREAM_BASED 0x12
+#define USB_VIDEO_VS_FORMAT_H264 0x13
+#define USB_VIDEO_VS_FRAME_H264 0x14
+#define USB_VIDEO_VS_FORMAT_H264_SIMULCAST 0x15
+#define USB_VIDEO_VS_FORMAT_VP8 0x16
+#define USB_VIDEO_VS_FRAME_VP8 0x17
+#define USB_VIDEO_VS_FORMAT_VP8_SIMULCAST 0x18
+
+// video class specific endpoint descriptor subtypes
+#define USB_VIDEO_EP_GENERAL 0x01
+#define USB_VIDEO_EP_ENDPOINT 0x02
+#define USB_VIDEO_EP_INTERRUPT 0x03
+
+// video class specific request codes
+#define USB_VIDEO_SET_CUR 0x01
+#define USB_VIDEO_SET_CUR_ALL 0x11
+#define USB_VIDEO_GET_CUR 0x81
+#define USB_VIDEO_GET_MIN 0x82
+#define USB_VIDEO_GET_MAX 0x83
+#define USB_VIDEO_GET_RES 0x84
+#define USB_VIDEO_GET_LEN 0x85
+#define USB_VIDEO_GET_INFO 0x86
+#define USB_VIDEO_GET_DEF 0x87
+#define USB_VIDEO_GET_CUR_ALL 0x91
+#define USB_VIDEO_GET_MIN_ALL 0x92
+#define USB_VIDEO_GET_MAX_ALL 0x93
+#define USB_VIDEO_GET_RES_ALL 0x94
+#define USB_VIDEO_GET_DEF_ALL 0x97
+
+// video streaming interface control selectors
+#define USB_VIDEO_VS_PROBE_CONTROL 0x01
+#define USB_VIDEO_VS_COMMIT_CONTROL 0x02
+#define USB_VIDEO_VS_STILL_PROBE_CONTROL 0x03
+#define USB_VIDEO_VS_STILL_COMMIT_CONTROL 0x04
+#define USB_VIDEO_VS_STILL_IMAGE_TRIGGER_CONTROL 0x05
+#define USB_VIDEO_VS_STREAM_ERROR_CODE_CONTROL 0x06
+#define USB_VIDEO_VS_GENERATE_KEY_FRAME_CONTROL 0x07
+#define USB_VIDEO_VS_UPDATE_FRAME_SEGMENT_CONTROL 0x08
+#define USB_VIDEO_VS_SYNCH_DELAY_CONTROL 0x09
+
+// header for usb_video_vc_* below
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_VIDEO_CS_INTERFACE
+ uint8_t bDescriptorSubtype;
+} __PACKED usb_video_vc_desc_header;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_VIDEO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_VIDEO_VC_HEADER
+ uint16_t bcdUVC;
+ uint16_t wTotalLength;
+ uint32_t dwClockFrequency;
+ uint8_t bInCollection;
+ uint8_t baInterfaceNr[];
+} __PACKED usb_video_vc_header_desc;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_VIDEO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_VIDEO_VC_INPUT_TERMINAL
+ uint8_t bTerminalID;
+ uint16_t wTerminalType;
+ uint8_t bAssocTerminal;
+ uint8_t iTerminal;
+} __PACKED usb_video_vc_input_terminal_desc;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_VIDEO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_VIDEO_VC_OUTPUT_TERMINAL
+ uint8_t bTerminalID;
+ uint16_t wTerminalType;
+ uint8_t bAssocTerminal;
+ uint8_t bSourceID;
+ uint8_t iTerminal;
+} __PACKED usb_video_vc_output_terminal_desc;
+
+// class specific VC interrupt endpoint descriptor
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_VIDEO_CS_ENDPOINT
+ uint8_t bDescriptorSubtype; // USB_ENDPOINT_INTERRUPT
+ uint16_t wMaxTransferSize;
+} __PACKED usb_video_vc_interrupt_endpoint_desc;
+
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_VIDEO_CS_INTERFACE
+ uint8_t bDescriptorSubtype; // USB_VIDEO_VS_HEADER
+ uint8_t bNumFormats;
+ uint16_t wTotalLength;
+ uint8_t bEndpointAddress;
+ uint8_t bmInfo;
+ uint8_t bTerminalLink;
+ uint8_t bStillCaptureMethod;
+ uint8_t bTriggerSupport;
+ uint8_t bTriggerUsage;
+ uint8_t bControlSize;
+ uint8_t bmaControls[];
+} __PACKED usb_video_vs_input_header_desc;
+
+#define GUID_LENGTH 16
+
+// A GUID consists of a:
+// - four-byte integer
+// - two-byte integer
+// - two-byte integer
+// - eight-byte array
+//
+// The string representation uses big endian format, so to convert it
+// to a byte array we need to reverse the byte order of the three integers.
+//
+// See USB Video Class revision 1.5, FAQ section 2.9
+// for GUID Data Structure Layout.
+
+#define USB_VIDEO_GUID_YUY2_STRING "32595559-0000-0010-8000-00AA00389B71"
+#define USB_VIDEO_GUID_YUY2_VALUE { \
+ 0x59, 0x55, 0x59, 0x32, \
+ 0x00, 0x00, \
+ 0x10, 0x00, \
+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 \
+}
+
+#define USB_VIDEO_GUID_NV12_STRING "3231564E-0000-0010-8000-00AA00389B71"
+#define USB_VIDEO_GUID_NV12_VALUE { \
+ 0x4e, 0x56, 0x31, 0x32, \
+ 0x00, 0x00, \
+ 0x10, 0x00, \
+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 \
+}
+
+#define USB_VIDEO_GUID_M420_STRING "3032344D-0000-0010-8000-00AA00389B71"
+#define USB_VIDEO_GUID_M420_VALUE { \
+ 0x4d, 0x34, 0x32, 0x30, \
+ 0x00, 0x00, \
+ 0x10, 0x00, \
+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 \
+}
+
+#define USB_VIDEO_GUID_I420_STRING "30323449-0000-0010-8000-00AA00389B71"
+#define USB_VIDEO_GUID_I420_VALUE { \
+ 0x49, 0x34, 0x32, 0x30, \
+ 0x00, 0x00, \
+ 0x10, 0x00, \
+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 \
+}
+
+// USB Video Payload Uncompressed
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_VIDEO_CS_INTERFACE
+ uint8_t bDescriptorSubType; // USB_VIDEO_VS_FORMAT_UNCOMPRESSED
+ uint8_t bFormatIndex;
+ uint8_t bNumFrameDescriptors;
+ uint8_t guidFormat[GUID_LENGTH];
+ uint8_t bBitsPerPixel;
+ uint8_t bDefaultFrameIndex;
+ uint8_t bAspectRatioX;
+ uint8_t bAspectRatioY;
+ uint8_t bmInterfaceFlags;
+ uint8_t bCopyProtect;
+} __PACKED usb_video_vs_uncompressed_format_desc;
+
+// USB Video Payload MJPEG
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_VIDEO_CS_INTERFACE
+ uint8_t bDescriptorSubType; // USB_VIDEO_VS_FORMAT_MJPEG
+ uint8_t bFormatIndex;
+ uint8_t bNumFrameDescriptors;
+ uint8_t bmFlags;
+ uint8_t bDefaultFrameIndex;
+ uint8_t bAspectRatioX;
+ uint8_t bAspectRatioY;
+ uint8_t bmInterfaceFlags;
+ uint8_t bCopyProtect;
+} __PACKED usb_video_vs_mjpeg_format_desc;
+
+// Uncompressed and MJPEG formats have the same frame descriptor structure.
+typedef struct {
+ uint8_t bLength;
+ uint8_t bDescriptorType; // USB_VIDEO_CS_INTERFACE
+ uint8_t bDescriptorSubType; // USB_VIDEO_VS_FRAME_UNCOMPRESSED / USB_VIDEO_VS_FRAME_MJPEG
+ uint8_t bFrameIndex;
+ uint8_t bmCapabilities;
+ uint16_t wWidth;
+ uint16_t wHeight;
+ uint32_t dwMinBitRate;
+ uint32_t dwMaxBitRate;
+ uint32_t dwMaxVideoFrameBufferSize;
+ uint32_t dwDefaultFrameInterval;
+ uint8_t bFrameIntervalType;
+ uint32_t dwFrameInterval[];
+} __PACKED usb_video_vs_frame_desc;
+
+// Stream negotiation
+#define USB_VIDEO_BM_HINT_FRAME_INTERVAL (1 << 0)
+#define USB_VIDEO_BM_HINT_KEY_FRAME_RATE (1 << 1)
+#define USB_VIDEO_BM_HINT_P_FRAME_RATE (1 << 2)
+#define USB_VIDEO_BM_HINT_COMP_QUALITY (1 << 3)
+#define USB_VIDEO_BM_HINT_COMP_WINDOW_SIZE (1 << 4)
+
+typedef struct {
+ uint16_t bmHint;
+ uint8_t bFormatIndex;
+ uint8_t bFrameIndex;
+ uint32_t dwFrameInterval;
+ uint16_t wKeyFrameRate;
+ uint16_t wPFrameRate;
+ uint16_t wCompQuality;
+ uint16_t wCompWindowSize;
+ uint16_t wDelay;
+ uint32_t dwMaxVideoFrameSize;
+ uint32_t dwMaxPayloadTransferSize;
+ // The following fields are optional.
+ uint32_t dwClockFrequency;
+ uint8_t bmFramingInfo;
+ uint8_t bPreferedVersion;
+ uint8_t bMinVersion;
+ uint8_t bMaxVersion;
+ uint8_t bUsage;
+ uint8_t bBitDepthLuma;
+ uint8_t bmSettings;
+ uint8_t bMaxNumberOfRefFramesPlus1;
+ uint16_t bmRateControlModes;
+ uint32_t bmLayoutPerStream;
+} __PACKED usb_video_vc_probe_and_commit_controls;
+
+// For accessing payload bmHeaderInfo bitmap
+#define USB_VIDEO_VS_PAYLOAD_HEADER_FID (1 << 0)
+#define USB_VIDEO_VS_PAYLOAD_HEADER_EOF (1 << 1)
+#define USB_VIDEO_VS_PAYLOAD_HEADER_PTS (1 << 2)
+#define USB_VIDEO_VS_PAYLOAD_HEADER_SCR (1 << 3)
+#define USB_VIDEO_VS_PAYLOAD_HEADER_RES (1 << 4)
+#define USB_VIDEO_VS_PAYLOAD_HEADER_STI (1 << 5)
+#define USB_VIDEO_VS_PAYLOAD_HEADER_ERR (1 << 6)
+#define USB_VIDEO_VS_PAYLOAD_HEADER_EOH (1 << 7)
+
+// Common header for all payloads.
+typedef struct {
+ uint8_t bHeaderLength;
+ uint8_t bmHeaderInfo;
+
+} __PACKED usb_video_vs_payload_header;
+
+typedef struct {
+ uint8_t bHeaderLength;
+ uint8_t bmHeaderInfo;
+ uint32_t dwPresentationTime;
+ uint32_t scrSourceTimeClock;
+ // Frame number when the source clock was sampled.
+ uint16_t scrSourceClockSOFCounter;
+} __PACKED usb_video_vs_uncompressed_payload_header;
+
+__END_CDECLS;
+
+
+#endif // SYSROOT_ZIRCON_HW_USB_VIDEO_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/limits.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/limits.h
new file mode 100644
index 0000000..f062d5e
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/limits.h
@@ -0,0 +1,14 @@
+// Copyright 2018 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.
+
+#ifndef SYSROOT_ZIRCON_LIMITS_H_
+#define SYSROOT_ZIRCON_LIMITS_H_
+
+#include <stdint.h>
+
+#define ZX_PAGE_SHIFT ((uint32_t)12u)
+#define ZX_PAGE_SIZE ((uintptr_t)(1u << ZX_PAGE_SHIFT))
+#define ZX_PAGE_MASK (ZX_PAGE_SIZE - 1u)
+
+#endif // SYSROOT_ZIRCON_LIMITS_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/listnode.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/listnode.h
new file mode 100644
index 0000000..fb64acf
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/listnode.h
@@ -0,0 +1,300 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_LISTNODE_H_
+#define SYSROOT_ZIRCON_LISTNODE_H_
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <zircon/compiler.h>
+
+__BEGIN_CDECLS
+
+#define containerof(ptr, type, member) ((type*)((uintptr_t)(ptr)-offsetof(type, member)))
+
+typedef struct list_node list_node_t;
+
+struct list_node {
+ list_node_t* prev;
+ list_node_t* next;
+};
+
+#define LIST_INITIAL_VALUE(list) \
+ { &(list), &(list) }
+#define LIST_INITIAL_CLEARED_VALUE \
+ { NULL, NULL }
+
+static inline void list_initialize(list_node_t* list) { list->prev = list->next = list; }
+
+static inline void list_clear_node(list_node_t* item) { item->prev = item->next = 0; }
+
+static inline bool list_in_list(const list_node_t* item) {
+ if (item->prev == 0 && item->next == 0)
+ return false;
+ else
+ return true;
+}
+
+static inline void list_add_head(list_node_t* list, list_node_t* item) {
+ item->next = list->next;
+ item->prev = list;
+ list->next->prev = item;
+ list->next = item;
+}
+
+#define list_add_after(entry, new_entry) list_add_head(entry, new_entry)
+
+static inline void list_add_tail(list_node_t* list, list_node_t* item) {
+ item->prev = list->prev;
+ item->next = list;
+ list->prev->next = item;
+ list->prev = item;
+}
+
+#define list_add_before(entry, new_entry) list_add_tail(entry, new_entry)
+
+static inline void list_delete(list_node_t* item) {
+ item->next->prev = item->prev;
+ item->prev->next = item->next;
+ item->prev = item->next = 0;
+}
+
+static inline void list_replace_node(list_node_t* old_node, list_node_t* new_node) {
+ // replace a spot in a list with a new node
+ // assumes old_node is part of a list and new_node is not
+ new_node->next = old_node->next;
+ new_node->prev = old_node->prev;
+ old_node->prev = old_node->next = 0;
+
+ new_node->next->prev = new_node;
+ new_node->prev->next = new_node;
+}
+
+static inline list_node_t* list_remove_head(list_node_t* list) {
+ if (list->next != list) {
+ list_node_t* item = list->next;
+ list_delete(item);
+ return item;
+ } else {
+ return NULL;
+ }
+}
+
+#define list_remove_head_type(list, type, element) \
+ ({ \
+ list_node_t* __nod = list_remove_head(list); \
+ type* __t; \
+ if (__nod) \
+ __t = containerof(__nod, type, element); \
+ else \
+ __t = (type*)0; \
+ __t; \
+ })
+
+static inline list_node_t* list_remove_tail(list_node_t* list) {
+ if (list->prev != list) {
+ list_node_t* item = list->prev;
+ list_delete(item);
+ return item;
+ } else {
+ return NULL;
+ }
+}
+
+#define list_remove_tail_type(list, type, element) \
+ ({ \
+ list_node_t* __nod = list_remove_tail(list); \
+ type* __t; \
+ if (__nod) \
+ __t = containerof(__nod, type, element); \
+ else \
+ __t = (type*)0; \
+ __t; \
+ })
+
+static inline list_node_t* list_peek_head(const list_node_t* list) {
+ if (list->next != list) {
+ return list->next;
+ } else {
+ return NULL;
+ }
+}
+
+#define list_peek_head_type(list, type, element) \
+ ({ \
+ list_node_t* __nod = list_peek_head(list); \
+ type* __t; \
+ if (__nod) \
+ __t = containerof(__nod, type, element); \
+ else \
+ __t = (type*)0; \
+ __t; \
+ })
+
+static inline list_node_t* list_peek_tail(const list_node_t* list) {
+ if (list->prev != list) {
+ return list->prev;
+ } else {
+ return NULL;
+ }
+}
+
+#define list_peek_tail_type(list, type, element) \
+ ({ \
+ list_node_t* __nod = list_peek_tail(list); \
+ type* __t; \
+ if (__nod) \
+ __t = containerof(__nod, type, element); \
+ else \
+ __t = (type*)0; \
+ __t; \
+ })
+
+static inline list_node_t* list_prev(list_node_t* list, list_node_t* item) {
+ if (item->prev != list)
+ return item->prev;
+ else
+ return NULL;
+}
+
+#define list_prev_type(list, item, type, element) \
+ ({ \
+ list_node_t* __nod = list_prev(list, item); \
+ type* __t; \
+ if (__nod) \
+ __t = containerof(__nod, type, element); \
+ else \
+ __t = (type*)0; \
+ __t; \
+ })
+
+static inline list_node_t* list_prev_wrap(list_node_t* list, list_node_t* item) {
+ if (item->prev != list)
+ return item->prev;
+ else if (item->prev->prev != list)
+ return item->prev->prev;
+ else
+ return NULL;
+}
+
+#define list_prev_wrap_type(list, item, type, element) \
+ ({ \
+ list_node_t* __nod = list_prev_wrap(list, item); \
+ type* __t; \
+ if (__nod) \
+ __t = containerof(__nod, type, element); \
+ else \
+ __t = (type*)0; \
+ __t; \
+ })
+
+static inline list_node_t* list_next(list_node_t* list, list_node_t* item) {
+ if (item->next != list)
+ return item->next;
+ else
+ return NULL;
+}
+
+#define list_next_type(list, item, type, element) \
+ ({ \
+ list_node_t* __nod = list_next(list, item); \
+ type* __t; \
+ if (__nod) \
+ __t = containerof(__nod, type, element); \
+ else \
+ __t = (type*)0; \
+ __t; \
+ })
+
+static inline list_node_t* list_next_wrap(list_node_t* list, list_node_t* item) {
+ if (item->next != list)
+ return item->next;
+ else if (item->next->next != list)
+ return item->next->next;
+ else
+ return NULL;
+}
+
+#define list_next_wrap_type(list, item, type, element) \
+ ({ \
+ list_node_t* __nod = list_next_wrap(list, item); \
+ type* __t; \
+ if (__nod) \
+ __t = containerof(__nod, type, element); \
+ else \
+ __t = (type*)0; \
+ __t; \
+ })
+
+// iterates over the list, node should be list_node_t*
+#define list_for_every(list, node) for (node = (list)->next; node != (list); node = node->next)
+
+// iterates over the list in a safe way for deletion of current node
+// node and temp_node should be list_node_t*
+#define list_for_every_safe(list, node, temp_node) \
+ for (node = (list)->next, temp_node = (node)->next; node != (list); \
+ node = temp_node, temp_node = (node)->next)
+
+// iterates over the list, entry should be the container structure type *
+#define list_for_every_entry(list, entry, type, member) \
+ for ((entry) = containerof((list)->next, type, member); &(entry)->member != (list); \
+ (entry) = containerof((entry)->member.next, type, member))
+
+// iterates over the list in a safe way for deletion of current node
+// entry and temp_entry should be the container structure type *
+#define list_for_every_entry_safe(list, entry, temp_entry, type, member) \
+ for (entry = containerof((list)->next, type, member), \
+ temp_entry = containerof((entry)->member.next, type, member); \
+ &(entry)->member != (list); \
+ entry = temp_entry, temp_entry = containerof((temp_entry)->member.next, type, member))
+
+static inline bool list_is_empty(const list_node_t* list) {
+ return (list->next == list) ? true : false;
+}
+
+static inline size_t list_length(const list_node_t* list) {
+ size_t cnt = 0;
+ const list_node_t* node = list;
+ list_for_every(list, node) { cnt++; }
+
+ return cnt;
+}
+
+// Splice the contents of splice_from into the list immediately following pos.
+static inline void list_splice_after(list_node_t* splice_from, list_node_t* pos) {
+ if (list_is_empty(splice_from)) {
+ return;
+ }
+ splice_from->next->prev = pos;
+ splice_from->prev->next = pos->next;
+ pos->next->prev = splice_from->prev;
+ pos->next = splice_from->next;
+ list_initialize(splice_from);
+}
+
+// Split the contents of list after (but not including) pos, into split_to
+// (which should be empty).
+static inline void list_split_after(list_node_t* list, list_node_t* pos, list_node_t* split_to) {
+ if (pos->next == list) {
+ list_initialize(split_to);
+ return;
+ }
+ split_to->prev = list->prev;
+ split_to->prev->next = split_to;
+ split_to->next = pos->next;
+ split_to->next->prev = split_to;
+ pos->next = list;
+ list->prev = pos;
+}
+
+// Moves all the contents of old_list (which may or may not be empty)
+// to new_list (which should be empty).
+static inline void list_move(list_node_t* old_list, list_node_t* new_list) {
+ list_initialize(new_list);
+ list_splice_after(old_list, new_list);
+}
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_LISTNODE_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/pixelformat.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/pixelformat.h
new file mode 100644
index 0000000..f28f35f
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/pixelformat.h
@@ -0,0 +1,28 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_PIXELFORMAT_H_
+#define SYSROOT_ZIRCON_PIXELFORMAT_H_
+
+#include <stdint.h>
+
+typedef uint32_t zx_pixel_format_t;
+// clang-format off
+
+#define ZX_PIXEL_FORMAT_NONE ((zx_pixel_format_t)0x00000000)
+
+#define ZX_PIXEL_FORMAT_RGB_565 ((zx_pixel_format_t)0x00020001)
+#define ZX_PIXEL_FORMAT_RGB_332 ((zx_pixel_format_t)0x00010002)
+#define ZX_PIXEL_FORMAT_RGB_2220 ((zx_pixel_format_t)0x00010003)
+#define ZX_PIXEL_FORMAT_ARGB_8888 ((zx_pixel_format_t)0x00040004)
+#define ZX_PIXEL_FORMAT_RGB_x888 ((zx_pixel_format_t)0x00040005)
+#define ZX_PIXEL_FORMAT_MONO_8 ((zx_pixel_format_t)0x00010007)
+#define ZX_PIXEL_FORMAT_GRAY_8 ((zx_pixel_format_t)0x00010007)
+#define ZX_PIXEL_FORMAT_NV12 ((zx_pixel_format_t)0x00010008)
+#define ZX_PIXEL_FORMAT_RGB_888 ((zx_pixel_format_t)0x00030009)
+#define ZX_PIXEL_FORMAT_ABGR_8888 ((zx_pixel_format_t)0x0004000a)
+#define ZX_PIXEL_FORMAT_BGR_888x ((zx_pixel_format_t)0x0004000b)
+#define ZX_PIXEL_FORMAT_BYTES(pf) (((pf) >> 16) & 7)
+
+#endif // SYSROOT_ZIRCON_PIXELFORMAT_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/process.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/process.h
new file mode 100644
index 0000000..ef2bcb1
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/process.h
@@ -0,0 +1,35 @@
+// Copyright 2017 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.
+
+#ifndef SYSROOT_ZIRCON_PROCESS_H_
+#define SYSROOT_ZIRCON_PROCESS_H_
+
+#include <stdint.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// Accessors for Zircon-specific state maintained by the language runtime
+
+// Examines the set of handles received at process startup for one matching
+// |hnd_info|. If one is found, atomically returns it and removes it from the
+// set available to future calls.
+// |hnd_info| is a value returned by PA_HND().
+zx_handle_t zx_take_startup_handle(uint32_t hnd_info);
+
+zx_handle_t _zx_thread_self(void);
+zx_handle_t zx_thread_self(void);
+
+zx_handle_t _zx_process_self(void);
+zx_handle_t zx_process_self(void);
+
+zx_handle_t _zx_vmar_root_self(void);
+zx_handle_t zx_vmar_root_self(void);
+
+zx_handle_t _zx_job_default(void);
+zx_handle_t zx_job_default(void);
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_PROCESS_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/processargs.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/processargs.h
new file mode 100644
index 0000000..fbad376
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/processargs.h
@@ -0,0 +1,170 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_PROCESSARGS_H_
+#define SYSROOT_ZIRCON_PROCESSARGS_H_
+
+#include <stdint.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// This is a protocol for passing state to a new process
+// via a message in a channel.
+
+#define ZX_PROCARGS_PROTOCOL ((uint32_t)0x4150585du) // MXPA
+#define ZX_PROCARGS_VERSION ((uint32_t)0x0001000u)
+
+typedef struct zx_proc_args zx_proc_args_t;
+
+struct zx_proc_args {
+ // Protocol and version identifiers to allow for
+ // different process start message protocols and
+ // versioning of the same.
+ uint32_t protocol;
+ uint32_t version;
+
+ // Offset from start of message to handle info
+ // array, which contains one uint32_t per handle
+ // passed along with the message.
+ uint32_t handle_info_off;
+
+ // Offset from start of message to arguments and
+ // count of arguments. Arguments are provided as
+ // a set of null-terminated utf-8 strings, one
+ // after the other.
+ uint32_t args_off;
+ uint32_t args_num;
+
+ // Offset from start of message to environment strings and count of
+ // them. Environment entries are provided as a set of null-terminated
+ // UTF-8 strings, one after the other. Canonically each string has
+ // the form "NAME=VALUE", but nothing enforces this.
+ uint32_t environ_off;
+ uint32_t environ_num;
+
+ // Offset from start of message to name strings and count of them.
+ // These strings are packed similar to the argument strings,
+ // but are referenced by PA_NS_* handle table entries and used
+ // to set up namespaces.
+ //
+ // Specifically: In a handle table entry with PA_HND_TYPE(info)
+ // of PA_NS_*, PA_HND_ARG(info) is an index into this name table.
+ uint32_t names_off;
+ uint32_t names_num;
+};
+
+// Handle Info entries associate a type and optional
+// argument with each handle included in the process
+// arguments message.
+#define PA_HND(type, arg) (((type)&0xFF) | (((arg)&0xFFFF) << 16))
+#define PA_HND_TYPE(n) ((n)&0xFF)
+#define PA_HND_ARG(n) (((n) >> 16) & 0xFFFF)
+
+// --- Core Runtime Handles ---
+// Used by libc init (or equivalent) and dynamic loader
+
+// Handle to our own process.
+#define PA_PROC_SELF 0x01u
+
+// Handle to the initial thread of our own process.
+#define PA_THREAD_SELF 0x02u
+
+// Handle to a job object which can be used to make child processes.
+//
+// The job can be the same as the one used to create this process or it can
+// be different.
+#define PA_JOB_DEFAULT 0x03u
+
+// Handle to the root of our address space
+#define PA_VMAR_ROOT 0x04u
+
+// Handle to the VMAR used to load the initial program image.
+#define PA_VMAR_LOADED 0x05u
+
+// --- Loader Service and VMO Handles ---
+// Used by libc init (or equivalent) and dynamic loader
+
+// Service for loading shared libraries.
+//
+// See |fuchsia.ldsvc.Loader| for the interface definition.
+#define PA_LDSVC_LOADER 0x10u
+
+// Handle to the VMO containing the ELF image of the system vDSO. This
+// handle is duplicable, transferable, readable, and executable, but not
+// writable. The contents of the VM object should be treated like any
+// other general-purpose ELF file image of type ET_DYN. A process only
+// needs this handle so that it can map the vDSO into new processes it
+// might create or propagate it on to its children so they can do so.
+// Each process's own vDSO was mapped in by its creator before the
+// process started, its address passed as an argument to entry point.
+#define PA_VMO_VDSO 0x11u
+
+// Handle to the VMO used to map the initial thread's stack. This
+// handle usually has all rights. The protocol between process creator
+// and new process is that this entire VM object has been mapped in
+// before the process starts. The initial value for the SP register in
+// the new process is the high edge of the mapping (assuming stacks grow
+// downwards), adjusted down as required by the particular machine's C
+// calling convention for function entry. Thus the new process can
+// compute its exact stack bounds by subtracting the size reported by
+// this VMO from the (adjusted back up) initial SP value.
+#define PA_VMO_STACK 0x13u
+
+// VM object handle for the main executable file
+#define PA_VMO_EXECUTABLE 0x14u
+
+// Used by kernel and userboot during startup
+#define PA_VMO_BOOTDATA 0x1Au
+
+// Used by kernel and userboot during startup
+#define PA_VMO_BOOTFS 0x1Bu
+
+// Used by the kernel to export debug information as a file in bootfs. When
+// devmgr starts, it looks for handles of this type, and adds them as files in
+// /boot/kernel/<vmo-name>.
+#define PA_VMO_KERNEL_FILE 0x1Cu
+
+// --- Namespace Handles ---
+
+// A handle which will handle OPEN requests relative
+// to a particular path which is specified by the
+// nametable entry referred to by the "arg" field
+#define PA_NS_DIR 0x20u
+
+// --- File Descriptor Handles ---
+
+// A handle which will be used as a file descriptor.
+#define PA_FD 0x30u
+
+// -- Lifecyle handle --
+//
+// A Handle to a channel on which the process may receive lifecycle events from
+// the ELF runner by serving the |fuchsia.process.Lifecycle| protocol.
+#define PA_LIFECYCLE 0x3Au
+
+// Server endpoint for handling connection to appmgr services.
+#define PA_DIRECTORY_REQUEST 0x3Bu
+
+// Used by devmgr and devhosts
+#define PA_RESOURCE 0x3Fu
+
+// --- Clock handles ---
+//
+// A clock which provides access to UTC. Used by runtimes which are expected to
+// provide access to UTC via their standard libraries.
+//
+#define PA_CLOCK_UTC 0x40u
+
+// --- Various ---
+
+// Handle types for one-off use and prototyping
+#define PA_USER0 0xF0u
+#define PA_USER1 0xF1u
+#define PA_USER2 0xF2u
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_PROCESSARGS_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/rights.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/rights.h
new file mode 100644
index 0000000..2ab61b9
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/rights.h
@@ -0,0 +1,123 @@
+// Copyright 2017 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.
+
+#ifndef SYSROOT_ZIRCON_RIGHTS_H_
+#define SYSROOT_ZIRCON_RIGHTS_H_
+
+#include <stdint.h>
+
+typedef uint32_t zx_rights_t;
+#define ZX_RIGHT_NONE ((zx_rights_t)0u)
+#define ZX_RIGHT_DUPLICATE ((zx_rights_t)1u << 0)
+#define ZX_RIGHT_TRANSFER ((zx_rights_t)1u << 1)
+#define ZX_RIGHT_READ ((zx_rights_t)1u << 2)
+#define ZX_RIGHT_WRITE ((zx_rights_t)1u << 3)
+#define ZX_RIGHT_EXECUTE ((zx_rights_t)1u << 4)
+#define ZX_RIGHT_MAP ((zx_rights_t)1u << 5)
+#define ZX_RIGHT_GET_PROPERTY ((zx_rights_t)1u << 6)
+#define ZX_RIGHT_SET_PROPERTY ((zx_rights_t)1u << 7)
+#define ZX_RIGHT_ENUMERATE ((zx_rights_t)1u << 8)
+#define ZX_RIGHT_DESTROY ((zx_rights_t)1u << 9)
+#define ZX_RIGHT_SET_POLICY ((zx_rights_t)1u << 10)
+#define ZX_RIGHT_GET_POLICY ((zx_rights_t)1u << 11)
+#define ZX_RIGHT_SIGNAL ((zx_rights_t)1u << 12)
+#define ZX_RIGHT_SIGNAL_PEER ((zx_rights_t)1u << 13)
+#define ZX_RIGHT_WAIT ((zx_rights_t)1u << 14)
+#define ZX_RIGHT_INSPECT ((zx_rights_t)1u << 15)
+#define ZX_RIGHT_MANAGE_JOB ((zx_rights_t)1u << 16)
+#define ZX_RIGHT_MANAGE_PROCESS ((zx_rights_t)1u << 17)
+#define ZX_RIGHT_MANAGE_THREAD ((zx_rights_t)1u << 18)
+#define ZX_RIGHT_APPLY_PROFILE ((zx_rights_t)1u << 19)
+#define ZX_RIGHT_SAME_RIGHTS ((zx_rights_t)1u << 31)
+
+// Convenient names for commonly grouped rights.
+#define ZX_RIGHTS_BASIC (ZX_RIGHT_TRANSFER | ZX_RIGHT_DUPLICATE | ZX_RIGHT_WAIT | ZX_RIGHT_INSPECT)
+
+#define ZX_RIGHTS_IO (ZX_RIGHT_READ | ZX_RIGHT_WRITE)
+
+#define ZX_RIGHTS_PROPERTY (ZX_RIGHT_GET_PROPERTY | ZX_RIGHT_SET_PROPERTY)
+
+#define ZX_RIGHTS_POLICY (ZX_RIGHT_GET_POLICY | ZX_RIGHT_SET_POLICY)
+
+#define ZX_DEFAULT_CHANNEL_RIGHTS \
+ ((ZX_RIGHTS_BASIC & (~ZX_RIGHT_DUPLICATE)) | ZX_RIGHTS_IO | ZX_RIGHT_SIGNAL | \
+ ZX_RIGHT_SIGNAL_PEER)
+
+#define ZX_DEFAULT_EVENT_RIGHTS (ZX_RIGHTS_BASIC | ZX_RIGHT_SIGNAL)
+
+#define ZX_DEFAULT_SYSTEM_EVENT_LOW_MEMORY_RIGHTS \
+ (ZX_RIGHT_WAIT | ZX_RIGHT_DUPLICATE | ZX_RIGHT_TRANSFER)
+
+#define ZX_DEFAULT_EVENTPAIR_RIGHTS (ZX_RIGHTS_BASIC | ZX_RIGHT_SIGNAL | ZX_RIGHT_SIGNAL_PEER)
+
+#define ZX_DEFAULT_FIFO_RIGHTS \
+ (ZX_RIGHTS_BASIC | ZX_RIGHTS_IO | ZX_RIGHT_SIGNAL | ZX_RIGHT_SIGNAL_PEER)
+
+#define ZX_DEFAULT_GUEST_RIGHTS \
+ (ZX_RIGHT_TRANSFER | ZX_RIGHT_DUPLICATE | ZX_RIGHT_WRITE | ZX_RIGHT_INSPECT | \
+ ZX_RIGHT_MANAGE_PROCESS)
+
+#define ZX_DEFAULT_INTERRUPT_RIGHTS (ZX_RIGHTS_BASIC | ZX_RIGHTS_IO | ZX_RIGHT_SIGNAL)
+
+#define ZX_DEFAULT_IO_MAPPING_RIGHTS (ZX_RIGHT_READ | ZX_RIGHT_INSPECT)
+
+#define ZX_DEFAULT_JOB_RIGHTS \
+ (ZX_RIGHTS_BASIC | ZX_RIGHTS_IO | ZX_RIGHTS_PROPERTY | ZX_RIGHTS_POLICY | ZX_RIGHT_ENUMERATE | \
+ ZX_RIGHT_DESTROY | ZX_RIGHT_SIGNAL | ZX_RIGHT_MANAGE_JOB | ZX_RIGHT_MANAGE_PROCESS | \
+ ZX_RIGHT_MANAGE_THREAD)
+
+#define ZX_DEFAULT_LOG_RIGHTS (ZX_RIGHTS_BASIC | ZX_RIGHT_WRITE | ZX_RIGHT_SIGNAL)
+
+#define ZX_DEFAULT_MSI_RIGHTS (ZX_RIGHTS_BASIC | ZX_RIGHT_INSPECT)
+
+#define ZX_DEFAULT_PCI_DEVICE_RIGHTS (ZX_RIGHTS_BASIC | ZX_RIGHTS_IO)
+
+#define ZX_DEFAULT_PCI_INTERRUPT_RIGHTS (ZX_RIGHTS_BASIC | ZX_RIGHTS_IO | ZX_RIGHT_SIGNAL)
+
+#define ZX_DEFAULT_PORT_RIGHTS ((ZX_RIGHTS_BASIC & (~ZX_RIGHT_WAIT)) | ZX_RIGHTS_IO)
+
+#define ZX_DEFAULT_PROCESS_RIGHTS \
+ (ZX_RIGHTS_BASIC | ZX_RIGHTS_IO | ZX_RIGHTS_PROPERTY | ZX_RIGHT_ENUMERATE | ZX_RIGHT_DESTROY | \
+ ZX_RIGHT_SIGNAL | ZX_RIGHT_MANAGE_PROCESS | ZX_RIGHT_MANAGE_THREAD)
+
+#define ZX_DEFAULT_RESOURCE_RIGHTS \
+ (ZX_RIGHT_TRANSFER | ZX_RIGHT_DUPLICATE | ZX_RIGHT_WRITE | ZX_RIGHT_INSPECT)
+
+#define ZX_DEFAULT_SOCKET_RIGHTS \
+ (ZX_RIGHTS_BASIC | ZX_RIGHTS_IO | ZX_RIGHT_GET_PROPERTY | ZX_RIGHT_SET_PROPERTY | \
+ ZX_RIGHT_SIGNAL | ZX_RIGHT_SIGNAL_PEER)
+
+#define ZX_DEFAULT_STREAM_RIGHTS (ZX_RIGHTS_BASIC | ZX_RIGHTS_PROPERTY | ZX_RIGHT_SIGNAL)
+
+#define ZX_DEFAULT_THREAD_RIGHTS \
+ (ZX_RIGHTS_BASIC | ZX_RIGHTS_IO | ZX_RIGHTS_PROPERTY | ZX_RIGHT_DESTROY | ZX_RIGHT_SIGNAL | \
+ ZX_RIGHT_MANAGE_THREAD)
+
+#define ZX_DEFAULT_TIMER_RIGHTS (ZX_RIGHTS_BASIC | ZX_RIGHT_WRITE | ZX_RIGHT_SIGNAL)
+
+#define ZX_DEFAULT_VCPU_RIGHTS (ZX_RIGHTS_BASIC | ZX_RIGHTS_IO | ZX_RIGHT_EXECUTE | ZX_RIGHT_SIGNAL)
+
+#define ZX_DEFAULT_VMAR_RIGHTS (ZX_RIGHTS_BASIC & (~ZX_RIGHT_WAIT))
+
+#define ZX_DEFAULT_VMO_RIGHTS \
+ (ZX_RIGHTS_BASIC | ZX_RIGHTS_IO | ZX_RIGHTS_PROPERTY | ZX_RIGHT_MAP | ZX_RIGHT_SIGNAL)
+
+#define ZX_DEFAULT_IOMMU_RIGHTS (ZX_RIGHTS_BASIC & (~ZX_RIGHT_WAIT))
+
+#define ZX_DEFAULT_BTI_RIGHTS ((ZX_RIGHTS_BASIC & (~ZX_RIGHT_WAIT)) | ZX_RIGHTS_IO | ZX_RIGHT_MAP)
+
+#define ZX_DEFAULT_PROFILE_RIGHTS ((ZX_RIGHTS_BASIC & (~ZX_RIGHT_WAIT)) | ZX_RIGHT_APPLY_PROFILE)
+
+#define ZX_DEFAULT_PMT_RIGHTS (ZX_RIGHT_INSPECT)
+
+#define ZX_DEFAULT_SUSPEND_TOKEN_RIGHTS (ZX_RIGHT_TRANSFER | ZX_RIGHT_INSPECT)
+
+#define ZX_DEFAULT_PAGER_RIGHTS \
+ (ZX_RIGHT_INSPECT | ZX_RIGHT_GET_PROPERTY | ZX_RIGHT_SET_PROPERTY | ZX_RIGHT_TRANSFER)
+
+#define ZX_DEFAULT_EXCEPTION_RIGHTS (ZX_RIGHT_TRANSFER | ZX_RIGHTS_PROPERTY | ZX_RIGHT_INSPECT)
+
+#define ZX_DEFAULT_CLOCK_RIGHTS (ZX_RIGHTS_BASIC | ZX_RIGHTS_IO)
+
+#endif // SYSROOT_ZIRCON_RIGHTS_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/sanitizer.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/sanitizer.h
new file mode 100644
index 0000000..c2f2e8e
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/sanitizer.h
@@ -0,0 +1,171 @@
+// Copyright 2017 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.
+
+#ifndef SYSROOT_ZIRCON_SANITIZER_H_
+#define SYSROOT_ZIRCON_SANITIZER_H_
+
+// Interfaces declared in this file are intended for the use of sanitizer
+// runtime library implementation code. Each sanitizer runtime works only
+// with the appropriately sanitized build of libc. These functions should
+// never be called when using the unsanitized libc. But these names are
+// always exported so that the libc ABI is uniform across sanitized and
+// unsanitized builds (only unsanitized shared library binaries are used at
+// link time, including linking the sanitizer runtime shared libraries).
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include <threads.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// These are aliases for the functions defined in libc, which are always
+// the unsanitized versions. The sanitizer runtimes can call them by these
+// aliases when they are overriding libc's definitions of the unadorned
+// symbols.
+__typeof(memcpy) __unsanitized_memcpy;
+__typeof(memmove) __unsanitized_memmove;
+__typeof(memset) __unsanitized_memset;
+
+// The sanitized libc allocates the shadow memory in the appropriate ratio for
+// the particular sanitizer (shadow_base == shadow_limit >> SHADOW_SCALE)
+// early during startup, before any other address space allocations can occur.
+// Shadow memory always starts at address zero:
+// [memory_limit, UINTPTR_MAX) Address space reserved by the system.
+// [shadow_limit, memory_limit) Address space available to the user.
+// [shadow_base, shadow_limit) Shadow memory, preallocated.
+// [0, shadow_base) Shadow gap, cannot be allocated.
+typedef struct saniziter_shadow_bounds {
+ uintptr_t shadow_base;
+ uintptr_t shadow_limit;
+ uintptr_t memory_limit;
+} sanitizer_shadow_bounds_t;
+
+// Returns the shadow bounds for the current process.
+sanitizer_shadow_bounds_t __sanitizer_shadow_bounds(void);
+
+// Fill the shadow memory corresponding to [base, base+size) with |value|. The
+// threshold is used as a hint to determine when to switch to a more efficient
+// mechanism when zero-filling large shadow regions. This assumes that both
+// |base| and |size| are aligned to the shadow multiple.
+void __sanitizer_fill_shadow(uintptr_t base, size_t size, uint8_t value, size_t threshold);
+
+// Write logging information from the sanitizer runtime. The buffer
+// is expected to be printable text with '\n' ending each line.
+// Timestamps and globally unique identifiers of the calling process
+// and thread (zx_koid_t) are attached to all messages, so there is no
+// need to include those details in the text. The log of messages
+// written with this call automatically includes address and ELF build
+// ID details of the program and all shared libraries sufficient to
+// translate raw address values into program symbols or source
+// locations via a post-processor that has access to the original ELF
+// files and their debugging information. The text can contain markup
+// around address values that should be resolved symbolically; see
+// TODO(mcgrathr) for the format and details of the post-processor.
+void __sanitizer_log_write(const char* buffer, size_t len);
+
+// Runtimes that have binary data to publish (e.g. coverage) use this
+// interface. The name describes the data sink that will receive this
+// blob of data; the string is not used after this call returns. The
+// caller creates a VMO (e.g. zx_vmo_create) and passes it in; the VMO
+// handle is consumed by this call. Each particular data sink has its
+// own conventions about both the format of the data in the VMO and the
+// protocol for when data must be written there. For some sinks, the
+// VMO's data is used immediately. For other sinks, the caller is
+// expected to have the VMO mapped in and be writing more data there
+// throughout the life of the process, to be analyzed only after the
+// process terminates. Yet others might use an asynchronous shared
+// memory protocol between producer and consumer.
+void __sanitizer_publish_data(const char* sink_name, zx_handle_t vmo);
+
+// Runtimes that want to read configuration files use this interface.
+// The name is a string from the user (something akin to a file name
+// but not necessarily actually a file name); the string is not used
+// after this call returns. On success, this yields a read-only VMO
+// handle from which the contents associated with that name can be
+// read; the caller is responsible for closing this handle.
+zx_status_t __sanitizer_get_configuration(const char* config_name, zx_handle_t* out_vmo);
+
+// Changes protection of the code in the range of len bytes starting
+// from addr. The writable argument specifies whether the code should
+// be made writable or not. This function is only valid on ranges within
+// the caller's own code segment.
+// TODO(phosek) removes this when the proper debugging interface exists.
+zx_status_t __sanitizer_change_code_protection(uintptr_t addr, size_t len, bool writable);
+
+// This stops all other threads in the process so memory should be quiescent.
+// Then it makes callbacks for memory regions containing non-const global
+// variables, thread stacks, thread registers, and thread-local storage
+// regions (this includes thread_local variables as well as tss_set or
+// pthread_setspecific values). Each callback is optional; no such callbacks
+// are made if a null function pointer is given. The memory region passed to
+// each callback can be accessed only during that single callback and might no
+// longer be valid once the callback returns. Then it makes a final callback
+// before allowing other threads to resume running normally. If there are
+// problems stopping threads, no memory callbacks will be made and the
+// argument to the final callback will get an error code rather than ZX_OK.
+typedef void sanitizer_memory_snapshot_callback_t(void* mem, size_t len, void* arg);
+void __sanitizer_memory_snapshot(sanitizer_memory_snapshot_callback_t* globals,
+ sanitizer_memory_snapshot_callback_t* stacks,
+ sanitizer_memory_snapshot_callback_t* regs,
+ sanitizer_memory_snapshot_callback_t* tls,
+ void (*done)(zx_status_t, void*), void* arg);
+
+// The "hook" interfaces are functions that the sanitizer runtime library
+// can define and libc will call. There are default definitions in libc
+// which do nothing, but any other definitions will override those. These
+// declarations use __EXPORT (i.e. explicit STV_DEFAULT) to ensure any user
+// definitions are seen by libc even if the user code is being compiled
+// with -fvisibility=hidden or equivalent.
+
+// This is called at program startup, with the arguments that will be
+// passed to main. This is called before any other application code,
+// including both static constructors and initialization of things like
+// fdio and zx_take_startup_handle. It's basically the first thing called
+// after libc's most basic internal global initialization is complete and
+// the initial thread has switched to its real thread stack. Since not
+// even all of libc's own constructors have run yet, this should not call
+// into libc or other library code.
+__EXPORT void __sanitizer_startup_hook(int argc, char** argv, char** envp, void* stack_base,
+ size_t stack_size);
+
+// This is called when a new thread has been created but is not yet
+// running. Its C11 thrd_t value has been determined and its stack has
+// been allocated. All that remains is to actually start the thread
+// running (which can fail only in catastrophic bug situations). Its
+// return value will be passed to __sanitizer_thread_create_hook, below.
+__EXPORT void* __sanitizer_before_thread_create_hook(thrd_t thread, bool detached, const char* name,
+ void* stack_base, size_t stack_size);
+
+// This is called after a new thread has been created or creation has
+// failed at the final stage; __sanitizer_before_thread_create_hook has
+// been called first, and its return value is the first argument here.
+// The second argument is what the return value of C11 thrd_create would
+// be for this creation attempt (which might have been instigated by
+// either thrd_create or pthread_create). If it's thrd_success, then
+// the new thread has now started running. Otherwise (it's a different
+// <threads.h> thrd_* value), thread creation has failed and the thread
+// details reported to __sanitizer_before_thread_create_hook will be
+// freed without the thread ever starting.
+__EXPORT void __sanitizer_thread_create_hook(void* hook, thrd_t thread, int error);
+
+// This is called in each new thread as it starts up. The argument is
+// the same one returned by __sanitizer_before_thread_create_hook and
+// previously passed to __sanitizer_thread_create_hook.
+__EXPORT void __sanitizer_thread_start_hook(void* hook, thrd_t self);
+
+// This is called in each thread just before it dies.
+// All thread-specific destructors have been run.
+// The argument is the same one passed to __sanitizer_thread_start_hook.
+__EXPORT void __sanitizer_thread_exit_hook(void* hook, thrd_t self);
+
+// This is called with the argument to _exit and its return value
+// is the actual exit status for the process.
+__EXPORT int __sanitizer_process_exit_hook(int status);
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SANITIZER_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/status.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/status.h
new file mode 100644
index 0000000..798d2b0
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/status.h
@@ -0,0 +1,23 @@
+// Copyright 2016 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.
+
+#pragma once
+
+#include <zircon/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Given one of the status codes defined in <zircon/errors.h> (ZX_ERR_* or
+// ZX_OK), this function returns an identifier string for the status code.
+//
+// For example, zx_status_get_string(ZX_ERR_TIMED_OUT) returns the string
+// "ZX_ERR_TIMED_OUT".
+__EXPORT const char* _zx_status_get_string(zx_status_t status);
+__EXPORT const char* zx_status_get_string(zx_status_t status);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/string_view.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/string_view.h
new file mode 100644
index 0000000..f54ff2a
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/string_view.h
@@ -0,0 +1,67 @@
+// Copyright 2020 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.
+
+#pragma once
+
+#include <stddef.h>
+#if __cplusplus >= 201103L && __has_include(<type_traits>)
+#include <type_traits>
+#endif
+
+// This represents a UTF-8 string constant provided by the vDSO itself.
+// This pointer remains valid and the string doesn't change for the
+// life of the process (if not the system).
+//
+// This type exists to be the return value type for vDSO functions.
+// In current machine ABIs, it's returned "for free" in two registers.
+// To a C caller, these functions have ABIs indistinguishable from if
+// they simply returned `const char*` so there is no overhead to
+// supporting the explicit-length API as well as the traditional C
+// string API, though it does require writing out `.c_str` in the
+// source. C++ 17 callers can take advantage of direct coercion to
+// the standard std::string_view and std::u8string_view types, which
+// also allows e.g. direct construction of std::string.
+typedef struct {
+ const char* c_str; // UTF-8, guaranteed to be '\0'-terminated.
+ size_t length; // Length, not including the '\0' terminator.
+
+#ifdef __cplusplus
+ // This is ABI-identical to the usual implementation of std::string_view,
+ // when applied to NUL-terminated C strings. But this API doesn't presume
+ // that std::string_view has a particular implementation or exists at all.
+ // For convenience of use without directly using the C++ standard library
+ // API, a templatized implicit coercion is defined to types that have the
+ // API of std::string_view or std::u8string_view. With the most common
+ // implementations, this coercion will be compiled away to nothing.
+ template <
+ typename _T
+#if __cplusplus >= 201103L && __has_include(<type_traits>)
+ ,
+ typename = typename std::enable_if<sizeof(typename _T::value_type) == sizeof(char)>::type
+#endif
+ >
+ operator _T() {
+ // It's preferable to exclude incompatible types via SFINAE so that
+ // the user's diagnostic experience is exactly as if no coercion
+ // operator existed. SFINAE should exclude this definition when a
+ // C++11 <type_traits> is available to define std::enable_if. If
+ // no standard C++ library header is available, this will provide
+ // a specific diagnostic.
+ static_assert(sizeof(typename _T::value_type) == sizeof(char),
+ "zx_string_view_t can be coerced to C++ 17 std::string_view"
+ " or std::u8string_view or types with equivalent API");
+ return {reinterpret_cast<typename _T::const_pointer>(c_str), length};
+ }
+
+ // Preferably zx_string_view_t values should just be coerced to
+ // std::string_view. But it provides the most minimal aspects of
+ // the equivalent API in case a return value expression is used
+ // directly as `zx_foo_string().data()`, for example.
+ using value_type = char;
+ using const_pointer = const char*;
+ using size_type = size_t;
+ const_pointer data() const { return c_str; }
+ size_type size() const { return length; }
+#endif
+} zx_string_view_t;
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls.h
new file mode 100644
index 0000000..9e79e55
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls.h
@@ -0,0 +1,41 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_H_
+#define SYSROOT_ZIRCON_SYSCALLS_H_
+
+#include <zircon/string_view.h>
+#include <zircon/syscalls/object.h>
+#include <zircon/syscalls/pci.h>
+#include <zircon/syscalls/profile.h>
+#include <zircon/syscalls/types.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+#define _ZX_SYSCALL_DECL(name, type, attrs, nargs, arglist, prototype) \
+ extern attrs type zx_##name prototype; \
+ extern attrs type _zx_##name prototype;
+
+#ifdef __clang__
+#define _ZX_SYSCALL_ANNO(attr) __attribute__((attr))
+#else
+#define _ZX_SYSCALL_ANNO(attr) // Nothing for compilers without the support.
+#endif
+
+#include <zircon/syscalls/internal/cdecls.inc>
+
+#undef _ZX_SYSCALL_ANNO
+#undef _ZX_SYSCALL_DECL
+
+// Compatibility wrappers for deprecated syscalls also go here, when
+// there are any.
+
+// This DEPRECATED interface is replaced by zx_system_get_version_string.
+zx_status_t zx_system_get_version(char* version, size_t version_size) __LEAF_FN;
+zx_status_t _zx_system_get_version(char* version, size_t version_size) __LEAF_FN;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/clock.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/clock.h
new file mode 100644
index 0000000..eab1cd1
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/clock.h
@@ -0,0 +1,90 @@
+// 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_CLOCK_H_
+#define SYSROOT_ZIRCON_SYSCALLS_CLOCK_H_
+
+#include <zircon/time.h>
+
+// clang-format off
+
+// Argument version identifiers.
+//
+// All zx_clock_* syscalls which fetch or receive a structure's worth of
+// arguments encode a version number in the options field of the syscall. This
+// version field is in the same location and is the same size for each syscall,
+// so a common set of macros may be used for encoding and decoding.
+#define ZX_CLOCK_ARGS_VERSION_SHIFT ((uint64_t)58u)
+#define ZX_CLOCK_ARGS_VERSION_BITS ((uint64_t)6u)
+#define ZX_CLOCK_ARGS_VERSION_MASK \
+ (((((uint64_t)1) << ZX_CLOCK_ARGS_VERSION_BITS) - 1) << ZX_CLOCK_ARGS_VERSION_SHIFT)
+#define ZX_CLOCK_ARGS_VERSION(_N) \
+ (((uint64_t)(_N) << ZX_CLOCK_ARGS_VERSION_SHIFT) & ZX_CLOCK_ARGS_VERSION_MASK)
+
+// Clock creation options.
+#define ZX_CLOCK_OPT_MONOTONIC ((uint64_t)1u << 0)
+#define ZX_CLOCK_OPT_CONTINUOUS ((uint64_t)1u << 1)
+#define ZX_CLOCK_OPT_AUTO_START ((uint64_t)1u << 2)
+
+#define ZX_CLOCK_OPTS_ALL ( \
+ ZX_CLOCK_OPT_MONOTONIC | \
+ ZX_CLOCK_OPT_CONTINUOUS | \
+ ZX_CLOCK_OPT_AUTO_START)
+
+// Clock update flags
+#define ZX_CLOCK_UPDATE_OPTION_VALUE_VALID ((uint64_t)1u << 0)
+#define ZX_CLOCK_UPDATE_OPTION_RATE_ADJUST_VALID ((uint64_t)1u << 1)
+#define ZX_CLOCK_UPDATE_OPTION_ERROR_BOUND_VALID ((uint64_t)1u << 2)
+
+#define ZX_CLOCK_UPDATE_OPTIONS_ALL ( \
+ ZX_CLOCK_UPDATE_OPTION_VALUE_VALID | \
+ ZX_CLOCK_UPDATE_OPTION_RATE_ADJUST_VALID | \
+ ZX_CLOCK_UPDATE_OPTION_ERROR_BOUND_VALID)
+
+// Clock rate adjustment limits
+#define ZX_CLOCK_UPDATE_MIN_RATE_ADJUST ((int32_t)-1000)
+#define ZX_CLOCK_UPDATE_MAX_RATE_ADJUST ((int32_t)1000)
+
+// Special clock error values
+#define ZX_CLOCK_UNKNOWN_ERROR ((uint64_t)0xFFFFFFFFFFFFFFFF)
+
+// clang-format on
+
+typedef struct zx_clock_create_args_v1 {
+ zx_time_t backstop_time;
+} zx_clock_create_args_v1_t;
+
+typedef struct zx_clock_rate {
+ uint32_t synthetic_ticks;
+ uint32_t reference_ticks;
+} zx_clock_rate_t;
+
+typedef struct zx_clock_transformation {
+ int64_t reference_offset;
+ int64_t synthetic_offset;
+ zx_clock_rate_t rate;
+} zx_clock_transformation_t;
+
+typedef struct zx_clock_details_v1 {
+ uint64_t options;
+ zx_time_t backstop_time;
+ zx_clock_transformation_t ticks_to_synthetic;
+ zx_clock_transformation_t mono_to_synthetic;
+ uint64_t error_bound;
+ zx_ticks_t query_ticks;
+ zx_ticks_t last_value_update_ticks;
+ zx_ticks_t last_rate_adjust_update_ticks;
+ zx_ticks_t last_error_bounds_update_ticks;
+ uint32_t generation_counter;
+ uint8_t padding1[4];
+} zx_clock_details_v1_t;
+
+typedef struct zx_clock_update_args_v1 {
+ int32_t rate_adjust;
+ uint8_t padding1[4];
+ int64_t value;
+ uint64_t error_bound;
+} zx_clock_update_args_v1_t;
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_CLOCK_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/debug.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/debug.h
new file mode 100644
index 0000000..373381f
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/debug.h
@@ -0,0 +1,179 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_DEBUG_
+#define SYSROOT_ZIRCON_SYSCALLS_DEBUG_
+
+#include <stdint.h>
+#include <zircon/compiler.h>
+
+__BEGIN_CDECLS
+
+#if defined(__x86_64__)
+
+// Value for ZX_THREAD_STATE_GENERAL_REGS on x86-64 platforms.
+typedef struct zx_thread_state_general_regs {
+ uint64_t rax;
+ uint64_t rbx;
+ uint64_t rcx;
+ uint64_t rdx;
+ uint64_t rsi;
+ uint64_t rdi;
+ uint64_t rbp;
+ uint64_t rsp;
+ uint64_t r8;
+ uint64_t r9;
+ uint64_t r10;
+ uint64_t r11;
+ uint64_t r12;
+ uint64_t r13;
+ uint64_t r14;
+ uint64_t r15;
+ uint64_t rip;
+ uint64_t rflags;
+ uint64_t fs_base;
+ uint64_t gs_base;
+} zx_thread_state_general_regs_t;
+
+// Value for ZX_THREAD_STATE_FP_REGS on x64. Holds x87 and MMX state.
+typedef struct zx_thread_state_fp_regs {
+ uint16_t fcw; // Control word.
+ uint16_t fsw; // Status word.
+ uint8_t ftw; // Tag word.
+ uint8_t reserved;
+ uint16_t fop; // Opcode.
+ uint64_t fip; // Instruction pointer.
+ uint64_t fdp; // Data pointer.
+
+ uint8_t padding1[8];
+
+ // The x87/MMX state. For x87 the each "st" entry has the low 80 bits used for the register
+ // contents. For MMX, the low 64 bits are used. The higher bits are unused.
+ __ALIGNED(16)
+ struct {
+ uint64_t low;
+ uint64_t high;
+ } st[8];
+} zx_thread_state_fp_regs_t;
+
+// Value for ZX_THREAD_STATE_VECTOR_REGS on x64. Holds SSE and AVX registers.
+//
+// Setting vector registers will only work for threads that have previously executed an
+// instruction using the corresponding register class.
+typedef struct zx_thread_state_vector_regs {
+ // When only 16 registers are supported (pre-AVX-512), zmm[16-31] will be 0.
+ // YMM registers (256 bits) are v[0-4], XMM registers (128 bits) are v[0-2].
+ struct {
+ uint64_t v[8];
+ } zmm[32];
+
+ // AVX-512 opmask registers. Will be 0 unless AVX-512 is supported.
+ uint64_t opmask[8];
+
+ // SIMD control and status register.
+ uint32_t mxcsr;
+
+ uint8_t padding1[4];
+} zx_thread_state_vector_regs_t;
+
+// Value for ZX_THREAD_STATE_DEBUG_REGS on x64 platforms.
+typedef struct zx_thread_state_debug_regs {
+ uint64_t dr[4];
+ // DR4 and D5 are not used.
+ uint64_t dr6; // Status register.
+ uint64_t dr7; // Control register.
+} zx_thread_state_debug_regs_t;
+
+#elif defined(__aarch64__)
+
+// Value for ZX_THREAD_STATE_GENERAL_REGS on ARM64 platforms.
+typedef struct zx_thread_state_general_regs {
+ uint64_t r[30];
+ uint64_t lr;
+ uint64_t sp;
+ uint64_t pc;
+ uint64_t cpsr;
+ uint64_t tpidr;
+} zx_thread_state_general_regs_t;
+
+// Value for ZX_THREAD_STATE_FP_REGS on ARM64 platforms.
+// This is unused because vector state is used for all floating point on ARM64.
+typedef struct zx_thread_state_fp_regs {
+ // Avoids sizing differences for empty structs between C and C++.
+ uint32_t unused;
+} zx_thread_state_fp_regs_t;
+
+// Value for ZX_THREAD_STATE_VECTOR_REGS on ARM64 platforms.
+typedef struct zx_thread_state_vector_regs {
+ uint32_t fpcr;
+ uint32_t fpsr;
+ struct {
+ uint64_t low;
+ uint64_t high;
+ } v[32];
+} zx_thread_state_vector_regs_t;
+
+// ARMv8-A provides 2 to 16 hardware breakpoint registers.
+// The number is obtained by the BRPs field in the EDDFR register.
+#define AARCH64_MAX_HW_BREAKPOINTS 16
+// ARMv8-A provides 2 to 16 watchpoint breakpoint registers.
+// The number is obtained by the WRPs field in the EDDFR register.
+#define AARCH64_MAX_HW_WATCHPOINTS 16
+
+// Value for XZ_THREAD_STATE_DEBUG_REGS for ARM64 platforms.
+typedef struct zx_thread_state_debug_regs {
+ struct {
+ uint32_t dbgbcr; // HW Breakpoint Control register.
+ uint8_t padding1[4];
+ uint64_t dbgbvr; // HW Breakpoint Value register.
+ } hw_bps[AARCH64_MAX_HW_BREAKPOINTS];
+ // Number of HW Breakpoints in the platform.
+ // Will be set on read and ignored on write.
+
+ struct {
+ uint32_t dbgwcr; // HW Watchpoint Control register.
+ uint8_t padding1[4];
+ uint64_t dbgwvr; // HW Watchpoint Value register.
+ } hw_wps[AARCH64_MAX_HW_WATCHPOINTS];
+
+ // Faulting Virtual Address for watchpoint exceptions.
+ // Read-only, values are ignored on write.
+ uint64_t far;
+
+ // The esr value since the last exception.
+ // Read-only, values are ignored on write.
+ uint32_t esr;
+
+ // Number of HW Breakpoints/Watchpoints in the platform.
+ // Will be set on read and ignored on write.
+ uint8_t hw_bps_count;
+ uint8_t hw_wps_count;
+
+ uint8_t padding1[2];
+
+} zx_thread_state_debug_regs_t;
+
+#endif
+
+// Value for ZX_THREAD_STATE_SINGLE_STEP. The value can be 0 (not single-stepping), or 1
+// (single-stepping). Other values will give ZX_ERR_INVALID_ARGS.
+typedef uint32_t zx_thread_state_single_step_t;
+
+// Values for ZX_THREAD_X86_REGISTER_FS and ZX_THREAD_X86_REGISTER_GS;
+typedef uint64_t zx_thread_x86_register_fs_t;
+typedef uint64_t zx_thread_x86_register_gs_t;
+
+// Possible values for "kind" in zx_thread_read_state and zx_thread_write_state.
+typedef uint32_t zx_thread_state_topic_t;
+#define ZX_THREAD_STATE_GENERAL_REGS ((uint32_t)0) // zx_thread_state_general_regs_t value.
+#define ZX_THREAD_STATE_FP_REGS ((uint32_t)1) // zx_thread_state_fp_regs_t value.
+#define ZX_THREAD_STATE_VECTOR_REGS ((uint32_t)2) // zx_thread_state_vector_regs_t value.
+#define ZX_THREAD_STATE_DEBUG_REGS ((uint32_t)4) // zx_thread_state_debug_regs_t value.
+#define ZX_THREAD_STATE_SINGLE_STEP ((uint32_t)5) // zx_thread_state_single_step_t value.
+#define ZX_THREAD_X86_REGISTER_FS ((uint32_t)6) // zx_thread_x86_register_fs_t value.
+#define ZX_THREAD_X86_REGISTER_GS ((uint32_t)7) // zx_thread_x86_register_gs_t value.
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_DEBUG_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/exception.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/exception.h
new file mode 100644
index 0000000..6191e0f
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/exception.h
@@ -0,0 +1,136 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_EXCEPTION_H_
+#define SYSROOT_ZIRCON_SYSCALLS_EXCEPTION_H_
+
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// ask clang format not to mess up the indentation:
+// clang-format off
+
+// The following exception values were chosen for historical reasons.
+
+// Architectural exceptions.
+//
+// Depending on the exception, further information can be found in
+// |report.context.arch|.
+
+#define ZX_EXCP_GENERAL ((uint32_t) 0x008u)
+#define ZX_EXCP_FATAL_PAGE_FAULT ((uint32_t) 0x108u)
+#define ZX_EXCP_UNDEFINED_INSTRUCTION ((uint32_t) 0x208u)
+#define ZX_EXCP_SW_BREAKPOINT ((uint32_t) 0x308u)
+#define ZX_EXCP_HW_BREAKPOINT ((uint32_t) 0x408u)
+#define ZX_EXCP_UNALIGNED_ACCESS ((uint32_t) 0x508u)
+
+// Synthetic exceptions.
+
+// These bits are set for synthetic exceptions to distinguish them from
+// architectural exceptions.
+#define ZX_EXCP_SYNTH ((uint32_t) 0x8000u)
+
+// A thread is starting.
+// This exception is sent to debuggers only (ZX_EXCEPTION_CHANNEL_TYPE_DEBUGGER).
+// The thread that generates this exception is paused until it the debugger
+// handles the exception.
+#define ZX_EXCP_THREAD_STARTING ((uint32_t) 0x008u | ZX_EXCP_SYNTH)
+
+// A thread is exiting.
+// This exception is sent to debuggers only (ZX_EXCEPTION_CHANNEL_TYPE_DEBUGGER).
+// This exception is different from ZX_EXCP_GONE in that a debugger can
+// still examine thread state.
+// The thread that generates this exception is paused until it the debugger
+// handles the exception.
+#define ZX_EXCP_THREAD_EXITING ((uint32_t) 0x108u | ZX_EXCP_SYNTH)
+
+// This exception is generated when a syscall fails with a job policy
+// error (for example, an invalid handle argument is passed to the
+// syscall when the ZX_POL_BAD_HANDLE policy is enabled) and
+// ZX_POL_ACTION_EXCEPTION is set for the policy.
+// The thread that generates this exception is paused until it the debugger
+// handles the exception.
+#define ZX_EXCP_POLICY_ERROR ((uint32_t) 0x208u | ZX_EXCP_SYNTH)
+
+// A process is starting.
+// This exception is sent to job debuggers only
+// (ZX_EXCEPTION_CHANNEL_TYPE_JOB_DEBUGGER).
+// The thread that generates this exception is paused until it the debugger
+// handles the exception.
+#define ZX_EXCP_PROCESS_STARTING ((uint32_t) 0x308u | ZX_EXCP_SYNTH)
+
+typedef uint32_t zx_excp_type_t;
+
+// Assuming |excp| is an exception type, the following returns true if the
+// type is architectural.
+#define ZX_EXCP_IS_ARCH(excp) (((excp) & ZX_EXCP_SYNTH) == 0)
+
+typedef struct zx_x86_64_exc_data {
+ uint64_t vector;
+ uint64_t err_code;
+ uint64_t cr2;
+} zx_x86_64_exc_data_t;
+
+typedef struct zx_arm64_exc_data {
+ uint32_t esr;
+ uint8_t padding1[4];
+ uint64_t far;
+} zx_arm64_exc_data_t;
+
+// data associated with an exception (siginfo in linux parlance)
+// Things available from regsets (e.g., pc) are not included here.
+// For an example list of things one might add, see linux siginfo.
+typedef struct zx_exception_context {
+ struct {
+ union {
+ zx_x86_64_exc_data_t x86_64;
+ struct {
+ zx_arm64_exc_data_t arm_64;
+ uint8_t padding1[8];
+ };
+ } u;
+ } arch;
+} zx_exception_context_t;
+
+// The common header of all exception reports.
+typedef struct zx_exception_header {
+ // The actual size, in bytes, of the report (including this field).
+ uint32_t size;
+
+ zx_excp_type_t type;
+} zx_exception_header_t;
+
+// Data reported to an exception handler for most exceptions.
+typedef struct zx_exception_report {
+ zx_exception_header_t header;
+ // The remainder of the report is exception-specific.
+ zx_exception_context_t context;
+} zx_exception_report_t;
+
+// Basic info sent along with the handle over an exception channel.
+typedef struct zx_exception_info {
+ zx_koid_t pid;
+ zx_koid_t tid;
+ zx_excp_type_t type;
+ uint8_t padding1[4];
+} zx_exception_info_t;
+
+// Options for zx_create_exception_channel.
+// When creating an exception channel, use the task's debug channel.
+#define ZX_EXCEPTION_CHANNEL_DEBUGGER ((uint32_t)1)
+
+// The type of exception handler a thread may be waiting for a response from.
+// These values are reported in zx_info_thread_t.wait_exception_channel_type.
+#define ZX_EXCEPTION_CHANNEL_TYPE_NONE ((uint32_t)0u)
+#define ZX_EXCEPTION_CHANNEL_TYPE_DEBUGGER ((uint32_t)1u)
+#define ZX_EXCEPTION_CHANNEL_TYPE_THREAD ((uint32_t)2u)
+#define ZX_EXCEPTION_CHANNEL_TYPE_PROCESS ((uint32_t)3u)
+#define ZX_EXCEPTION_CHANNEL_TYPE_JOB ((uint32_t)4u)
+#define ZX_EXCEPTION_CHANNEL_TYPE_JOB_DEBUGGER ((uint32_t)5u)
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_EXCEPTION_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/hypervisor.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/hypervisor.h
new file mode 100644
index 0000000..f574d4e
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/hypervisor.h
@@ -0,0 +1,78 @@
+// Copyright 2017 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_HYPERVISOR_H_
+#define SYSROOT_ZIRCON_SYSCALLS_HYPERVISOR_H_
+
+#include <assert.h>
+
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// clang-format off
+typedef uint32_t zx_guest_trap_t;
+
+#define ZX_GUEST_TRAP_BELL ((zx_guest_trap_t) 0u)
+#define ZX_GUEST_TRAP_MEM ((zx_guest_trap_t) 1u)
+#define ZX_GUEST_TRAP_IO ((zx_guest_trap_t) 2u)
+
+typedef uint32_t zx_vcpu_t;
+
+#define ZX_VCPU_STATE ((zx_vcpu_t) 0u)
+#define ZX_VCPU_IO ((zx_vcpu_t) 1u)
+// clang-format on
+
+// Structure to read and write VCPU state.
+typedef struct zx_vcpu_state {
+#if __aarch64__
+ uint64_t x[31];
+ uint64_t sp;
+ // Contains only the user-controllable upper 4-bits (NZCV).
+ uint32_t cpsr;
+ uint8_t padding1[4];
+#elif __x86_64__
+ uint64_t rax;
+ uint64_t rcx;
+ uint64_t rdx;
+ uint64_t rbx;
+ uint64_t rsp;
+ uint64_t rbp;
+ uint64_t rsi;
+ uint64_t rdi;
+ uint64_t r8;
+ uint64_t r9;
+ uint64_t r10;
+ uint64_t r11;
+ uint64_t r12;
+ uint64_t r13;
+ uint64_t r14;
+ uint64_t r15;
+ // Contains only the user-controllable lower 32-bits.
+ uint64_t rflags;
+#endif
+} zx_vcpu_state_t;
+
+// Structure to read and write VCPU state for IO ports.
+typedef struct zx_vcpu_io {
+ uint8_t access_size;
+ uint8_t padding1[3];
+ union {
+ struct {
+ uint8_t u8;
+ uint8_t padding2[3];
+ };
+ struct {
+ uint16_t u16;
+ uint8_t padding3[2];
+ };
+ uint32_t u32;
+ uint8_t data[4];
+ };
+} zx_vcpu_io_t;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_HYPERVISOR_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/internal/cdecls.inc b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/internal/cdecls.inc
new file mode 100644
index 0000000..1a14308
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/internal/cdecls.inc
@@ -0,0 +1,1057 @@
+// 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.
+
+// WARNING: THIS FILE IS MACHINE GENERATED BY //tools/kazoo. DO NOT EDIT.
+
+#ifndef _ZX_SYSCALL_DECL
+#error "<zircon/syscalls.h> is the public API header"
+#endif
+
+_ZX_SYSCALL_DECL(bti_create, zx_status_t, /* no attributes */, 4,
+ (iommu, options, bti_id, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t iommu,
+ uint32_t options,
+ uint64_t bti_id,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(bti_pin, zx_status_t, /* no attributes */, 8,
+ (handle, options, vmo, offset, size, addrs, num_addrs, pmt), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t vmo,
+ uint64_t offset,
+ uint64_t size,
+ zx_paddr_t* addrs,
+ size_t num_addrs,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* pmt))
+
+_ZX_SYSCALL_DECL(bti_release_quarantine, zx_status_t, /* no attributes */, 1,
+ (handle), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle))
+
+_ZX_SYSCALL_DECL(cache_flush, zx_status_t, /* no attributes */, 3,
+ (addr, size, options), (
+ const void* addr,
+ size_t size,
+ uint32_t options))
+
+_ZX_SYSCALL_DECL(channel_create, zx_status_t, /* no attributes */, 3,
+ (options, out0, out1), (
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out0,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out1))
+
+_ZX_SYSCALL_DECL(channel_read, zx_status_t, /* no attributes */, 8,
+ (handle, options, bytes, handles, num_bytes, num_handles, actual_bytes, actual_handles), (
+ _ZX_SYSCALL_ANNO(use_handle("FuchsiaUnchecked")) zx_handle_t handle,
+ uint32_t options,
+ void* bytes,
+ _ZX_SYSCALL_ANNO(acquire_handle("FuchsiaUnchecked")) zx_handle_t* handles,
+ uint32_t num_bytes,
+ uint32_t num_handles,
+ uint32_t* actual_bytes,
+ uint32_t* actual_handles))
+
+_ZX_SYSCALL_DECL(channel_read_etc, zx_status_t, /* no attributes */, 8,
+ (handle, options, bytes, handles, num_bytes, num_handles, actual_bytes, actual_handles), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ void* bytes,
+ zx_handle_info_t* handles,
+ uint32_t num_bytes,
+ uint32_t num_handles,
+ uint32_t* actual_bytes,
+ uint32_t* actual_handles))
+
+_ZX_SYSCALL_DECL(channel_write, zx_status_t, /* no attributes */, 6,
+ (handle, options, bytes, num_bytes, handles, num_handles), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ const void* bytes,
+ uint32_t num_bytes,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) const zx_handle_t* handles,
+ uint32_t num_handles))
+
+_ZX_SYSCALL_DECL(channel_write_etc, zx_status_t, /* no attributes */, 6,
+ (handle, options, bytes, num_bytes, handles, num_handles), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ const void* bytes,
+ uint32_t num_bytes,
+ zx_handle_disposition_t* handles,
+ uint32_t num_handles))
+
+_ZX_SYSCALL_DECL(channel_call, zx_status_t, /* no attributes */, 6,
+ (handle, options, deadline, args, actual_bytes, actual_handles), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ zx_time_t deadline,
+ const zx_channel_call_args_t* args,
+ uint32_t* actual_bytes,
+ uint32_t* actual_handles))
+
+_ZX_SYSCALL_DECL(clock_get, zx_status_t, /* no attributes */, 2,
+ (clock_id, out), (
+ zx_clock_t clock_id,
+ zx_time_t* out))
+
+_ZX_SYSCALL_DECL(clock_get_monotonic, zx_time_t, /* no attributes */, 0,
+ (), (void))
+
+_ZX_SYSCALL_DECL(clock_adjust, zx_status_t, /* no attributes */, 3,
+ (handle, clock_id, offset), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_clock_t clock_id,
+ int64_t offset))
+
+_ZX_SYSCALL_DECL(clock_create, zx_status_t, /* no attributes */, 3,
+ (options, args, out), (
+ uint64_t options,
+ const void* args,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(clock_read, zx_status_t, /* no attributes */, 2,
+ (handle, now), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_time_t* now))
+
+_ZX_SYSCALL_DECL(clock_get_details, zx_status_t, /* no attributes */, 3,
+ (handle, options, details), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint64_t options,
+ void* details))
+
+_ZX_SYSCALL_DECL(clock_update, zx_status_t, /* no attributes */, 3,
+ (handle, options, args), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint64_t options,
+ const void* args))
+
+_ZX_SYSCALL_DECL(cprng_draw, void, /* no attributes */, 2,
+ (buffer, buffer_size), (
+ void* buffer,
+ size_t buffer_size))
+
+_ZX_SYSCALL_DECL(cprng_add_entropy, zx_status_t, /* no attributes */, 2,
+ (buffer, buffer_size), (
+ const void* buffer,
+ size_t buffer_size))
+
+_ZX_SYSCALL_DECL(debug_read, zx_status_t, /* no attributes */, 4,
+ (handle, buffer, buffer_size, actual), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ char* buffer,
+ size_t buffer_size,
+ size_t* actual))
+
+_ZX_SYSCALL_DECL(debug_write, zx_status_t, /* no attributes */, 2,
+ (buffer, buffer_size), (
+ const char* buffer,
+ size_t buffer_size))
+
+_ZX_SYSCALL_DECL(debug_send_command, zx_status_t, /* no attributes */, 3,
+ (resource, buffer, buffer_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t resource,
+ const char* buffer,
+ size_t buffer_size))
+
+_ZX_SYSCALL_DECL(debuglog_create, zx_status_t, /* no attributes */, 3,
+ (resource, options, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t resource,
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(debuglog_write, zx_status_t, /* no attributes */, 4,
+ (handle, options, buffer, buffer_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ const void* buffer,
+ size_t buffer_size))
+
+_ZX_SYSCALL_DECL(debuglog_read, zx_status_t, /* no attributes */, 4,
+ (handle, options, buffer, buffer_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ void* buffer,
+ size_t buffer_size))
+
+_ZX_SYSCALL_DECL(event_create, zx_status_t, /* no attributes */, 2,
+ (options, out), (
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(eventpair_create, zx_status_t, /* no attributes */, 3,
+ (options, out0, out1), (
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out0,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out1))
+
+_ZX_SYSCALL_DECL(exception_get_thread, zx_status_t, /* no attributes */, 2,
+ (handle, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(exception_get_process, zx_status_t, /* no attributes */, 2,
+ (handle, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(fifo_create, zx_status_t, /* no attributes */, 5,
+ (elem_count, elem_size, options, out0, out1), (
+ size_t elem_count,
+ size_t elem_size,
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out0,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out1))
+
+_ZX_SYSCALL_DECL(fifo_read, zx_status_t, /* no attributes */, 5,
+ (handle, elem_size, data, data_size, actual_count), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ size_t elem_size,
+ void* data,
+ size_t data_size,
+ size_t* actual_count))
+
+_ZX_SYSCALL_DECL(fifo_write, zx_status_t, /* no attributes */, 5,
+ (handle, elem_size, data, count, actual_count), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ size_t elem_size,
+ const void* data,
+ size_t count,
+ size_t* actual_count))
+
+_ZX_SYSCALL_DECL(framebuffer_get_info, zx_status_t, /* no attributes */, 5,
+ (resource, format, width, height, stride), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t resource,
+ uint32_t* format,
+ uint32_t* width,
+ uint32_t* height,
+ uint32_t* stride))
+
+_ZX_SYSCALL_DECL(framebuffer_set_range, zx_status_t, /* no attributes */, 7,
+ (resource, vmo, len, format, width, height, stride), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t resource,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t vmo,
+ uint32_t len,
+ uint32_t format,
+ uint32_t width,
+ uint32_t height,
+ uint32_t stride))
+
+_ZX_SYSCALL_DECL(futex_wait, zx_status_t, /* no attributes */, 4,
+ (value_ptr, current_value, new_futex_owner, deadline), (
+ const zx_futex_t* value_ptr,
+ zx_futex_t current_value,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t new_futex_owner,
+ zx_time_t deadline))
+
+_ZX_SYSCALL_DECL(futex_wake, zx_status_t, /* no attributes */, 2,
+ (value_ptr, wake_count), (
+ const zx_futex_t* value_ptr,
+ uint32_t wake_count))
+
+_ZX_SYSCALL_DECL(futex_requeue, zx_status_t, /* no attributes */, 6,
+ (value_ptr, wake_count, current_value, requeue_ptr, requeue_count, new_requeue_owner), (
+ const zx_futex_t* value_ptr,
+ uint32_t wake_count,
+ zx_futex_t current_value,
+ const zx_futex_t* requeue_ptr,
+ uint32_t requeue_count,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t new_requeue_owner))
+
+_ZX_SYSCALL_DECL(futex_wake_single_owner, zx_status_t, /* no attributes */, 1,
+ (value_ptr), (
+ const zx_futex_t* value_ptr))
+
+_ZX_SYSCALL_DECL(futex_requeue_single_owner, zx_status_t, /* no attributes */, 5,
+ (value_ptr, current_value, requeue_ptr, requeue_count, new_requeue_owner), (
+ const zx_futex_t* value_ptr,
+ zx_futex_t current_value,
+ const zx_futex_t* requeue_ptr,
+ uint32_t requeue_count,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t new_requeue_owner))
+
+_ZX_SYSCALL_DECL(futex_get_owner, zx_status_t, /* no attributes */, 2,
+ (value_ptr, koid), (
+ const zx_futex_t* value_ptr,
+ zx_koid_t* koid))
+
+_ZX_SYSCALL_DECL(guest_create, zx_status_t, /* no attributes */, 4,
+ (resource, options, guest_handle, vmar_handle), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t resource,
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* guest_handle,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* vmar_handle))
+
+_ZX_SYSCALL_DECL(guest_set_trap, zx_status_t, /* no attributes */, 6,
+ (handle, kind, addr, size, port_handle, key), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t kind,
+ zx_vaddr_t addr,
+ size_t size,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t port_handle,
+ uint64_t key))
+
+_ZX_SYSCALL_DECL(handle_close, zx_status_t, /* no attributes */, 1,
+ (handle), (
+ _ZX_SYSCALL_ANNO(release_handle("Fuchsia")) zx_handle_t handle))
+
+_ZX_SYSCALL_DECL(handle_close_many, zx_status_t, /* no attributes */, 2,
+ (handles, num_handles), (
+ _ZX_SYSCALL_ANNO(release_handle("Fuchsia")) const zx_handle_t* handles,
+ size_t num_handles))
+
+_ZX_SYSCALL_DECL(handle_duplicate, zx_status_t, /* no attributes */, 3,
+ (handle, rights, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_rights_t rights,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(handle_replace, zx_status_t, /* no attributes */, 3,
+ (handle, rights, out), (
+ _ZX_SYSCALL_ANNO(release_handle("Fuchsia")) zx_handle_t handle,
+ zx_rights_t rights,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(interrupt_create, zx_status_t, /* no attributes */, 4,
+ (src_obj, src_num, options, out_handle), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t src_obj,
+ uint32_t src_num,
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out_handle))
+
+_ZX_SYSCALL_DECL(interrupt_bind, zx_status_t, /* no attributes */, 4,
+ (handle, port_handle, key, options), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t port_handle,
+ uint64_t key,
+ uint32_t options))
+
+_ZX_SYSCALL_DECL(interrupt_wait, zx_status_t, /* no attributes */, 2,
+ (handle, out_timestamp), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_time_t* out_timestamp))
+
+_ZX_SYSCALL_DECL(interrupt_destroy, zx_status_t, /* no attributes */, 1,
+ (handle), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle))
+
+_ZX_SYSCALL_DECL(interrupt_ack, zx_status_t, /* no attributes */, 1,
+ (handle), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle))
+
+_ZX_SYSCALL_DECL(interrupt_trigger, zx_status_t, /* no attributes */, 3,
+ (handle, options, timestamp), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ zx_time_t timestamp))
+
+_ZX_SYSCALL_DECL(interrupt_bind_vcpu, zx_status_t, /* no attributes */, 3,
+ (handle, vcpu, options), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t vcpu,
+ uint32_t options))
+
+_ZX_SYSCALL_DECL(iommu_create, zx_status_t, /* no attributes */, 5,
+ (resource, type, desc, desc_size, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t resource,
+ uint32_t type,
+ const void* desc,
+ size_t desc_size,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(ioports_request, zx_status_t, /* no attributes */, 3,
+ (resource, io_addr, len), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t resource,
+ uint16_t io_addr,
+ uint32_t len))
+
+_ZX_SYSCALL_DECL(ioports_release, zx_status_t, /* no attributes */, 3,
+ (resource, io_addr, len), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t resource,
+ uint16_t io_addr,
+ uint32_t len))
+
+_ZX_SYSCALL_DECL(job_create, zx_status_t, /* no attributes */, 3,
+ (parent_job, options, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t parent_job,
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(job_set_policy, zx_status_t, /* no attributes */, 5,
+ (handle, options, topic, policy, policy_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ uint32_t topic,
+ const void* policy,
+ uint32_t policy_size))
+
+_ZX_SYSCALL_DECL(job_set_critical, zx_status_t, /* no attributes */, 3,
+ (job, options, process), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t job,
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t process))
+
+_ZX_SYSCALL_DECL(ktrace_read, zx_status_t, /* no attributes */, 5,
+ (handle, data, offset, data_size, actual), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ void* data,
+ uint32_t offset,
+ size_t data_size,
+ size_t* actual))
+
+_ZX_SYSCALL_DECL(ktrace_control, zx_status_t, /* no attributes */, 4,
+ (handle, action, options, ptr), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t action,
+ uint32_t options,
+ void* ptr))
+
+_ZX_SYSCALL_DECL(ktrace_write, zx_status_t, /* no attributes */, 4,
+ (handle, id, arg0, arg1), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t id,
+ uint32_t arg0,
+ uint32_t arg1))
+
+_ZX_SYSCALL_DECL(nanosleep, zx_status_t, /* no attributes */, 1,
+ (deadline), (
+ zx_time_t deadline))
+
+_ZX_SYSCALL_DECL(ticks_get, zx_ticks_t, /* no attributes */, 0,
+ (), (void))
+
+_ZX_SYSCALL_DECL(ticks_per_second, zx_ticks_t, __CONST, 0,
+ (), (void))
+
+_ZX_SYSCALL_DECL(deadline_after, zx_time_t, /* no attributes */, 1,
+ (nanoseconds), (
+ zx_duration_t nanoseconds))
+
+_ZX_SYSCALL_DECL(vmar_unmap_handle_close_thread_exit, zx_status_t, /* no attributes */, 4,
+ (vmar_handle, addr, size, close_handle), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t vmar_handle,
+ zx_vaddr_t addr,
+ size_t size,
+ _ZX_SYSCALL_ANNO(release_handle("Fuchsia")) zx_handle_t close_handle))
+
+_ZX_SYSCALL_DECL(futex_wake_handle_close_thread_exit, void, __NO_RETURN, 4,
+ (value_ptr, wake_count, new_value, close_handle), (
+ const zx_futex_t* value_ptr,
+ uint32_t wake_count,
+ int32_t new_value,
+ _ZX_SYSCALL_ANNO(release_handle("Fuchsia")) zx_handle_t close_handle))
+
+_ZX_SYSCALL_DECL(mtrace_control, zx_status_t, /* no attributes */, 6,
+ (handle, kind, action, options, ptr, ptr_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t kind,
+ uint32_t action,
+ uint32_t options,
+ void* ptr,
+ size_t ptr_size))
+
+_ZX_SYSCALL_DECL(object_wait_one, zx_status_t, /* no attributes */, 4,
+ (handle, signals, deadline, observed), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_signals_t signals,
+ zx_time_t deadline,
+ zx_signals_t* observed))
+
+_ZX_SYSCALL_DECL(object_wait_many, zx_status_t, /* no attributes */, 3,
+ (items, num_items, deadline), (
+ zx_wait_item_t* items,
+ size_t num_items,
+ zx_time_t deadline))
+
+_ZX_SYSCALL_DECL(object_wait_async, zx_status_t, /* no attributes */, 5,
+ (handle, port, key, signals, options), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t port,
+ uint64_t key,
+ zx_signals_t signals,
+ uint32_t options))
+
+_ZX_SYSCALL_DECL(object_signal, zx_status_t, /* no attributes */, 3,
+ (handle, clear_mask, set_mask), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t clear_mask,
+ uint32_t set_mask))
+
+_ZX_SYSCALL_DECL(object_signal_peer, zx_status_t, /* no attributes */, 3,
+ (handle, clear_mask, set_mask), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t clear_mask,
+ uint32_t set_mask))
+
+_ZX_SYSCALL_DECL(object_get_property, zx_status_t, /* no attributes */, 4,
+ (handle, property, value, value_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t property,
+ void* value,
+ size_t value_size))
+
+_ZX_SYSCALL_DECL(object_set_property, zx_status_t, /* no attributes */, 4,
+ (handle, property, value, value_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t property,
+ const void* value,
+ size_t value_size))
+
+_ZX_SYSCALL_DECL(object_get_info, zx_status_t, /* no attributes */, 6,
+ (handle, topic, buffer, buffer_size, actual, avail), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t topic,
+ void* buffer,
+ size_t buffer_size,
+ size_t* actual,
+ size_t* avail))
+
+_ZX_SYSCALL_DECL(object_get_child, zx_status_t, /* no attributes */, 4,
+ (handle, koid, rights, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint64_t koid,
+ zx_rights_t rights,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(object_set_profile, zx_status_t, /* no attributes */, 3,
+ (handle, profile, options), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t profile,
+ uint32_t options))
+
+_ZX_SYSCALL_DECL(pager_create, zx_status_t, /* no attributes */, 2,
+ (options, out), (
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(pager_create_vmo, zx_status_t, /* no attributes */, 6,
+ (pager, options, port, key, size, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t pager,
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t port,
+ uint64_t key,
+ uint64_t size,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(pager_detach_vmo, zx_status_t, /* no attributes */, 2,
+ (pager, vmo), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t pager,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t vmo))
+
+_ZX_SYSCALL_DECL(pager_supply_pages, zx_status_t, /* no attributes */, 6,
+ (pager, pager_vmo, offset, length, aux_vmo, aux_offset), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t pager,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t pager_vmo,
+ uint64_t offset,
+ uint64_t length,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t aux_vmo,
+ uint64_t aux_offset))
+
+_ZX_SYSCALL_DECL(pc_firmware_tables, zx_status_t, /* no attributes */, 3,
+ (handle, acpi_rsdp, smbios), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_paddr_t* acpi_rsdp,
+ zx_paddr_t* smbios))
+
+_ZX_SYSCALL_DECL(pci_get_nth_device, zx_status_t, /* no attributes */, 4,
+ (handle, index, out_info, out_handle), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t index,
+ zx_pcie_device_info_t* out_info,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out_handle))
+
+_ZX_SYSCALL_DECL(pci_enable_bus_master, zx_status_t, /* no attributes */, 2,
+ (handle, enable), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ bool enable))
+
+_ZX_SYSCALL_DECL(pci_reset_device, zx_status_t, /* no attributes */, 1,
+ (handle), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle))
+
+_ZX_SYSCALL_DECL(pci_config_read, zx_status_t, /* no attributes */, 4,
+ (handle, offset, width, out_val), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint16_t offset,
+ size_t width,
+ uint32_t* out_val))
+
+_ZX_SYSCALL_DECL(pci_config_write, zx_status_t, /* no attributes */, 4,
+ (handle, offset, width, val), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint16_t offset,
+ size_t width,
+ uint32_t val))
+
+_ZX_SYSCALL_DECL(pci_cfg_pio_rw, zx_status_t, /* no attributes */, 8,
+ (handle, bus, dev, func, offset, val, width, write), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint8_t bus,
+ uint8_t dev,
+ uint8_t func,
+ uint8_t offset,
+ uint32_t* val,
+ size_t width,
+ bool write))
+
+_ZX_SYSCALL_DECL(pci_get_bar, zx_status_t, /* no attributes */, 4,
+ (handle, bar_num, out_bar, out_handle), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t bar_num,
+ zx_pci_bar_t* out_bar,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out_handle))
+
+_ZX_SYSCALL_DECL(pci_map_interrupt, zx_status_t, /* no attributes */, 3,
+ (handle, which_irq, out_handle), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ int32_t which_irq,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out_handle))
+
+_ZX_SYSCALL_DECL(pci_query_irq_mode, zx_status_t, /* no attributes */, 3,
+ (handle, mode, out_max_irqs), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t mode,
+ uint32_t* out_max_irqs))
+
+_ZX_SYSCALL_DECL(pci_set_irq_mode, zx_status_t, /* no attributes */, 3,
+ (handle, mode, requested_irq_count), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t mode,
+ uint32_t requested_irq_count))
+
+_ZX_SYSCALL_DECL(pci_init, zx_status_t, /* no attributes */, 3,
+ (handle, init_buf, len), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ const zx_pci_init_arg_t* init_buf,
+ uint32_t len))
+
+_ZX_SYSCALL_DECL(pci_add_subtract_io_range, zx_status_t, /* no attributes */, 5,
+ (handle, mmio, base, len, add), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ bool mmio,
+ uint64_t base,
+ uint64_t len,
+ bool add))
+
+_ZX_SYSCALL_DECL(pmt_unpin, zx_status_t, /* no attributes */, 1,
+ (handle), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle))
+
+_ZX_SYSCALL_DECL(port_create, zx_status_t, /* no attributes */, 2,
+ (options, out), (
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(port_queue, zx_status_t, /* no attributes */, 2,
+ (handle, packet), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ const zx_port_packet_t* packet))
+
+_ZX_SYSCALL_DECL(port_wait, zx_status_t, /* no attributes */, 3,
+ (handle, deadline, packet), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_time_t deadline,
+ zx_port_packet_t* packet))
+
+_ZX_SYSCALL_DECL(port_cancel, zx_status_t, /* no attributes */, 3,
+ (handle, source, key), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t source,
+ uint64_t key))
+
+_ZX_SYSCALL_DECL(process_exit, void, __NO_RETURN, 1,
+ (retcode), (
+ int64_t retcode))
+
+_ZX_SYSCALL_DECL(process_create, zx_status_t, /* no attributes */, 6,
+ (job, name, name_size, options, proc_handle, vmar_handle), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t job,
+ const char* name,
+ size_t name_size,
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* proc_handle,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* vmar_handle))
+
+_ZX_SYSCALL_DECL(process_start, zx_status_t, /* no attributes */, 6,
+ (handle, thread, entry, stack, arg1, arg2), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t thread,
+ zx_vaddr_t entry,
+ zx_vaddr_t stack,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t arg1,
+ uintptr_t arg2))
+
+_ZX_SYSCALL_DECL(process_read_memory, zx_status_t, /* no attributes */, 5,
+ (handle, vaddr, buffer, buffer_size, actual), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_vaddr_t vaddr,
+ void* buffer,
+ size_t buffer_size,
+ size_t* actual))
+
+_ZX_SYSCALL_DECL(process_write_memory, zx_status_t, /* no attributes */, 5,
+ (handle, vaddr, buffer, buffer_size, actual), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_vaddr_t vaddr,
+ const void* buffer,
+ size_t buffer_size,
+ size_t* actual))
+
+_ZX_SYSCALL_DECL(profile_create, zx_status_t, /* no attributes */, 4,
+ (root_job, options, profile, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t root_job,
+ uint32_t options,
+ const zx_profile_info_t* profile,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(resource_create, zx_status_t, /* no attributes */, 7,
+ (parent_rsrc, options, base, size, name, name_size, resource_out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t parent_rsrc,
+ uint32_t options,
+ uint64_t base,
+ size_t size,
+ const char* name,
+ size_t name_size,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* resource_out))
+
+_ZX_SYSCALL_DECL(smc_call, zx_status_t, /* no attributes */, 3,
+ (handle, parameters, out_smc_result), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ const zx_smc_parameters_t* parameters,
+ zx_smc_result_t* out_smc_result))
+
+_ZX_SYSCALL_DECL(socket_create, zx_status_t, /* no attributes */, 3,
+ (options, out0, out1), (
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out0,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out1))
+
+_ZX_SYSCALL_DECL(socket_write, zx_status_t, /* no attributes */, 5,
+ (handle, options, buffer, buffer_size, actual), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ const void* buffer,
+ size_t buffer_size,
+ size_t* actual))
+
+_ZX_SYSCALL_DECL(socket_read, zx_status_t, /* no attributes */, 5,
+ (handle, options, buffer, buffer_size, actual), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ void* buffer,
+ size_t buffer_size,
+ size_t* actual))
+
+_ZX_SYSCALL_DECL(socket_shutdown, zx_status_t, /* no attributes */, 2,
+ (handle, options), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options))
+
+_ZX_SYSCALL_DECL(stream_create, zx_status_t, /* no attributes */, 4,
+ (options, vmo, seek, out_stream), (
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t vmo,
+ zx_off_t seek,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out_stream))
+
+_ZX_SYSCALL_DECL(stream_writev, zx_status_t, /* no attributes */, 5,
+ (handle, options, vector, num_vector, actual), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ const zx_iovec_t* vector,
+ size_t num_vector,
+ size_t* actual))
+
+_ZX_SYSCALL_DECL(stream_writev_at, zx_status_t, /* no attributes */, 6,
+ (handle, options, offset, vector, num_vector, actual), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ zx_off_t offset,
+ const zx_iovec_t* vector,
+ size_t num_vector,
+ size_t* actual))
+
+_ZX_SYSCALL_DECL(stream_readv, zx_status_t, /* no attributes */, 5,
+ (handle, options, vector, num_vector, actual), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ zx_iovec_t* vector,
+ size_t num_vector,
+ size_t* actual))
+
+_ZX_SYSCALL_DECL(stream_readv_at, zx_status_t, /* no attributes */, 6,
+ (handle, options, offset, vector, num_vector, actual), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ zx_off_t offset,
+ zx_iovec_t* vector,
+ size_t num_vector,
+ size_t* actual))
+
+_ZX_SYSCALL_DECL(stream_seek, zx_status_t, /* no attributes */, 4,
+ (handle, whence, offset, out_seek), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_stream_seek_origin_t whence,
+ int64_t offset,
+ zx_off_t* out_seek))
+
+_ZX_SYSCALL_DECL(system_get_dcache_line_size, uint32_t, __CONST, 0,
+ (), (void))
+
+_ZX_SYSCALL_DECL(system_get_num_cpus, uint32_t, __CONST, 0,
+ (), (void))
+
+_ZX_SYSCALL_DECL(system_get_version_string, zx_string_view_t, __CONST, 0,
+ (), (void))
+
+_ZX_SYSCALL_DECL(system_get_physmem, uint64_t, /* no attributes */, 0,
+ (), (void))
+
+_ZX_SYSCALL_DECL(system_get_features, zx_status_t, /* no attributes */, 2,
+ (kind, features), (
+ uint32_t kind,
+ uint32_t* features))
+
+_ZX_SYSCALL_DECL(system_get_event, zx_status_t, /* no attributes */, 3,
+ (root_job, kind, event), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t root_job,
+ uint32_t kind,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* event))
+
+_ZX_SYSCALL_DECL(system_mexec, zx_status_t, /* no attributes */, 3,
+ (resource, kernel_vmo, bootimage_vmo), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t resource,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t kernel_vmo,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t bootimage_vmo))
+
+_ZX_SYSCALL_DECL(system_mexec_payload_get, zx_status_t, /* no attributes */, 3,
+ (resource, buffer, buffer_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t resource,
+ void* buffer,
+ size_t buffer_size))
+
+_ZX_SYSCALL_DECL(system_powerctl, zx_status_t, /* no attributes */, 3,
+ (resource, cmd, arg), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t resource,
+ uint32_t cmd,
+ const zx_system_powerctl_arg_t* arg))
+
+_ZX_SYSCALL_DECL(task_suspend, zx_status_t, /* no attributes */, 2,
+ (handle, token), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* token))
+
+_ZX_SYSCALL_DECL(task_suspend_token, zx_status_t, /* no attributes */, 2,
+ (handle, token), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* token))
+
+_ZX_SYSCALL_DECL(task_create_exception_channel, zx_status_t, /* no attributes */, 3,
+ (handle, options, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(task_kill, zx_status_t, /* no attributes */, 1,
+ (handle), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle))
+
+_ZX_SYSCALL_DECL(thread_exit, void, __NO_RETURN, 0,
+ (), (void))
+
+_ZX_SYSCALL_DECL(thread_create, zx_status_t, /* no attributes */, 5,
+ (process, name, name_size, options, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t process,
+ const char* name,
+ size_t name_size,
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(thread_start, zx_status_t, /* no attributes */, 5,
+ (handle, thread_entry, stack, arg1, arg2), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_vaddr_t thread_entry,
+ zx_vaddr_t stack,
+ uintptr_t arg1,
+ uintptr_t arg2))
+
+_ZX_SYSCALL_DECL(thread_read_state, zx_status_t, /* no attributes */, 4,
+ (handle, kind, buffer, buffer_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t kind,
+ void* buffer,
+ size_t buffer_size))
+
+_ZX_SYSCALL_DECL(thread_write_state, zx_status_t, /* no attributes */, 4,
+ (handle, kind, buffer, buffer_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t kind,
+ const void* buffer,
+ size_t buffer_size))
+
+_ZX_SYSCALL_DECL(timer_create, zx_status_t, /* no attributes */, 3,
+ (options, clock_id, out), (
+ uint32_t options,
+ zx_clock_t clock_id,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(timer_set, zx_status_t, /* no attributes */, 3,
+ (handle, deadline, slack), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_time_t deadline,
+ zx_duration_t slack))
+
+_ZX_SYSCALL_DECL(timer_cancel, zx_status_t, /* no attributes */, 1,
+ (handle), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle))
+
+_ZX_SYSCALL_DECL(vcpu_create, zx_status_t, /* no attributes */, 4,
+ (guest, options, entry, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t guest,
+ uint32_t options,
+ zx_vaddr_t entry,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(vcpu_resume, zx_status_t, /* no attributes */, 2,
+ (handle, packet), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_port_packet_t* packet))
+
+_ZX_SYSCALL_DECL(vcpu_interrupt, zx_status_t, /* no attributes */, 2,
+ (handle, vector), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t vector))
+
+_ZX_SYSCALL_DECL(vcpu_read_state, zx_status_t, /* no attributes */, 4,
+ (handle, kind, buffer, buffer_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t kind,
+ void* buffer,
+ size_t buffer_size))
+
+_ZX_SYSCALL_DECL(vcpu_write_state, zx_status_t, /* no attributes */, 4,
+ (handle, kind, buffer, buffer_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t kind,
+ const void* buffer,
+ size_t buffer_size))
+
+_ZX_SYSCALL_DECL(vmar_allocate, zx_status_t, /* no attributes */, 6,
+ (parent_vmar, options, offset, size, child_vmar, child_addr), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t parent_vmar,
+ zx_vm_option_t options,
+ size_t offset,
+ size_t size,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* child_vmar,
+ zx_vaddr_t* child_addr))
+
+_ZX_SYSCALL_DECL(vmar_destroy, zx_status_t, /* no attributes */, 1,
+ (handle), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle))
+
+_ZX_SYSCALL_DECL(vmar_map, zx_status_t, /* no attributes */, 7,
+ (handle, options, vmar_offset, vmo, vmo_offset, len, mapped_addr), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_vm_option_t options,
+ size_t vmar_offset,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t vmo,
+ uint64_t vmo_offset,
+ size_t len,
+ zx_vaddr_t* mapped_addr))
+
+_ZX_SYSCALL_DECL(vmar_unmap, zx_status_t, /* no attributes */, 3,
+ (handle, addr, len), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_vaddr_t addr,
+ size_t len))
+
+_ZX_SYSCALL_DECL(vmar_protect, zx_status_t, /* no attributes */, 4,
+ (handle, options, addr, len), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ zx_vm_option_t options,
+ zx_vaddr_t addr,
+ size_t len))
+
+_ZX_SYSCALL_DECL(vmar_op_range, zx_status_t, /* no attributes */, 6,
+ (handle, op, address, size, buffer, buffer_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t op,
+ zx_vaddr_t address,
+ size_t size,
+ void* buffer,
+ size_t buffer_size))
+
+_ZX_SYSCALL_DECL(vmo_create, zx_status_t, /* no attributes */, 3,
+ (size, options, out), (
+ uint64_t size,
+ uint32_t options,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(vmo_read, zx_status_t, /* no attributes */, 4,
+ (handle, buffer, offset, buffer_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ void* buffer,
+ uint64_t offset,
+ size_t buffer_size))
+
+_ZX_SYSCALL_DECL(vmo_write, zx_status_t, /* no attributes */, 4,
+ (handle, buffer, offset, buffer_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ const void* buffer,
+ uint64_t offset,
+ size_t buffer_size))
+
+_ZX_SYSCALL_DECL(vmo_get_size, zx_status_t, /* no attributes */, 2,
+ (handle, size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint64_t* size))
+
+_ZX_SYSCALL_DECL(vmo_set_size, zx_status_t, /* no attributes */, 2,
+ (handle, size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint64_t size))
+
+_ZX_SYSCALL_DECL(vmo_op_range, zx_status_t, /* no attributes */, 6,
+ (handle, op, offset, size, buffer, buffer_size), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t op,
+ uint64_t offset,
+ uint64_t size,
+ void* buffer,
+ size_t buffer_size))
+
+_ZX_SYSCALL_DECL(vmo_create_child, zx_status_t, /* no attributes */, 5,
+ (handle, options, offset, size, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t options,
+ uint64_t offset,
+ uint64_t size,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(vmo_set_cache_policy, zx_status_t, /* no attributes */, 2,
+ (handle, cache_policy), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle,
+ uint32_t cache_policy))
+
+_ZX_SYSCALL_DECL(vmo_replace_as_executable, zx_status_t, /* no attributes */, 3,
+ (handle, vmex, out), (
+ _ZX_SYSCALL_ANNO(release_handle("Fuchsia")) zx_handle_t handle,
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t vmex,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(vmo_create_contiguous, zx_status_t, /* no attributes */, 4,
+ (bti, size, alignment_log2, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t bti,
+ size_t size,
+ uint32_t alignment_log2,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
+_ZX_SYSCALL_DECL(vmo_create_physical, zx_status_t, /* no attributes */, 4,
+ (resource, paddr, size, out), (
+ _ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t resource,
+ zx_paddr_t paddr,
+ size_t size,
+ _ZX_SYSCALL_ANNO(acquire_handle("Fuchsia")) zx_handle_t* out))
+
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/iommu.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/iommu.h
new file mode 100644
index 0000000..708b606
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/iommu.h
@@ -0,0 +1,97 @@
+// Copyright 2017 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_IOMMU_H_
+#define SYSROOT_ZIRCON_SYSCALLS_IOMMU_H_
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <zircon/compiler.h>
+
+__BEGIN_CDECLS
+
+#define ZX_IOMMU_MAX_DESC_LEN 4096
+
+// Values for the |type| argument of the zx_iommu_create() syscall.
+#define ZX_IOMMU_TYPE_DUMMY 0
+#define ZX_IOMMU_TYPE_INTEL 1
+
+// Data structures for creating a dummy IOMMU instance
+typedef struct zx_iommu_desc_dummy {
+ uint8_t reserved;
+} zx_iommu_desc_dummy_t;
+
+// Data structures for creating an Intel IOMMU instance
+
+// This scope represents a single PCI endpoint device
+#define ZX_IOMMU_INTEL_SCOPE_ENDPOINT 0
+// This scope represents a PCI-PCI bridge. The bridge and all of its downstream
+// devices will be included in this scope.
+#define ZX_IOMMU_INTEL_SCOPE_BRIDGE 1
+
+// TODO(teisenbe): Investigate FIDL for this. Multiple embedded lists seems
+// right up its alley.
+typedef struct zx_iommu_desc_intel_scope {
+ uint8_t type;
+ // The bus number of the first bus decoded by the host bridge this scope is attached to.
+ uint8_t start_bus;
+ // Number of bridges (including the host bridge) between host bridge and the
+ // device.
+ uint8_t num_hops;
+ // The device number and function numbers of the bridges along the way,
+ // ending with the device itself.
+ // |dev_func[0]| is the address on |start_bus| of the first bridge in the
+ // path (excluding the host bridge). |dev_func[num_hops-1]| is the address
+ // of the device itself.
+ uint8_t dev_func[5];
+} zx_iommu_desc_intel_scope_t;
+
+typedef struct zx_iommu_desc_intel_reserved_memory {
+ uint64_t base_addr; // Physical address of the base of reserved memory.
+ uint64_t len; // Number of bytes of reserved memory.
+
+ // The number of bytes of zx_iommu_desc_intel_scope_t's that follow this descriptor.
+ uint8_t scope_bytes;
+
+ uint8_t _reserved[7]; // Padding
+
+ // This is a list of all devices that need access to this memory range.
+ //
+ // zx_iommu_desc_intel_scope_t scopes[num_scopes];
+} zx_iommu_desc_intel_reserved_memory_t;
+
+typedef struct zx_iommu_desc_intel {
+ uint64_t register_base; // Physical address of registers
+ uint16_t pci_segment; // The PCI segment associated with this IOMMU
+
+ // If true, this IOMMU has all PCI devices in its segment under its scope.
+ // In this case, the list of scopes acts as a blacklist.
+ bool whole_segment;
+
+ // The number of bytes of zx_iommu_desc_intel_scope_t's that follow this descriptor.
+ uint8_t scope_bytes;
+
+ // The number of bytes of zx_iommu_desc_intel_reserved_memory_t's that follow the scope
+ // list.
+ uint16_t reserved_memory_bytes;
+
+ uint8_t _reserved[2]; // Padding
+
+ // If |whole_segment| is false, this is a list of all devices managed by
+ // this IOMMU. If |whole_segment| is true, this is a list of all devices on
+ // this segment *not* managed by this IOMMU. It has a total length in bytes of
+ // |scope_bytes|.
+ //
+ // zx_iommu_desc_intel_scope_t scopes[];
+
+ // A list of all BIOS-reserved memory regions this IOMMU needs to translate.
+ // It has a total length in bytes of |reserved_memory_bytes|.
+ //
+ // zx_iommu_desc_intel_reserved_memory_t reserved_mem[];
+} zx_iommu_desc_intel_t;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_IOMMU_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/log.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/log.h
new file mode 100644
index 0000000..0ea4c04
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/log.h
@@ -0,0 +1,58 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_LOG_H_
+#define SYSROOT_ZIRCON_SYSCALLS_LOG_H_
+
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// Defines and structures for zx_log_*()
+typedef struct zx_log_record {
+ uint32_t reserved;
+ uint16_t datalen;
+ uint16_t flags;
+ zx_time_t timestamp;
+ uint64_t pid;
+ uint64_t tid;
+ char data[];
+} zx_log_record_t;
+
+// ask clang format not to mess up the indentation:
+// clang-format off
+
+#define ZX_LOG_RECORD_MAX 256
+
+// Common Log Levels
+#define ZX_LOG_ERROR (0x0001)
+#define ZX_LOG_WARN (0x0002)
+#define ZX_LOG_INFO (0x0004)
+
+// Verbose log levels
+#define ZX_LOG_TRACE (0x0010)
+#define ZX_LOG_SPEW (0x0020)
+
+// Custom Log Levels
+#define ZX_LOG_DEBUG1 (0x0100)
+#define ZX_LOG_DEBUG2 (0x0200)
+#define ZX_LOG_DEBUG3 (0x0400)
+#define ZX_LOG_DEBUG4 (0x0800)
+
+// Filter Flags
+
+// Do not forward this message via network
+// (for logging in network core and drivers)
+#define ZX_LOG_LOCAL (0x1000)
+
+#define ZX_LOG_LEVEL_MASK (0x0FFF)
+#define ZX_LOG_FLAGS_MASK (0xFFFF)
+
+// Options
+
+#define ZX_LOG_FLAG_READABLE 0x40000000
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_LOG_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/object.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/object.h
new file mode 100644
index 0000000..7139ffe
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/object.h
@@ -0,0 +1,685 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_OBJECT_H_
+#define SYSROOT_ZIRCON_SYSCALLS_OBJECT_H_
+
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// ask clang format not to mess up the indentation:
+// clang-format off
+
+// Valid topics for zx_object_get_info.
+typedef uint32_t zx_object_info_topic_t;
+#define ZX_INFO_NONE ((zx_object_info_topic_t) 0u)
+#define ZX_INFO_HANDLE_VALID ((zx_object_info_topic_t) 1u)
+#define ZX_INFO_HANDLE_BASIC ((zx_object_info_topic_t) 2u) // zx_info_handle_basic_t[1]
+#define ZX_INFO_PROCESS ((zx_object_info_topic_t) 3u) // zx_info_process_t[1]
+#define ZX_INFO_PROCESS_THREADS ((zx_object_info_topic_t) 4u) // zx_koid_t[n]
+#define ZX_INFO_VMAR ((zx_object_info_topic_t) 7u) // zx_info_vmar_t[1]
+#define ZX_INFO_JOB_CHILDREN ((zx_object_info_topic_t) 8u) // zx_koid_t[n]
+#define ZX_INFO_JOB_PROCESSES ((zx_object_info_topic_t) 9u) // zx_koid_t[n]
+#define ZX_INFO_THREAD ((zx_object_info_topic_t) 10u) // zx_info_thread_t[1]
+#define ZX_INFO_THREAD_EXCEPTION_REPORT ((zx_object_info_topic_t) 11u) // zx_exception_report_t[1]
+#define ZX_INFO_TASK_STATS ((zx_object_info_topic_t) 12u) // zx_info_task_stats_t[1]
+#define ZX_INFO_PROCESS_MAPS ((zx_object_info_topic_t) 13u) // zx_info_maps_t[n]
+#define ZX_INFO_PROCESS_VMOS ((zx_object_info_topic_t) 14u) // zx_info_vmo_t[n]
+#define ZX_INFO_THREAD_STATS ((zx_object_info_topic_t) 15u) // zx_info_thread_stats_t[1]
+#define ZX_INFO_CPU_STATS ((zx_object_info_topic_t) 16u) // zx_info_cpu_stats_t[n]
+#define ZX_INFO_KMEM_STATS ((zx_object_info_topic_t) 17u) // zx_info_kmem_stats_t[1]
+#define ZX_INFO_RESOURCE ((zx_object_info_topic_t) 18u) // zx_info_resource_t[1]
+#define ZX_INFO_HANDLE_COUNT ((zx_object_info_topic_t) 19u) // zx_info_handle_count_t[1]
+#define ZX_INFO_BTI ((zx_object_info_topic_t) 20u) // zx_info_bti_t[1]
+#define ZX_INFO_PROCESS_HANDLE_STATS ((zx_object_info_topic_t) 21u) // zx_info_process_handle_stats_t[1]
+#define ZX_INFO_SOCKET ((zx_object_info_topic_t) 22u) // zx_info_socket_t[1]
+#define ZX_INFO_VMO ((zx_object_info_topic_t) 23u) // zx_info_vmo_t[1]
+#define ZX_INFO_JOB ((zx_object_info_topic_t) 24u) // zx_info_job_t[1]
+#define ZX_INFO_TIMER ((zx_object_info_topic_t) 25u) // zx_info_timer_t[1]
+#define ZX_INFO_STREAM ((zx_object_info_topic_t) 26u) // zx_info_stream_t[1]
+#define ZX_INFO_HANDLE_TABLE ((zx_object_info_topic_t) 27u) // zx_info_handle_extended_t[n]
+#define ZX_INFO_MSI ((zx_object_info_topic_t) 28u) // zx_info_msi_t[1]
+#define ZX_INFO_GUEST_STATS ((zx_object_info_topic_t) 29u) // zx_info_guest_stats_t[1]
+
+typedef uint32_t zx_obj_props_t;
+#define ZX_OBJ_PROP_NONE ((zx_obj_props_t) 0u)
+#define ZX_OBJ_PROP_WAITABLE ((zx_obj_props_t) 1u)
+
+// Return codes set when a task is killed.
+#define ZX_TASK_RETCODE_SYSCALL_KILL ((int64_t) -1024) // via zx_task_kill().
+#define ZX_TASK_RETCODE_OOM_KILL ((int64_t) -1025) // by the OOM killer.
+#define ZX_TASK_RETCODE_POLICY_KILL ((int64_t) -1026) // by the Job policy.
+#define ZX_TASK_RETCODE_VDSO_KILL ((int64_t) -1027) // by the VDSO.
+#define ZX_TASK_RETCODE_EXCEPTION_KILL ((int64_t) -1028) // Exception not handled.
+#define ZX_TASK_RETCODE_CRITICAL_PROCESS_KILL ((int64_t) -1029) // by a critical process.
+
+// Sentinel indicating an invalid or missing CPU.
+#define ZX_INFO_INVALID_CPU ((uint32_t)0xFFFFFFFFu)
+
+
+typedef struct zx_info_handle_basic {
+ // The unique id assigned by kernel to the object referenced by the
+ // handle.
+ zx_koid_t koid;
+
+ // The immutable rights assigned to the handle. Two handles that
+ // have the same koid and the same rights are equivalent and
+ // interchangeable.
+ zx_rights_t rights;
+
+ // The object type: channel, event, socket, etc.
+ zx_obj_type_t type;
+
+ // If the object referenced by the handle is related to another (such
+ // as the other end of a channel, or the parent of a job) then
+ // |related_koid| is the koid of that object, otherwise it is zero.
+ // This relationship is immutable: an object's |related_koid| does
+ // not change even if the related object no longer exists.
+ zx_koid_t related_koid;
+
+ // Set to ZX_OBJ_PROP_WAITABLE if the object referenced by the
+ // handle can be waited on; zero otherwise.
+ zx_obj_props_t props;
+
+ uint8_t padding1[4];
+} zx_info_handle_basic_t;
+
+typedef struct zx_info_handle_extended {
+ // The object type: channel, event, socket, etc.
+ zx_obj_type_t type;
+
+ // The handle value which is only valid for the process which
+ // was passed to ZX_INFO_HANDLE_TABLE.
+ zx_handle_t handle_value;
+
+ // The immutable rights assigned to the handle. Two handles that
+ // have the same koid and the same rights are equivalent and
+ // interchangeable.
+ zx_rights_t rights;
+
+ // Set to ZX_OBJ_PROP_WAITABLE if the object referenced by the
+ // handle can be waited on; zero otherwise.
+ zx_obj_props_t props;
+
+ // The unique id assigned by kernel to the object referenced by the
+ // handle.
+ zx_koid_t koid;
+
+ // If the object referenced by the handle is related to another (such
+ // as the other end of a channel, or the parent of a job) then
+ // |related_koid| is the koid of that object, otherwise it is zero.
+ // This relationship is immutable: an object's |related_koid| does
+ // not change even if the related object no longer exists.
+ zx_koid_t related_koid;
+
+ // If the object referenced by the handle has a peer, like the
+ // other end of a channel, then this is the koid of the process
+ // which currently owns it. This value is not stable; the process
+ // can change the owner at any moment.
+ //
+ // This is currently unimplemented and contains 0.
+ zx_koid_t peer_owner_koid;
+} zx_info_handle_extended_t;
+
+typedef struct zx_info_handle_count {
+ // The number of outstanding handles to a kernel object.
+ uint32_t handle_count;
+} zx_info_handle_count_t;
+
+typedef struct zx_info_process_handle_stats {
+ // The number of outstanding handles to kernel objects of each type.
+ uint32_t handle_count[ZX_OBJ_TYPE_UPPER_BOUND];
+} zx_info_process_handle_stats_t;
+
+typedef struct zx_info_process {
+ // The process's return code; only valid if |exited| is true.
+ // If the process was killed, it will be one of the ZX_TASK_RETCODE values.
+ int64_t return_code;
+
+ // True if the process has ever left the initial creation state,
+ // even if it has exited as well.
+ bool started;
+
+ // If true, the process has exited and |return_code| is valid.
+ bool exited;
+
+ // True if a debugger is attached to the process.
+ bool debugger_attached;
+
+ uint8_t padding1[5];
+} zx_info_process_t;
+
+typedef struct zx_info_job {
+ // The job's return code; only valid if |exited| is true.
+ // If the process was killed, it will be one of the ZX_TASK_RETCODE values.
+ int64_t return_code;
+
+ // If true, the job has exited and |return_code| is valid.
+ bool exited;
+
+ // True if the ZX_PROP_JOB_KILL_ON_OOM was set.
+ bool kill_on_oom;
+
+ // True if a debugger is attached to the job.
+ bool debugger_attached;
+
+ uint8_t padding1[5];
+} zx_info_job_t;
+
+typedef struct zx_info_timer {
+ // The options passed to zx_timer_create().
+ uint32_t options;
+
+ uint8_t padding1[4];
+
+ // The deadline with respect to ZX_CLOCK_MONOTONIC at which the timer will
+ // fire next.
+ //
+ // This value will be zero if the timer is not set to fire.
+ zx_time_t deadline;
+
+ // Specifies a range from deadline - slack to deadline + slack during which
+ // the timer is allowed to fire. The system uses this parameter as a hint to
+ // coalesce nearby timers.
+ //
+ // The precise coalescing behavior is controlled by the options parameter
+ // specified when the timer was created.
+ //
+ // This value will be zero if the timer is not set to fire.
+ zx_duration_t slack;
+} zx_info_timer_t;
+
+typedef struct zx_info_stream {
+ // The options passed to zx_stream_create().
+ uint32_t options;
+
+ uint8_t padding1[4];
+
+ // The current seek offset.
+ //
+ // Used by zx_stream_readv and zx_stream_writev to determine where to read
+ // and write the stream.
+ zx_off_t seek;
+
+ // The current size of the stream.
+ //
+ // The number of bytes in the stream that store data. The stream itself
+ // might have a larger capacity to avoid reallocating the underlying storage
+ // as the stream grows or shrinks.
+ uint64_t content_size;
+} zx_info_stream_t;
+
+typedef uint32_t zx_thread_state_t;
+
+typedef struct zx_info_thread {
+ // One of ZX_THREAD_STATE_* values.
+ zx_thread_state_t state;
+
+ // If |state| is ZX_THREAD_STATE_BLOCKED_EXCEPTION, the thread has gotten
+ // an exception and is waiting for the exception response from the specified
+ // handler.
+
+ // The value is one of ZX_EXCEPTION_CHANNEL_TYPE_*.
+ uint32_t wait_exception_channel_type;
+
+ // CPUs this thread may be scheduled on, as specified by
+ // a profile object applied to this thread.
+ //
+ // The kernel may not internally store invalid CPUs in the mask, so
+ // this may not exactly match the mask applied to the thread for
+ // CPUs beyond what the system is able to use.
+ zx_cpu_set_t cpu_affinity_mask;
+} zx_info_thread_t;
+
+typedef struct zx_info_thread_stats {
+ // Total accumulated running time of the thread.
+ zx_duration_t total_runtime;
+
+ // CPU number that this thread was last scheduled on, or ZX_INFO_INVALID_CPU
+ // if the thread has never been scheduled on a CPU. By the time this call
+ // returns, the thread may have been scheduled elsewhere, so this
+ // information should only be used as a hint or for statistics.
+ uint32_t last_scheduled_cpu;
+
+ uint8_t padding1[4];
+} zx_info_thread_stats_t;
+
+// Statistics about resources (e.g., memory) used by a task. Can be relatively
+// expensive to gather.
+typedef struct zx_info_task_stats {
+ // The total size of mapped memory ranges in the task.
+ // Not all will be backed by physical memory.
+ size_t mem_mapped_bytes;
+
+ // For the fields below, a byte is considered committed if it's backed by
+ // physical memory. Some of the memory may be double-mapped, and thus
+ // double-counted.
+
+ // Committed memory that is only mapped into this task.
+ size_t mem_private_bytes;
+
+ // Committed memory that is mapped into this and at least one other task.
+ size_t mem_shared_bytes;
+
+ // A number that estimates the fraction of mem_shared_bytes that this
+ // task is responsible for keeping alive.
+ //
+ // An estimate of:
+ // For each shared, committed byte:
+ // mem_scaled_shared_bytes += 1 / (number of tasks mapping this byte)
+ //
+ // This number is strictly smaller than mem_shared_bytes.
+ size_t mem_scaled_shared_bytes;
+} zx_info_task_stats_t;
+
+typedef struct zx_info_vmar {
+ // Base address of the region.
+ uintptr_t base;
+
+ // Length of the region, in bytes.
+ size_t len;
+} zx_info_vmar_t;
+
+typedef struct zx_info_bti {
+ // zx_bti_pin will always be able to return addresses that are contiguous for at
+ // least this many bytes. E.g. if this returns 1MB, then a call to
+ // zx_bti_pin() with a size of 2MB will return at most two physically-contiguous runs.
+ // If the size were 2.5MB, it will return at most three physically-contiguous runs.
+ uint64_t minimum_contiguity;
+
+ // The number of bytes in the device's address space (UINT64_MAX if 2^64).
+ uint64_t aspace_size;
+
+ // The count of the pinned memory object tokens. Requesting this count is
+ // racy, so this should only be used for informative reasons.
+ uint64_t pmo_count;
+
+ // The count of the quarantined pinned memory object tokens. Requesting this count is
+ // racy, so this should only be used for informative reasons.
+ uint64_t quarantine_count;
+} zx_info_bti_t;
+
+typedef struct zx_info_socket {
+ // The options passed to zx_socket_create().
+ uint32_t options;
+
+ uint8_t padding1[4];
+
+ // The maximum size of the receive buffer of a socket, in bytes.
+ //
+ // The receive buffer may become full at a capacity less than the maximum
+ // due to overhead.
+ size_t rx_buf_max;
+
+ // The size of the receive buffer of a socket, in bytes.
+ size_t rx_buf_size;
+
+ // The amount of data, in bytes, that is available for reading in a single
+ // zx_socket_read call.
+ //
+ // For stream sockets, this value will match |rx_buf_size|. For datagram
+ // sockets, this value will be the size of the next datagram in the receive
+ // buffer.
+ size_t rx_buf_available;
+
+ // The maximum size of the transmit buffer of a socket, in bytes.
+ //
+ // The transmit buffer may become full at a capacity less than the maximum
+ // due to overhead.
+ //
+ // Will be zero if the peer endpoint is closed.
+ size_t tx_buf_max;
+
+ // The size of the transmit buffer of a socket, in bytes.
+ //
+ // Will be zero if the peer endpoint is closed.
+ size_t tx_buf_size;
+} zx_info_socket_t;
+
+// Types and values used by ZX_INFO_PROCESS_MAPS.
+
+// Describes a VM mapping.
+typedef struct zx_info_maps_mapping {
+ // MMU flags for the mapping.
+ // Bitwise OR of ZX_VM_PERM_{READ,WRITE,EXECUTE} values.
+ zx_vm_option_t mmu_flags;
+ uint8_t padding1[4];
+ // koid of the mapped VMO.
+ zx_koid_t vmo_koid;
+ // Offset into the above VMO.
+ uint64_t vmo_offset;
+ // The number of PAGE_SIZE pages in the mapped region of the VMO
+ // that are backed by physical memory.
+ size_t committed_pages;
+} zx_info_maps_mapping_t;
+
+// Types of entries represented by zx_info_maps_t.
+// Can't use zx_obj_type_t because not all of these are
+// user-visible kernel object types.
+typedef uint32_t zx_info_maps_type_t;
+#define ZX_INFO_MAPS_TYPE_NONE ((zx_info_maps_type_t) 0u)
+#define ZX_INFO_MAPS_TYPE_ASPACE ((zx_info_maps_type_t) 1u)
+#define ZX_INFO_MAPS_TYPE_VMAR ((zx_info_maps_type_t) 2u)
+#define ZX_INFO_MAPS_TYPE_MAPPING ((zx_info_maps_type_t) 3u)
+
+// Describes a node in the aspace/vmar/mapping hierarchy for a user process.
+typedef struct zx_info_maps {
+ // Name if available; empty string otherwise.
+ char name[ZX_MAX_NAME_LEN];
+ // Base address.
+ zx_vaddr_t base;
+ // Size in bytes.
+ size_t size;
+
+ // The depth of this node in the tree.
+ // Can be used for indentation, or to rebuild the tree from an array
+ // of zx_info_maps_t entries, which will be in depth-first pre-order.
+ size_t depth;
+ // The type of this entry; indicates which union entry is valid.
+ zx_info_maps_type_t type;
+ uint8_t padding1[4];
+ union {
+ zx_info_maps_mapping_t mapping;
+ // No additional fields for other types.
+ } u;
+} zx_info_maps_t;
+
+
+// Values and types used by ZX_INFO_PROCESS_VMOS.
+
+// The VMO is backed by RAM, consuming memory.
+// Mutually exclusive with ZX_INFO_VMO_TYPE_PHYSICAL.
+// See ZX_INFO_VMO_TYPE(flags)
+#define ZX_INFO_VMO_TYPE_PAGED (1u<<0)
+
+// The VMO points to a physical address range, and does not consume memory.
+// Typically used to access memory-mapped hardware.
+// Mutually exclusive with ZX_INFO_VMO_TYPE_PAGED.
+// See ZX_INFO_VMO_TYPE(flags)
+#define ZX_INFO_VMO_TYPE_PHYSICAL (0u<<0)
+
+// Returns a VMO's type based on its flags, allowing for checks like
+// if (ZX_INFO_VMO_TYPE(f) == ZX_INFO_VMO_TYPE_PAGED)
+#define ZX_INFO_VMO_TYPE(flags) ((flags) & (1u<<0))
+
+// The VMO is resizable.
+#define ZX_INFO_VMO_RESIZABLE (1u<<1)
+
+// The VMO is a child, and is a copy-on-write clone.
+#define ZX_INFO_VMO_IS_COW_CLONE (1u<<2)
+
+// When reading a list of VMOs pointed to by a process, indicates that the
+// process has a handle to the VMO, which isn't necessarily mapped.
+#define ZX_INFO_VMO_VIA_HANDLE (1u<<3)
+
+// When reading a list of VMOs pointed to by a process, indicates that the
+// process maps the VMO into a VMAR, but doesn't necessarily have a handle to
+// the VMO.
+#define ZX_INFO_VMO_VIA_MAPPING (1u<<4)
+
+// The VMO is a pager owned VMO created by zx_pager_create_vmo or is
+// a clone of a VMO with this flag set. Will only be set on VMOs with
+// the ZX_INFO_VMO_TYPE_PAGED flag set.
+#define ZX_INFO_VMO_PAGER_BACKED (1u<<5)
+
+// The VMO is contiguous
+#define ZX_INFO_VMO_CONTIGUOUS (1u<<6)
+
+// Describes a VMO. For mapping information, see |zx_info_maps_t|.
+typedef struct zx_info_vmo {
+ // The koid of this VMO.
+ zx_koid_t koid;
+
+ // The name of this VMO.
+ char name[ZX_MAX_NAME_LEN];
+
+ // The size of this VMO; i.e., the amount of virtual address space it
+ // would consume if mapped.
+ uint64_t size_bytes;
+
+ // If this VMO is a clone, the koid of its parent. Otherwise, zero.
+ // See |flags| for the type of clone.
+ zx_koid_t parent_koid;
+
+ // The number of clones of this VMO, if any.
+ size_t num_children;
+
+ // The number of times this VMO is currently mapped into VMARs.
+ // Note that the same process will often map the same VMO twice,
+ // and both mappings will be counted here. (I.e., this is not a count
+ // of the number of processes that map this VMO; see share_count.)
+ size_t num_mappings;
+
+ // An estimate of the number of unique address spaces that
+ // this VMO is mapped into. Every process has its own address space,
+ // and so does the kernel.
+ size_t share_count;
+
+ // Bitwise OR of ZX_INFO_VMO_* values.
+ uint32_t flags;
+
+ uint8_t padding1[4];
+
+ // If |ZX_INFO_VMO_TYPE(flags) == ZX_INFO_VMO_TYPE_PAGED|, the amount of
+ // memory currently allocated to this VMO; i.e., the amount of physical
+ // memory it consumes. Undefined otherwise.
+ uint64_t committed_bytes;
+
+ // If |flags & ZX_INFO_VMO_VIA_HANDLE|, the handle rights.
+ // Undefined otherwise.
+ zx_rights_t handle_rights;
+
+ // VMO mapping cache policy. One of ZX_CACHE_POLICY_*
+ uint32_t cache_policy;
+} zx_info_vmo_t;
+
+typedef struct zx_info_guest_stats {
+ uint32_t cpu_number;
+ uint32_t flags;
+
+ uint64_t vm_entries;
+ uint64_t vm_exits;
+#ifdef __aarch64__
+ uint64_t wfi_wfe_instructions;
+ uint64_t instruction_aborts;
+ uint64_t data_aborts;
+ uint64_t system_instructions;
+ uint64_t smc_instructions;
+ uint64_t interrupts;
+#else
+ uint64_t interrupts;
+ uint64_t interrupt_windows;
+ uint64_t cpuid_instructions;
+ uint64_t hlt_instructions;
+ uint64_t control_register_accesses;
+ uint64_t io_instructions;
+ uint64_t rdmsr_instructions;
+ uint64_t wrmsr_instructions;
+ uint64_t ept_violations;
+ uint64_t xsetbv_instructions;
+ uint64_t pause_instructions;
+ uint64_t vmcall_instructions;
+#endif
+} zx_info_guest_stats_t;
+
+// kernel statistics per cpu
+// TODO(cpu), expose the deprecated stats via a new syscall.
+typedef struct zx_info_cpu_stats {
+ uint32_t cpu_number;
+ uint32_t flags;
+
+ zx_duration_t idle_time;
+
+ // kernel scheduler counters
+ uint64_t reschedules;
+ uint64_t context_switches;
+ uint64_t irq_preempts;
+ uint64_t preempts;
+ uint64_t yields;
+
+ // cpu level interrupts and exceptions
+ uint64_t ints; // hardware interrupts, minus timer interrupts or inter-processor interrupts
+ uint64_t timer_ints; // timer interrupts
+ uint64_t timers; // timer callbacks
+ uint64_t page_faults; // (deprecated, returns 0) page faults
+ uint64_t exceptions; // (deprecated, returns 0) exceptions such as undefined opcode
+ uint64_t syscalls;
+
+ // inter-processor interrupts
+ uint64_t reschedule_ipis;
+ uint64_t generic_ipis;
+} zx_info_cpu_stats_t;
+
+// Information about kernel memory usage.
+// Can be expensive to gather.
+typedef struct zx_info_kmem_stats {
+ // The total amount of physical memory available to the system.
+ uint64_t total_bytes;
+
+ // The amount of unallocated memory.
+ uint64_t free_bytes;
+
+ // The amount of memory reserved by and mapped into the kernel for reasons
+ // not covered by other fields in this struct. Typically for readonly data
+ // like the ram disk and kernel image, and for early-boot dynamic memory.
+ uint64_t wired_bytes;
+
+ // The amount of memory allocated to the kernel heap.
+ uint64_t total_heap_bytes;
+
+ // The portion of |total_heap_bytes| that is not in use.
+ uint64_t free_heap_bytes;
+
+ // The amount of memory committed to VMOs, both kernel and user.
+ // A superset of all userspace memory.
+ // Does not include certain VMOs that fall under |wired_bytes|.
+ //
+ // TODO(dbort): Break this into at least two pieces: userspace VMOs that
+ // have koids, and kernel VMOs that don't. Or maybe look at VMOs
+ // mapped into the kernel aspace vs. everything else.
+ uint64_t vmo_bytes;
+
+ // The amount of memory used for architecture-specific MMU metadata
+ // like page tables.
+ uint64_t mmu_overhead_bytes;
+
+ // The amount of memory in use by IPC.
+ uint64_t ipc_bytes;
+
+ // Non-free memory that isn't accounted for in any other field.
+ uint64_t other_bytes;
+} zx_info_kmem_stats_t;
+
+typedef struct zx_info_resource {
+ // The resource kind; resource object kinds are detailed in the resource.md
+ uint32_t kind;
+ // Resource's creation flags
+ uint32_t flags;
+ // Resource's base value (inclusive)
+ uint64_t base;
+ // Resource's length value
+ size_t size;
+ char name[ZX_MAX_NAME_LEN];
+} zx_info_resource_t;
+
+typedef struct zx_info_msi {
+ // The target adress for write transactions.
+ uint64_t target_addr;
+ // The data that the device ill write when triggering an IRQ.
+ uint32_t target_data;
+ // The first IRQ in the allocated block.
+ uint32_t base_irq_id;
+ // The number of IRQs in the allocated block.
+ uint32_t num_irq;
+} zx_info_msi_t;
+
+
+#define ZX_INFO_CPU_STATS_FLAG_ONLINE (1u<<0)
+
+// Object properties.
+
+// Argument is a char[ZX_MAX_NAME_LEN].
+#define ZX_PROP_NAME ((uint32_t) 3u)
+
+#if __x86_64__
+// Argument is a uintptr_t.
+#define ZX_PROP_REGISTER_GS ((uint32_t) 2u)
+#define ZX_PROP_REGISTER_FS ((uint32_t) 4u)
+#endif
+
+// Argument is the value of ld.so's _dl_debug_addr, a uintptr_t. If the
+// property is set to the magic value of ZX_PROCESS_DEBUG_ADDR_BREAK_ON_SET
+// on process startup, ld.so will trigger a debug breakpoint immediately after
+// setting the property to the correct value.
+#define ZX_PROP_PROCESS_DEBUG_ADDR ((uint32_t) 5u)
+#define ZX_PROCESS_DEBUG_ADDR_BREAK_ON_SET ((uintptr_t) 1u)
+
+// Argument is the base address of the vDSO mapping (or zero), a uintptr_t.
+#define ZX_PROP_PROCESS_VDSO_BASE_ADDRESS ((uint32_t) 6u)
+
+// Whether the dynamic loader should issue a debug trap when loading a shared library,
+// either initially or when running (e.g. dlopen).
+//
+// See docs/reference/syscalls/object_get_property.md
+// See third_party/ulib/musl/ldso/dynlink.c.
+#define ZX_PROP_PROCESS_BREAK_ON_LOAD ((uint32_t) 7u)
+
+// The process's context id as recorded by h/w instruction tracing, a uintptr_t.
+// On X86 this is the cr3 value.
+// TODO(dje): Wasn't sure whether the gaps in property numbers are unusable
+// due to being old dleeted values. For now I just picked something.
+#define ZX_PROP_PROCESS_HW_TRACE_CONTEXT_ID ((uint32_t) 8u)
+
+// Argument is a size_t.
+#define ZX_PROP_SOCKET_RX_THRESHOLD 12u
+#define ZX_PROP_SOCKET_TX_THRESHOLD 13u
+
+// Terminate this job if the system is low on memory.
+#define ZX_PROP_JOB_KILL_ON_OOM 15u
+
+// Exception close behavior.
+#define ZX_PROP_EXCEPTION_STATE 16u
+
+// The size of the content in a VMO, in bytes.
+//
+// The content size of a VMO can be larger or smaller than the actual size of
+// the VMO.
+//
+// Argument is a uint64_t.
+#define ZX_PROP_VMO_CONTENT_SIZE 17u
+
+// Basic thread states, in zx_info_thread_t.state.
+#define ZX_THREAD_STATE_NEW ((zx_thread_state_t) 0x0000u)
+#define ZX_THREAD_STATE_RUNNING ((zx_thread_state_t) 0x0001u)
+#define ZX_THREAD_STATE_SUSPENDED ((zx_thread_state_t) 0x0002u)
+// ZX_THREAD_STATE_BLOCKED is never returned by itself.
+// It is always returned with a more precise reason.
+// See ZX_THREAD_STATE_BLOCKED_* below.
+#define ZX_THREAD_STATE_BLOCKED ((zx_thread_state_t) 0x0003u)
+#define ZX_THREAD_STATE_DYING ((zx_thread_state_t) 0x0004u)
+#define ZX_THREAD_STATE_DEAD ((zx_thread_state_t) 0x0005u)
+
+// More precise thread states.
+#define ZX_THREAD_STATE_BLOCKED_EXCEPTION ((zx_thread_state_t) 0x0103u)
+#define ZX_THREAD_STATE_BLOCKED_SLEEPING ((zx_thread_state_t) 0x0203u)
+#define ZX_THREAD_STATE_BLOCKED_FUTEX ((zx_thread_state_t) 0x0303u)
+#define ZX_THREAD_STATE_BLOCKED_PORT ((zx_thread_state_t) 0x0403u)
+#define ZX_THREAD_STATE_BLOCKED_CHANNEL ((zx_thread_state_t) 0x0503u)
+#define ZX_THREAD_STATE_BLOCKED_WAIT_ONE ((zx_thread_state_t) 0x0603u)
+#define ZX_THREAD_STATE_BLOCKED_WAIT_MANY ((zx_thread_state_t) 0x0703u)
+#define ZX_THREAD_STATE_BLOCKED_INTERRUPT ((zx_thread_state_t) 0x0803u)
+#define ZX_THREAD_STATE_BLOCKED_PAGER ((zx_thread_state_t) 0x0903u)
+
+// Reduce possibly-more-precise state to a basic state.
+// Useful if, for example, you want to check for BLOCKED on anything.
+#define ZX_THREAD_STATE_BASIC(n) ((n) & 0xff)
+
+// How a thread should behave when the current exception is closed.
+#define ZX_EXCEPTION_STATE_TRY_NEXT 0u
+#define ZX_EXCEPTION_STATE_HANDLED 1u
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_OBJECT_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/pci.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/pci.h
new file mode 100644
index 0000000..d1049c2
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/pci.h
@@ -0,0 +1,134 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_PCI_H_
+#define SYSROOT_ZIRCON_SYSCALLS_PCI_H_
+
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// ask clang format not to mess up the indentation:
+// clang-format off
+
+
+// Base Address Registers are accessed in userspace via the get_bar protocol method. The
+// Bar is represented via a pci_bar_t struct which contains a handle pointer to a VMO
+// in the case of an MMIO bar, as well as a PIO addr/size pair for the memory region
+// to access if a PIO bar. In the latter case, the protocol will acquire the appropriate
+// permissions for the process to write to that PIO region on that architecture.
+typedef uint32_t zx_pci_bar_types_t;
+#define ZX_PCI_BAR_TYPE_UNUSED ((zx_pci_bar_types_t) 0u)
+#define ZX_PCI_BAR_TYPE_MMIO ((zx_pci_bar_types_t) 1u)
+#define ZX_PCI_BAR_TYPE_PIO ((zx_pci_bar_types_t) 2u)
+
+// TODO(cja): This makes some assumptions that anything in an arch's PIO region
+// is going to be defined as a base address and size. This will need to be
+// updated to a per-platform structure in the event that doesn't pan out
+// in the future.
+typedef struct zx_pci_bar {
+ uint32_t id;
+ uint32_t type;
+ size_t size;
+ union {
+ uintptr_t addr;
+ struct {
+ zx_handle_t handle;
+ uint8_t padding1[4];
+ };
+ };
+} zx_pci_bar_t;
+
+// Defines and structures related to zx_pci_*()
+// Info returned to dev manager for PCIe devices when probing.
+typedef struct zx_pcie_device_info {
+ uint16_t vendor_id;
+ uint16_t device_id;
+
+ uint8_t base_class;
+ uint8_t sub_class;
+ uint8_t program_interface;
+ uint8_t revision_id;
+
+ uint8_t bus_id;
+ uint8_t dev_id;
+ uint8_t func_id;
+
+ uint8_t padding1;
+} zx_pcie_device_info_t;
+
+#define ZX_PCI_MAX_BUSSES (256u)
+#define ZX_PCI_MAX_DEVICES_PER_BUS (32u)
+#define ZX_PCI_MAX_FUNCTIONS_PER_DEVICE (8u)
+#define ZX_PCI_MAX_FUNCTIONS_PER_BUS (ZX_PCI_MAX_DEVICES_PER_BUS * ZX_PCI_MAX_FUNCTIONS_PER_DEVICE)
+
+#define ZX_PCI_MAX_LEGACY_IRQ_PINS (4u)
+#define ZX_PCI_MAX_MSI_IRQS (32u)
+#define ZX_PCI_MAX_MSIX_IRQS (2048u)
+
+#define ZX_PCI_STANDARD_CONFIG_HDR_SIZE (64u)
+#define ZX_PCI_BASE_CONFIG_SIZE (256u)
+#define ZX_PCI_EXTENDED_CONFIG_SIZE (4096u)
+#define ZX_PCI_ECAM_BYTE_PER_BUS (ZX_PCI_EXTENDED_CONFIG_SIZE * ZX_PCI_MAX_FUNCTIONS_PER_BUS)
+
+#define ZX_PCI_BAR_REGS_PER_BRIDGE (2u)
+#define ZX_PCI_BAR_REGS_PER_DEVICE (6u)
+#define ZX_PCI_MAX_BAR_REGS (6u)
+
+#define ZX_PCI_NO_IRQ_MAPPING UINT32_MAX
+
+// Used for zx_pci_init_arg_t::addr_windows::cfg_space_type
+#define PCI_CFG_SPACE_TYPE_PIO (0u)
+#define PCI_CFG_SPACE_TYPE_MMIO (1u)
+#define PCI_CFG_SPACE_TYPE_DW_ROOT (2u) // Designware Root Bridge ECAM
+#define PCI_CFG_SPACE_TYPE_DW_DS (3u) // Designware Downstream ECAM
+
+// Dimensions: device id, function id, legacy pin number
+// ZX_PCI_NO_IRQ_MAPPING if no mapping specified.
+typedef uint32_t zx_pci_irq_swizzle_lut_t[ZX_PCI_MAX_DEVICES_PER_BUS]
+ [ZX_PCI_MAX_FUNCTIONS_PER_DEVICE]
+ [ZX_PCI_MAX_LEGACY_IRQ_PINS];
+
+// We support up to 224 IRQs on a system, this is the maximum supported by
+// LAPICs (today) so this should be a safe number.
+#define ZX_PCI_MAX_IRQS 224
+
+typedef struct zx_pci_init_arg {
+ zx_pci_irq_swizzle_lut_t dev_pin_to_global_irq;
+
+ uint32_t num_irqs;
+ struct {
+ uint32_t global_irq;
+ bool level_triggered;
+ bool active_high;
+ uint8_t padding1[2];
+ } irqs[ZX_PCI_MAX_IRQS];
+
+ uint32_t addr_window_count;
+ struct {
+ uint64_t base;
+ size_t size;
+ uint8_t bus_start;
+ uint8_t bus_end;
+ uint8_t cfg_space_type;
+ bool has_ecam;
+ uint8_t padding1[4];
+ } addr_windows[];
+} zx_pci_init_arg_t;
+
+#define ZX_PCI_INIT_ARG_MAX_ECAM_WINDOWS 2
+#define ZX_PCI_INIT_ARG_MAX_SIZE (sizeof(((zx_pci_init_arg_t*)NULL)->addr_windows[0]) * \
+ ZX_PCI_INIT_ARG_MAX_ECAM_WINDOWS + \
+ sizeof(zx_pci_init_arg_t))
+
+// Enum used to select PCIe IRQ modes
+typedef uint32_t zx_pci_irq_mode_t;
+#define ZX_PCIE_IRQ_MODE_DISABLED ((zx_pci_irq_mode_t) 0u)
+#define ZX_PCIE_IRQ_MODE_LEGACY ((zx_pci_irq_mode_t) 1u)
+#define ZX_PCIE_IRQ_MODE_MSI ((zx_pci_irq_mode_t) 2u)
+#define ZX_PCIE_IRQ_MODE_MSI_X ((zx_pci_irq_mode_t) 3u)
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_PCI_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/policy.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/policy.h
new file mode 100644
index 0000000..158c604
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/policy.h
@@ -0,0 +1,89 @@
+// Copyright 2017 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_POLICY_H_
+#define SYSROOT_ZIRCON_SYSCALLS_POLICY_H_
+
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// ask clang format not to mess up the indentation:
+// clang-format off
+
+// Policy is applied for the conditions that are not
+// specified by the parent job policy.
+#define ZX_JOB_POL_RELATIVE 0u
+// Policy is either applied as-is or the syscall fails.
+#define ZX_JOB_POL_ABSOLUTE 1u
+
+// Basic policy topic.
+#define ZX_JOB_POL_BASIC_V1 0u
+#define ZX_JOB_POL_BASIC_V2 0x01000000u
+
+// Timer slack policy topic.
+#define ZX_JOB_POL_TIMER_SLACK 1u
+
+// Input structure to use with ZX_JOB_POL_BASIC_V1.
+typedef struct zx_policy_basic_v1 {
+ uint32_t condition;
+ uint32_t policy;
+} zx_policy_basic_v1_t;
+
+// Input structure to use with ZX_JOB_POL_BASIC_V2.
+typedef struct zx_policy_basic_v2 {
+ uint32_t condition;
+ uint32_t action;
+ uint32_t flags;
+} zx_policy_basic_v2_t;
+
+#define ZX_JOB_POL_BASIC ZX_JOB_POL_BASIC_V1
+typedef struct zx_policy_basic_v1 zx_policy_basic;
+typedef struct zx_policy_basic_v1 zx_policy_basic_t;
+
+// Conditions handled by job policy.
+#define ZX_POL_BAD_HANDLE 0u
+#define ZX_POL_WRONG_OBJECT 1u
+#define ZX_POL_VMAR_WX 2u
+#define ZX_POL_NEW_ANY 3u
+#define ZX_POL_NEW_VMO 4u
+#define ZX_POL_NEW_CHANNEL 5u
+#define ZX_POL_NEW_EVENT 6u
+#define ZX_POL_NEW_EVENTPAIR 7u
+#define ZX_POL_NEW_PORT 8u
+#define ZX_POL_NEW_SOCKET 9u
+#define ZX_POL_NEW_FIFO 10u
+#define ZX_POL_NEW_TIMER 11u
+#define ZX_POL_NEW_PROCESS 12u
+#define ZX_POL_NEW_PROFILE 13u
+#define ZX_POL_AMBIENT_MARK_VMO_EXEC 14u
+#ifdef _KERNEL
+#define ZX_POL_MAX 15u
+#endif
+
+// Policy actions.
+#define ZX_POL_ACTION_ALLOW 0u
+#define ZX_POL_ACTION_DENY 1u
+#define ZX_POL_ACTION_ALLOW_EXCEPTION 2u
+#define ZX_POL_ACTION_DENY_EXCEPTION 3u
+#define ZX_POL_ACTION_KILL 4u
+#ifdef _KERNEL
+#define ZX_POL_ACTION_MAX 5u
+#endif
+
+// Policy override.
+#define ZX_POL_OVERRIDE_ALLOW 0u
+#define ZX_POL_OVERRIDE_DENY 1u
+
+
+// Input structure to use with ZX_JOB_POL_TIMER_SLACK.
+typedef struct zx_policy_timer_slack {
+ zx_duration_t min_slack;
+ uint32_t default_mode;
+ uint8_t padding1[4];
+} zx_policy_timer_slack_t;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_POLICY_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/port.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/port.h
new file mode 100644
index 0000000..9feb4dc
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/port.h
@@ -0,0 +1,173 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_PORT_H_
+#define SYSROOT_ZIRCON_SYSCALLS_PORT_H_
+
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// clang-format off
+
+// zx_object_wait_async() options
+#define ZX_WAIT_ASYNC_ONCE ((uint32_t)0u)
+#define ZX_WAIT_ASYNC_TIMESTAMP ((uint32_t)1u)
+
+// packet types. zx_port_packet_t::type
+#define ZX_PKT_TYPE_USER ((uint8_t)0x00u)
+#define ZX_PKT_TYPE_SIGNAL_ONE ((uint8_t)0x01u)
+// 0x02 was previously used for "ZX_PKT_TYPE_SIGNAL_REP".
+#define ZX_PKT_TYPE_GUEST_BELL ((uint8_t)0x03u)
+#define ZX_PKT_TYPE_GUEST_MEM ((uint8_t)0x04u)
+#define ZX_PKT_TYPE_GUEST_IO ((uint8_t)0x05u)
+#define ZX_PKT_TYPE_GUEST_VCPU ((uint8_t)0x06u)
+#define ZX_PKT_TYPE_INTERRUPT ((uint8_t)0x07u)
+#define ZX_PKT_TYPE_PAGE_REQUEST ((uint8_t)0x09u)
+
+// For options passed to port_create
+#define ZX_PORT_BIND_TO_INTERRUPT ((uint32_t)(0x1u << 0))
+
+#define ZX_PKT_TYPE_MASK ((uint32_t)0x000000FFu)
+
+#define ZX_PKT_IS_USER(type) ((type) == ZX_PKT_TYPE_USER)
+#define ZX_PKT_IS_SIGNAL_ONE(type) ((type) == ZX_PKT_TYPE_SIGNAL_ONE)
+#define ZX_PKT_IS_GUEST_BELL(type) ((type) == ZX_PKT_TYPE_GUEST_BELL)
+#define ZX_PKT_IS_GUEST_MEM(type) ((type) == ZX_PKT_TYPE_GUEST_MEM)
+#define ZX_PKT_IS_GUEST_IO(type) ((type) == ZX_PKT_TYPE_GUEST_IO)
+#define ZX_PKT_IS_GUEST_VCPU(type) ((type) == ZX_PKT_TYPE_GUEST_VCPU)
+#define ZX_PKT_IS_INTERRUPT(type) ((type) == ZX_PKT_TYPE_INTERRUPT)
+#define ZX_PKT_IS_PAGE_REQUEST(type) ((type) == ZX_PKT_TYPE_PAGE_REQUEST)
+
+// zx_packet_guest_vcpu_t::type
+#define ZX_PKT_GUEST_VCPU_INTERRUPT ((uint8_t)0)
+#define ZX_PKT_GUEST_VCPU_STARTUP ((uint8_t)1)
+
+// zx_packet_page_request_t::command
+#define ZX_PAGER_VMO_READ ((uint16_t) 0)
+#define ZX_PAGER_VMO_COMPLETE ((uint16_t) 1)
+// clang-format on
+
+// port_packet_t::type ZX_PKT_TYPE_USER.
+typedef union zx_packet_user {
+ uint64_t u64[4];
+ uint32_t u32[8];
+ uint16_t u16[16];
+ uint8_t c8[32];
+} zx_packet_user_t;
+
+// port_packet_t::type ZX_PKT_TYPE_SIGNAL_ONE.
+typedef struct zx_packet_signal {
+ zx_signals_t trigger;
+ zx_signals_t observed;
+ uint64_t count;
+ uint64_t timestamp;
+ uint64_t reserved1;
+} zx_packet_signal_t;
+
+typedef struct zx_packet_guest_bell {
+ zx_gpaddr_t addr;
+ uint64_t reserved0;
+ uint64_t reserved1;
+ uint64_t reserved2;
+} zx_packet_guest_bell_t;
+
+typedef struct zx_packet_guest_mem {
+ zx_gpaddr_t addr;
+#if __aarch64__
+ uint8_t access_size;
+ bool sign_extend;
+ uint8_t xt;
+ bool read;
+ uint8_t padding1[4];
+ uint64_t data;
+ uint64_t reserved;
+#elif __x86_64__
+// NOTE: x86 instructions are guaranteed to be 15 bytes or fewer.
+#define X86_MAX_INST_LEN 15u
+ uint8_t inst_len;
+ uint8_t inst_buf[X86_MAX_INST_LEN];
+ // This is the default operand size as determined by the CS and EFER register (Volume 3,
+ // Section 5.2.1). If operating in 64-bit mode then near branches and all instructions, except
+ // far branches, that implicitly reference the RSP will actually have a default operand size of
+ // 64-bits (Volume 2, Section 2.2.1.7), and not the 32-bits that will be given here.
+ uint8_t default_operand_size;
+ uint8_t reserved[7];
+#endif
+} zx_packet_guest_mem_t;
+
+typedef struct zx_packet_guest_io {
+ uint16_t port;
+ uint8_t access_size;
+ bool input;
+ union {
+ struct {
+ uint8_t u8;
+ uint8_t padding1[3];
+ };
+ struct {
+ uint16_t u16;
+ uint8_t padding2[2];
+ };
+ uint32_t u32;
+ uint8_t data[4];
+ };
+ uint64_t reserved0;
+ uint64_t reserved1;
+ uint64_t reserved2;
+} zx_packet_guest_io_t;
+
+typedef struct zx_packet_guest_vcpu {
+ union {
+ struct {
+ uint64_t mask;
+ uint8_t vector;
+ uint8_t padding1[7];
+ } interrupt;
+ struct {
+ uint64_t id;
+ zx_gpaddr_t entry;
+ } startup;
+ };
+ uint8_t type;
+ uint8_t padding1[7];
+ uint64_t reserved;
+} zx_packet_guest_vcpu_t;
+
+typedef struct zx_packet_interrupt {
+ zx_time_t timestamp;
+ uint64_t reserved0;
+ uint64_t reserved1;
+ uint64_t reserved2;
+} zx_packet_interrupt_t;
+
+typedef struct zx_packet_page_request {
+ uint16_t command;
+ uint16_t flags;
+ uint32_t reserved0;
+ uint64_t offset;
+ uint64_t length;
+ uint64_t reserved1;
+} zx_packet_page_request_t;
+
+typedef struct zx_port_packet {
+ uint64_t key;
+ uint32_t type;
+ zx_status_t status;
+ union {
+ zx_packet_user_t user;
+ zx_packet_signal_t signal;
+ zx_packet_guest_bell_t guest_bell;
+ zx_packet_guest_mem_t guest_mem;
+ zx_packet_guest_io_t guest_io;
+ zx_packet_guest_vcpu_t guest_vcpu;
+ zx_packet_interrupt_t interrupt;
+ zx_packet_page_request_t page_request;
+ };
+} zx_port_packet_t;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_PORT_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/profile.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/profile.h
new file mode 100644
index 0000000..5abf561
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/profile.h
@@ -0,0 +1,49 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_PROFILE_H_
+#define SYSROOT_ZIRCON_SYSCALLS_PROFILE_H_
+
+#include <zircon/syscalls/scheduler.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+#define ZX_PRIORITY_LOWEST 0
+#define ZX_PRIORITY_LOW 8
+#define ZX_PRIORITY_DEFAULT 16
+#define ZX_PRIORITY_HIGH 24
+#define ZX_PRIORITY_HIGHEST 31
+
+#define ZX_PROFILE_INFO_FLAG_PRIORITY (1 << 0)
+#define ZX_PROFILE_INFO_FLAG_CPU_MASK (1 << 1)
+#define ZX_PROFILE_INFO_FLAG_DEADLINE (1 << 2)
+
+typedef struct zx_profile_info {
+ // A bitmask of ZX_PROFILE_INFO_FLAG_* values. Specifies which fields
+ // below have been specified. Other fields are considered unset.
+ uint32_t flags;
+
+ uint8_t padding1[4];
+
+ union {
+ struct {
+ // Scheduling priority. |flags| must have ZX_PROFILE_INFO_FLAG_PRIORITY set.
+ int32_t priority;
+
+ uint8_t padding2[20];
+ };
+
+ // Scheduling deadline. |flags| must have ZX_PROFILE_INFO_FLAG_DEADLINE set.
+ zx_sched_deadline_params_t deadline_params;
+ };
+
+ // CPUs that threads may be scheduled on. |flags| must have
+ // ZX_PROFILE_INFO_FLAG_CPU_MASK set.
+ zx_cpu_set_t cpu_affinity_mask;
+} zx_profile_info_t;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_PROFILE_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/resource.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/resource.h
new file mode 100644
index 0000000..84b12a1
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/resource.h
@@ -0,0 +1,37 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_RESOURCE_H_
+#define SYSROOT_ZIRCON_SYSCALLS_RESOURCE_H_
+
+#include <stdint.h>
+
+#include <zircon/compiler.h>
+
+// Resources that require a region allocator to handle exclusive reservations
+// are defined in a contiguous block starting at 0 up to ZX_RSRC_KIND_COUNT-1.
+// After that point, all resource 'kinds' are abstract and need no underlying
+// bookkeeping. It's important that ZX_RSRC_KIND_COUNT is defined for each
+// architecture to properly allocate only the bookkeeping necessary.
+//
+// TODO(ZX-2419): Don't expose ZX_RSRC_KIND_COUNT to userspace
+
+typedef uint32_t zx_rsrc_kind_t;
+#define ZX_RSRC_KIND_MMIO ((zx_rsrc_kind_t)0u)
+#define ZX_RSRC_KIND_IRQ ((zx_rsrc_kind_t)1u)
+#define ZX_RSRC_KIND_IOPORT ((zx_rsrc_kind_t)2u)
+#define ZX_RSRC_KIND_HYPERVISOR ((zx_rsrc_kind_t)3u)
+#define ZX_RSRC_KIND_ROOT ((zx_rsrc_kind_t)4u)
+#define ZX_RSRC_KIND_VMEX ((zx_rsrc_kind_t)5u)
+#define ZX_RSRC_KIND_SMC ((zx_rsrc_kind_t)6u)
+#define ZX_RSRC_KIND_COUNT ((zx_rsrc_kind_t)7u)
+
+typedef uint32_t zx_rsrc_flags_t;
+#define ZX_RSRC_FLAG_EXCLUSIVE ((zx_rsrc_flags_t)0x00010000u)
+#define ZX_RSRC_FLAGS_MASK ((zx_rsrc_flags_t)ZX_RSRC_FLAG_EXCLUSIVE)
+
+#define ZX_RSRC_EXTRACT_KIND(x) ((x)&0x0000FFFF)
+#define ZX_RSRC_EXTRACT_FLAGS(x) ((x)&0xFFFF0000)
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_RESOURCE_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/scheduler.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/scheduler.h
new file mode 100644
index 0000000..c119562
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/scheduler.h
@@ -0,0 +1,36 @@
+// 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_SCHEDULER_H_
+#define SYSROOT_ZIRCON_SYSCALLS_SCHEDULER_H_
+
+#include <zircon/compiler.h>
+#include <zircon/time.h>
+
+__BEGIN_CDECLS
+
+// Parameters for deadline scheduler profiles.
+//
+// At minimum, the following relation must hold:
+//
+// 0 < capacity <= relative_deadline <= period
+//
+// Additional restrictions on the range and granularity of the parameters may be
+// enforced, which can vary from system to system.
+//
+typedef struct zx_sched_deadline_params {
+ // The worst case execution time of the deadline work per interarrival period.
+ zx_duration_t capacity;
+
+ // The worst case finish time of the deadline work, relative to the beginning
+ // of the current interarrival period.
+ zx_duration_t relative_deadline;
+
+ // The worst case interarrival period of the deadline work.
+ zx_duration_t period;
+} zx_sched_deadline_params_t;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_SCHEDULER_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/smc.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/smc.h
new file mode 100644
index 0000000..93f1761
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/smc.h
@@ -0,0 +1,47 @@
+// Copyright 2018 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_SMC_H_
+#define SYSROOT_ZIRCON_SYSCALLS_SMC_H_
+
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// Silicon Partner.
+#define ARM_SMC_SERVICE_CALL_NUM_SIP_SERVICE_BASE 0x02
+#define ARM_SMC_SERVICE_CALL_NUM_SIP_SERVICE_LENGTH 0x01
+#define ARM_SMC_SERVICE_CALL_NUM_TRUSTED_OS_BASE 0x32
+#define ARM_SMC_SERVICE_CALL_NUM_TRUSTED_OS_LENGTH 0xE
+#define ARM_SMC_SERVICE_CALL_NUM_MAX 0x3F
+#define ARM_SMC_SERVICE_CALL_NUM_MASK 0x3F
+#define ARM_SMC_SERVICE_CALL_NUM_SHIFT 24
+#define ARM_SMC_GET_SERVICE_CALL_NUM_FROM_FUNC_ID(func_id) \
+ (((func_id) >> ARM_SMC_SERVICE_CALL_NUM_SHIFT) & ARM_SMC_SERVICE_CALL_NUM_MASK)
+
+typedef struct zx_smc_parameters {
+ uint32_t func_id;
+ uint8_t padding1[4];
+ uint64_t arg1;
+ uint64_t arg2;
+ uint64_t arg3;
+ uint64_t arg4;
+ uint64_t arg5;
+ uint64_t arg6;
+ uint16_t client_id;
+ uint16_t secure_os_id;
+ uint8_t padding2[4];
+} zx_smc_parameters_t;
+
+typedef struct zx_smc_result {
+ uint64_t arg0;
+ uint64_t arg1;
+ uint64_t arg2;
+ uint64_t arg3;
+ uint64_t arg6; // at least one implementation uses it as a way to return session_id.
+} zx_smc_result_t;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_SMC_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/system.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/system.h
new file mode 100644
index 0000000..b54d443
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/system.h
@@ -0,0 +1,44 @@
+// Copyright 2017 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_SYSTEM_H_
+#define SYSROOT_ZIRCON_SYSCALLS_SYSTEM_H_
+
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// Commands used by zx_system_powerctl()
+#define ZX_SYSTEM_POWERCTL_ENABLE_ALL_CPUS 1u
+#define ZX_SYSTEM_POWERCTL_DISABLE_ALL_CPUS_BUT_PRIMARY 2u
+#define ZX_SYSTEM_POWERCTL_ACPI_TRANSITION_S_STATE 3u
+#define ZX_SYSTEM_POWERCTL_X86_SET_PKG_PL1 4u
+#define ZX_SYSTEM_POWERCTL_REBOOT 5u
+#define ZX_SYSTEM_POWERCTL_REBOOT_BOOTLOADER 6u
+#define ZX_SYSTEM_POWERCTL_REBOOT_RECOVERY 7u
+#define ZX_SYSTEM_POWERCTL_SHUTDOWN 8u
+
+typedef struct zx_system_powerctl_arg {
+ union {
+ struct {
+ struct {
+ uint8_t target_s_state; // Value between 1 and 5 indicating which S-state
+ uint8_t sleep_type_a; // Value from ACPI VM (SLP_TYPa)
+ uint8_t sleep_type_b; // Value from ACPI VM (SLP_TYPb)
+ } acpi_transition_s_state;
+ uint8_t padding1[9];
+ };
+ struct {
+ uint32_t power_limit; // PL1 value in milliwatts
+ uint32_t time_window; // PL1 time window in microseconds
+ uint8_t clamp; // PL1 clamping enable
+ uint8_t enable; // PL1 enable
+ uint8_t padding2[2];
+ } x86_power_limit;
+ };
+} zx_system_powerctl_arg_t;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_SYSTEM_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/types.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/types.h
new file mode 100644
index 0000000..b7910f2
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/syscalls/types.h
@@ -0,0 +1,25 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_SYSCALLS_TYPES_H_
+#define SYSROOT_ZIRCON_SYSCALLS_TYPES_H_
+
+#include <zircon/compiler.h>
+
+__BEGIN_CDECLS
+
+// forward declarations needed by syscalls.h
+typedef struct zx_port_packet zx_port_packet_t;
+typedef struct zx_pci_bar zx_pci_bar_t;
+typedef struct zx_pcie_device_info zx_pcie_device_info_t;
+typedef struct zx_pci_init_arg zx_pci_init_arg_t;
+typedef union zx_rrec zx_rrec_t;
+typedef struct zx_system_powerctl_arg zx_system_powerctl_arg_t;
+typedef struct zx_profile_info zx_profile_info_t;
+typedef struct zx_smc_parameters zx_smc_parameters_t;
+typedef struct zx_smc_result zx_smc_result_t;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_SYSCALLS_TYPES_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/testonly-syscalls.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/testonly-syscalls.h
new file mode 100644
index 0000000..d994d86
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/testonly-syscalls.h
@@ -0,0 +1,30 @@
+// Copyright 2020 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.
+
+#ifndef SYSROOT_ZIRCON_TESTONLY_SYSCALLS_H_
+#define SYSROOT_ZIRCON_TESTONLY_SYSCALLS_H_
+
+#include <zircon/syscalls.h>
+
+__BEGIN_CDECLS
+
+// Make sure this matches <zircon/syscalls.h>.
+#define _ZX_SYSCALL_DECL(name, type, attrs, nargs, arglist, prototype) \
+ extern attrs type zx_##name prototype; \
+ extern attrs type _zx_##name prototype;
+
+#ifdef __clang__
+#define _ZX_SYSCALL_ANNO(attr) __attribute__((attr))
+#else
+#define _ZX_SYSCALL_ANNO(attr) // Nothing for compilers without the support.
+#endif
+
+#include <zircon/syscalls/internal/testonly-cdecls.inc>
+
+#undef _ZX_SYSCALL_ANNO
+#undef _ZX_SYSCALL_DECL
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_ONLY_SYSCALLS_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/threads.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/threads.h
new file mode 100644
index 0000000..5bfc4b0
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/threads.h
@@ -0,0 +1,40 @@
+// Copyright 2018 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.
+
+#ifndef SYSROOT_ZIRCON_THREADS_H_
+#define SYSROOT_ZIRCON_THREADS_H_
+
+#include <threads.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// Get the zx_handle_t corresponding to the thrd_t. This handle is
+// still owned by the C11 thread, and will not persist after the
+// thread exits and is joined or detached. Callers must duplicate the
+// handle, therefore, if they wish the thread handle to outlive the
+// execution of the C11 thread.
+zx_handle_t thrd_get_zx_handle(thrd_t t);
+
+// Converts a threads.h-style status value to an |zx_status_t|.
+static inline zx_status_t __PURE thrd_status_to_zx_status(int thrd_status) {
+ switch (thrd_status) {
+ case thrd_success:
+ return ZX_OK;
+ case thrd_nomem:
+ return ZX_ERR_NO_MEMORY;
+ case thrd_timedout:
+ return ZX_ERR_TIMED_OUT;
+ case thrd_busy:
+ return ZX_ERR_SHOULD_WAIT;
+ default:
+ case thrd_error:
+ return ZX_ERR_INTERNAL;
+ }
+}
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_THREADS_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/time.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/time.h
new file mode 100644
index 0000000..e6bd862
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/time.h
@@ -0,0 +1,153 @@
+// Copyright 2018 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.
+
+#ifndef SYSROOT_ZIRCON_TIME_H_
+#define SYSROOT_ZIRCON_TIME_H_
+
+#include <stdint.h>
+#include <zircon/compiler.h>
+
+__BEGIN_CDECLS
+
+// absolute time in nanoseconds (generally with respect to the monotonic clock)
+typedef int64_t zx_time_t;
+// a duration in nanoseconds
+typedef int64_t zx_duration_t;
+// a duration in hardware ticks
+typedef int64_t zx_ticks_t;
+
+#define ZX_TIME_INFINITE INT64_MAX
+#define ZX_TIME_INFINITE_PAST INT64_MIN
+
+// These functions perform overflow-safe time arithmetic and unit conversion, clamping to
+// ZX_TIME_INFINITE in case of overflow and ZX_TIME_INFINITE_PAST in case of underflow.
+//
+// C++ code should use zx::time and zx::duration instead.
+//
+// For arithmetic the naming scheme is:
+// zx_<first argument>_<operation>_<second argument>
+//
+// For unit conversion the naming scheme is:
+// zx_duration_from_<unit of argument>
+//
+// TODO(maniscalco): Consider expanding the set of operations to include division, modulo, and
+// floating point math.
+
+__CONSTEXPR static inline zx_time_t zx_time_add_duration(zx_time_t time, zx_duration_t duration) {
+ zx_time_t x = 0;
+ if (unlikely(add_overflow(time, duration, &x))) {
+ if (x >= 0) {
+ return ZX_TIME_INFINITE_PAST;
+ } else {
+ return ZX_TIME_INFINITE;
+ }
+ }
+ return x;
+}
+
+__CONSTEXPR static inline zx_time_t zx_time_sub_duration(zx_time_t time, zx_duration_t duration) {
+ zx_time_t x = 0;
+ if (unlikely(sub_overflow(time, duration, &x))) {
+ if (x >= 0) {
+ return ZX_TIME_INFINITE_PAST;
+ } else {
+ return ZX_TIME_INFINITE;
+ }
+ }
+ return x;
+}
+
+__CONSTEXPR static inline zx_duration_t zx_time_sub_time(zx_time_t time1, zx_time_t time2) {
+ zx_duration_t x = 0;
+ if (unlikely(sub_overflow(time1, time2, &x))) {
+ if (x >= 0) {
+ return ZX_TIME_INFINITE_PAST;
+ } else {
+ return ZX_TIME_INFINITE;
+ }
+ }
+ return x;
+}
+
+__CONSTEXPR static inline zx_duration_t zx_duration_add_duration(zx_duration_t dur1,
+ zx_duration_t dur2) {
+ zx_duration_t x = 0;
+ if (unlikely(add_overflow(dur1, dur2, &x))) {
+ if (x >= 0) {
+ return ZX_TIME_INFINITE_PAST;
+ } else {
+ return ZX_TIME_INFINITE;
+ }
+ }
+ return x;
+}
+
+__CONSTEXPR static inline zx_duration_t zx_duration_sub_duration(zx_duration_t dur1,
+ zx_duration_t dur2) {
+ zx_duration_t x = 0;
+ if (unlikely(sub_overflow(dur1, dur2, &x))) {
+ if (x >= 0) {
+ return ZX_TIME_INFINITE_PAST;
+ } else {
+ return ZX_TIME_INFINITE;
+ }
+ }
+ return x;
+}
+
+__CONSTEXPR static inline zx_duration_t zx_duration_mul_int64(zx_duration_t duration,
+ int64_t multiplier) {
+ zx_duration_t x = 0;
+ if (unlikely(mul_overflow(duration, multiplier, &x))) {
+ if ((duration > 0 && multiplier > 0) || (duration < 0 && multiplier < 0)) {
+ return ZX_TIME_INFINITE;
+ } else {
+ return ZX_TIME_INFINITE_PAST;
+ }
+ }
+ return x;
+}
+
+__CONSTEXPR static inline int64_t zx_nsec_from_duration(zx_duration_t n) { return n; }
+
+__CONSTEXPR static inline zx_duration_t zx_duration_from_nsec(int64_t n) {
+ return zx_duration_mul_int64(1, n);
+}
+
+__CONSTEXPR static inline zx_duration_t zx_duration_from_usec(int64_t n) {
+ return zx_duration_mul_int64(1000, n);
+}
+
+__CONSTEXPR static inline zx_duration_t zx_duration_from_msec(int64_t n) {
+ return zx_duration_mul_int64(1000000, n);
+}
+
+__CONSTEXPR static inline zx_duration_t zx_duration_from_sec(int64_t n) {
+ return zx_duration_mul_int64(1000000000, n);
+}
+
+__CONSTEXPR static inline zx_duration_t zx_duration_from_min(int64_t n) {
+ return zx_duration_mul_int64(60000000000, n);
+}
+
+__CONSTEXPR static inline zx_duration_t zx_duration_from_hour(int64_t n) {
+ return zx_duration_mul_int64(3600000000000, n);
+}
+
+// Similar to the functions above, these macros perform overflow-safe unit conversion. Prefer to use
+// the functions above instead of these macros.
+#define ZX_NSEC(n) (__ISCONSTANT(n) ? ((zx_duration_t)(1LL * (n))) : (zx_duration_from_nsec(n)))
+#define ZX_USEC(n) (__ISCONSTANT(n) ? ((zx_duration_t)(1000LL * (n))) : (zx_duration_from_usec(n)))
+#define ZX_MSEC(n) \
+ (__ISCONSTANT(n) ? ((zx_duration_t)(1000000LL * (n))) : (zx_duration_from_msec(n)))
+#define ZX_SEC(n) \
+ (__ISCONSTANT(n) ? ((zx_duration_t)(1000000000LL * (n))) : (zx_duration_from_sec(n)))
+#define ZX_MIN(n) \
+ (__ISCONSTANT(n) ? ((zx_duration_t)(60LL * 1000000000LL * (n))) : (zx_duration_from_min(n)))
+#define ZX_HOUR(n) \
+ (__ISCONSTANT(n) ? ((zx_duration_t)(3600LL * 1000000000LL * (n))) : (zx_duration_from_hour(n)))
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_TIME_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/tls.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/tls.h
new file mode 100644
index 0000000..dae9694
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/tls.h
@@ -0,0 +1,29 @@
+// Copyright 2017 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.
+
+#ifndef SYSROOT_ZIRCON_TLS_
+#define SYSROOT_ZIRCON_TLS_
+
+// These constants are part of the C/C++ ABI known to compilers for
+// *-fuchsia targets. These are offsets from the thread pointer.
+
+// This file must be includable in assembly files.
+
+#if defined(__x86_64__)
+
+#define ZX_TLS_STACK_GUARD_OFFSET 0x10
+#define ZX_TLS_UNSAFE_SP_OFFSET 0x18
+
+#elif defined(__aarch64__)
+
+#define ZX_TLS_STACK_GUARD_OFFSET (-0x10)
+#define ZX_TLS_UNSAFE_SP_OFFSET (-0x8)
+
+#else
+
+#error what architecture?
+
+#endif
+
+#endif // SYSROOT_ZIRCON_TLS_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/types.h b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/types.h
new file mode 100644
index 0000000..10faebb
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/include/zircon/types.h
@@ -0,0 +1,489 @@
+// Copyright 2016 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.
+
+#ifndef SYSROOT_ZIRCON_TYPES_H_
+#define SYSROOT_ZIRCON_TYPES_H_
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <zircon/compiler.h>
+#include <zircon/errors.h>
+#include <zircon/limits.h>
+#include <zircon/rights.h>
+#include <zircon/time.h>
+
+#ifndef __cplusplus
+#ifndef _KERNEL
+// We don't want to include <stdatomic.h> from the kernel code because the
+// kernel definitions of atomic operations are incompatible with those defined
+// in <stdatomic.h>.
+//
+// A better solution would be to use <stdatomic.h> and C11 atomic operation
+// even in the kernel, but that would require modifying all the code that uses
+// the existing homegrown atomics.
+#include <stdatomic.h>
+#endif
+#endif
+
+__BEGIN_CDECLS
+
+// ask clang format not to mess up the indentation:
+// clang-format off
+
+typedef uint32_t zx_handle_t;
+
+#define ZX_HANDLE_INVALID ((zx_handle_t)0)
+#define ZX_HANDLE_FIXED_BITS_MASK ((zx_handle_t)0x3)
+
+// See errors.h for the values zx_status_t can take.
+typedef int32_t zx_status_t;
+
+// clock ids
+typedef uint32_t zx_clock_t;
+#define ZX_CLOCK_MONOTONIC ((zx_clock_t)0)
+#define ZX_CLOCK_UTC ((zx_clock_t)1)
+#define ZX_CLOCK_THREAD ((zx_clock_t)2)
+
+typedef uint32_t zx_signals_t;
+
+#define ZX_SIGNAL_NONE ((zx_signals_t)0u)
+#define ZX_USER_SIGNAL_ALL ((zx_signals_t)0xff000000u)
+
+// Implementation details (__ZX_* not intended for public consumption)
+//
+// Signals that have a common meaning where used are named with that
+// meaning. Signals that do not, or are not yet in use, are named
+// generically.
+#define __ZX_OBJECT_SIGNAL_ALL ((zx_signals_t)0x00ffffffu)
+#define __ZX_OBJECT_READABLE ((zx_signals_t)1u << 0)
+#define __ZX_OBJECT_WRITABLE ((zx_signals_t)1u << 1)
+#define __ZX_OBJECT_PEER_CLOSED ((zx_signals_t)1u << 2)
+#define __ZX_OBJECT_SIGNALED ((zx_signals_t)1u << 3)
+#define __ZX_OBJECT_SIGNAL_4 ((zx_signals_t)1u << 4)
+#define __ZX_OBJECT_SIGNAL_5 ((zx_signals_t)1u << 5)
+#define __ZX_OBJECT_SIGNAL_6 ((zx_signals_t)1u << 6)
+#define __ZX_OBJECT_SIGNAL_7 ((zx_signals_t)1u << 7)
+#define __ZX_OBJECT_SIGNAL_8 ((zx_signals_t)1u << 8)
+#define __ZX_OBJECT_SIGNAL_9 ((zx_signals_t)1u << 9)
+#define __ZX_OBJECT_SIGNAL_10 ((zx_signals_t)1u << 10)
+#define __ZX_OBJECT_SIGNAL_11 ((zx_signals_t)1u << 11)
+#define __ZX_OBJECT_SIGNAL_12 ((zx_signals_t)1u << 12)
+#define __ZX_OBJECT_SIGNAL_13 ((zx_signals_t)1u << 13)
+#define __ZX_OBJECT_SIGNAL_14 ((zx_signals_t)1u << 14)
+#define __ZX_OBJECT_SIGNAL_15 ((zx_signals_t)1u << 15)
+#define __ZX_OBJECT_SIGNAL_16 ((zx_signals_t)1u << 16)
+#define __ZX_OBJECT_SIGNAL_17 ((zx_signals_t)1u << 17)
+#define __ZX_OBJECT_SIGNAL_18 ((zx_signals_t)1u << 18)
+#define __ZX_OBJECT_SIGNAL_19 ((zx_signals_t)1u << 19)
+#define __ZX_OBJECT_SIGNAL_20 ((zx_signals_t)1u << 20)
+#define __ZX_OBJECT_SIGNAL_21 ((zx_signals_t)1u << 21)
+#define __ZX_OBJECT_SIGNAL_22 ((zx_signals_t)1u << 22)
+#define __ZX_OBJECT_HANDLE_CLOSED ((zx_signals_t)1u << 23)
+
+
+
+// User Signals (for zx_object_signal() and zx_object_signal_peer())
+#define ZX_USER_SIGNAL_0 ((zx_signals_t)1u << 24)
+#define ZX_USER_SIGNAL_1 ((zx_signals_t)1u << 25)
+#define ZX_USER_SIGNAL_2 ((zx_signals_t)1u << 26)
+#define ZX_USER_SIGNAL_3 ((zx_signals_t)1u << 27)
+#define ZX_USER_SIGNAL_4 ((zx_signals_t)1u << 28)
+#define ZX_USER_SIGNAL_5 ((zx_signals_t)1u << 29)
+#define ZX_USER_SIGNAL_6 ((zx_signals_t)1u << 30)
+#define ZX_USER_SIGNAL_7 ((zx_signals_t)1u << 31)
+
+// Cancellation (handle was closed while waiting with it)
+#define ZX_SIGNAL_HANDLE_CLOSED __ZX_OBJECT_HANDLE_CLOSED
+
+// Event
+#define ZX_EVENT_SIGNALED __ZX_OBJECT_SIGNALED
+#define ZX_EVENT_SIGNAL_MASK (ZX_USER_SIGNAL_ALL | __ZX_OBJECT_SIGNALED)
+
+// EventPair
+#define ZX_EVENTPAIR_SIGNALED __ZX_OBJECT_SIGNALED
+#define ZX_EVENTPAIR_PEER_CLOSED __ZX_OBJECT_PEER_CLOSED
+#define ZX_EVENTPAIR_SIGNAL_MASK (ZX_USER_SIGNAL_ALL | __ZX_OBJECT_SIGNALED | __ZX_OBJECT_PEER_CLOSED)
+
+// Channel
+#define ZX_CHANNEL_READABLE __ZX_OBJECT_READABLE
+#define ZX_CHANNEL_WRITABLE __ZX_OBJECT_WRITABLE
+#define ZX_CHANNEL_PEER_CLOSED __ZX_OBJECT_PEER_CLOSED
+
+// Clock
+#define ZX_CLOCK_STARTED __ZX_OBJECT_SIGNAL_4
+
+// Socket
+#define ZX_SOCKET_READABLE __ZX_OBJECT_READABLE
+#define ZX_SOCKET_WRITABLE __ZX_OBJECT_WRITABLE
+#define ZX_SOCKET_PEER_CLOSED __ZX_OBJECT_PEER_CLOSED
+#define ZX_SOCKET_PEER_WRITE_DISABLED __ZX_OBJECT_SIGNAL_4
+#define ZX_SOCKET_WRITE_DISABLED __ZX_OBJECT_SIGNAL_5
+#define ZX_SOCKET_READ_THRESHOLD __ZX_OBJECT_SIGNAL_10
+#define ZX_SOCKET_WRITE_THRESHOLD __ZX_OBJECT_SIGNAL_11
+
+// Fifo
+#define ZX_FIFO_READABLE __ZX_OBJECT_READABLE
+#define ZX_FIFO_WRITABLE __ZX_OBJECT_WRITABLE
+#define ZX_FIFO_PEER_CLOSED __ZX_OBJECT_PEER_CLOSED
+
+// Task signals (process, thread, job)
+#define ZX_TASK_TERMINATED __ZX_OBJECT_SIGNALED
+
+// Job
+#define ZX_JOB_TERMINATED __ZX_OBJECT_SIGNALED
+#define ZX_JOB_NO_JOBS __ZX_OBJECT_SIGNAL_4
+#define ZX_JOB_NO_PROCESSES __ZX_OBJECT_SIGNAL_5
+
+// Process
+#define ZX_PROCESS_TERMINATED __ZX_OBJECT_SIGNALED
+
+// Thread
+#define ZX_THREAD_TERMINATED __ZX_OBJECT_SIGNALED
+#define ZX_THREAD_RUNNING __ZX_OBJECT_SIGNAL_4
+#define ZX_THREAD_SUSPENDED __ZX_OBJECT_SIGNAL_5
+
+// Log
+#define ZX_LOG_READABLE __ZX_OBJECT_READABLE
+#define ZX_LOG_WRITABLE __ZX_OBJECT_WRITABLE
+
+// Timer
+#define ZX_TIMER_SIGNALED __ZX_OBJECT_SIGNALED
+
+// VMO
+#define ZX_VMO_ZERO_CHILDREN __ZX_OBJECT_SIGNALED
+
+// global kernel object id.
+// Note: kernel object ids use 63 bits, with the most significant bit being zero.
+// The remaining values (msb==1) are for use by programs and tools that wish to
+// create koids for artificial objects.
+typedef uint64_t zx_koid_t;
+#define ZX_KOID_INVALID ((uint64_t) 0)
+#define ZX_KOID_KERNEL ((uint64_t) 1)
+// The first non-reserved koid. The first 1024 are reserved.
+#define ZX_KOID_FIRST ((uint64_t) 1024)
+
+// Maximum number of wait items allowed for zx_object_wait_many()
+#define ZX_WAIT_MANY_MAX_ITEMS ((size_t)64)
+
+// Structure for zx_object_wait_many():
+typedef struct zx_wait_item {
+ zx_handle_t handle;
+ zx_signals_t waitfor;
+ zx_signals_t pending;
+} zx_wait_item_t;
+
+// VM Object creation options
+#define ZX_VMO_RESIZABLE ((uint32_t)1u << 1)
+
+// VM Object opcodes
+#define ZX_VMO_OP_COMMIT ((uint32_t)1u)
+#define ZX_VMO_OP_DECOMMIT ((uint32_t)2u)
+#define ZX_VMO_OP_LOCK ((uint32_t)3u)
+#define ZX_VMO_OP_UNLOCK ((uint32_t)4u)
+// opcode 5 was ZX_VMO_OP_LOOKUP, but is now unused.
+#define ZX_VMO_OP_CACHE_SYNC ((uint32_t)6u)
+#define ZX_VMO_OP_CACHE_INVALIDATE ((uint32_t)7u)
+#define ZX_VMO_OP_CACHE_CLEAN ((uint32_t)8u)
+#define ZX_VMO_OP_CACHE_CLEAN_INVALIDATE ((uint32_t)9u)
+#define ZX_VMO_OP_ZERO ((uint32_t)10u)
+
+// VM Object clone flags
+#define ZX_VMO_CHILD_SNAPSHOT ((uint32_t)1u << 0)
+#define ZX_VMO_CHILD_SNAPSHOT_AT_LEAST_ON_WRITE ((uint32_t)1u << 4)
+#define ZX_VMO_CHILD_RESIZABLE ((uint32_t)1u << 2)
+#define ZX_VMO_CHILD_SLICE ((uint32_t)1u << 3)
+#define ZX_VMO_CHILD_NO_WRITE ((uint32_t)1u << 5)
+// Old clone flags that are on the path to deprecation.
+#define ZX_VMO_CLONE_COPY_ON_WRITE ((uint32_t)1u << 4)
+#define ZX_VMO_CHILD_COPY_ON_WRITE ((uint32_t)1u << 4)
+#define ZX_VMO_CHILD_PRIVATE_PAGER_COPY ((uint32_t)1u << 4)
+
+typedef uint32_t zx_vm_option_t;
+// Mapping flags to vmar routines
+#define ZX_VM_PERM_READ ((zx_vm_option_t)(1u << 0))
+#define ZX_VM_PERM_WRITE ((zx_vm_option_t)(1u << 1))
+#define ZX_VM_PERM_EXECUTE ((zx_vm_option_t)(1u << 2))
+#define ZX_VM_COMPACT ((zx_vm_option_t)(1u << 3))
+#define ZX_VM_SPECIFIC ((zx_vm_option_t)(1u << 4))
+#define ZX_VM_SPECIFIC_OVERWRITE ((zx_vm_option_t)(1u << 5))
+#define ZX_VM_CAN_MAP_SPECIFIC ((zx_vm_option_t)(1u << 6))
+#define ZX_VM_CAN_MAP_READ ((zx_vm_option_t)(1u << 7))
+#define ZX_VM_CAN_MAP_WRITE ((zx_vm_option_t)(1u << 8))
+#define ZX_VM_CAN_MAP_EXECUTE ((zx_vm_option_t)(1u << 9))
+#define ZX_VM_MAP_RANGE ((zx_vm_option_t)(1u << 10))
+#define ZX_VM_REQUIRE_NON_RESIZABLE ((zx_vm_option_t)(1u << 11))
+#define ZX_VM_ALLOW_FAULTS ((zx_vm_option_t)(1u << 12))
+
+#define ZX_VM_ALIGN_BASE 24
+#define ZX_VM_ALIGN_1KB ((zx_vm_option_t)(10u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_2KB ((zx_vm_option_t)(11u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_4KB ((zx_vm_option_t)(12u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_8KB ((zx_vm_option_t)(13u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_16KB ((zx_vm_option_t)(14u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_32KB ((zx_vm_option_t)(15u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_64KB ((zx_vm_option_t)(16u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_128KB ((zx_vm_option_t)(17u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_256KB ((zx_vm_option_t)(18u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_512KB ((zx_vm_option_t)(19u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_1MB ((zx_vm_option_t)(20u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_2MB ((zx_vm_option_t)(21u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_4MB ((zx_vm_option_t)(22u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_8MB ((zx_vm_option_t)(23u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_16MB ((zx_vm_option_t)(24u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_32MB ((zx_vm_option_t)(25u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_64MB ((zx_vm_option_t)(26u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_128MB ((zx_vm_option_t)(27u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_256MB ((zx_vm_option_t)(28u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_512MB ((zx_vm_option_t)(29u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_1GB ((zx_vm_option_t)(30u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_2GB ((zx_vm_option_t)(31u << ZX_VM_ALIGN_BASE))
+#define ZX_VM_ALIGN_4GB ((zx_vm_option_t)(32u << ZX_VM_ALIGN_BASE))
+
+// virtual address
+typedef uintptr_t zx_vaddr_t;
+
+// physical address
+typedef uintptr_t zx_paddr_t;
+// low mem physical address
+typedef uint32_t zx_paddr32_t;
+// Hypervisor guest physical addresses.
+typedef uintptr_t zx_gpaddr_t;
+
+// offset
+typedef uint64_t zx_off_t;
+
+// vectorized I/O
+typedef struct zx_iovec {
+ void* buffer;
+ size_t capacity;
+} zx_iovec_t;
+
+// Maximum string length for kernel names (process name, thread name, etc)
+#define ZX_MAX_NAME_LEN ((size_t)32u)
+
+// Buffer size limits on the cprng syscalls
+#define ZX_CPRNG_DRAW_MAX_LEN ((size_t)256u)
+#define ZX_CPRNG_ADD_ENTROPY_MAX_LEN ((size_t)256u)
+
+// interrupt_create flags
+#define ZX_INTERRUPT_REMAP_IRQ ((uint32_t)0x1u)
+#define ZX_INTERRUPT_MODE_DEFAULT ((uint32_t)0u << 1)
+#define ZX_INTERRUPT_MODE_EDGE_LOW ((uint32_t)1u << 1)
+#define ZX_INTERRUPT_MODE_EDGE_HIGH ((uint32_t)2u << 1)
+#define ZX_INTERRUPT_MODE_LEVEL_LOW ((uint32_t)3u << 1)
+#define ZX_INTERRUPT_MODE_LEVEL_HIGH ((uint32_t)4u << 1)
+#define ZX_INTERRUPT_MODE_EDGE_BOTH ((uint32_t)5u << 1)
+#define ZX_INTERRUPT_MODE_MASK ((uint32_t)0xe)
+#define ZX_INTERRUPT_VIRTUAL ((uint32_t)0x10)
+
+// interrupt_bind flags
+#define ZX_INTERRUPT_BIND ((uint32_t)0x0u)
+#define ZX_INTERRUPT_UNBIND ((uint32_t)0x1u)
+
+// Preallocated virtual interrupt slot, typically used for signaling interrupt threads to exit.
+#define ZX_INTERRUPT_SLOT_USER ((uint32_t)62u)
+// interrupt wait slots must be in the range 0 - 62 inclusive
+#define ZX_INTERRUPT_MAX_SLOTS ((uint32_t)62u)
+
+// PCI interrupt handles use interrupt slot 0 for the PCI hardware interrupt
+#define ZX_PCI_INTERRUPT_SLOT ((uint32_t)0u)
+
+// Channel options and limits.
+#define ZX_CHANNEL_READ_MAY_DISCARD ((uint32_t)1u)
+
+#define ZX_CHANNEL_MAX_MSG_BYTES ((uint32_t)65536u)
+#define ZX_CHANNEL_MAX_MSG_HANDLES ((uint32_t)64u)
+
+// Fifo limits.
+#define ZX_FIFO_MAX_SIZE_BYTES ZX_PAGE_SIZE
+
+// Socket options and limits.
+// These options can be passed to zx_socket_shutdown().
+#define ZX_SOCKET_SHUTDOWN_WRITE ((uint32_t)1u << 0)
+#define ZX_SOCKET_SHUTDOWN_READ ((uint32_t)1u << 1)
+#define ZX_SOCKET_SHUTDOWN_MASK (ZX_SOCKET_SHUTDOWN_WRITE | ZX_SOCKET_SHUTDOWN_READ)
+
+// These can be passed to zx_socket_create().
+#define ZX_SOCKET_STREAM ((uint32_t)0u)
+#define ZX_SOCKET_DATAGRAM ((uint32_t)1u << 0)
+#define ZX_SOCKET_CREATE_MASK (ZX_SOCKET_DATAGRAM)
+
+// These can be passed to zx_socket_read().
+#define ZX_SOCKET_PEEK ((uint32_t)1u << 3)
+
+// These can be passed to zx_stream_create().
+#define ZX_STREAM_MODE_READ ((uint32_t)1u << 0)
+#define ZX_STREAM_MODE_WRITE ((uint32_t)1u << 1)
+#define ZX_STREAM_CREATE_MASK (ZX_STREAM_MODE_READ | ZX_STREAM_MODE_WRITE)
+
+// These can be passed to zx_stream_writev().
+#define ZX_STREAM_APPEND ((uint32_t)1u << 0)
+
+typedef uint32_t zx_stream_seek_origin_t;
+#define ZX_STREAM_SEEK_ORIGIN_START ((zx_stream_seek_origin_t)0u)
+#define ZX_STREAM_SEEK_ORIGIN_CURRENT ((zx_stream_seek_origin_t)1u)
+#define ZX_STREAM_SEEK_ORIGIN_END ((zx_stream_seek_origin_t)2u)
+
+// Flags which can be used to to control cache policy for APIs which map memory.
+#define ZX_CACHE_POLICY_CACHED ((uint32_t)0u)
+#define ZX_CACHE_POLICY_UNCACHED ((uint32_t)1u)
+#define ZX_CACHE_POLICY_UNCACHED_DEVICE ((uint32_t)2u)
+#define ZX_CACHE_POLICY_WRITE_COMBINING ((uint32_t)3u)
+#define ZX_CACHE_POLICY_MASK ((uint32_t)3u)
+
+// Flag bits for zx_cache_flush.
+#define ZX_CACHE_FLUSH_INSN ((uint32_t)1u << 0)
+#define ZX_CACHE_FLUSH_DATA ((uint32_t)1u << 1)
+#define ZX_CACHE_FLUSH_INVALIDATE ((uint32_t)1u << 2)
+
+// Timer options.
+#define ZX_TIMER_SLACK_CENTER ((uint32_t)0u)
+#define ZX_TIMER_SLACK_EARLY ((uint32_t)1u)
+#define ZX_TIMER_SLACK_LATE ((uint32_t)2u)
+
+// Bus Transaction Initiator options.
+#define ZX_BTI_PERM_READ ((uint32_t)1u << 0)
+#define ZX_BTI_PERM_WRITE ((uint32_t)1u << 1)
+#define ZX_BTI_PERM_EXECUTE ((uint32_t)1u << 2)
+#define ZX_BTI_COMPRESS ((uint32_t)1u << 3)
+#define ZX_BTI_CONTIGUOUS ((uint32_t)1u << 4)
+
+// Job options.
+// These options can be passed to zx_job_set_critical().
+#define ZX_JOB_CRITICAL_PROCESS_RETCODE_NONZERO ((uint32_t)1u << 0)
+
+typedef uint32_t zx_obj_type_t;
+
+#define ZX_OBJ_TYPE_NONE ((zx_obj_type_t)0u)
+#define ZX_OBJ_TYPE_PROCESS ((zx_obj_type_t)1u)
+#define ZX_OBJ_TYPE_THREAD ((zx_obj_type_t)2u)
+#define ZX_OBJ_TYPE_VMO ((zx_obj_type_t)3u)
+#define ZX_OBJ_TYPE_CHANNEL ((zx_obj_type_t)4u)
+#define ZX_OBJ_TYPE_EVENT ((zx_obj_type_t)5u)
+#define ZX_OBJ_TYPE_PORT ((zx_obj_type_t)6u)
+#define ZX_OBJ_TYPE_INTERRUPT ((zx_obj_type_t)9u)
+#define ZX_OBJ_TYPE_PCI_DEVICE ((zx_obj_type_t)11u)
+#define ZX_OBJ_TYPE_LOG ((zx_obj_type_t)12u)
+#define ZX_OBJ_TYPE_SOCKET ((zx_obj_type_t)14u)
+#define ZX_OBJ_TYPE_RESOURCE ((zx_obj_type_t)15u)
+#define ZX_OBJ_TYPE_EVENTPAIR ((zx_obj_type_t)16u)
+#define ZX_OBJ_TYPE_JOB ((zx_obj_type_t)17u)
+#define ZX_OBJ_TYPE_VMAR ((zx_obj_type_t)18u)
+#define ZX_OBJ_TYPE_FIFO ((zx_obj_type_t)19u)
+#define ZX_OBJ_TYPE_GUEST ((zx_obj_type_t)20u)
+#define ZX_OBJ_TYPE_VCPU ((zx_obj_type_t)21u)
+#define ZX_OBJ_TYPE_TIMER ((zx_obj_type_t)22u)
+#define ZX_OBJ_TYPE_IOMMU ((zx_obj_type_t)23u)
+#define ZX_OBJ_TYPE_BTI ((zx_obj_type_t)24u)
+#define ZX_OBJ_TYPE_PROFILE ((zx_obj_type_t)25u)
+#define ZX_OBJ_TYPE_PMT ((zx_obj_type_t)26u)
+#define ZX_OBJ_TYPE_SUSPEND_TOKEN ((zx_obj_type_t)27u)
+#define ZX_OBJ_TYPE_PAGER ((zx_obj_type_t)28u)
+#define ZX_OBJ_TYPE_EXCEPTION ((zx_obj_type_t)29u)
+#define ZX_OBJ_TYPE_CLOCK ((zx_obj_type_t)30u)
+#define ZX_OBJ_TYPE_STREAM ((zx_obj_type_t)31u)
+#define ZX_OBJ_TYPE_MSI_ALLOCATION ((zx_obj_type_t)32u)
+#define ZX_OBJ_TYPE_MSI_INTERRUPT ((zx_obj_type_t)33u)
+
+// System ABI commits to having no more than 64 object types.
+//
+// See zx_info_process_handle_stats_t for an example of a binary interface that
+// depends on having an upper bound for the number of object types.
+#define ZX_OBJ_TYPE_UPPER_BOUND ((zx_obj_type_t)64u)
+
+typedef uint32_t zx_system_event_type_t;
+#define ZX_SYSTEM_EVENT_OUT_OF_MEMORY ((zx_system_event_type_t)1u)
+#define ZX_SYSTEM_EVENT_MEMORY_PRESSURE_CRITICAL ((zx_system_event_type_t)2u)
+#define ZX_SYSTEM_EVENT_MEMORY_PRESSURE_WARNING ((zx_system_event_type_t)3u)
+#define ZX_SYSTEM_EVENT_MEMORY_PRESSURE_NORMAL ((zx_system_event_type_t)4u)
+
+// Used in channel_read_etc.
+typedef struct zx_handle_info {
+ zx_handle_t handle;
+ zx_obj_type_t type;
+ zx_rights_t rights;
+ uint32_t unused;
+} zx_handle_info_t;
+
+typedef uint32_t zx_handle_op_t;
+
+#define ZX_HANDLE_OP_MOVE ((zx_handle_op_t)0u)
+#define ZX_HANDLE_OP_DUPLICATE ((zx_handle_op_t)1u)
+
+// Used in channel_write_etc.
+typedef struct zx_handle_disposition {
+ zx_handle_op_t operation;
+ zx_handle_t handle;
+ zx_obj_type_t type;
+ zx_rights_t rights;
+ zx_status_t result;
+} zx_handle_disposition_t;
+
+// Transaction ID and argument types for zx_channel_call.
+typedef uint32_t zx_txid_t;
+
+typedef struct zx_channel_call_args {
+ const void* wr_bytes;
+ const zx_handle_t* wr_handles;
+ void *rd_bytes;
+ zx_handle_t* rd_handles;
+ uint32_t wr_num_bytes;
+ uint32_t wr_num_handles;
+ uint32_t rd_num_bytes;
+ uint32_t rd_num_handles;
+} zx_channel_call_args_t;
+
+// The ZX_VM_FLAG_* constants are to be deprecated in favor of the ZX_VM_*
+// versions.
+#define ZX_VM_FLAG_PERM_READ ((uint32_t)1u << 0)
+#define ZX_VM_FLAG_PERM_WRITE ((uint32_t)1u << 1)
+#define ZX_VM_FLAG_PERM_EXECUTE ((uint32_t)1u << 2)
+#define ZX_VM_FLAG_COMPACT ((uint32_t)1u << 3)
+#define ZX_VM_FLAG_SPECIFIC ((uint32_t)1u << 4)
+#define ZX_VM_FLAG_SPECIFIC_OVERWRITE ((uint32_t)1u << 5)
+#define ZX_VM_FLAG_CAN_MAP_SPECIFIC ((uint32_t)1u << 6)
+#define ZX_VM_FLAG_CAN_MAP_READ ((uint32_t)1u << 7)
+#define ZX_VM_FLAG_CAN_MAP_WRITE ((uint32_t)1u << 8)
+#define ZX_VM_FLAG_CAN_MAP_EXECUTE ((uint32_t)1u << 9)
+#define ZX_VM_FLAG_MAP_RANGE ((uint32_t)1u << 10)
+#define ZX_VM_FLAG_REQUIRE_NON_RESIZABLE ((uint32_t)1u << 11)
+
+// CPU masks specifying sets of CPUs.
+//
+// We currently are limited to systems with 512 CPUs or less.
+#define ZX_CPU_SET_MAX_CPUS 512
+#define ZX_CPU_SET_BITS_PER_WORD 64
+
+typedef struct zx_cpu_set {
+ // The |N|'th CPU is considered in the CPU set if the bit:
+ //
+ // cpu_mask[N / ZX_CPU_SET_BITS_PER_WORD]
+ // & (1 << (N % ZX_CPU_SET_BITS_PER_WORD))
+ //
+ // is set.
+ uint64_t mask[ZX_CPU_SET_MAX_CPUS / ZX_CPU_SET_BITS_PER_WORD];
+} zx_cpu_set_t;
+
+#ifdef __cplusplus
+// We cannot use <stdatomic.h> with C++ code as _Atomic qualifier defined by
+// C11 is not valid in C++11. There is not a single standard name that can
+// be used in both C and C++. C++ <atomic> defines names which are equivalent
+// to those in <stdatomic.h>, but these are contained in the std namespace.
+//
+// In kernel, the only operation done is a user_copy (of sizeof(int)) inside a
+// lock; otherwise the futex address is treated as a key.
+typedef int zx_futex_t;
+#else
+#ifdef _KERNEL
+typedef int zx_futex_t;
+#else
+typedef atomic_int zx_futex_t;
+#endif
+#endif
+typedef int zx_futex_storage_t;
+
+__END_CDECLS
+
+#endif // SYSROOT_ZIRCON_TYPES_H_
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/lib/Scrt1.o b/third_party/fuchsia-sdk/arch/x64/sysroot/lib/Scrt1.o
new file mode 100644
index 0000000..d33aff5
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/lib/Scrt1.o
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/lib/libc.so b/third_party/fuchsia-sdk/arch/x64/sysroot/lib/libc.so
new file mode 100755
index 0000000..19cfb6b
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/lib/libc.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/lib/libdl.so b/third_party/fuchsia-sdk/arch/x64/sysroot/lib/libdl.so
new file mode 100644
index 0000000..f2072c3
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/lib/libdl.so
@@ -0,0 +1,5 @@
+/*
+ * The APIs traditionally found in -lm, -ldl, or -lpthread are all implemented
+ * in libc.so, so this file just redirects the linker to refer there instead.
+ */
+INPUT(AS_NEEDED(libc.so))
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/lib/libm.so b/third_party/fuchsia-sdk/arch/x64/sysroot/lib/libm.so
new file mode 100644
index 0000000..f2072c3
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/lib/libm.so
@@ -0,0 +1,5 @@
+/*
+ * The APIs traditionally found in -lm, -ldl, or -lpthread are all implemented
+ * in libc.so, so this file just redirects the linker to refer there instead.
+ */
+INPUT(AS_NEEDED(libc.so))
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/lib/libpthread.so b/third_party/fuchsia-sdk/arch/x64/sysroot/lib/libpthread.so
new file mode 100644
index 0000000..f2072c3
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/lib/libpthread.so
@@ -0,0 +1,5 @@
+/*
+ * The APIs traditionally found in -lm, -ldl, or -lpthread are all implemented
+ * in libc.so, so this file just redirects the linker to refer there instead.
+ */
+INPUT(AS_NEEDED(libc.so))
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/lib/librt.so b/third_party/fuchsia-sdk/arch/x64/sysroot/lib/librt.so
new file mode 100644
index 0000000..f2072c3
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/lib/librt.so
@@ -0,0 +1,5 @@
+/*
+ * The APIs traditionally found in -lm, -ldl, or -lpthread are all implemented
+ * in libc.so, so this file just redirects the linker to refer there instead.
+ */
+INPUT(AS_NEEDED(libc.so))
diff --git a/third_party/fuchsia-sdk/arch/x64/sysroot/lib/libzircon.so b/third_party/fuchsia-sdk/arch/x64/sysroot/lib/libzircon.so
new file mode 100755
index 0000000..394ba86
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/sysroot/lib/libzircon.so
Binary files differ
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/alias_workarounds.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/alias_workarounds.fidl
new file mode 100644
index 0000000..bdcfc5f
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/alias_workarounds.fidl
@@ -0,0 +1,100 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+// These are all aliases that will be subsumed by the future implementation of
+// templating, constraints, etc. in fidlc.
+//
+// The right hand side is completely ignored by kazoo, that is, only the name of
+// the alias is significant. Generally the right hand side is set so that if
+// there were no handling of the alias (and the alias was "expanded" as is the
+// default behaviour), it would result in something sensible.
+
+// TODO(fidlc): (mutable) char*
+using charptr = uint64;
+
+// TODO(fidl)
+using const_futexptr = int32;
+
+// TODO(fidlc): const void*
+using const_voidptr = uint64;
+
+// TODO(fidlc): mutable<string>
+using mutable_string = string;
+
+// TODO(fidlc): mutable<uint32>
+using mutable_uint32 = uint32;
+
+// TODO(fidlc): mutable<usize>
+using mutable_usize = usize;
+
+// TODO(fidlc): uint32 size
+// TODO(fidlc): mutable<vector<HandleDisposition>
+using mutable_vector_HandleDisposition_u32size = vector<HandleDisposition>;
+
+// TODO(fidlc): mutable<vector<WaitItem>>
+using mutable_vector_WaitItem = vector<WaitItem>;
+
+// TODO(fidlc): uint32 size
+// TODO(fidlc): mutable<vector<handle>
+using mutable_vector_handle_u32size = vector<handle>;
+
+// TODO(fidlc): mutable<vector<void>>
+using mutable_vector_void = vector<byte>;
+
+// TODO(fidlc): uint32 size
+// TODO(fidlc): mutable<vector<void>>
+using mutable_vector_void_u32size = vector<byte>;
+
+// TODO(fidlc): optional<PciBar>
+using optional_PciBar = PciBar;
+
+// TODO(fidlc): optional<PortPacket>
+using optional_PortPacket = PortPacket;
+
+// TODO(fidlc): optional<koid>
+using optional_koid = koid;
+
+// TODO(fidlc): optional<signals>
+using optional_signals = signals;
+
+// TODO(fidlc): optional<time>
+using optional_time = time;
+
+// TODO(fidlc): optional<uint32>
+using optional_uint32 = uint32;
+
+// TODO(fidlc): optional<usize>
+using optional_usize = usize;
+
+// TODO(fidlc): optional<usize>
+using optional_off = off;
+
+// TODO(fidlc): uint32 size
+// TODO(fidlc): vector<HandleInfo>
+using vector_HandleInfo_u32size = vector<HandleInfo>;
+
+// TODO(fidlc): vector<handle> uint32 size
+using vector_handle_u32size = vector<handle>;
+
+// TODO(fidlc): vector<paddr>>
+using vector_paddr = vector<paddr>;
+
+// TODO(fidlc): vector<void>
+using vector_void = vector<byte>;
+
+// TODO(fidlc): vector<iovec>
+using vector_iovec = vector<byte>;
+
+// TODO(fidlc): uint32 size
+// TODO(fidlc): vector<void>
+using vector_void_u32size = vector<byte>;
+
+// TODO(fidlc): (mutable) void*
+using voidptr = uint64;
+
+// This is <zircon/string_view.h>'s zx_string_view_t in C/C++.
+using string_view = uint64;
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/bti.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/bti.fidl
new file mode 100644
index 0000000..8ec1c08
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/bti.fidl
@@ -0,0 +1,32 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol bti {
+ /// Create a new bus transaction initiator.
+ /// Rights: iommu must be of type ZX_OBJ_TYPE_IOMMU and have ZX_RIGHT_NONE.
+ // TODO(ZX-2967): This is an unusual rights spec.
+ bti_create(handle<iommu> iommu, uint32 options, uint64 bti_id) -> (status status, handle<bti> out);
+
+ /// Pin pages and grant devices access to them.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_BTI and have ZX_RIGHT_MAP.
+ /// Rights: vmo must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_MAP.
+ /// Rights: If options & ZX_BTI_PERM_READ, vmo must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_READ.
+ /// Rights: If options & ZX_BTI_PERM_WRITE, vmo must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_WRITE.
+ /// Rights: If options & ZX_BTI_PERM_EXECUTE, vmo must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_READ.
+ // READ is intentional in the EXECUTE condition.
+ bti_pin(handle<bti> handle,
+ uint32 options,
+ handle<vmo> vmo,
+ uint64 offset,
+ uint64 size)
+ -> (status status, vector_paddr addrs, handle<pmt> pmt);
+
+ /// Releases all quarantined PMTs.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_BTI and have ZX_RIGHT_WRITE.
+ bti_release_quarantine(handle<bti> handle) -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/cache.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/cache.fidl
new file mode 100644
index 0000000..f1f8567
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/cache.fidl
@@ -0,0 +1,13 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol cache {
+ /// Flush CPU data and/or instruction caches.
+ [vdsocall]
+ cache_flush(const_voidptr addr, usize size, uint32 options) -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/channel.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/channel.fidl
new file mode 100644
index 0000000..25c8ca3
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/channel.fidl
@@ -0,0 +1,107 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+using ObjType = uint32;
+
+// TODO(scottmg): ZX_OBJ_TYPE_xyz here.
+
+using HandleOp = uint32;
+
+// TODO(scottmg): ZX_HANDLE_OP_xyz here.
+
+struct HandleInfo {
+ handle handle;
+ ObjType type;
+ rights rights;
+ uint32 unused;
+};
+
+struct ChannelCallArgs {
+ vector<byte> wr_bytes;
+ vector<handle> wr_handles;
+ // TODO(scottmg): mutable_vector_void
+ vector<byte> rd_bytes;
+ // TODO(scottmg): mutable_vector_handle
+ vector<handle> rd_handles;
+};
+
+struct HandleDisposition {
+ HandleOp operation;
+ handle handle;
+ ObjType type;
+ rights rights;
+ status result;
+};
+
+[Transport = "Syscall"]
+protocol channel {
+ /// Create a channel.
+ channel_create(uint32 options) -> (status status, handle out0, handle out1);
+
+ /// Read a message from a channel.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_CHANNEL and have ZX_RIGHT_READ.
+ [ArgReorder = "handle, options, bytes, handles, num_bytes, num_handles, actual_bytes, actual_handles",
+ HandleUnchecked]
+ channel_read(handle<channel> handle,
+ uint32 options)
+ -> (status status,
+ vector_void_u32size bytes,
+ vector_handle_u32size handles,
+ optional_uint32 actual_bytes,
+ optional_uint32 actual_handles);
+
+ /// Read a message from a channel.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_CHANNEL and have ZX_RIGHT_READ.
+ [ArgReorder = "handle, options, bytes, handles, num_bytes, num_handles, actual_bytes, actual_handles"]
+ channel_read_etc(handle<channel> handle,
+ uint32 options)
+ -> (status status,
+ vector_void_u32size bytes,
+ vector_HandleInfo_u32size handles,
+ optional_uint32 actual_bytes,
+ optional_uint32 actual_handles);
+
+ /// Write a message to a channel.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_CHANNEL and have ZX_RIGHT_WRITE.
+ /// Rights: Every entry of handles must have ZX_RIGHT_TRANSFER.
+ channel_write(handle<channel> handle,
+ uint32 options,
+ vector_void_u32size bytes,
+ vector_handle_u32size handles)
+ -> (status status);
+
+ /// Write a message to a channel.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_CHANNEL and have ZX_RIGHT_WRITE.
+ /// Rights: Every entry of handles must have ZX_RIGHT_TRANSFER.
+ channel_write_etc(handle<channel> handle,
+ uint32 options,
+ vector_void_u32size bytes,
+ mutable_vector_HandleDisposition_u32size handles)
+ -> (status status);
+
+ /// Rights: handle must be of type ZX_OBJ_TYPE_CHANNEL and have ZX_RIGHT_READ and have ZX_RIGHT_WRITE.
+ /// Rights: All wr_handles of args must have ZX_RIGHT_TRANSFER.
+ [internal]
+ channel_call_noretry(handle<channel> handle,
+ uint32 options,
+ time deadline,
+ ChannelCallArgs args)
+ -> (status status, uint32 actual_bytes, uint32 actual_handles);
+
+ [internal]
+ channel_call_finish(time deadline, ChannelCallArgs args)
+ -> (status status, uint32 actual_bytes, uint32 actual_handles);
+
+ /// Send a message to a channel and await a reply.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_CHANNEL and have ZX_RIGHT_READ and have ZX_RIGHT_WRITE.
+ /// Rights: All wr_handles of args must have ZX_RIGHT_TRANSFER.
+ [blocking,
+ vdsocall]
+ // TODO(scottmg): Express "All wr_handles of args must have ZX_RIGHT_TRANSFER."
+ channel_call(handle handle, uint32 options, time deadline, ChannelCallArgs args)
+ -> (status status, uint32 actual_bytes, uint32 actual_handles);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/clock.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/clock.fidl
new file mode 100644
index 0000000..5aecb3b
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/clock.fidl
@@ -0,0 +1,51 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+enum Clock : uint32 {
+ MONOTONIC = 0;
+ UTC = 1;
+ THREAD = 2;
+};
+
+[Transport = "Syscall"]
+protocol clock {
+ /// Acquire the current time.
+ clock_get(Clock clock_id) -> (status status, time out);
+
+ /// Acquire the current monotonic time.
+ [vdsocall]
+ clock_get_monotonic() -> (time time);
+
+ /// Rights: handle must have resource kind ZX_RSRC_KIND_ROOT.
+ clock_adjust(handle<resource> handle, Clock clock_id, int64 offset) -> (status status);
+
+ // Read clock monotonic, but demand that the read be performed using a
+ // syscall, instead of a vdso call.
+ //
+ // See the notes for ticks_get_via_kernel; this is not a syscall meant
+ // to be used by application code.
+ [internal]
+ clock_get_monotonic_via_kernel() -> (time time);
+
+ // TODO: handle<clock> for all of these.
+
+ /// Create a new clock object.
+ /// Rights: None.
+ clock_create(uint64 options, const_voidptr args) -> (status status, handle out);
+
+ /// Perform a basic read of the clock.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_CLOCK and have ZX_RIGHT_READ.
+ clock_read(handle handle) -> (status status, time now);
+
+ /// Fetch all of the low level details of the clock's current status.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_CLOCK and have ZX_RIGHT_READ.
+ clock_get_details(handle handle, uint64 options) -> (status status, voidptr details);
+
+ /// Make adjustments to a clock object.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_CLOCK and have ZX_RIGHT_WRITE.
+ clock_update(handle handle, uint64 options, const_voidptr args) -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/cprng.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/cprng.fidl
new file mode 100644
index 0000000..7431bde
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/cprng.fidl
@@ -0,0 +1,19 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol cprng {
+ [internal]
+ cprng_draw_once() -> (status status, vector_void buffer);
+
+ /// Draw from the kernel's CPRNG.
+ [vdsocall]
+ cprng_draw() -> (vector_void buffer);
+
+ /// Add entropy to the kernel CPRNG.
+ cprng_add_entropy(vector_void buffer) -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/debug.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/debug.fidl
new file mode 100644
index 0000000..e629799
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/debug.fidl
@@ -0,0 +1,17 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol debug {
+ /// Rights: handle must have resource kind ZX_RSRC_KIND_ROOT.
+ debug_read(handle<resource> handle) -> (status status, string buffer, usize actual);
+
+ debug_write(string buffer) -> (status status);
+
+ /// Rights: resource must have resource kind ZX_RSRC_KIND_ROOT.
+ debug_send_command(handle<resource> resource, string buffer) -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/debuglog.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/debuglog.fidl
new file mode 100644
index 0000000..23e1faf
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/debuglog.fidl
@@ -0,0 +1,20 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol debuglog {
+ // TODO(ZX-2967): handle == ZX_HANDLE_INVALID accepted.
+ /// Rights: resource must have resource kind ZX_RSRC_KIND_ROOT.
+ debuglog_create(handle<resource> resource, uint32 options)
+ -> (status status, handle<debuglog> out);
+
+ /// Rights: handle must be of type ZX_OBJ_TYPE_LOG and have ZX_RIGHT_WRITE.
+ debuglog_write(handle<debuglog> handle, uint32 options, vector_void buffer) -> (status status);
+
+ /// Rights: handle must be of type ZX_OBJ_TYPE_LOG and have ZX_RIGHT_READ.
+ debuglog_read(handle<debuglog> handle, uint32 options) -> (status status, vector_void buffer);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/event.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/event.fidl
new file mode 100644
index 0000000..4f12cd8
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/event.fidl
@@ -0,0 +1,12 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol event {
+ /// Create an event.
+ event_create(uint32 options) -> (status status, handle<event> out);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/eventpair.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/eventpair.fidl
new file mode 100644
index 0000000..a7a3e38
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/eventpair.fidl
@@ -0,0 +1,12 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol eventpair {
+ /// Create an event pair.
+ eventpair_create(uint32 options) -> (status status, handle<event> out0, handle<event> out1);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/exception.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/exception.fidl
new file mode 100644
index 0000000..db3e45a
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/exception.fidl
@@ -0,0 +1,17 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol exception {
+ /// Create a handle for the exception's thread.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_EXCEPTION.
+ exception_get_thread(handle<exception> handle) -> (status status, handle<thread> out);
+
+ /// Create a handle for the exception's process.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_EXCEPTION.
+ exception_get_process(handle<exception> handle) -> (status status, handle<process> out);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/fifo.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/fifo.fidl
new file mode 100644
index 0000000..0e9ee21
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/fifo.fidl
@@ -0,0 +1,23 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol fifo {
+ /// Create a fifo.
+ fifo_create(usize elem_count, usize elem_size, uint32 options)
+ -> (status status, handle<fifo> out0, handle<fifo> out1);
+
+ /// Read data from a fifo.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_FIFO and have ZX_RIGHT_READ.
+ fifo_read(handle<fifo> handle, usize elem_size)
+ -> (status status, vector_void data, optional_usize actual_count);
+
+ /// Write data to a fifo.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_FIFO and have ZX_RIGHT_WRITE.
+ fifo_write(handle<fifo> handle, usize elem_size, const_voidptr data, usize count)
+ -> (status status, optional_usize actual_count);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/framebuffer.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/framebuffer.fidl
new file mode 100644
index 0000000..2ab69c7
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/framebuffer.fidl
@@ -0,0 +1,24 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol framebuffer {
+ /// Rights: resource must have resource kind ZX_RSRC_KIND_ROOT.
+ framebuffer_get_info(handle<resource> resource)
+ -> (status status, uint32 format, uint32 width, uint32 height, uint32 stride);
+
+ // TODO(ZX-2967): vmo ZX_OBJ_TYPE_VMO; No rights required?
+ /// Rights: resource must have resource kind ZX_RSRC_KIND_ROOT.
+ framebuffer_set_range(handle<resource> resource,
+ handle<vmo> vmo,
+ uint32 len,
+ uint32 format,
+ uint32 width,
+ uint32 height,
+ uint32 stride)
+ -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/futex.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/futex.fidl
new file mode 100644
index 0000000..69ab6dc
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/futex.fidl
@@ -0,0 +1,58 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+// TODO(scottmg): This is approximately right, but will need to match the
+// current definition of zx_futex_t (atomic_int in some #if branches).
+using Futex = int32;
+
+// TODO(scottmg): The futex is unusual in that by virtue of being an int,
+// sometimes it's passed by pointer, and sometimes by value.
+
+[Transport = "Syscall"]
+protocol futex {
+ /// Wait on a futex.
+ /// Rights: None.
+ [blocking]
+ futex_wait(const_futexptr value_ptr, Futex current_value, handle new_futex_owner, time deadline)
+ -> (status status);
+
+ /// Wake some number of threads waiting on a futex, and set the ownership of the futex to nothing.
+ /// Rights: None.
+ futex_wake(const_futexptr value_ptr, uint32 wake_count) -> (status status);
+
+ /// Wake some number of threads waiting on a futex, and move more waiters to another wait queue.
+ /// Rights: None.
+ futex_requeue(const_futexptr value_ptr,
+ uint32 wake_count,
+ Futex current_value,
+ const_futexptr requeue_ptr,
+ uint32 requeue_count,
+ handle new_requeue_owner)
+ -> (status status);
+
+ /// Wake one thread waiting on a futex. If a thread is woken,
+ /// ownership of the futex is transferred to that thread. If no
+ /// thread is woken (because none are waiting), ownership of the
+ /// futex is set to none.
+ /// Rights: None.
+ futex_wake_single_owner(const_futexptr value_ptr) -> (status status);
+
+ /// Wake one thread waiting on a futex, and move more waiters to
+ /// another wait queue. Ownership is transferred to the woken thread,
+ /// or cancelled, as with |futex_wake_single_owner|.
+ /// Rights: None.
+ futex_requeue_single_owner(const_futexptr value_ptr,
+ Futex current_value,
+ const_futexptr requeue_ptr,
+ uint32 requeue_count,
+ handle new_requeue_owner)
+ -> (status status);
+
+ /// Fetch the koid current owner of a futex, if any.
+ /// Rights: None.
+ futex_get_owner(const_futexptr value_ptr) -> (status status, optional_koid koid);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/guest.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/guest.fidl
new file mode 100644
index 0000000..a75093e
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/guest.fidl
@@ -0,0 +1,25 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol guest {
+ /// Create a guest.
+ /// Rights: resource must have resource kind ZX_RSRC_KIND_HYPERVISOR.
+ guest_create(handle<resource> resource, uint32 options)
+ -> (status status, handle<guest> guest_handle, handle<vmar> vmar_handle);
+
+ /// Sets a trap within a guest.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_GUEST and have ZX_RIGHT_WRITE.
+ /// Rights: port_handle must be of type ZX_OBJ_TYPE_PORT and have ZX_RIGHT_WRITE.
+ guest_set_trap(handle<guest> handle,
+ uint32 kind,
+ vaddr addr,
+ usize size,
+ handle<port> port_handle,
+ uint64 key)
+ -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/handle.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/handle.fidl
new file mode 100644
index 0000000..b29842b
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/handle.fidl
@@ -0,0 +1,25 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol handle {
+ /// Close a handle.
+ /// Rights: None.
+ handle_close([Release] handle handle) -> (status status);
+
+ /// Close a number of handles.
+ /// Rights: None.
+ handle_close_many([Release] vector<handle> handles) -> (status status);
+
+ /// Duplicate a handle.
+ /// Rights: handle must have ZX_RIGHT_DUPLICATE.
+ handle_duplicate(handle handle, rights rights) -> (status status, handle out);
+
+ /// Replace a handle.
+ /// Rights: None.
+ handle_replace([Release] handle handle, rights rights) -> (status status, handle out);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/interrupt.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/interrupt.fidl
new file mode 100644
index 0000000..506df65
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/interrupt.fidl
@@ -0,0 +1,43 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol interrupt {
+ /// Create an interrupt object.
+ /// Rights: src_obj must have resource kind ZX_RSRC_KIND_IRQ.
+ interrupt_create(handle<resource> src_obj, uint32 src_num, uint32 options)
+ -> (status status, handle<interrupt> out_handle);
+
+ /// Bind an interrupt object to a port.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_INTERRUPT and have ZX_RIGHT_READ.
+ /// Rights: port_handle must be of type ZX_OBJ_TYPE_PORT and have ZX_RIGHT_WRITE.
+ interrupt_bind(handle<interrupt> handle, handle<port> port_handle, uint64 key, uint32 options)
+ -> (status status);
+
+ /// Wait for an interrupt.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_INTERRUPT and have ZX_RIGHT_WAIT.
+ [blocking]
+ interrupt_wait(handle<interrupt> handle) -> (status status, optional_time out_timestamp);
+
+ // TODO(ZX-2967): No DESTROY rights here.
+ /// Destroys an interrupt object.
+ interrupt_destroy(handle<interrupt> handle) -> (status status);
+
+ /// Acknowledge an interrupt and re-arm it.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_INTERRUPT and have ZX_RIGHT_WRITE.
+ interrupt_ack(handle<interrupt> handle) -> (status status);
+
+ /// Triggers a virtual interrupt object.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_INTERRUPT and have ZX_RIGHT_SIGNAL.
+ interrupt_trigger(handle<interrupt> handle, uint32 options, time timestamp) -> (status status);
+
+ /// Bind an interrupt object to a VCPU.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_INTERRUPT and have ZX_RIGHT_READ.
+ /// Rights: vcpu must be of type ZX_OBJ_TYPE_VCPU and have ZX_RIGHT_WRITE.
+ interrupt_bind_vcpu(handle<interrupt> handle, handle<vcpu> vcpu, uint32 options)
+ -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/iommu.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/iommu.fidl
new file mode 100644
index 0000000..84ac2a9
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/iommu.fidl
@@ -0,0 +1,14 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol iommu {
+ /// Create a new IOMMU object in the kernel.
+ /// Rights: resource must have resource kind ZX_RSRC_KIND_ROOT.
+ iommu_create(handle<resource> resource, uint32 type, vector_void desc)
+ -> (status status, handle<iommu> out);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/ioports.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/ioports.fidl
new file mode 100644
index 0000000..72353d3
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/ioports.fidl
@@ -0,0 +1,15 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol ioports {
+ /// Rights: resource must have resource kind ZX_RSRC_KIND_IOPORT.
+ ioports_request(handle<resource> resource, uint16 io_addr, uint32 len) -> (status status);
+
+ /// Rights: resource must have resource kind ZX_RSRC_KIND_IOPORT.
+ ioports_release(handle<resource> resource, uint16 io_addr, uint32 len) -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/job.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/job.fidl
new file mode 100644
index 0000000..edbdd2c
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/job.fidl
@@ -0,0 +1,24 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol job {
+ // TODO(ZX-2967): parent_job with ZX_RIGHT_WRITE is also accepted.
+ /// Create a new job.
+ /// Rights: parent_job must be of type ZX_OBJ_TYPE_JOB and have ZX_RIGHT_MANAGE_JOB.
+ job_create(handle<job> parent_job, uint32 options) -> (status status, handle<job> out);
+
+ /// Set job security and resource policies.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_JOB and have ZX_RIGHT_SET_POLICY.
+ job_set_policy(handle<job> handle, uint32 options, uint32 topic, vector_void_u32size policy)
+ -> (status status);
+
+ /// Set a process as critical to a job.
+ /// Rights: job must have ZX_RIGHT_DESTROY.
+ /// Rights: process must have ZX_RIGHT_WAIT.
+ job_set_critical(handle<job> job, uint32 options, handle<process> process) -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/ktrace.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/ktrace.fidl
new file mode 100644
index 0000000..d3234e6
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/ktrace.fidl
@@ -0,0 +1,26 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol ktrace {
+ // TODO(scottmg): This is another one where it's:
+ // (handle, data, offset, data_size)
+ // rather than:
+ // (handle, data, data_size, offset).
+ /// Rights: handle must have resource kind ZX_RSRC_KIND_ROOT.
+ [ArgReorder = "handle, data, offset, data_size, actual"]
+ ktrace_read(handle<resource> handle, uint32 offset)
+ -> (status status, vector_void data, usize actual);
+
+ // TODO(scottmg): syscalls.banjo had the length of |ptr| being |action|?
+ /// Rights: handle must have resource kind ZX_RSRC_KIND_ROOT.
+ ktrace_control(handle<resource> handle, uint32 action, uint32 options, voidptr ptr)
+ -> (status status);
+
+ /// Rights: handle must have resource kind ZX_RSRC_KIND_ROOT.
+ ktrace_write(handle<resource> handle, uint32 id, uint32 arg0, uint32 arg1) -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/misc.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/misc.fidl
new file mode 100644
index 0000000..6c0e4c4
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/misc.fidl
@@ -0,0 +1,57 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+// TODO(scottmg): These syscalls don't match the general naming convention of
+// zx_something_name(), they're just zx_name(), so NoProtocolPrefix tells the
+// generator to exclude putting "Misc" in the name.
+[Transport = "Syscall",
+NoProtocolPrefix]
+protocol misc {
+ /// High resolution sleep.
+ /// Rights: None.
+ [blocking]
+ nanosleep(time deadline) -> (status status);
+
+ /// Read the number of high-precision timer ticks since boot.
+ [vdsocall]
+ ticks_get() -> (ticks ticks);
+
+ /// Read the number of high-precision timer ticks in a second.
+ [const,
+ vdsocall]
+ ticks_per_second() -> (ticks ticks);
+
+ /// Convert a time relative to now to an absolute deadline.
+ [vdsocall]
+ deadline_after(duration nanoseconds) -> (time time);
+
+ /// Unmap memory, close handle, exit.
+ [vdsocall]
+ vmar_unmap_handle_close_thread_exit(handle<vmar> vmar_handle,
+ vaddr addr, usize size,
+ [Release] handle close_handle)
+ -> (status status);
+
+ /// Write to futex, wake futex, close handle, exit.
+ [noreturn,
+ vdsocall]
+ futex_wake_handle_close_thread_exit(const_futexptr value_ptr,
+ uint32 wake_count,
+ int32 new_value,
+ [Release] handle close_handle);
+
+ // Read the number of high-precision timer ticks since boot, but demand
+ // that the read be performed using a syscall, instead of a vdso call.
+ //
+ // Note that this is an internal syscall, not meant to be used by
+ // application code. By default, the vdso version of this syscall will do
+ // the proper thing, either directly reading from the hardware register
+ // backing the tick counter, or by making a syscall if the register is not
+ // accessible from user mode code (for whatever reason).
+ [internal]
+ ticks_get_via_kernel() -> (ticks ticks);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/mtrace.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/mtrace.fidl
new file mode 100644
index 0000000..f3c1f1c
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/mtrace.fidl
@@ -0,0 +1,17 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol mtrace {
+ /// Rights: handle must have resource kind ZX_RSRC_KIND_ROOT.
+ mtrace_control(handle<resource> handle,
+ uint32 kind,
+ uint32 action,
+ uint32 options,
+ mutable_vector_void ptr)
+ -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/object.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/object.fidl
new file mode 100644
index 0000000..f510fec
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/object.fidl
@@ -0,0 +1,95 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+// TODO(scottmg): Apply rights spec from WaitMany on |items| to |handle| here,
+// somehow.
+struct WaitItem {
+ handle handle;
+ signals waitfor;
+ signals pending;
+};
+
+[Transport = "Syscall"]
+protocol object {
+ /// Wait for signals on an object.
+ /// Rights: handle must have ZX_RIGHT_WAIT.
+ [blocking]
+ object_wait_one(handle handle, signals signals, time deadline)
+ -> (status status, optional_signals observed);
+
+ /// Wait for signals on multiple objects.
+ /// Rights: Every entry of items must have a handle field with ZX_RIGHT_WAIT.
+ [blocking]
+ object_wait_many(mutable_vector_WaitItem items, time deadline) -> (status status);
+
+ /// Subscribe for signals on an object.
+ /// Rights: handle must have ZX_RIGHT_WAIT.
+ /// Rights: port must be of type ZX_OBJ_TYPE_PORT and have ZX_RIGHT_WRITE.
+ object_wait_async(handle handle, handle<port> port, uint64 key, signals signals, uint32 options)
+ -> (status status);
+
+ /// Signal an object.
+ /// Rights: handle must have ZX_RIGHT_SIGNAL.
+ object_signal(handle handle, uint32 clear_mask, uint32 set_mask) -> (status status);
+
+ /// Signal an object's peer.
+ /// Rights: handle must have ZX_RIGHT_SIGNAL_PEER.
+ object_signal_peer(handle handle, uint32 clear_mask, uint32 set_mask) -> (status status);
+
+ /// Ask for various properties of various kernel objects.
+ /// Rights: handle must have ZX_RIGHT_GET_PROPERTY.
+ /// Rights: If property is ZX_PROP_PROCESS_DEBUG_ADDR, handle must be of type ZX_OBJ_TYPE_PROCESS.
+ /// Rights: If property is ZX_PROP_PROCESS_BREAK_ON_LOAD, handle must be of type ZX_OBJ_TYPE_PROCESS.
+ /// Rights: If property is ZX_PROP_PROCESS_VDSO_BASE_ADDRESS, handle must be of type ZX_OBJ_TYPE_PROCESS.
+ /// Rights: If property is ZX_PROP_SOCKET_RX_THRESHOLD, handle must be of type ZX_OBJ_TYPE_SOCKET.
+ /// Rights: If property is ZX_PROP_SOCKET_TX_THRESHOLD, handle must be of type ZX_OBJ_TYPE_SOCKET.
+ object_get_property(handle handle, uint32 property) -> (status status, vector_void value);
+
+ /// Set various properties of various kernel objects.
+ /// Rights: handle must have ZX_RIGHT_SET_PROPERTY.
+ /// Rights: If property is ZX_PROP_PROCESS_DEBUG_ADDR, handle must be of type ZX_OBJ_TYPE_PROCESS.
+ /// Rights: If property is ZX_PROP_PROCESS_BREAK_ON_LOAD, handle must be of type ZX_OBJ_TYPE_PROCESS.
+ /// Rights: If property is ZX_PROP_SOCKET_RX_THRESHOLD, handle must be of type ZX_OBJ_TYPE_SOCKET.
+ /// Rights: If property is ZX_PROP_SOCKET_TX_THRESHOLD, handle must be of type ZX_OBJ_TYPE_SOCKET.
+ /// Rights: If property is ZX_PROP_JOB_KILL_ON_OOM, handle must be of type ZX_OBJ_TYPE_JOB.
+ object_set_property(handle handle, uint32 property, vector_void value) -> (status status);
+
+ /// Query information about an object.
+ /// Rights: If topic is ZX_INFO_PROCESS, handle must be of type ZX_OBJ_TYPE_PROCESS and have ZX_RIGHT_INSPECT.
+ /// Rights: If topic is ZX_INFO_JOB, handle must be of type ZX_OBJ_TYPE_JOB and have ZX_RIGHT_INSPECT.
+ /// Rights: If topic is ZX_INFO_PROCESS_THREADS, handle must be of type ZX_OBJ_TYPE_PROCESS and have ZX_RIGHT_ENUMERATE.
+ /// Rights: If topic is ZX_INFO_JOB_CHILDREN, handle must be of type ZX_OBJ_TYPE_JOB and have ZX_RIGHT_ENUMERATE.
+ /// Rights: If topic is ZX_INFO_JOB_PROCESSES, handle must be of type ZX_OBJ_TYPE_JOB and have ZX_RIGHT_ENUMERATE.
+ /// Rights: If topic is ZX_INFO_THREAD, handle must be of type ZX_OBJ_TYPE_THREAD and have ZX_RIGHT_INSPECT.
+ /// Rights: If topic is ZX_INFO_THREAD_EXCEPTION_REPORT, handle must be of type ZX_OBJ_TYPE_THREAD and have ZX_RIGHT_INSPECT.
+ /// Rights: If topic is ZX_INFO_THREAD_STATS, handle must be of type ZX_OBJ_TYPE_THREAD and have ZX_RIGHT_INSPECT.
+ /// Rights: If topic is ZX_INFO_TASK_STATS, handle must be of type ZX_OBJ_TYPE_PROCESS and have ZX_RIGHT_INSPECT.
+ /// Rights: If topic is ZX_INFO_PROCESS_MAPS, handle must be of type ZX_OBJ_TYPE_PROCESS and have ZX_RIGHT_INSPECT.
+ /// Rights: If topic is ZX_INFO_PROCESS_VMOS, handle must be of type ZX_OBJ_TYPE_PROCESS and have ZX_RIGHT_INSPECT.
+ /// Rights: If topic is ZX_INFO_VMO, handle must be of type ZX_OBJ_TYPE_VMO.
+ /// TODO(ZX-2967), Should this require INSPECT?
+ /// Rights: If topic is ZX_INFO_VMAR, handle must be of type ZX_OBJ_TYPE_VMAR and have ZX_RIGHT_INSPECT.
+ /// Rights: If topic is ZX_INFO_CPU_STATS, handle must have resource kind ZX_RSRC_KIND_ROOT.
+ /// Rights: If topic is ZX_INFO_KMEM_STATS, handle must have resource kind ZX_RSRC_KIND_ROOT.
+ /// Rights: If topic is ZX_INFO_RESOURCE, handle must be of type ZX_OBJ_TYPE_RESOURCE and have ZX_RIGHT_INSPECT.
+ /// Rights: If topic is ZX_INFO_HANDLE_COUNT, handle must have ZX_RIGHT_INSPECT.
+ /// Rights: If topic is ZX_INFO_BTI, handle must be of type ZX_OBJ_TYPE_BTI and have ZX_RIGHT_INSPECT.
+ /// Rights: If topic is ZX_INFO_PROCESS_HANDLE_STATS, handle must be of type ZX_OBJ_TYPE_PROCESS and have ZX_RIGHT_INSPECT.
+ /// Rights: If topic is ZX_INFO_SOCKET, handle must be of type ZX_OBJ_TYPE_SOCKET and have ZX_RIGHT_INSPECT.
+ object_get_info(handle handle, uint32 topic)
+ -> (status status, vector_void buffer, optional_usize actual, optional_usize avail);
+
+ /// Given a kernel object with children objects, obtain a handle to the child specified by the provided kernel object id.
+ /// Rights: handle must have ZX_RIGHT_ENUMERATE.
+ object_get_child(handle handle, uint64 koid, rights rights) -> (status status, handle out);
+
+ /// Apply a scheduling profile to a thread.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_THREAD and have ZX_RIGHT_MANAGE_THREAD.
+ /// Rights: profile must be of type ZX_OBJ_TYPE_PROFILE and have ZX_RIGHT_APPLY_PROFILE.
+ object_set_profile(handle<thread> handle, handle<profile> profile, uint32 options)
+ -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/pager.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/pager.fidl
new file mode 100644
index 0000000..6c7c581
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/pager.fidl
@@ -0,0 +1,36 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol pager {
+ /// Create a new pager object.
+ /// Rights: None.
+ pager_create(uint32 options) -> (status status, handle<pager> out);
+
+ /// Create a pager owned vmo.
+ /// Rights: pager must be of type ZX_OBJ_TYPE_PAGER.
+ /// Rights: port must be of type ZX_OBJ_TYPE_PORT and have ZX_RIGHT_WRITE.
+ pager_create_vmo(handle<pager> pager, uint32 options, handle<port> port, uint64 key, uint64 size)
+ -> (status status, handle<vmo> out);
+
+ /// Detaches a vmo from a pager.
+ /// Rights: pager must be of type ZX_OBJ_TYPE_PAGER.
+ /// Rights: vmo must be of type ZX_OBJ_TYPE_VMO.
+ pager_detach_vmo(handle<pager> pager, handle<vmo> vmo) -> (status status);
+
+ /// Supply pages into a pager owned vmo.
+ /// Rights: pager must be of type ZX_OBJ_TYPE_PAGER.
+ /// Rights: pager_vmo must be of type ZX_OBJ_TYPE_VMO.
+ /// Rights: aux_vmo must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_READ and have ZX_RIGHT_WRITE.
+ pager_supply_pages(handle<pager> pager,
+ handle<vmo> pager_vmo,
+ uint64 offset,
+ uint64 length,
+ handle<vmo> aux_vmo,
+ uint64 aux_offset)
+ -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/pc.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/pc.fidl
new file mode 100644
index 0000000..cb10baa
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/pc.fidl
@@ -0,0 +1,12 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol pc {
+ /// Rights: handle must have resource kind ZX_RSRC_KIND_ROOT.
+ pc_firmware_tables(handle<resource> handle) -> (status status, paddr acpi_rsdp, paddr smbios);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/pci.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/pci.fidl
new file mode 100644
index 0000000..d5c80db
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/pci.fidl
@@ -0,0 +1,127 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+// TODO(cja): This makes some assumptions that anything in an arch's PIO region
+// is going to be defined as a base address and size. This will need to be
+// updated to a per-platform structure in the event that doesn't pan out
+// in the future.
+struct PciBar {
+ uint32 id;
+ uint32 type;
+ usize size;
+ // TODO(scottmg): Unnamed union.
+ //union {
+ // uintptr_t addr;
+ // zx_handle_t handle;
+ //};
+};
+
+// Defines and structures related to zx_pci_*()
+// Info returned to dev manager for PCIe devices when probing.
+struct PcieDeviceInfo {
+ uint16 vendor_id;
+ uint16 device_id;
+
+ uint8 base_class;
+ uint8 sub_class;
+ uint8 program_interface;
+ uint8 revision_id;
+
+ uint8 bus_id;
+ uint8 dev_id;
+ uint8 func_id;
+};
+
+// TODO(scottmg): Lots of constants here.
+
+// TODO(scottmg): This one is hard.
+struct PciInitArg {
+ // TODO(scottmg): [][][] array.
+ // zx_pci_irq_swizzle_lut_t dev_pin_to_global_irq;
+
+ uint32 num_irqs;
+ //struct {
+ // uint32_t global_irq;
+ // bool level_triggered;
+ // bool active_high;
+ //} irqs[ZX_PCI_MAX_IRQS];
+
+ uint32 addr_window_count;
+ // TODO(scottmg): struct-hack sized.
+ //struct {
+ // uint64_t base;
+ // size_t size;
+ // uint8_t bus_start;
+ // uint8_t bus_end;
+ // uint8_t cfg_space_type;
+ // bool has_ecam;
+ //} addr_windows[];
+};
+
+[Transport = "Syscall"]
+protocol pci {
+ /// Rights: handle must have resource kind ZX_RSRC_KIND_ROOT.
+ pci_get_nth_device(handle<resource> handle, uint32 index)
+ -> (status status, PcieDeviceInfo out_info, handle out_handle);
+
+ /// Rights: handle must be of type ZX_OBJ_TYPE_PCI_DEVICE and have ZX_RIGHT_WRITE.
+ pci_enable_bus_master(handle<pcidevice> handle, bool enable) -> (status status);
+
+ /// Rights: handle must be of type ZX_OBJ_TYPE_PCI_DEVICE and have ZX_RIGHT_WRITE.
+ pci_reset_device(handle<pcidevice> handle) -> (status status);
+
+ // TODO(scottmg): In banjo/abigen out_val wasn't optional, but was an input
+ // OUT, so didn't get the __NONNULL() tag, so we match by making it optional
+ // here. I think this is probably not the intention, and it should be
+ // non-optional.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_PCI_DEVICE and have ZX_RIGHT_READ and have ZX_RIGHT_WRITE.
+ pci_config_read(handle<pcidevice> handle, uint16 offset, usize width)
+ -> (status status, optional_uint32 out_val);
+
+ /// Rights: handle must be of type ZX_OBJ_TYPE_PCI_DEVICE and have ZX_RIGHT_READ and have ZX_RIGHT_WRITE.
+ pci_config_write(handle<pcidevice> handle, uint16 offset, usize width, uint32 val)
+ -> (status status);
+
+ /// Rights: handle must have resource kind ZX_RSRC_KIND_ROOT.
+ pci_cfg_pio_rw(handle<resource> handle,
+ uint8 bus,
+ uint8 dev,
+ uint8 func,
+ uint8 offset,
+ mutable_uint32 val,
+ usize width,
+ bool write)
+ -> (status status);
+
+ // TODO(scottmg): type of out_handle?
+ // TODO(scottmg): In banjo/abigen out_bar wasn't optional, but was an input
+ // OUT, so has no __NONNULL(). I think this is probably not the intention.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_PCI_DEVICE and have ZX_RIGHT_READ and have ZX_RIGHT_WRITE.
+ pci_get_bar(handle<pcidevice> handle, uint32 bar_num)
+ -> (status status, optional_PciBar out_bar, handle out_handle);
+
+ /// Rights: handle must be of type ZX_OBJ_TYPE_PCI_DEVICE and have ZX_RIGHT_READ.
+ pci_map_interrupt(handle<pcidevice> handle, int32 which_irq)
+ -> (status status, handle out_handle);
+
+ /// Rights: handle must be of type ZX_OBJ_TYPE_PCI_DEVICE and have ZX_RIGHT_READ.
+ pci_query_irq_mode(handle<pcidevice> handle, uint32 mode)
+ -> (status status, uint32 out_max_irqs);
+
+ /// Rights: handle must be of type ZX_OBJ_TYPE_PCI_DEVICE and have ZX_RIGHT_WRITE.
+ pci_set_irq_mode(handle<pcidevice> handle, uint32 mode, uint32 requested_irq_count)
+ -> (status status);
+
+ // Note that init_buf isn't a vector of PciInitArg, it's a variable sized
+ // structure starting with a zx_pci_init_arg_t.
+ /// Rights: handle must have resource kind ZX_RSRC_KIND_ROOT.
+ pci_init(handle<resource> handle, PciInitArg init_buf, uint32 len) -> (status status);
+
+ /// Rights: handle must have resource kind ZX_RSRC_KIND_ROOT.
+ pci_add_subtract_io_range(handle<resource> handle, bool mmio, uint64 base, uint64 len, bool add)
+ -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/pmt.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/pmt.fidl
new file mode 100644
index 0000000..0e37311
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/pmt.fidl
@@ -0,0 +1,13 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol pmt {
+ // TODO(ZX-2967): handle ZX_OBJ_TYPE_PMT; No rights required?
+ /// Unpin pages and revoke device access to them.
+ pmt_unpin(handle<pmt> handle) -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/port.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/port.fidl
new file mode 100644
index 0000000..b07fb7b
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/port.fidl
@@ -0,0 +1,146 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+// port_packet_t::type ZX_PKT_TYPE_USER.
+union PacketUser {
+ 1: array<uint64>:4 u64;
+ 2: array<uint32>:8 u32;
+ 3: array<uint16>:16 u16;
+ 4: array<int8>:32 c8;
+};
+
+// port_packet_t::type ZX_PKT_TYPE_SIGNAL_ONE.
+struct PacketSignal {
+ signals trigger;
+ signals observed;
+ uint64 count;
+ uint64 reserved0;
+ uint64 reserved1;
+};
+
+struct PacketException {
+ uint64 pid;
+ uint64 tid;
+ uint64 reserved0;
+ uint64 reserved1;
+};
+
+struct PacketGuestBell {
+ gpaddr addr;
+ uint64 reserved0;
+ uint64 reserved1;
+ uint64 reserved2;
+};
+
+// TODO(scottmg): Arch-specific definition.
+struct PacketGuestMem {
+ gpaddr addr;
+ //#if __aarch64__
+ //uint8_t access_size;
+ //bool sign_extend;
+ //uint8_t xt;
+ //bool read;
+ //uint64_t data;
+ //uint64_t reserved;
+ //#elif __x86_64__
+ //// NOTE: x86 instructions are guaranteed to be 15 bytes or fewer.
+ //#define X86_MAX_INST_LEN 15u
+ //uint8_t inst_len;
+ //uint8_t inst_buf[X86_MAX_INST_LEN];
+ //// This is the default operand size as determined by the CS and EFER register (Volume 3,
+ //// Section 5.2.1). If operating in 64-bit mode then near branches and all instructions, except
+ //// far branches, that implicitly reference the RSP will actually have a default operand size of
+ //// 64-bits (Volume 2, Section 2.2.1.7), and not the 32-bits that will be given here.
+ //uint8_t default_operand_size;
+ //uint8_t reserved[7];
+ //#endif
+};
+
+struct PacketGuestIo {
+ uint16 port;
+ uint8 access_size;
+ bool input;
+ // TODO(scottmg): Unnamed union.
+ //union {
+ // uint8_t u8;
+ // uint16_t u16;
+ // uint32_t u32;
+ // uint8_t data[4];
+ //};
+ uint64 reserved0;
+ uint64 reserved1;
+ uint64 reserved2;
+};
+
+struct PacketGuestVcpu {
+ // TODO(scottmg): Unnamed union.
+ //union {
+ // struct {
+ // uint64_t mask;
+ // uint8_t vector;
+ // } interrupt;
+ // struct {
+ // uint64_t id;
+ // zx_gpaddr_t entry;
+ // } startup;
+ //};
+ uint8 type;
+ uint64 reserved;
+};
+
+struct PacketInterrupt {
+ time timestamp;
+ uint64 reserved0;
+ uint64 reserved1;
+ uint64 reserved2;
+};
+
+struct PacketPageRequest {
+ uint16 command;
+ uint16 flags;
+ uint32 reserved0;
+ uint64 offset;
+ uint64 length;
+ uint64 reserved1;
+};
+
+struct PortPacket {
+ uint64 key;
+ uint32 type;
+ status status;
+ // TODO(scottmg): Unnamed union.
+ // union {
+ PacketUser user;
+ PacketSignal signal;
+ PacketException exception;
+ PacketGuestBell guest_bell;
+ PacketGuestMem guest_mem;
+ PacketGuestIo guest_io;
+ PacketGuestVcpu guest_vcpu;
+ PacketInterrupt interrupt;
+ PacketPageRequest page_request;
+ // };
+};
+
+[Transport = "Syscall"]
+protocol port {
+ /// Create an IO port.
+ port_create(uint32 options) -> (status status, handle<port> out);
+
+ /// Queue a packet to a port.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_PORT and have ZX_RIGHT_WRITE.
+ port_queue(handle<port> handle, PortPacket packet) -> (status status);
+
+ /// Wait for a packet arrival in a port.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_PORT and have ZX_RIGHT_READ.
+ [blocking]
+ port_wait(handle<port> handle, time deadline) -> (status status, optional_PortPacket packet);
+
+ /// Cancels async port notifications on an object.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_PORT and have ZX_RIGHT_WRITE.
+ port_cancel(handle<port> handle, handle source, uint64 key) -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/process.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/process.fidl
new file mode 100644
index 0000000..b9c3eb3
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/process.fidl
@@ -0,0 +1,38 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol process {
+ /// Exits the currently running process.
+ [noreturn]
+ process_exit(int64 retcode);
+
+ // TODO(ZX-2967): job with ZX_RIGHT_WRITE is also accepted.
+ /// Create a new process.
+ /// Rights: job must be of type ZX_OBJ_TYPE_JOB and have ZX_RIGHT_MANAGE_PROCESS.
+ process_create(handle<job> job, string name, uint32 options)
+ -> (status status, handle<process> proc_handle, handle<vmar> vmar_handle);
+
+ /// Start execution on a process.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_PROCESS and have ZX_RIGHT_WRITE.
+ /// Rights: thread must be of type ZX_OBJ_TYPE_THREAD and have ZX_RIGHT_WRITE.
+ /// Rights: arg1 must have ZX_RIGHT_TRANSFER.
+ process_start(handle<process> handle, handle<thread> thread,
+ vaddr entry, vaddr stack,
+ handle arg1, uintptr arg2)
+ -> (status status);
+
+ /// Read from the given process's address space.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_PROCESS and have ZX_RIGHT_READ and have ZX_RIGHT_WRITE.
+ process_read_memory(handle<process> handle, vaddr vaddr)
+ -> (status status, vector_void buffer, usize actual);
+
+ /// Write into the given process's address space.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_PROCESS and have ZX_RIGHT_WRITE.
+ process_write_memory(handle<process> handle, vaddr vaddr, vector_void buffer)
+ -> (status status, usize actual);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/profile.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/profile.fidl
new file mode 100644
index 0000000..c808f4d
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/profile.fidl
@@ -0,0 +1,43 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+enum ProfileInfoType {
+ ZX_PROFILE_INFO_SCHEDULER = 1;
+};
+
+union ProfileScheduler {
+ 1: int32 priority;
+ 2: uint32 boost;
+ 3: uint32 deboost;
+ 4: uint32 quantum;
+};
+
+const int32 ZX_PRIORITY_LOWEST = 0;
+const int32 ZX_PRIORITY_LOW = 8;
+const int32 ZX_PRIORITY_DEFAULT = 16;
+const int32 ZX_PRIORITY_HIGH = 24;
+const int32 ZX_PRIORITY_HIGHEST = 31;
+
+union ProfileInfoData {
+ 1: ProfileScheduler scheduler;
+};
+
+struct ProfileInfo {
+ ProfileInfoType type;
+ // TODO(scottmg): This needs to be presented as an unnamed union in C, and
+ // ProfileInfoData doesn't really need a name. Not sure if the semantics of
+ // fidl unions make sense here.
+ ProfileInfoData unnamed;
+};
+
+[Transport = "Syscall"]
+protocol profile {
+ /// Create a scheduler profile.
+ /// Rights: root_job must be of type ZX_OBJ_TYPE_JOB and have ZX_RIGHT_MANAGE_PROCESS.
+ profile_create(handle<job> root_job, uint32 options, ProfileInfo profile)
+ -> (status status, handle<profile> out);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/resource.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/resource.fidl
new file mode 100644
index 0000000..1854504
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/resource.fidl
@@ -0,0 +1,18 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol resource {
+ /// Create a resource object.
+ /// Rights: parent_rsrc must be of type ZX_OBJ_TYPE_RESOURCE and have ZX_RIGHT_WRITE.
+ resource_create(handle<resource> parent_rsrc,
+ uint32 options,
+ uint64 base,
+ usize size,
+ string name)
+ -> (status status, handle<resource> resource_out);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/rights.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/rights.fidl
new file mode 100644
index 0000000..69ba88f
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/rights.fidl
@@ -0,0 +1,36 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+// TODO(scottmg): (1 << 4) notation or something else for bits would be nice.
+bits rights : uint32 {
+ // TODO(scottmg): "bits members must be powers of two"
+ // NONE = 0x00000000;
+ DUPLICATE = 0x00000001;
+ TRANSFER = 0x00000002;
+ READ = 0x00000004;
+ WRITE = 0x00000008;
+ EXECUTE = 0x00000010;
+ MAP = 0x00000020;
+ GET_PROPERTY = 0x00000040;
+ SET_PROPERTY = 0x00000080;
+ ENUMERATE = 0x00000100;
+ DESTROY = 0x00000200;
+ SET_POLICY = 0x00000400;
+ GET_POLICY = 0x00000800;
+ SIGNAL = 0x00001000;
+ SIGNAL_PEER = 0x00002000;
+ WAIT = 0x00004000;
+ INSPECT = 0x00008000;
+ MANAGE_JOB = 0x00010000;
+ MANAGE_PROCESS = 0x00020000;
+ MANAGE_THREAD = 0x00040000;
+ APPLY_PROFILE = 0x00080000;
+ SAME_RIGHTS = 0x80000000;
+
+ // TODO(scottmg): Derived settings using |, &, ~, e.g.:
+ // BASIC = (TRANSFER | DUPLICATE | WAIT | INSPECT);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/smc.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/smc.fidl
new file mode 100644
index 0000000..b039311
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/smc.fidl
@@ -0,0 +1,36 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+// TODO(scottmg): ARM_SMC_xyz.
+
+struct SmcParameters {
+ uint32 func_id;
+ uint64 arg1;
+ uint64 arg2;
+ uint64 arg3;
+ uint64 arg4;
+ uint64 arg5;
+ uint64 arg6;
+ uint16 client_id;
+ uint16 secure_os_id;
+};
+
+struct SmcResult {
+ uint64 arg0;
+ uint64 arg1;
+ uint64 arg2;
+ uint64 arg3;
+ uint64 arg6; // at least one implementation uses it as a way to return session_id.
+};
+
+[Transport = "Syscall"]
+protocol smc {
+ // TODO(ZX-2967): handle No rights required?
+ // TODO(scottmg): No handle type?
+ /// Make Secure Monitor Call (SMC) from user space.
+ smc_call(handle handle, SmcParameters parameters) -> (status status, SmcResult out_smc_result);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/socket.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/socket.fidl
new file mode 100644
index 0000000..00f7159
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/socket.fidl
@@ -0,0 +1,26 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol socket {
+ /// Create a socket.
+ socket_create(uint32 options) -> (status status, handle out0, handle out1);
+
+ /// Write data to a socket.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_SOCKET and have ZX_RIGHT_WRITE.
+ socket_write(handle<socket> handle, uint32 options, vector_void buffer)
+ -> (status status, optional_usize actual);
+
+ /// Read data from a socket.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_SOCKET and have ZX_RIGHT_READ.
+ socket_read(handle<socket> handle, uint32 options)
+ -> (status status, vector_void buffer, optional_usize actual);
+
+ /// Prevent reading or writing.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_SOCKET and have ZX_RIGHT_WRITE.
+ socket_shutdown(handle<socket> handle, uint32 options) -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/stream.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/stream.fidl
new file mode 100644
index 0000000..cf6cdbd
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/stream.fidl
@@ -0,0 +1,44 @@
+// Copyright 2020 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+enum stream_seek_origin : uint32 {
+ START = 0;
+ CURRENT = 1;
+ END = 2;
+};
+
+[Transport = "Syscall"]
+protocol stream {
+ /// Create a stream from a VMO.
+ stream_create(uint32 options, handle<vmo> vmo, off seek)
+ -> (status status, handle<stream> out_stream);
+
+ /// Write data to a stream at the current seek offset.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_STREAM and have ZX_RIGHT_WRITE.
+ stream_writev(handle<stream> handle, uint32 options, vector_iovec vector)
+ -> (status status, optional_usize actual);
+
+ /// Write data to a stream at the given offset.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_STREAM and have ZX_RIGHT_WRITE.
+ stream_writev_at(handle<stream> handle, uint32 options, off offset, vector_iovec vector)
+ -> (status status, optional_usize actual);
+
+ /// Read data from a stream at the current seek offset.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_STREAM and have ZX_RIGHT_READ.
+ stream_readv(handle<stream> handle, uint32 options)
+ -> (status status, vector_iovec vector, optional_usize actual);
+
+ /// Read data from a stream at the given offset.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_STREAM and have ZX_RIGHT_READ.
+ stream_readv_at(handle<stream> handle, uint32 options, off offset)
+ -> (status status, vector_iovec vector, optional_usize actual);
+
+ /// Modify the seek offset.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_STREAM and have ZX_RIGHT_READ or have ZX_RIGHT_WRITE.
+ stream_seek(handle<stream> handle, stream_seek_origin whence, int64 offset)
+ -> (status status, optional_off out_seek);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/syscall.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/syscall.fidl
new file mode 100644
index 0000000..06e5683
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/syscall.fidl
@@ -0,0 +1,46 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol syscall {
+ [testonly]
+ syscall_test_0() -> (status status);
+
+ [testonly,
+ test_category1]
+ syscall_test_1(int32 a) -> (status status);
+
+ [testonly,
+ test_category1]
+ syscall_test_2(int32 a, int32 b) -> (status status);
+
+ [testonly,
+ test_category2]
+ syscall_test_3(int32 a, int32 b, int32 c) -> (status status);
+
+ [testonly]
+ syscall_test_4(int32 a, int32 b, int32 c, int32 d) -> (status status);
+
+ [testonly]
+ syscall_test_5(int32 a, int32 b, int32 c, int32 d, int32 e) -> (status status);
+
+ [testonly]
+ syscall_test_6(int32 a, int32 b, int32 c, int32 d, int32 e, int32 f) -> (status status);
+
+ [testonly]
+ syscall_test_7(int32 a, int32 b, int32 c, int32 d, int32 e, int32 f, int32 g) -> (status status);
+
+ [testonly]
+ syscall_test_8(int32 a, int32 b, int32 c, int32 d, int32 e, int32 f, int32 g, int32 h)
+ -> (status status);
+
+ [testonly]
+ syscall_test_wrapper(int32 a, int32 b, int32 c) -> (status status);
+
+ [testonly]
+ syscall_test_handle_create(status return_value) -> (status status, handle<event> out);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/system.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/system.fidl
new file mode 100644
index 0000000..12ada66
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/system.fidl
@@ -0,0 +1,65 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+struct SystemPowerctlArg {
+ // TODO(scottmg): More unnamed unions.
+ //union {
+ // struct {
+ // uint8_t target_s_state; // Value between 1 and 5 indicating which S-state
+ // uint8_t sleep_type_a; // Value from ACPI VM (SLP_TYPa)
+ // uint8_t sleep_type_b; // Value from ACPI VM (SLP_TYPb)
+ // } acpi_transition_s_state;
+ // struct {
+ // uint32_t power_limit; // PL1 value in milliwatts
+ // uint32_t time_window; // PL1 time window in microseconds
+ // uint8_t clamp; // PL1 clamping enable
+ // uint8_t enable; // PL1 enable
+ // } x86_power_limit;
+ //};
+};
+
+[Transport = "Syscall"]
+protocol system {
+ [const, vdsocall]
+ system_get_dcache_line_size() -> (uint32 size);
+
+ /// Get number of logical processors on the system.
+ [const, vdsocall]
+ system_get_num_cpus() -> (uint32 count);
+
+ /// Get version string for system.
+ [const, vdsocall]
+ system_get_version_string() -> (string_view version);
+
+ /// Get amount of physical memory on the system.
+ [vdsocall]
+ system_get_physmem() -> (uint64 physmem);
+
+ // TODO(scottmg): "features" has a features attribute. I'm not sure if/how it's used.
+ /// Get supported hardware capabilities.
+ [vdsocall]
+ system_get_features(uint32 kind) -> (status status, uint32 features);
+
+ /// Retrieve a handle to a system event.
+ /// Rights: None.
+ system_get_event(handle<job> root_job, uint32 kind) -> (status status, handle<event> event);
+
+ /// Soft reboot the system with a new kernel and bootimage.
+ /// Rights: resource must have resource kind ZX_RSRC_KIND_ROOT.
+ /// Rights: kernel_vmo must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_READ.
+ /// Rights: bootimage_vmo must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_READ.
+ system_mexec(handle<resource> resource, handle<vmo> kernel_vmo, handle<vmo> bootimage_vmo)
+ -> (status status);
+
+ /// Return a ZBI containing ZBI entries necessary to boot this system.
+ /// Rights: resource must have resource kind ZX_RSRC_KIND_ROOT.
+ system_mexec_payload_get(handle<resource> resource) -> (status status, vector_void buffer);
+
+ /// Rights: resource must have resource kind ZX_RSRC_KIND_ROOT.
+ system_powerctl(handle<resource> resource, uint32 cmd, SystemPowerctlArg arg)
+ -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/task.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/task.fidl
new file mode 100644
index 0000000..56cc556
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/task.fidl
@@ -0,0 +1,29 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol task {
+ // TODO(scottmg): Need something like handle<task> in this file to mean {job, process, thread}.
+ // Or otherwise some way to express multiple options for constraints on inputs in this protocol.
+
+ /// Suspend the given task. Currently only thread or process handles may be suspended.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_THREAD or ZX_OBJ_TYPE_PROCESS and have ZX_RIGHT_WRITE.
+ task_suspend(handle handle) -> (status status, handle token);
+
+ /// Suspend the given task. Currently only thread or process handles may be suspended.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_THREAD or ZX_OBJ_TYPE_PROCESS and have ZX_RIGHT_WRITE.
+ task_suspend_token(handle handle) -> (status status, handle token);
+
+ /// Create an exception channel for a given job, process, or thread.
+ /// Rights: handle must have ZX_RIGHT_INSPECT and have ZX_RIGHT_DUPLICATE and have ZX_RIGHT_TRANSFER and have ZX_RIGHT_MANAGE_THREAD.
+ /// Rights: If handle is of type ZX_OBJ_TYPE_JOB or ZX_OBJ_TYPE_PROCESS, it must have ZX_RIGHT_ENUMERATE.
+ task_create_exception_channel(handle handle, uint32 options) -> (status status, handle<channel> out);
+
+ /// Kill the provided task (job, process, or thread).
+ /// Rights: handle must have ZX_RIGHT_DESTROY.
+ task_kill(handle handle) -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/thread.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/thread.fidl
new file mode 100644
index 0000000..9754d05
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/thread.fidl
@@ -0,0 +1,31 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol thread {
+ /// Terminate the current running thread.
+ [noreturn]
+ thread_exit();
+
+ /// Create a thread.
+ /// Rights: process must be of type ZX_OBJ_TYPE_PROCESS and have ZX_RIGHT_MANAGE_THREAD.
+ thread_create(handle<process> process, string name, uint32 options)
+ -> (status status, handle<thread> out);
+
+ /// Start execution on a thread.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_THREAD and have ZX_RIGHT_MANAGE_THREAD.
+ thread_start(handle<thread> handle, vaddr thread_entry, vaddr stack, uintptr arg1, uintptr arg2)
+ -> (status status);
+
+ /// Read one aspect of thread state.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_THREAD and have ZX_RIGHT_READ.
+ thread_read_state(handle<thread> handle, uint32 kind) -> (status status, vector_void buffer);
+
+ /// Write one aspect of thread state.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_THREAD and have ZX_RIGHT_WRITE.
+ thread_write_state(handle<thread> handle, uint32 kind, vector_void buffer) -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/timer.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/timer.fidl
new file mode 100644
index 0000000..1eae5a9
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/timer.fidl
@@ -0,0 +1,20 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol timer {
+ /// Create a timer.
+ timer_create(uint32 options, Clock clock_id) -> (status status, handle<timer> out);
+
+ /// Start a timer.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_TIMER and have ZX_RIGHT_WRITE.
+ timer_set(handle<timer> handle, time deadline, duration slack) -> (status status);
+
+ /// Cancel a timer.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_TIMER and have ZX_RIGHT_WRITE.
+ timer_cancel(handle<timer> handle) -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/vcpu.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/vcpu.fidl
new file mode 100644
index 0000000..72cc954
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/vcpu.fidl
@@ -0,0 +1,31 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol vcpu {
+ /// Create a VCPU.
+ /// Rights: guest must be of type ZX_OBJ_TYPE_GUEST and have ZX_RIGHT_MANAGE_PROCESS.
+ vcpu_create(handle<guest> guest, uint32 options, vaddr entry) -> (status status, handle<vcpu> out);
+
+ // See port.fidl for definition of PortPacket.
+ /// Resume execution of a VCPU.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_VCPU and have ZX_RIGHT_EXECUTE.
+ [blocking]
+ vcpu_resume(handle<vcpu> handle) -> (status status, PortPacket packet);
+
+ /// Raise an interrupt on a VCPU.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_VCPU and have ZX_RIGHT_SIGNAL.
+ vcpu_interrupt(handle<vcpu> handle, uint32 vector) -> (status status);
+
+ /// Read the state of a VCPU.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_VCPU and have ZX_RIGHT_READ.
+ vcpu_read_state(handle<vcpu> handle, uint32 kind) -> (status status, vector_void buffer);
+
+ /// Write the state of a VCPU.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_VCPU and have ZX_RIGHT_WRITE.
+ vcpu_write_state(handle<vcpu> handle, uint32 kind, vector_void buffer) -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/vmar.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/vmar.fidl
new file mode 100644
index 0000000..0256623
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/vmar.fidl
@@ -0,0 +1,53 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+using VmOption = uint32;
+
+// TODO(scottmg): bits for ZX_VM_xyz flags, and const for ZX_VM_ALIGN_xyz.
+
+[Transport = "Syscall"]
+protocol vmar {
+ /// Allocate a new subregion.
+ /// Rights: If options & ZX_VM_CAN_MAP_READ, parent_vmar must be of type ZX_OBJ_TYPE_VMAR and have ZX_RIGHT_READ.
+ /// Rights: If options & ZX_VM_CAN_MAP_WRITE, parent_vmar must be of type ZX_OBJ_TYPE_VMAR and have ZX_RIGHT_WRITE.
+ /// Rights: If options & ZX_VM_CAN_MAP_EXECUTE, parent_vmar must be of type ZX_OBJ_TYPE_VMAR and have ZX_RIGHT_EXECUTE.
+ vmar_allocate(handle<vmar> parent_vmar, VmOption options, usize offset, usize size)
+ -> (status status, handle<vmar> child_vmar, vaddr child_addr);
+
+ // TODO(ZX-2967): handle No rights required?
+ /// Destroy a virtual memory address region.
+ vmar_destroy(handle<vmar> handle) -> (status status);
+
+ // TODO(ZX-2399): TODO handle and vmo and options must all match, and options can't specify them.
+ /// Add a memory mapping.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_VMAR.
+ /// Rights: vmo must be of type ZX_OBJ_TYPE_VMO.
+ vmar_map(handle<vmar> handle, VmOption options, usize vmar_offset,
+ handle<vmo> vmo, uint64 vmo_offset,
+ usize len)
+ -> (status status, vaddr mapped_addr);
+
+ // TODO(ZX-2967): handle No rights required?
+ /// Unmap virtual memory pages.
+ vmar_unmap(handle<vmo> handle, vaddr addr, usize len) -> (status status);
+
+ /// Set protection of virtual memory pages.
+ /// Rights: If options & ZX_VM_PERM_READ, handle must be of type ZX_OBJ_TYPE_VMAR and have ZX_RIGHT_READ.
+ /// Rights: If options & ZX_VM_PERM_WRITE, handle must be of type ZX_OBJ_TYPE_VMAR and have ZX_RIGHT_WRITE.
+ /// Rights: If options & ZX_VM_PERM_EXECUTE, handle must be of type ZX_OBJ_TYPE_VMAR and have ZX_RIGHT_EXECUTE.
+ vmar_protect(handle<vmo> handle, VmOption options, vaddr addr, usize len) -> (status status);
+
+ /// Perform an operation on VMOs mapped into this VMAR.
+ /// Rights: If op is ZX_VMO_OP_DECOMMIT, affected mappings must be writable.
+ [Blocking]
+ vmar_op_range(handle<vmar> handle,
+ uint32 op,
+ vaddr address,
+ usize size,
+ mutable_vector_void buffer)
+ -> (status status);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/vmo.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/vmo.fidl
new file mode 100644
index 0000000..060d4cd
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/vmo.fidl
@@ -0,0 +1,81 @@
+// 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.
+
+// TODO(fxb/39732): This should be read as "library zx".
+library zz;
+
+[Transport = "Syscall"]
+protocol vmo {
+ /// Create a VM object.
+ vmo_create(uint64 size, uint32 options) -> (status status, handle<vmo> out);
+
+ // TODO(scottmg): This syscall is very weird, it's currently:
+ // (handle, buffer, offset, buffer_size)
+ // rather than:
+ // (handle, buffer, buffer_size, offset)
+ // which means the vector<byte> buffer won't work. Unfortunately offset and
+ // buffer_size have the same underlying type, so moving them will be
+ // error-prone.
+ /// Read bytes from the VMO.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_READ.
+ [blocking,
+ ArgReorder = "handle, buffer, offset, buffer_size"]
+ vmo_read(handle<vmo> handle, uint64 offset) -> (status status, vector_void buffer);
+
+ // TODO(scottmg): Same problem as Read() above.
+ /// Write bytes to the VMO.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_WRITE.
+ [blocking,
+ ArgReorder = "handle, buffer, offset, buffer_size"]
+ vmo_write(handle<vmo> handle, vector_void buffer, uint64 offset) -> (status status);
+
+ // TODO(ZX-2967): No rights required?
+ /// Read the current size of a VMO object.
+ vmo_get_size(handle<vmo> handle) -> (status status, uint64 size);
+
+ /// Resize a VMO object.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_WRITE.
+ vmo_set_size(handle<vmo> handle, uint64 size) -> (status status);
+
+ /// Perform an operation on a range of a VMO.
+ /// Rights: If op is ZX_VMO_OP_COMMIT, handle must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_WRITE.
+ /// Rights: If op is ZX_VMO_OP_DECOMMIT, handle must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_WRITE.
+ /// Rights: If op is ZX_VMO_OP_CACHE_SYNC, handle must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_READ.
+ /// Rights: If op is ZX_VMO_OP_CACHE_INVALIDATE, handle must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_WRITE.
+ /// Rights: If op is ZX_VMO_OP_CACHE_CLEAN, handle must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_READ.
+ /// Rights: If op is ZX_VMO_OP_CACHE_CLEAN_INVALIDATE, handle must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_READ.
+ [blocking]
+ vmo_op_range(handle<vmo> handle,
+ uint32 op,
+ uint64 offset,
+ uint64 size,
+ mutable_vector_void buffer)
+ -> (status status);
+
+ /// Create a child of a VM Object.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_DUPLICATE and have ZX_RIGHT_READ.
+ vmo_create_child(handle<vmo> handle, uint32 options, uint64 offset, uint64 size)
+ -> (status status, handle<vmo> out);
+
+ /// Set the caching policy for pages held by a VMO.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_VMO and have ZX_RIGHT_MAP.
+ vmo_set_cache_policy(handle<vmo> handle, uint32 cache_policy) -> (status status);
+
+ // TODO(ZX-2967): handle: No rights required, ZX_RIGHT_EXECUTE added to dup out
+ // TODO(ZX-2967): vmex == ZX_HANDLE_INVALID also accepted.
+ /// Add execute rights to a VMO.
+ /// Rights: handle must be of type ZX_OBJ_TYPE_VMO.
+ /// Rights: vmex must have resource kind ZX_RSRC_KIND_VMEX.
+ vmo_replace_as_executable([Release] handle<vmo> handle, handle<resource> vmex)
+ -> (status status, handle<vmo> out);
+
+ /// Rights: bti must be of type ZX_OBJ_TYPE_BTI and have ZX_RIGHT_MAP.
+ vmo_create_contiguous(handle<bti> bti, usize size, uint32 alignment_log2)
+ -> (status status, handle<vmo> out);
+
+ /// Create a VM object referring to a specific contiguous range of physical memory.
+ /// Rights: resource must have resource kind ZX_RSRC_KIND_MMIO.
+ vmo_create_physical(handle<resource> resource, paddr paddr, usize size)
+ -> (status status, handle<vmo> out);
+};
diff --git a/third_party/fuchsia-sdk/arch/x64/vdso/zx.fidl b/third_party/fuchsia-sdk/arch/x64/vdso/zx.fidl
new file mode 100644
index 0000000..ac9903a
--- /dev/null
+++ b/third_party/fuchsia-sdk/arch/x64/vdso/zx.fidl
@@ -0,0 +1,41 @@
+// 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.
+
+// TODO(scottmg): This library is temporarily "zz" instead of "zx" because a
+// "zx" is force-injected by fidlc. Eventually, we'll stop that and use this one
+// instead as "zx". fxb/39732.
+library zz;
+
+using status = int32;
+
+using time = int64;
+using duration = int64;
+using ticks = uint64;
+
+using koid = uint64;
+
+using vaddr = uint64;
+using paddr = uint64;
+using paddr32 = uint32;
+using gpaddr = uint64;
+using off = uint64;
+
+// TODO(scottmg): Not sure what this is.
+using procarg = uint32;
+
+const uint64 CHANNEL_MAX_MSG_BYTES = 65536;
+const uint64 CHANNEL_MAX_MSG_HANDLES = 64;
+
+// TODO(scottmg): == size_t, not sure if this is a good idea.
+using usize = uint64;
+
+// TODO(scottmg): == uintptr_t, not sure if this is a good idea.
+using uintptr = uint64;
+
+// TODO(scottmg): Maybe a void for vector<void> (or vector<any>?) to distinguish
+// polymorphic arguments that are passed as void* from buffers of bytes.
+
+using signals = uint32;
+// TODO(scottmg): Lots of aliases/variations required here. Not sure if bits
+// make sense.
diff --git a/third_party/fuchsia-sdk/bin/aemu.version b/third_party/fuchsia-sdk/bin/aemu.version
new file mode 100644
index 0000000..a738521
--- /dev/null
+++ b/third_party/fuchsia-sdk/bin/aemu.version
@@ -0,0 +1 @@
+git_revision:8f06ec782485dccd8488906df414665ad5a5c9f6
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/bin/devshell/emu b/third_party/fuchsia-sdk/bin/devshell/emu
new file mode 100755
index 0000000..9eac155
--- /dev/null
+++ b/third_party/fuchsia-sdk/bin/devshell/emu
@@ -0,0 +1,425 @@
+#!/bin/bash
+# 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.
+
+#### CATEGORY=Run, inspect and debug
+### start fuchsia in an emulator
+
+## usage: fx emu [-a <mode>] [-c <text>] [-N [-I <ifname>]] [-u <path>] [-g <port> [-r <fps>] [-t <cmd>]] [-x <port> [-X <directory>]] [-e <directory>] [-w <size>] [-s <cpus>] [-k <authorized_keys_file>] [-K <kernel_image>] [-z <zbi_image>] [-f <fvm_image>] [--audio] [--headless] [--software-gpu] [--debugger]
+## -a <mode> acceleration mode (auto, off, kvm, hvf, hax), default is auto
+## -c <text> add item to kernel command line
+## -ds <size> extends the fvm image size to <size> bytes. Default is twice the original size
+## -N run with emulated nic via tun/tap
+## -I <ifname> uses the tun/tap interface named ifname
+## -u <path> execute emu if-up script, default: linux: no script, macos: tap ifup script.
+## -e <directory> location of emulator, defaults to looking in prebuilt/third_party/aemu/PLATFORM
+## -g <port> enable gRPC service on port to control the emulator, default is 5556 when WebRTC service is enabled
+## -r <fps> webrtc frame rate when using gRPC service, default is 30
+## -t <cmd> execute the given command to obtain turn configuration
+## -x <port> enable WebRTC HTTP service on port
+## -X <directory> location of grpcwebproxy, defaults to looking in prebuilt/third_party/grpcwebproxy
+## -w <size> window size, default is 1280x800
+## -s <cpus> number of cpus, 1 for uniprocessor, default is 4
+## -k <authorized_keys_file> SSH authorized keys file, otherwise defaults to //.ssh/authorized_keys
+## -K <kernel_image> path to image to use as kernel, defaults to kernel generated by the current build.
+## -z <zbi_image> path to image to use as ZBI, defaults to zircon-a generated by the current build.
+## -f <fvm_image> path to full FVM image, defaults to image generated by the current build.
+## --audio run with audio hardware added to the virtual machine
+## --headless run in headless mode
+## --host-gpu run with host GPU acceleration
+## --software-gpu run without host GPU acceleration
+## --debugger pause on launch and wait for a debugger process to attach before resuming
+
+set -e
+
+DEVSHELL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
+source "${DEVSHELL_DIR}"/lib/image_build_vars.sh || exit $?
+source "${DEVSHELL_DIR}"/lib/fvm.sh || exit $?
+
+ACCEL="auto"
+NET=0
+DEBUGGER=0
+IFNAME=""
+AUDIO=0
+HEADLESS=0
+AEMU="emulator"
+AEMU_DIR=""
+UPSCRIPT=
+WINDOW_SIZE="1280x800"
+GRPC=
+RTCFPS="30"
+TURNCFG=""
+GPU="auto"
+VULKAN=1
+HTTP=0
+GRPCWEBPROXY_DIR=""
+CMDLINE=""
+SMP=4
+AUTHORIZED_KEYS="${FUCHSIA_DIR}/.ssh/authorized_keys"
+IMAGE_SIZE=
+EXPERIMENT_ARM64=false
+KERNEL_IMAGE="${FUCHSIA_BUILD_DIR}/${IMAGE_QEMU_KERNEL_RAW}"
+ZBI_IMAGE="${FUCHSIA_BUILD_DIR}/${IMAGE_ZIRCONA_ZBI}"
+if [[ -n "${IMAGE_FVM_RAW}" ]]; then
+ FVM_IMAGE="${FUCHSIA_BUILD_DIR}/${IMAGE_FVM_RAW}"
+else
+ FVM_IMAGE=""
+fi
+
+
+case $(uname -m) in
+x86_64)
+ HOST_ARCH=x64
+ ;;
+aarch64)
+ HOST_ARCH=arm64
+ ;;
+*)
+ fx-error "Unsupported host architecture: $(uname -m)"
+ exit 1
+esac
+
+if [[ "$FUCHSIA_ARCH" != "$HOST_ARCH" ]]; then
+ ACCEL=off
+fi
+
+# Propagate our TERM environment variable as a kernel command line
+# argument. This is first so that an explicit -c TERM=foo argument
+# goes into CMDLINE later and overrides this.
+if [[ -n $TERM ]]; then
+ CMDLINE+="TERM=$TERM "
+fi
+
+while [[ $# -ge 1 ]]; do
+ case "$1" in
+ -h|--help)
+ fx-command-help
+ exit 0
+ ;;
+ -a)
+ shift
+ ACCEL="$1"
+ ;;
+ -c)
+ shift
+ CMDLINE+="$1 "
+ ;;
+ -ds)
+ shift
+ IMAGE_SIZE="$1"
+ ;;
+ -N)
+ NET=1
+ ;;
+ -I)
+ shift
+ IFNAME="$1"
+ ;;
+ -u)
+ shift
+ UPSCRIPT="$1"
+ ;;
+ -e)
+ shift
+ AEMU_DIR="$1"
+ ;;
+ -x)
+ shift
+ HTTP="$1"
+ ;;
+ -X)
+ shift
+ GRPCWEBPROXY_DIR="$1"
+ ;;
+ -g)
+ shift
+ GRPC="$1"
+ ;;
+ -r)
+ shift
+ RTCFPS="$1"
+ ;;
+ -t)
+ shift
+ TURNCFG="$1"
+ ;;
+ -w)
+ shift
+ WINDOW_SIZE="$1"
+ ;;
+ -s)
+ shift
+ SMP="$1"
+ ;;
+ -k)
+ shift
+ AUTHORIZED_KEYS="$1"
+ ;;
+ -K)
+ shift
+ KERNEL_IMAGE="$1"
+ ;;
+ -z)
+ shift
+ ZBI_IMAGE="$1"
+ ;;
+ -f)
+ shift
+ FVM_IMAGE="$1"
+ ;;
+ --audio)
+ AUDIO=1
+ ;;
+ --headless)
+ HEADLESS=1
+ ;;
+ --debugger)
+ DEBUGGER=1
+ ;;
+ --host-gpu)
+ GPU="host"
+ ;;
+ --software-gpu)
+ GPU="swiftshader_indirect"
+ ;;
+ --experiment-arm64)
+ EXPERIMENT_ARM64=true
+ ;;
+ *)
+ break
+ esac
+ shift
+done
+
+if [[ -z "$AEMU_DIR" && -d "$PREBUILT_AEMU_DIR" ]]; then
+ AEMU_DIR="$PREBUILT_AEMU_DIR"
+fi
+
+if [[ -z "$GRPCWEBPROXY_DIR" && -d "$PREBUILT_GRPCWEBPROXY_DIR" ]]; then
+ GRPCWEBPROXY_DIR="$PREBUILT_GRPCWEBPROXY_DIR"
+fi
+
+# construct the args for aemu
+ARGS=()
+ARGS+=("-m" "2048")
+ARGS+=("-serial" "stdio")
+ARGS+=("-vga" "none")
+ARGS+=("-device" "virtio-keyboard-pci")
+ARGS+=("-device" "virtio_input_multi_touch_pci_1")
+
+if [[ $SMP != 1 ]]; then
+ ARGS+=("-smp" "${SMP},threads=2")
+fi
+
+# TODO(raggi): do we want to use hda on arm64?
+if (( AUDIO )); then
+ ARGS+=("-soundhw" "hda")
+fi
+
+FEATURES="VirtioInput,RefCountPipe"
+
+if [[ "$ACCEL" == "auto" ]]; then
+ if [[ "$(uname -s)" == "Darwin" ]]; then
+ ACCEL="hvf"
+ else
+ ACCEL="kvm"
+ fi
+fi
+
+case "$FUCHSIA_ARCH" in
+x64)
+ ARGS+=("-machine" "q35")
+ ARGS+=("-device" "isa-debug-exit,iobase=0xf4,iosize=0x04")
+;;
+arm64)
+ ARGS+=("-machine" "virt")
+;;
+esac
+
+if [[ "$ACCEL" == "kvm" ]]; then
+ if [[ ! -w "/dev/kvm" ]]; then
+ echo "To use KVM acceleration, adjust permissions to /dev/kvm using:"
+ echo
+ echo "sudo chmod 666 /dev/kvm"
+ exit 1
+ fi
+ ARGS+=("-enable-kvm" "-cpu" "host,migratable=no,+invtsc")
+ FEATURES+=",KVM,GLDirectMem"
+elif [[ "$ACCEL" == "hvf" ]]; then
+ ARGS+=("-enable-hvf" "-cpu" "Haswell")
+ FEATURES+=",HVF,GLDirectMem"
+elif [[ "$ACCEL" == "hax" ]]; then
+ ARGS+=("-enable-hax" "-cpu" "Haswell")
+ FEATURES+=",HAXM,GLDirectMem"
+elif [[ "$ACCEL" == "off" ]]; then
+ case "$FUCHSIA_ARCH" in
+ x64)
+ ARGS+=("-cpu" "Haswell,+smap,-check,-fsgsbase")
+ ;;
+ arm64)
+ ARGS+=("-cpu" "cortex-a53")
+ ;;
+ esac
+ # disable vulkan as not useful without kvm,hvf,hax and support
+ # for coherent host visible memory.
+ VULKAN=0
+ FEATURES+=",-GLDirectMem"
+else
+ fx-error Unsupported acceleration mode
+ exit 1
+fi
+
+if (( VULKAN )); then
+ FEATURES+=",Vulkan"
+else
+ FEATURES+=",-Vulkan"
+fi
+
+OPTIONS=()
+OPTIONS+=("-feature" "$FEATURES")
+OPTIONS+=("-window-size" "$WINDOW_SIZE")
+OPTIONS+=("-gpu" "$GPU")
+if (( DEBUGGER )); then
+ OPTIONS+=("-wait-for-debugger")
+fi
+
+if (( HEADLESS )); then
+ OPTIONS+=("-no-window")
+fi
+
+if [[ "$FUCHSIA_ARCH" == "arm64" ]]; then
+ if ! "$EXPERIMENT_ARM64"; then
+ fx-error "arm64 support is still experimental, requires --experiment-arm64"
+ exit 1
+ fi
+ OPTIONS+=("-avd-arch" "arm64")
+fi
+
+# use port 5556 by default
+if (( HTTP )); then
+ GRPC="${GRPC:-5556}"
+fi
+
+if (( GRPC )); then
+ OPTIONS+=("-grpc" "$GRPC")
+ OPTIONS+=("-rtcfps" "$RTCFPS")
+ if [[ -n "$TURNCFG" ]]; then
+ OPTIONS+=("-turncfg" "$TURNCFG")
+ fi
+fi
+
+if (( NET )); then
+ if [[ "$(uname -s)" == "Darwin" ]]; then
+ if [[ -z "$IFNAME" ]]; then
+ IFNAME="tap0"
+ fi
+ if [[ "$IFNAME" != "fakenetwork" && ! -c "/dev/$IFNAME" ]]; then
+ echo "To use emu with networking on macOS, install the tun/tap driver:"
+ echo "http://tuntaposx.sourceforge.net/download.xhtml"
+ exit 1
+ fi
+ if [[ "$IFNAME" != "fakenetwork" && ! -w "/dev/$IFNAME" ]]; then
+ echo "For networking /dev/$IFNAME must be owned by $USER. Please run:"
+ echo " sudo chown $USER /dev/$IFNAME"
+ exit 1
+ fi
+ if [[ -z "${UPSCRIPT}" ]]; then
+ echo "sudo follows to configure the tap interface:"
+ UPSCRIPT="${DEVSHELL_DIR}"/lib/emu-ifup-macos.sh
+ fi
+ else
+ if [[ -z "$IFNAME" ]]; then
+ IFNAME="qemu"
+ fi
+ TAP_IFS=$(ip tuntap show 2>/dev/null)
+ if [[ "$IFNAME" != "fakenetwork" && ! "$TAP_IFS" =~ ${IFNAME}: ]]; then
+ echo "To use emu with networking on Linux, configure tun/tap:"
+ echo
+ echo "sudo ip tuntap add dev $IFNAME mode tap user $USER && \\"
+ echo "sudo ip link set $IFNAME up"
+ exit 1
+ fi
+ # Try to detect if a firewall is active. There are only few ways to do that
+ # without being root. Unfortunately, using systemd or systemctl does not work
+ # (at least on Debian), so use the following hack instead:
+ if (command -v ufw && grep -q "^ENABLED=yes" /etc/ufw/ufw.conf) >/dev/null 2>&1; then
+ fx-warn "Active firewall detected: If this emulator is unreachable, run: fx setup-ufw"
+ fi
+ if [[ -z "${UPSCRIPT}" ]]; then
+ UPSCRIPT=no
+ fi
+ fi
+ if [[ -n "${UPSCRIPT}" && "${UPSCRIPT}" != "no" && ! -x "${UPSCRIPT}" ]]; then
+ echo "The upscript ${UPSCRIPT} is not a valid executable"
+ exit 1
+ fi
+ ARGS+=("-netdev" "type=tap,ifname=$IFNAME,id=net0${UPSCRIPT:+,script=${UPSCRIPT}}")
+ HASH=$(echo $IFNAME | shasum)
+ SUFFIX=$(for i in {0..2}; do echo -n ":${HASH:$(( 2 * i )):2}"; done)
+ MAC=",mac=52:54:00$SUFFIX"
+ ARGS+=("-device" "e1000,netdev=net0${MAC}")
+else
+ ARGS+=("-net" "none")
+fi
+
+# Check for X11 on Linux
+if [[ "$(uname -s)" == "Linux" ]] && (( ! HEADLESS )); then
+ if [[ -z "$DISPLAY" ]]; then
+ echo "To use emulator on Linux, start X, or use a virtual framebuffer:"
+ echo
+ echo "xvfb-run fx emu"
+ exit 1
+ else
+ if [[ "$DISPLAY" != "fakedisplay" ]] && ! xset q >/dev/null 2>&1; then
+ echo "clients must be allowed to connect to DISPLAY. Please run:"
+ echo
+ echo "DISPLAY=$DISPLAY XAUTHORITY=/var/run/lightdm/root/$DISPLAY sudo xhost +"
+ exit 1
+ fi
+ fi
+fi
+
+# Construction of a qcow image prevents aemu from writing back to the
+# build-produced image file, which could cause timestamp issues with that file.
+# Construction of the new ZBI adds //.ssh/authorized_keys for SSH access.
+img_dir="$(mktemp -d)"
+if [[ ! -d "${img_dir}" ]]; then
+ fx-error "Failed to create temporary directory"
+ exit 1
+fi
+trap 'rm -Rf "${img_dir}" ; [[ "${GRPCWEBPROXY_PID}" ]] && kill "${GRPCWEBPROXY_PID}"; stty sane' EXIT
+
+KERNEL_ZBI="${img_dir}/fuchsia-ssh.zbi"
+fx-zbi -o "${KERNEL_ZBI}" "${ZBI_IMAGE}" \
+ --entry "data/ssh/authorized_keys=${AUTHORIZED_KEYS}"
+
+if [[ -n "$FVM_IMAGE" ]]; then
+ fvmimg="${img_dir}/fvm.blk"
+ fx-fvm-extend-image "${FVM_IMAGE}" "${fvmimg}" "${IMAGE_SIZE}"
+ ARGS+=("-drive" "file=${fvmimg},format=raw,if=none,id=vdisk")
+ ARGS+=("-device" "virtio-blk-pci,drive=vdisk")
+fi
+
+# Start gRPC web proxy if HTTP port is set
+if (( HTTP )); then
+ "${GRPCWEBPROXY_DIR}/grpcwebproxy" \
+ --backend_addr localhost:"$GRPC" --server_http_debug_port "$HTTP" \
+ --backend_tls=false --run_tls_server=false --allow_all_origins &
+ GRPCWEBPROXY_PID=$!
+fi
+
+# construct the kernel cmd line for aemu
+CMDLINE+="kernel.serial=legacy "
+
+# Add entropy to the kernel
+CMDLINE+="kernel.entropy-mixin=$(head -c 32 /dev/urandom | shasum -a 256 | awk '{ print $1 }') "
+
+# Don't 'reboot' the emulator if the kernel crashes
+CMDLINE+="kernel.halt-on-panic=true "
+
+# run aemu
+set -x
+"${AEMU_DIR}/${AEMU}" "${OPTIONS[@]}" -fuchsia \
+ -kernel "${KERNEL_IMAGE}" \
+ -initrd "$KERNEL_ZBI" "${ARGS[@]}" -append "$CMDLINE" "$@"
diff --git a/third_party/fuchsia-sdk/bin/devshell/lib/emu-ifup-macos.sh b/third_party/fuchsia-sdk/bin/devshell/lib/emu-ifup-macos.sh
new file mode 100755
index 0000000..974e535
--- /dev/null
+++ b/third_party/fuchsia-sdk/bin/devshell/lib/emu-ifup-macos.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+# Copyright 2020 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.
+#
+# This script is required by fx emu to bring up the network
+# interface on Mac OSX. Do not remove or edit this script
+# without testing it against fx emu.
+
+sudo ifconfig tap0 inet6 fc00::/7 up
diff --git a/third_party/fuchsia-sdk/bin/devshell/lib/fvm.sh b/third_party/fuchsia-sdk/bin/devshell/lib/fvm.sh
new file mode 100644
index 0000000..0892195
--- /dev/null
+++ b/third_party/fuchsia-sdk/bin/devshell/lib/fvm.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+# 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.
+
+# Arguments:
+# - raw image file
+# - extended image file
+# - (optional) size of extended image file, defaults to original*2
+function fx-fvm-extend-image {
+ fvmraw=$1
+ fvmimg=$2
+
+ stat_flags=()
+ if [[ $(uname) == "Darwin" ]]; then
+ stat_flags+=("-x")
+ fi
+ stat_output=$(stat "${stat_flags[@]}" "${fvmraw}")
+ if [[ "$stat_output" =~ Size:\ ([0-9]+) ]]; then
+ size="${BASH_REMATCH[1]}"
+ recommended_size=$((size * 2))
+ if [[ $# -gt 2 && -n "$3" ]]; then
+ newsize=$3
+ if [[ "${newsize}" -le "${size}" ]]; then
+ fx-error "Image size has to be greater than ${size} bytes. Recommended value is ${recommended_size} bytes."
+ return 1
+ fi
+ else
+ newsize="${recommended_size}"
+ fi
+ # We must take a copy of the build artifact, rather than re-use it, as we
+ # need to modify it in order to extend it.
+ echo -n "Creating disk image..."
+ cp "${fvmraw}" "${fvmimg}"
+ "${HOST_OUT_DIR}/fvm" "${fvmimg}" extend --length "${newsize}"
+ echo "done"
+ else
+ fx-error "Could not extend fvm, unable to stat fvm image"
+ return 1
+ fi
+ return 0
+}
diff --git a/third_party/fuchsia-sdk/bin/devshell/lib/image_build_vars.sh b/third_party/fuchsia-sdk/bin/devshell/lib/image_build_vars.sh
new file mode 100755
index 0000000..676393a
--- /dev/null
+++ b/third_party/fuchsia-sdk/bin/devshell/lib/image_build_vars.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+# 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.
+
+# Script to provide necessary variables for fx emu to run out-of-tree
+# This file must be located in `dirname emu`/lib so that emu can source it.
+SCRIPT_SRC_DIR="$(cd "$( dirname "${BASH_SOURCE[0]}" )/../.." >/dev/null 2>&1 && pwd)"
+source "${SCRIPT_SRC_DIR}"/fuchsia-common.sh || exit $?
+source "${SCRIPT_SRC_DIR}"/fx-image-common.sh || exit $?
diff --git a/third_party/fuchsia-sdk/bin/devtools.version b/third_party/fuchsia-sdk/bin/devtools.version
new file mode 100644
index 0000000..da7e64a
--- /dev/null
+++ b/third_party/fuchsia-sdk/bin/devtools.version
@@ -0,0 +1 @@
+m3hEivV_XBNLjgzoQz2382w_pOxlBWY11uu4w5Wv96sC
diff --git a/third_party/fuchsia-sdk/bin/fconfig-meta.json b/third_party/fuchsia-sdk/bin/fconfig-meta.json
new file mode 100644
index 0000000..415b6e7
--- /dev/null
+++ b/third_party/fuchsia-sdk/bin/fconfig-meta.json
@@ -0,0 +1,10 @@
+{
+ "files": [
+ "bin/fconfig.sh",
+ "bin/fuchsia-common.sh"
+ ],
+ "name": "fconfig",
+ "root": "bin",
+ "target_files": {},
+ "type": "host_tool"
+}
diff --git a/third_party/fuchsia-sdk/bin/fconfig.sh b/third_party/fuchsia-sdk/bin/fconfig.sh
new file mode 100755
index 0000000..dbd7b22
--- /dev/null
+++ b/third_party/fuchsia-sdk/bin/fconfig.sh
@@ -0,0 +1,105 @@
+#!/bin/bash
+# Copyright 2020 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.
+#
+#### CATEGORY=Device management
+### Sets configuration properties persistently so
+### they can be used as reasonable defaults for other commands.
+
+set -eu
+
+# Source common functions
+SCRIPT_SRC_DIR="$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)"
+
+# Fuchsia command common functions.
+# shellcheck disable=SC1090
+source "${SCRIPT_SRC_DIR}/fuchsia-common.sh" || exit $?
+
+function usage {
+ cat << EOF
+usage: fconfig.sh [set|get|default|list] propname [value]
+ Sets or gets the property values used as defaults for commands.
+
+ set: Sets the property to the given value.
+ get: Prints the value of the property or empty string if not found.
+ default: Restores the given property to the default value, or unsets.
+ list: Lists prop=value one per line.
+
+ propname: One of the predefined properties: $(get-fuchsia-property-names)).
+ value: if using setting, the value to set to the property. Otherwise ignored.
+EOF
+}
+
+function _do_set {
+ if is-valid-fuchsia-property "$1"; then
+ set-fuchsia-property "$1" "$2"
+ else
+ fx-error "Invalid property name: $1"
+ return 1
+ fi
+}
+
+function _do_get {
+ if is-valid-fuchsia-property "$1"; then
+ get-fuchsia-property "$1"
+ else
+ fx-error "Invalid property name: $1"
+ return 1
+ fi
+}
+
+function _do_list {
+ for p in $(get-fuchsia-property-names); do
+ echo "${p}=$(get-fuchsia-property "$p")"
+ done
+}
+
+CMD=""
+PROPNAME=""
+VALUE=""
+
+if (( "$#" >= 1 )); then
+ CMD="${1}"
+else
+ usage
+ exit 1
+fi
+shift
+
+if [[ "${CMD}" == "set" ]]; then
+ if (( "$#" >= 2 )); then
+ PROPNAME="${1}"
+ shift
+ VALUE="$*"
+ else
+ usage
+ exit 1
+ fi
+ _do_set "${PROPNAME}" "${VALUE}"
+elif [[ "${CMD}" == "get" ]]; then
+ if (( "$#" == 1 )); then
+ PROPNAME="${1}"
+ else
+ usage
+ exit 1
+ fi
+ _do_get "${PROPNAME}"
+elif [[ "${CMD}" == "default" ]]; then
+ if (( "$#" == 1 )); then
+ PROPNAME="${1}"
+ else
+ usage
+ exit 1
+ fi
+ _do_set "${PROPNAME}" ""
+elif [[ "${CMD}" == "list" ]]; then
+ if (( "$#" != 0 )); then
+ usage
+ exit 1
+ fi
+ _do_list
+else
+ usage
+ exit 1
+fi
diff --git a/third_party/fuchsia-sdk/bin/fcp-meta.json b/third_party/fuchsia-sdk/bin/fcp-meta.json
new file mode 100644
index 0000000..afa6be9
--- /dev/null
+++ b/third_party/fuchsia-sdk/bin/fcp-meta.json
@@ -0,0 +1,10 @@
+{
+ "files": [
+ "bin/fcp.sh",
+ "bin/fuchsia-common.sh"
+ ],
+ "name": "fcp",
+ "root": "bin",
+ "target_files": {},
+ "type": "host_tool"
+}
diff --git a/third_party/fuchsia-sdk/bin/fcp.sh b/third_party/fuchsia-sdk/bin/fcp.sh
new file mode 100755
index 0000000..a2a69e8
--- /dev/null
+++ b/third_party/fuchsia-sdk/bin/fcp.sh
@@ -0,0 +1,145 @@
+#!/bin/bash
+# Copyright 2020 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.
+#
+#### CATEGORY=Device management
+### copy a file to/from a target device
+
+set -eu
+
+# Source common functions
+SCRIPT_SRC_DIR="$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)"
+
+# Fuchsia command common functions.
+# shellcheck disable=SC1090
+source "${SCRIPT_SRC_DIR}/fuchsia-common.sh" || exit $?
+
+FUCHSIA_SDK_PATH="$(get-fuchsia-sdk-dir)"
+
+DEVICE_NAME_FILTER="$(get-fuchsia-property device-name)"
+DEFAULT_NAME_HELP=""
+if [[ "${DEVICE_NAME_FILTER}" != "" ]]; then
+ DEFAULT_NAME_HELP="The default device name is ${DEVICE_NAME_FILTER}."
+fi
+DEVICE_IP="$(get-fuchsia-property device-ip)"
+DEFAULT_IP_HELP=""
+if [[ "${DEVICE_IP}" != "" ]]; then
+ DEFAULT_IP_HELP="The default IP address is ${DEVICE_IP}."
+fi
+function usage {
+ cat << EOF
+usage: fcp.sh [(--device-name <device hostname> | --device-ip <device ip-addr>)] [--private-key <identity file>] [(--to-target|--to-host)] SRC... DST
+ Copies a file from the host to the target device, or vice versa.
+
+ --device-name <device hostname>
+ Connects to a device by looking up the given device hostname. ${DEFAULT_NAME_HELP}
+ --device-ip <device ipaddr>
+ Connects to a device by using the provided IP address, cannot use with --device-name.
+ If neither --device-name nor --device-ip are given, the connection is attempted to the
+ first device detected. ${DEFAULT_IP_HELP}
+ --private-key <identity file>
+ Uses additional private key when using ssh to access the device.
+ --to-target
+ Copy file SRC from host to DST on the target. This is the default.
+ --to-host
+ Copy file SRC from target to DST on the host.
+EOF
+}
+
+PRIVATE_KEY_FILE=""
+TO_TARGET=true
+
+# Process all the args except the last two.
+while (( "$#" > 2 )); do
+ case "$1" in
+ --to-target)
+ TO_TARGET=true
+ ;;
+ --to-host)
+ TO_TARGET=false
+ ;;
+ --device-name)
+ shift
+ DEVICE_NAME_FILTER="${1}"
+ ;;
+ --device-ip)
+ shift
+ DEVICE_IP="${1}"
+ ;;
+ --private-key)
+ shift
+ PRIVATE_KEY_FILE="${1}"
+ ;;
+ --help)
+ usage
+ exit 1
+ esac
+shift
+done
+
+readonly DEVICE_NAME_FILTER
+readonly DEVICE_IP
+readonly PRIVATE_KEY_FILE
+readonly TO_TARGET
+
+args=( "$@" )
+nargs=${#args[@]}
+dst=${args[$nargs-1]}
+srcs=( "${args[@]:0:$nargs-1}" )
+target_addr="${DEVICE_IP}"
+
+if [[ $# -ne 2 ]]; then
+ usage
+ exit 1
+fi
+
+# Check for core SDK being present
+if [[ ! -d "${FUCHSIA_SDK_PATH}" ]]; then
+ fx-error "Fuchsia Core SDK not found at ${FUCHSIA_SDK_PATH}."
+ exit 2
+fi
+
+# Get the device IP address if not specified.
+if [[ "${target_addr}" == "" ]]; then
+ # explicitly pass the sdk here since the name filter arg must be $2.
+ target_addr=$(get-device-ip-by-name "${FUCHSIA_SDK_PATH}" "${DEVICE_NAME_FILTER}")
+ if [[ ! "$?" || -z "${target_addr}" ]]; then
+ fx-error "Error finding device"
+ exit 2
+ fi
+else
+ if [[ "${DEVICE_NAME_FILTER}" != "" ]]; then
+ fx-error "Cannot specify both --device-name and --device-ip"
+ exit 3
+ fi
+fi
+
+# Build the command line
+sftp_cmd=( "sftp" "-F" "$(get-fuchsia-sshconfig-file)")
+if [[ "${PRIVATE_KEY_FILE}" != "" ]]; then
+ sftp_cmd+=( "-i" "${PRIVATE_KEY_FILE}")
+fi
+
+# Pass in commands in batch mode from stdin
+sftp_cmd+=( "-b" "-" )
+# sftp needs the [] around the ipv6 address, which is different than ssh.
+if [[ "${target_addr}" =~ : ]]; then
+ sftp_cmd+=( "[${target_addr}]" )
+else
+ sftp_cmd+=( "${target_addr}" )
+fi
+
+if [[ "${TO_TARGET}" = "true" ]]; then
+ (
+ for src in "${srcs[@]}"; do
+ echo "put \"${src}\" \"${dst}\""
+ done
+ ) | "${sftp_cmd[@]}" > /dev/null
+else
+ (
+ for src in "${srcs[@]}"; do
+ echo "get \"${src}\" \"${dst}\""
+ done
+ ) | "${sftp_cmd[@]}" > /dev/null
+fi
diff --git a/third_party/fuchsia-sdk/bin/fdevtools-meta.json b/third_party/fuchsia-sdk/bin/fdevtools-meta.json
new file mode 100644
index 0000000..12dbf89
--- /dev/null
+++ b/third_party/fuchsia-sdk/bin/fdevtools-meta.json
@@ -0,0 +1,11 @@
+{
+ "files": [
+ "bin/devtools.version",
+ "bin/fdevtools.sh",
+ "bin/fuchsia-common.sh"
+ ],
+ "name": "fdevtools",
+ "root": "bin",
+ "target_files": {},
+ "type": "host_tool"
+}
diff --git a/third_party/fuchsia-sdk/bin/fdevtools.sh b/third_party/fuchsia-sdk/bin/fdevtools.sh
new file mode 100755
index 0000000..abd6f3e
--- /dev/null
+++ b/third_party/fuchsia-sdk/bin/fdevtools.sh
@@ -0,0 +1,104 @@
+#!/bin/bash
+# Copyright 2020 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.
+
+# Enable error checking for all commands
+err_print() {
+ echo "Error at $1"
+ stty sane
+}
+trap 'err_print $0:$LINENO' ERR
+set -e
+
+SCRIPT_SRC_DIR="$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)"
+# shellcheck disable=SC1090
+source "${SCRIPT_SRC_DIR}/fuchsia-common.sh" || exit $?
+# Computed from instance id at https://chrome-infra-packages.appspot.com/p/fuchsia_internal/gui_tools/fuchsia_devtools/linux-amd64/+/dogfood-1-1
+VER_DEVTOOLS="$(cat "${SCRIPT_SRC_DIR}/devtools.version")"
+
+FUCHSIA_IMAGE_WORK_DIR="$(get-fuchsia-sdk-data-dir)"
+export FUCHSIA_IMAGE_WORK_DIR
+
+
+usage () {
+ echo "Usage: $0"
+ echo " [--work-dir <directory to store image assets>]"
+ echo " Defaults to ${FUCHSIA_IMAGE_WORK_DIR}"
+ echo " [--private-key <identity file>]"
+ echo " Uses additional private key when using ssh to access the device."
+ echo " [--version <version>"
+ echo " Specify the CIPD version of DevTools to download."
+ echo " Defaults to devtools.version file with ${VER_DEVTOOLS}"
+ echo " [--help] [-h]"
+ echo " Show command line options available"
+}
+
+PRIVATE_KEY_FILE=""
+FDT_ARGS=()
+
+# Parse command line
+while (( "$#" )); do
+case $1 in
+ --work-dir)
+ shift
+ FUCHSIA_IMAGE_WORK_DIR="${1:-.}"
+ ;;
+ --private-key)
+ shift
+ PRIVATE_KEY_FILE="${1}"
+ ;;
+ --version)
+ shift
+ VER_DEVTOOLS="${1}"
+ ;;
+ --help|-h)
+ usage
+ exit 0
+ ;;
+ *)
+ # Unknown options are passed to Fuchsia DevTools
+ FDT_ARGS+=( "$1" )
+ ;;
+esac
+shift
+done
+
+readonly PRIVATE_KEY_FILE
+
+# Do not create directory names with : otherwise LD_PRELOAD or PATH usage will fail.
+# Avoid / to prevent extra sub-directories being created.
+LABEL_DEVTOOLS="$(echo "${VER_DEVTOOLS}" | tr ':/' '_')"
+
+# Can download Fuchsia DevTools from CIPD with either "latest" or a CIPD hash
+echo "Downloading Fuchsia DevTools ${VER_DEVTOOLS} with CIPD"
+TEMP_ENSURE=$(mktemp /tmp/fuchsia_devtools_cipd_XXXXXX.ensure)
+cat << end > "${TEMP_ENSURE}"
+\$ServiceURL https://chrome-infra-packages.appspot.com/
+fuchsia_internal/gui_tools/fuchsia_devtools/\${platform} $VER_DEVTOOLS
+end
+
+FDT_DIR="${FUCHSIA_IMAGE_WORK_DIR}/fuchsia_devtools-${LABEL_DEVTOOLS}"
+if ! run-cipd ensure -ensure-file "${TEMP_ENSURE}" -root "${FDT_DIR}"; then
+ rm "$TEMP_ENSURE"
+ echo "Failed to download Fuchsia DevTools ${VER_DEVTOOLS}."
+ exit 1
+fi
+rm "${TEMP_ENSURE}"
+
+export FDT_TOOLCHAIN="GN"
+FDT_GN_SSH="$(command -v ssh)"
+export FDT_GN_SSH
+FDT_SSH_CONFIG="$(get-fuchsia-sshconfig-file)"
+export FDT_SSH_CONFIG
+FDT_GN_DEVFIND="$(get-fuchsia-sdk-dir)/tools/device-finder"
+export FDT_GN_DEVFIND
+export FDT_DEBUG="true"
+if [[ "${PRIVATE_KEY_FILE}" != "" ]]; then
+ FDT_SSH_KEY="${PRIVATE_KEY_FILE}"
+ export FDT_SSH_KEY
+fi
+echo "Starting system_monitor with FDT_ARGS=[${FDT_ARGS[*]}] and environment:"
+env | grep FDT_
+
+"${FDT_DIR}/system_monitor/linux/system_monitor" "${FDT_ARGS[@]}"
diff --git a/third_party/fuchsia-sdk/bin/femu-exec-wrapper.sh b/third_party/fuchsia-sdk/bin/femu-exec-wrapper.sh
new file mode 100755
index 0000000..278ab6a
--- /dev/null
+++ b/third_party/fuchsia-sdk/bin/femu-exec-wrapper.sh
@@ -0,0 +1,200 @@
+#!/bin/bash
+# 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.
+
+function usage() {
+ echo "Usage: $0"
+ echo
+ echo " Starts up femu.sh, runs a script, captures the result, and terminates the emulator"
+ echo
+ echo " [--exec <script>]"
+ echo " Executes the specified script or command that can access the emulator"
+ echo " [--femu-log <file>]"
+ echo " Specify log file instead of mktemp, can also be /dev/null or /dev/stdout"
+ echo " [--headless]"
+ echo " Do not use any graphics support, do not open any new windows"
+ echo " [--interactive]"
+ echo " Opens up xterm window with femu serial console"
+ echo " [--image <name>]"
+ echo " System image to use with femu.sh, defaults to ${IMAGE_NAME}"
+ echo
+ echo " All other arguments are passed on, see femu.sh --help for more info"
+}
+
+set -eu # Error checking
+err_print() {
+ echo "Error at $1"
+}
+trap 'err_print $0:$LINENO' ERR
+
+SCRIPT_SRC_DIR="$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)"
+# shellcheck disable=SC1090
+source "${SCRIPT_SRC_DIR}/fuchsia-common.sh" || exit $?
+
+function get_child_pids {
+ children=()
+ if is-mac; then
+ while IFS='' read -r v; do children+=("$v"); done < <(pgrep -P "$1")
+ else
+ while IFS='' read -r v; do children+=("$v"); done < <(ps -o pid= --ppid "$1")
+ fi
+ if (( ${#children[@]} )); then
+ for pid in "${children[@]}"; do
+ while IFS='' read -r v; do children+=("$v"); done < <(get_child_pids "$pid")
+ done
+ echo "${children[@]}"
+ fi
+}
+
+# Called when there is an error and we need to dump the log
+function dump_femu_log {
+ if [[ "${FEMU_LOG}" = /dev/* ]]; then
+ echo "Cannot dump log for device ${FEMU_LOG}"
+ else
+ echo "Dumping log file ${FEMU_LOG}"
+ cat -n "${FEMU_LOG}"
+ fi
+}
+
+# This is only used after femu.sh has been started
+function cleanup {
+ declare -a CHILD_PIDS=()
+ IFS=" " read -r -a CHILD_PIDS <<< "$(get_child_pids "${FEMU_PID}")"
+ msg="Cleaning up femu pid ${FEMU_PID}"
+
+ if (( "${#CHILD_PIDS[@]}" )); then
+ echo "$msg qemu child processes ${CHILD_PIDS[*]} and package server for exit ..."
+ kill "${CHILD_PIDS[@]}" > /dev/null 2>&1 || true
+ elif [[ "${FEMU_PID}" != "" ]]; then
+ echo "${msg}"
+ kill "${FEMU_PID}" > /dev/null 2>&1 || true
+ fi
+ "${SCRIPT_SRC_DIR}/fserve.sh" --kill > /dev/null 2>&1 || true
+}
+
+HEADLESS=""
+INTERACTIVE=""
+EXEC_SCRIPT=""
+IMAGE_NAME="qemu-x64"
+FEMU_LOG=""
+FEMU_LOG_TEMP=""
+EMU_ARGS=()
+
+# Check for some of the emu flags, but pass everything else on to femu.sh
+while (( "$#" )); do
+ case $1 in
+ --help|-h)
+ usage
+ exit 0
+ ;;
+ --headless)
+ HEADLESS="yes"
+ ;;
+ --interactive)
+ INTERACTIVE="yes"
+ ;;
+ --exec)
+ shift
+ EXEC_SCRIPT="${1}"
+ ;;
+ --femu-log)
+ shift
+ FEMU_LOG="${1}"
+ ;;
+ --image)
+ shift
+ IMAGE_NAME="${1}"
+ ;;
+ *)
+ # Everything else is passed on to the emulator
+ EMU_ARGS+=( "${1}" )
+ ;;
+ esac
+ shift
+done
+
+# This IPv6 address is always generated according to the hash of the qemu network interface in femu.sh
+EMULATOR_ADDRESS="fe80::5054:ff:fe63:5e7a%qemu"
+
+# Set up log file if not specified
+if [[ "${INTERACTIVE}" == "yes" && "${FEMU_LOG}" != "" && "${FEMU_LOG}" != "/dev/null" ]]; then
+ fx-error "--interactive does not write to --femu-log"
+ exit 1
+fi
+if [[ "${FEMU_LOG}" == "" ]]; then
+ FEMU_LOG="$(mktemp)"
+ FEMU_LOG_TEMP="${FEMU_LOG_TEMP}"
+fi
+
+# Always start femu with network access.
+femu_command_args=("${SCRIPT_SRC_DIR}/femu.sh" --image "${IMAGE_NAME}" -N)
+
+echo "Starting emulator with logging to ${FEMU_LOG}"
+if [[ "${INTERACTIVE}" == "yes" ]]; then
+ if (( ${#EMU_ARGS[@]} )); then
+ femu_command_args+=("${EMU_ARGS[@]}")
+ fi
+ # Start up the emulator in the background within a new window, useful for interactive debugging
+ xterm -T "femu" -e "${femu_command_args[@]}" &
+ FEMU_PID=$!
+elif [[ "${HEADLESS}" == "yes" ]]; then
+ # When there is no graphics support, run femu in the background with no output visible, and use a software GPU
+ femu_command_args+=("--headless" "--software-gpu")
+ if (( ${#EMU_ARGS[@]} )); then
+ femu_command_args+=("${EMU_ARGS[@]}")
+ fi
+ "${femu_command_args[@]}" &> "${FEMU_LOG}" < /dev/null &
+ FEMU_PID=$!
+else
+ # Allow femu to open up a window for the emulator and use hardware Vulkan support
+ if (( ${#EMU_ARGS[@]} )); then
+ femu_command_args+=("${EMU_ARGS[@]}")
+ fi
+ "${femu_command_args[@]}" &> "${FEMU_LOG}" < /dev/null &
+ FEMU_PID=$!
+fi
+trap cleanup EXIT
+
+# Wait for the emulator to start, and check if emu is still running in the background or this will never complete
+echo "Waiting for emulator to start"
+COUNT=0
+COUNT_TIMEOUT=120
+while [[ $COUNT -lt $COUNT_TIMEOUT ]] ; do
+ kill -0 ${FEMU_PID} &> /dev/null || ( echo "ERROR: Emulator pid $FEMU_PID has exited, cannot connect"; dump_femu_log; exit 1; )
+ "${SCRIPT_SRC_DIR}/fssh.sh" --device-ip "${EMULATOR_ADDRESS}" "echo hello" &> /dev/null && break
+ echo "Waiting for emulator SSH server ${EMULATOR_ADDRESS} - attempt ${COUNT} ..."
+ COUNT=$((COUNT+1))
+ sleep 1s
+done
+if (( COUNT == COUNT_TIMEOUT )); then
+ echo "ERROR: Timeout of ${COUNT_TIMEOUT} seconds reached waiting for emulator pid $FEMU_PID to start, cannot connect"
+ dump_femu_log
+ exit 1
+fi
+echo "Emulator pid ${FEMU_PID} is running and accepting connections"
+
+# Start the package server after the emulator is ready, so we know it is configured when we run commands
+echo "Starting package server"
+"${SCRIPT_SRC_DIR}/fserve.sh" --image "${IMAGE_NAME}"
+
+# Execute the script specified on the command-line
+EXEC_RESULT=0
+if [[ "${EXEC_SCRIPT}" == "" ]]; then
+ fx-warn "No --exec script specified, will now clean up"
+else
+ eval "${EXEC_SCRIPT}" "${EMULATOR_ADDRESS}" || EXEC_RESULT=$?
+fi
+
+if [[ "${EXEC_RESULT}" != "0" ]]; then
+ fx-error "ERROR: \"${EXEC_SCRIPT}\" returned ${EXEC_RESULT}"
+ dump_femu_log
+else
+ # Clean up the temporary file on success
+ if [[ "${FEMU_LOG_TEMP}" != "" ]]; then
+ rm -f "${FEMU_LOG_TEMP}"
+ fi
+fi
+
+# Exit with the result of the test script, and also run the cleanup function
+exit $EXEC_RESULT
diff --git a/third_party/fuchsia-sdk/bin/femu-meta.json b/third_party/fuchsia-sdk/bin/femu-meta.json
new file mode 100644
index 0000000..ffe6de9
--- /dev/null
+++ b/third_party/fuchsia-sdk/bin/femu-meta.json
@@ -0,0 +1,18 @@
+{
+ "files": [
+ "bin/aemu.version",
+ "bin/grpcwebproxy.version",
+ "bin/femu.sh",
+ "bin/femu-exec-wrapper.sh",
+ "bin/fuchsia-common.sh",
+ "bin/fx-image-common.sh",
+ "bin/devshell/emu",
+ "bin/devshell/lib/image_build_vars.sh",
+ "bin/devshell/lib/fvm.sh",
+ "bin/devshell/lib/emu-ifup-macos.sh"
+ ],
+ "name": "femu",
+ "root": "bin",
+ "target_files": {},
+ "type": "host_tool"
+}
diff --git a/third_party/fuchsia-sdk/bin/femu.sh b/third_party/fuchsia-sdk/bin/femu.sh
new file mode 100755
index 0000000..9c2f779
--- /dev/null
+++ b/third_party/fuchsia-sdk/bin/femu.sh
@@ -0,0 +1,186 @@
+#!/bin/bash
+# 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.
+
+# Enable error checking for all commands
+err_print() {
+ echo "Error at $1"
+ stty sane
+}
+trap 'err_print $0:$LINENO' ERR
+set -eu
+
+SCRIPT_SRC_DIR="$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)"
+# shellcheck disable=SC1090
+source "${SCRIPT_SRC_DIR}/fuchsia-common.sh" || exit $?
+FUCHSIA_BUCKET="${DEFAULT_FUCHSIA_BUCKET}"
+IMAGE_NAME="qemu-x64"
+VER_AEMU="$(cat "${SCRIPT_SRC_DIR}/aemu.version")"
+VER_GRPCWEBPROXY="$(cat "${SCRIPT_SRC_DIR}/grpcwebproxy.version")"
+ENABLE_GRPCWEBPROXY=0
+PREBUILT_GRPCWEBPROXY_DIR=""
+
+# Export variables needed here but also in femu.sh
+FUCHSIA_SDK_PATH="$(get-fuchsia-sdk-dir)"
+export FUCHSIA_SDK_PATH
+FUCHSIA_IMAGE_WORK_DIR="$(get-fuchsia-sdk-data-dir)"
+export FUCHSIA_IMAGE_WORK_DIR
+
+# Download a URL $1 from CIPD, extract into directory $2
+function download-extract-cipd {
+ CIPD_URL="${1}"
+ CIPD_DIR="${2}"
+ CIPD_FILE="${2}.zip"
+
+ if [ ! -f "${CIPD_FILE}" ]; then
+ echo "Downloading from ${CIPD_URL} ..."
+ curl -L "${CIPD_URL}" -o "${CIPD_FILE}" -#
+ echo "Verifying download ${CIPD_FILE}"
+ # CIPD will return a file containing "no such ref" if the URL is invalid, so need to check the ZIP file
+ if ! unzip -qq -t "${CIPD_FILE}" &> /dev/null; then
+ rm -f "${CIPD_FILE}"
+ fx-error "Downloaded archive from ${CIPD_URL} failed with invalid data - the version is probably invalid"
+ exit 1
+ fi
+ echo "Download complete."
+ fi
+ if [ ! -d "${CIPD_DIR}" ]; then
+ echo -e "Extracting archive to ${CIPD_DIR} ..."
+ rm -rf "${CIPD_DIR}" "${CIPD_DIR}-temp"
+ unzip -q "${CIPD_FILE}" -d "${CIPD_DIR}-temp"
+ mv "${CIPD_DIR}-temp" "${CIPD_DIR}"
+ echo "Extract complete."
+ else
+ echo "Using existing archive in ${CIPD_DIR}"
+ fi
+}
+
+emu_help () {
+ # Extract command-line argument help from emu script, similar to fx-print-command-help
+ sed -n -e 's/^## //p' -e 's/^##$//p' "${SCRIPT_SRC_DIR}/devshell/emu" | grep -v "usage: fx emu"
+}
+
+usage () {
+ echo "Usage: $0"
+ echo " [--work-dir <directory to store image assets>]"
+ echo " Defaults to ${FUCHSIA_IMAGE_WORK_DIR}"
+ echo " [--bucket <fuchsia gsutil bucket>]"
+ echo " Defaults to ${FUCHSIA_BUCKET}"
+ echo " [--image <image name>]"
+ echo " Defaults to ${IMAGE_NAME}"
+ echo " [--authorized-keys <file>]"
+ echo " The authorized public key file for securing the device. Defaults to "
+ echo " ${FUCHSIA_IMAGE_WORK_DIR}/.ssh/authorized_keys, which is generated if needed."
+ echo " [--version <version>"
+ echo " Specify the CIPD version of AEMU to download."
+ echo " Defaults to aemu.version file with ${VER_AEMU}"
+ echo " [--help] [-h]"
+ echo " Show command line options for femu.sh and emu subscript"
+ echo
+ echo "Remaining arguments are passed to emu wrapper and emulator:"
+ emu_help
+ echo
+ echo "Invalid argument names are not flagged as errors, and are passed on to emulator"
+}
+AUTH_KEYS_FILE=""
+EMU_ARGS=()
+
+# Parse command line
+while (( "$#" )); do
+case $1 in
+ --work-dir)
+ shift
+ FUCHSIA_IMAGE_WORK_DIR="${1:-.}"
+ ;;
+ --bucket)
+ shift
+ FUCHSIA_BUCKET="${1}"
+ ;;
+ --image)
+ shift
+ IMAGE_NAME="${1}"
+ ;;
+ --authorized-keys)
+ shift
+ AUTH_KEYS_FILE="${1}"
+ ;;
+ --version)
+ shift
+ VER_AEMU="${1}"
+ ;;
+ --help|-h)
+ usage
+ exit 0
+ ;;
+ -x)
+ shift
+ ENABLE_GRPCWEBPROXY=1
+ EMU_ARGS+=( -x "$1" )
+ ;;
+ -X)
+ shift
+ PREBUILT_GRPCWEBPROXY_DIR="$1"
+ ;;
+ *)
+ # Unknown options are passed to emu
+ EMU_ARGS+=( "$1" )
+ ;;
+esac
+shift
+done
+
+if [[ "${AUTH_KEYS_FILE}" != "" ]]; then
+ auth_keys_file="${AUTH_KEYS_FILE}"
+else
+ auth_keys_file="$(get-fuchsia-auth-keys-file)"
+fi
+
+# Download the system images and packages
+echo "Checking for system images and packages"
+"${SCRIPT_SRC_DIR}/fpave.sh" --prepare --image "${IMAGE_NAME}" --bucket "${FUCHSIA_BUCKET}" --work-dir "${FUCHSIA_IMAGE_WORK_DIR}"
+"${SCRIPT_SRC_DIR}/fserve.sh" --prepare --image "${IMAGE_NAME}" --bucket "${FUCHSIA_BUCKET}" --work-dir "${FUCHSIA_IMAGE_WORK_DIR}"
+
+# Do not create directory names with : otherwise LD_PRELOAD usage in aemu will fail.
+# Avoid / to prevent extra sub-directories being created.
+LABEL_AEMU="$(echo "${VER_AEMU}" | tr ':/' '_')"
+LABEL_GRPCWEBPROXY="$(echo "${VER_GRPCWEBPROXY}" | tr ':/' '_')"
+
+# Download CIPD prebuilt binaries if not already present
+DOWNLOADS_DIR="${FUCHSIA_IMAGE_WORK_DIR}/emulator"
+mkdir -p "${DOWNLOADS_DIR}"
+if is-mac; then
+ ARCH="mac-amd64"
+else
+ ARCH="linux-amd64"
+fi
+
+# Export variables needed for fx emu and fx-image-common.sh
+export FUCHSIA_BUILD_DIR="${FUCHSIA_IMAGE_WORK_DIR}/image"
+export PREBUILT_AEMU_DIR="${DOWNLOADS_DIR}/aemu-${ARCH}-${LABEL_AEMU}"
+
+download-extract-cipd \
+ "https://chrome-infra-packages.appspot.com/dl/fuchsia/third_party/aemu/${ARCH}/+/${VER_AEMU}" \
+ "${PREBUILT_AEMU_DIR}"
+
+if (( ENABLE_GRPCWEBPROXY )); then
+ if [[ -z "$PREBUILT_GRPCWEBPROXY_DIR" ]]; then
+ PREBUILT_GRPCWEBPROXY_DIR="${DOWNLOADS_DIR}/grpcwebproxy-${ARCH}-${LABEL_GRPCWEBPROXY}"
+ download-extract-cipd \
+ "https://chrome-infra-packages.appspot.com/dl/fuchsia/third_party/grpcwebproxy/${ARCH}/+/${VER_GRPCWEBPROXY}" \
+ "${PREBUILT_GRPCWEBPROXY_DIR}"
+ fi
+ EMU_ARGS+=( "-X" "${PREBUILT_GRPCWEBPROXY_DIR}" )
+fi
+
+# Need to make the SDK storage-full.blk writable so that the copy is writable as well, otherwise fvm extend fails in lib/fvm.sh
+# shellcheck disable=SC1090
+source "${SCRIPT_SRC_DIR}/fx-image-common.sh"
+echo "Setting writable permissions on $FUCHSIA_BUILD_DIR/$IMAGE_FVM_RAW"
+chmod u+w "$FUCHSIA_BUILD_DIR/$IMAGE_FVM_RAW"
+
+if (( "${#EMU_ARGS[@]}" )); then
+ "${SCRIPT_SRC_DIR}/devshell/emu" -k "${auth_keys_file}" "${EMU_ARGS[@]}"
+else
+ "${SCRIPT_SRC_DIR}/devshell/emu" -k "${auth_keys_file}"
+fi
diff --git a/third_party/fuchsia-sdk/bin/fpave-meta.json b/third_party/fuchsia-sdk/bin/fpave-meta.json
new file mode 100644
index 0000000..0e1c90f
--- /dev/null
+++ b/third_party/fuchsia-sdk/bin/fpave-meta.json
@@ -0,0 +1,10 @@
+{
+ "files": [
+ "bin/fpave.sh",
+ "bin/fuchsia-common.sh"
+ ],
+ "name": "fpave",
+ "root": "bin",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/bin/fpave.sh b/third_party/fuchsia-sdk/bin/fpave.sh
new file mode 100755
index 0000000..9cbf517
--- /dev/null
+++ b/third_party/fuchsia-sdk/bin/fpave.sh
@@ -0,0 +1,241 @@
+#!/bin/bash
+# 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.
+#
+# Command to pave a Fuchsia device.
+
+# note: set -e is not used in order to have custom error handling.
+set -u
+
+# Source common functions
+SCRIPT_SRC_DIR="$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)"
+
+# Fuchsia command common functions.
+# shellcheck disable=SC1090
+source "${SCRIPT_SRC_DIR}/fuchsia-common.sh" || exit $?
+
+FUCHSIA_SDK_PATH="$(get-fuchsia-sdk-dir)"
+FUCHSIA_IMAGE_WORK_DIR="$(get-fuchsia-sdk-data-dir)"
+
+DEVICE_NAME_FILTER="$(get-fuchsia-property device-name)"
+
+FUCHSIA_BUCKET="$(get-fuchsia-property bucket)"
+if [[ "${FUCHSIA_BUCKET}" == "" ]]; then
+ FUCHSIA_BUCKET="${DEFAULT_FUCHSIA_BUCKET}"
+fi
+
+IMAGE_NAME="$(get-fuchsia-property image)"
+if [[ "${IMAGE_NAME}" == "" ]]; then
+ IMAGE_NAME="generic-x64"
+fi
+
+function usage {
+ echo "Usage: $0"
+ echo " [--image <image name>"]
+ echo " Defaults to ${IMAGE_NAME}. Use --image list to list all available images."
+ echo " [--work-dir <working directory to store image assets>]"
+ echo " Defaults to ${FUCHSIA_IMAGE_WORK_DIR}."
+ echo " [--bucket <fuchsia gsutil bucket>]"
+ echo " Defaults to ${FUCHSIA_BUCKET}."
+ echo " [--authorized-keys <file>]"
+ echo " The authorized public key file for securing the device. Defaults to "
+ echo " ${FUCHSIA_IMAGE_WORK_DIR}/.ssh/authorized_keys, which is generated if needed."
+ echo " [--private-key <identity file>]"
+ echo " Uses additional private key when using ssh to access the device."
+ echo " [--device-name <device hostname>]"
+ echo " Only paves a device with the given device hostname."
+ if [[ "${DEVICE_NAME_FILTER}" != "" ]]; then
+ echo " Defaults to ${DEVICE_NAME_FILTER}."
+ fi
+ echo " [--prepare]"
+ echo " Downloads any dependencies but does not pave to a device."
+ echo " [--zedboot]"
+ echo " Updates the Zedboot bootloader and exits."
+ echo " [-x] Enable debug."
+}
+
+PRIVATE_KEY_FILE=""
+PREPARE_ONLY=""
+AUTH_KEYS_FILE=""
+UPDATE_ZEDBOOT=""
+
+
+# Parse command line
+while (( "$#" )); do
+case $1 in
+ --work-dir)
+ shift
+ FUCHSIA_IMAGE_WORK_DIR="${1:-.}"
+ ;;
+ --bucket)
+ shift
+ FUCHSIA_BUCKET="${1}"
+ ;;
+ --image)
+ shift
+ IMAGE_NAME="${1}"
+ ;;
+ --authorized-keys)
+ shift
+ AUTH_KEYS_FILE="${1}"
+ ;;
+ --private-key)
+ shift
+ PRIVATE_KEY_FILE="${1}"
+ ;;
+ --device-name)
+ DEVICE_NAME_FILTER="${1}"
+ shift
+ ;;
+ --prepare)
+ PREPARE_ONLY="yes"
+ ;;
+ --zedboot)
+ UPDATE_ZEDBOOT="yes"
+ ;;
+ -x)
+ set -x
+ ;;
+ *)
+ # unknown option
+ fx-error "Unknown option $1."
+ usage
+ exit 1
+ ;;
+esac
+shift
+done
+
+
+if ! SDK_ID="$(get-sdk-version)"; then
+ fx-error "Could not get SDK version"
+ exit 1
+fi
+
+if [[ "${IMAGE_NAME}" == "list" ]]; then
+ if ! IMAGES="$(get-available-images "${SDK_ID}" "${FUCHSIA_BUCKET}")"; then
+ fx-error "Could not get list of available images for ${SDK_ID}"
+ exit 1
+ fi
+ echo "Valid images for this SDK version are: ${IMAGES}."
+ exit 1
+fi
+
+FUCHSIA_TARGET_IMAGE="$(get-image-src-path "${SDK_ID}" "${IMAGE_NAME}")"
+# The image tarball, we add the SDK ID to make it unique, and note the
+# .tar.gz extension for packages vs .tgz extension for images.
+IMAGE_FILENAME="${SDK_ID}_${IMAGE_NAME}.tgz"
+
+# Validate the image is found
+if [[ ! -f "${FUCHSIA_IMAGE_WORK_DIR}/${IMAGE_FILENAME}" ]] ; then
+ if ! run-gsutil ls "${FUCHSIA_TARGET_IMAGE}" >/dev/null 2>&1; then
+ echo "Image ${IMAGE_NAME} not found. Valid images for this SDK version are:"
+ if ! IMAGES="$(get-available-images "${SDK_ID}" "${FUCHSIA_BUCKET}")"; then
+ fx-error "Could not get list of available images for ${SDK_ID}"
+ exit 1
+ fi
+ echo "${IMAGES}"
+ exit 2
+ fi
+
+ if ! run-gsutil cp "${FUCHSIA_TARGET_IMAGE}" "${FUCHSIA_IMAGE_WORK_DIR}/${IMAGE_FILENAME}"; then
+ fx-error "Could not copy image from ${FUCHSIA_TARGET_IMAGE} to ${FUCHSIA_IMAGE_WORK_DIR}/${IMAGE_FILENAME}."
+ exit 2
+ fi
+else
+ echo "Skipping download, image exists."
+fi
+
+# The checksum file contains the output from `md5`. This is used to detect content
+# changes in the image file.
+CHECKSUM_FILE="${FUCHSIA_IMAGE_WORK_DIR}/image/image.md5"
+
+# check that any existing contents of the image directory match the intended target device
+if [[ -f "${CHECKSUM_FILE}" ]]; then
+ if [[ $(run-md5 "${FUCHSIA_IMAGE_WORK_DIR}/${IMAGE_FILENAME}") != "$(< "${CHECKSUM_FILE}")" ]]; then
+ fx-warn "Removing old image files."
+ if ! rm -f "$(cut -d ' ' -f3 "${CHECKSUM_FILE}")"; then
+ fx-error "Could not clean up old image archive."
+ exit 2
+ fi
+ if ! rm -rf "${FUCHSIA_IMAGE_WORK_DIR}/image"; then
+ fx-error "Could not clean up old image."
+ exit 2
+ fi
+ fi
+else
+ # if the checksum file does not exist, something is inconsistent.
+ # so delete the entire directory to make sure we're starting clean.
+ # This also happens on a clean run, where the image directory does not
+ # exist.
+ if ! rm -rf "${FUCHSIA_IMAGE_WORK_DIR}/image"; then
+ fx-error "Could not clean up old image."
+ exit 2
+ fi
+fi
+
+if ! mkdir -p "${FUCHSIA_IMAGE_WORK_DIR}/image"; then
+ fx-error "Could not create image directory."
+ exit 2
+fi
+
+# if the tarball is not untarred, do it.
+if [[ ! -f "${FUCHSIA_IMAGE_WORK_DIR}/image/pave.sh" ]]; then
+ if ! tar xzf "${FUCHSIA_IMAGE_WORK_DIR}/${IMAGE_FILENAME}" --directory "${FUCHSIA_IMAGE_WORK_DIR}/image"; then
+ fx-error "Could not extract image from ${FUCHSIA_IMAGE_WORK_DIR}/${IMAGE_FILENAME}."
+ exit 1
+ fi
+ run-md5 "${FUCHSIA_IMAGE_WORK_DIR}/${IMAGE_FILENAME}" > "${CHECKSUM_FILE}"
+fi
+
+# Exit out if we only need to prepare the downloads
+if [[ "${PREPARE_ONLY}" == "yes" ]]; then
+ exit 0
+fi
+
+SSH_ARGS=()
+
+if [[ "${PRIVATE_KEY_FILE}" != "" ]]; then
+ SSH_ARGS+=( "-i" "${PRIVATE_KEY_FILE}")
+fi
+
+# Get the device IP address. If we can't find it, it could be at the zedboot
+# page, so it is not fatal.
+# Explicitly pass the sdk path to match the device_filter.
+DEVICE_IP=$(get-device-ip-by-name "$FUCHSIA_SDK_PATH" "$DEVICE_NAME_FILTER")
+if [[ "$?" && -n "$DEVICE_IP" ]]; then
+ SSH_ARGS+=( "${DEVICE_IP}" dm reboot-recovery )
+ ssh-cmd "${SSH_ARGS[@]}"
+ fx-warn "Confirm device is rebooting into recovery mode. Paving may fail if device is not in Zedboot."
+else
+ fx-warn "Device not detected. Make sure the device is connected and at the 'Zedboot' screen."
+fi
+
+# The prebuilt images do not have a bootserver for mac, so overwrite the bootserver with the
+# mac bootserver. See fxb/48346.
+if is-mac; then
+ cp -f "${FUCHSIA_SDK_PATH}/tools/bootserver" "${FUCHSIA_IMAGE_WORK_DIR}/image/bootserver.exe.linux-x64"
+fi
+
+
+if [[ "${UPDATE_ZEDBOOT}" == "yes" ]]; then
+ PAVE_CMD=("${FUCHSIA_IMAGE_WORK_DIR}/image/pave-zedboot.sh")
+else
+ PAVE_CMD=("${FUCHSIA_IMAGE_WORK_DIR}/image/pave.sh")
+fi
+
+if [[ "${AUTH_KEYS_FILE}" != "" ]]; then
+ auth_keys_file="${AUTH_KEYS_FILE}"
+else
+ auth_keys_file="$(get-fuchsia-auth-keys-file)"
+fi
+
+PAVE_CMD+=("--authorized-keys" "${auth_keys_file}" "-1")
+if ! "${PAVE_CMD[@]}"; then
+ # Currently there is a bug on the first attempt of paving, so retry.
+ sleep .33
+ if ! "${PAVE_CMD[@]}"; then
+ exit 2
+ fi
+fi
diff --git a/third_party/fuchsia-sdk/bin/fpublish-meta.json b/third_party/fuchsia-sdk/bin/fpublish-meta.json
new file mode 100644
index 0000000..2dcb339
--- /dev/null
+++ b/third_party/fuchsia-sdk/bin/fpublish-meta.json
@@ -0,0 +1,10 @@
+{
+ "files": [
+ "bin/fpublish.sh",
+ "bin/fuchsia-common.sh"
+ ],
+ "name": "fpublish",
+ "root": "bin",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/bin/fpublish.sh b/third_party/fuchsia-sdk/bin/fpublish.sh
new file mode 100755
index 0000000..278c04e
--- /dev/null
+++ b/third_party/fuchsia-sdk/bin/fpublish.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+# 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.
+#
+# Command to publish a package to make is accessible to a Fuchsia device.
+
+# note: set -e is not used in order to have custom error handling.
+set -u
+
+# Source common functions
+SCRIPT_SRC_DIR="$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)"
+
+# Fuchsia command common functions.
+# shellcheck disable=SC1090
+source "${SCRIPT_SRC_DIR}/fuchsia-common.sh" || exit $?
+
+FUCHSIA_SDK_PATH="$(get-fuchsia-sdk-dir)"
+FUCHSIA_IMAGE_WORK_DIR="$(get-fuchsia-sdk-data-dir)"
+
+usage () {
+ echo "Usage: $0 <files.far>"
+ echo " [--work-dir <working directory to store image assets>]"
+ echo " Defaults to ${FUCHSIA_IMAGE_WORK_DIR}"
+}
+
+POSITIONAL=()
+
+# Parse command line
+while (( "$#" )); do
+case $1 in
+ --work-dir)
+ shift
+ FUCHSIA_IMAGE_WORK_DIR="${1}"
+ ;;
+ -*)
+ if [[ "${#POSITIONAL[@]}" -eq 0 ]]; then
+ echo "Unknown option ${1}"
+ usage
+ exit 1
+ else
+ POSITIONAL+=("${1}")
+ fi
+ ;;
+ *)
+ POSITIONAL+=("${1}")
+ ;;
+esac
+shift
+done
+
+"${FUCHSIA_SDK_PATH}/tools/pm" publish -a -r "${FUCHSIA_IMAGE_WORK_DIR}/packages/amber-files" -f "${POSITIONAL[@]}";
diff --git a/third_party/fuchsia-sdk/bin/fserve-meta.json b/third_party/fuchsia-sdk/bin/fserve-meta.json
new file mode 100644
index 0000000..95b850e
--- /dev/null
+++ b/third_party/fuchsia-sdk/bin/fserve-meta.json
@@ -0,0 +1,10 @@
+{
+ "files": [
+ "bin/fserve.sh",
+ "bin/fuchsia-common.sh"
+ ],
+ "name": "fserve",
+ "root": "bin",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/bin/fserve-remote-meta.json b/third_party/fuchsia-sdk/bin/fserve-remote-meta.json
new file mode 100644
index 0000000..0e0b43f
--- /dev/null
+++ b/third_party/fuchsia-sdk/bin/fserve-remote-meta.json
@@ -0,0 +1,10 @@
+{
+ "files": [
+ "bin/fserve-remote.sh",
+ "bin/fuchsia-common.sh"
+ ],
+ "name": "fserve-remote",
+ "root": "bin",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/bin/fserve-remote.sh b/third_party/fuchsia-sdk/bin/fserve-remote.sh
new file mode 100755
index 0000000..2ff78c1
--- /dev/null
+++ b/third_party/fuchsia-sdk/bin/fserve-remote.sh
@@ -0,0 +1,158 @@
+#!/bin/bash
+# Copyright 2020 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.
+set -eu
+
+SCRIPT_SRC_DIR="$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)"
+
+# Fuchsia command common functions.
+# shellcheck disable=SC1090
+source "${SCRIPT_SRC_DIR}/fuchsia-common.sh" || exit $?
+
+usage() {
+ cat << EOF
+usage: fserve-remote.sh [--no-serve] [--device-name <device hostname>] HOSTNAME REMOTE-PATH
+ Uses SSH port forwarding to connect to a remote server and forward package serving and other connections to a local device.
+
+ --device-name <device hostname>
+ Connects to a device by looking up the given device hostname.
+ --image <image name>
+ Name of prebuilt image packages to serve.
+ --bucket <bucket name>
+ Name of GCS bucket containing the image archive.
+ --no-serve
+ Only tunnel, do not start a package server.
+
+ HOSTNAME
+ The hostname of the workstation you want to serve from
+ REMOTE-PATH
+ The path to the Fuchsia GN SDK bin directory on "HOSTNAME"
+EOF
+}
+
+START_SERVE=1
+REMOTE_HOST=""
+REMOTE_DIR=""
+DEVICE_NAME="$(get-fuchsia-property device-name)"
+FUCHSIA_SDK_PATH="$(get-fuchsia-sdk-dir)"
+BUCKET="$(get-fuchsia-property bucket)"
+IMAGE="$(get-fuchsia-property image)"
+
+while [[ $# -ne 0 ]]; do
+ case "$1" in
+ --help|-h)
+ usage
+ exit 0
+ ;;
+ --no-serve)
+ START_SERVE=0
+ ;;
+ --device-name)
+ shift
+ DEVICE_NAME="${1}"
+ ;;
+ --bucket)
+ shift
+ BUCKET="${1}"
+ ;;
+ --image)
+ shift
+ IMAGE="${1}"
+ ;;
+ -*)
+ fx-error "Unknown flag: $1"
+ usage
+ exit 1
+ ;;
+ *)
+ if [[ -z "${REMOTE_HOST}" ]]; then
+ REMOTE_HOST="$1"
+ elif [[ -z "${REMOTE_DIR}" ]]; then
+ REMOTE_DIR="$1"
+ else
+ fx-error "unexpected argument: '$1'"
+ usage
+ fi
+ ;;
+ esac
+ shift
+done
+
+if [[ -z "${REMOTE_HOST}" ]]; then
+ fx-error "HOSTNAME must be specified"
+ usage
+ exit 1
+fi
+
+if ((START_SERVE)); then
+ if [[ -z "${REMOTE_DIR}" ]]; then
+ fx-error "REMOTE-DIR must be specified"
+ usage
+ exit 1
+ fi
+fi
+
+if [[ "${DEVICE_NAME}" == "" ]]; then
+ DEVICE_NAME="$(get-device-name)"
+fi
+# Determine the local device name/address to use.
+if ! DEVICE_IP=$(get-device-ip-by-name "$FUCHSIA_SDK_PATH" "${DEVICE_NAME}"); then
+ fx-error "unable to discover device. Is the target up?"
+ exit 1
+fi
+
+if [[ -z "${DEVICE_IP}" ]]; then
+ fx-error "unable to discover device. Is the target up?"
+ exit 1
+fi
+
+echo "Using remote ${REMOTE_HOST}:${REMOTE_DIR}"
+echo "Using target device ${DEVICE_NAME}"
+
+# First we need to check if we already have a control master for the
+# host, if we do, we might already have the forwards and so we don't
+# need to worry about tearing down:
+if ! ssh -O check "${REMOTE_HOST}" > /dev/null 2>&1; then
+ # If we didn't have a control master, and the device already has 8022
+ # bound, then there's a good chance there's a stale sshd instance
+ # running from another device or another session that will block the
+ # forward, so we'll check for that and speculatively attempt to clean
+ # it up. Unfortunately this means authing twice, but it's likely the
+ # best we can do for now.
+ if ssh "${REMOTE_HOST}" 'ss -ln | grep :8022' > /dev/null; then
+ ssh "${REMOTE_HOST}" "pkill -u \$USER sshd"
+ ssh "${REMOTE_HOST}" -O exit > /dev/null 2>&1
+ fi
+fi
+
+args=(
+ -6 # We want ipv6 binds for the port forwards
+ -L "\*:8083:localhost:8083" # requests to the package server address locally go to the workstation
+ -R "8022:[${DEVICE_IP}]:22" # requests from the workstation to ssh to localhost:8022 will make it to the target
+ -o "ExitOnForwardFailure=yes"
+ "${REMOTE_HOST}"
+)
+
+# If the user requested serving, then we'll check to see if there's a
+# server already running and kill it, this prevents most cases where
+# signal propagation seems to sometimes not make it to "pm".
+if ((START_SERVE)) && ssh "${args[@]}" 'ss -ln | grep :8083' > /dev/null; then
+ ssh "${args[@]}" "pkill -u \$USER pm"
+fi
+
+if ((START_SERVE)); then
+ # Starts a package server
+ args+=(cd "${REMOTE_DIR}" "&&" ./bin/fconfig.sh set device-ip 127.0.0.1 "&&" ./bin/fserve.sh)
+ if [[ "${BUCKET}" != "" ]]; then
+ args+=(--bucket "${BUCKET}")
+ fi
+ if [[ "${IMAGE}" ]]; then
+ args+=(--image "${IMAGE}")
+ fi
+else
+ # Starts nothing, just goes to sleep
+ args+=("-nNT")
+fi
+
+ssh "${args[@]}"
diff --git a/third_party/fuchsia-sdk/bin/fserve.sh b/third_party/fuchsia-sdk/bin/fserve.sh
new file mode 100755
index 0000000..f0bacb2
--- /dev/null
+++ b/third_party/fuchsia-sdk/bin/fserve.sh
@@ -0,0 +1,257 @@
+#!/bin/bash
+# Copyright 2020 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.
+
+set -eu
+
+SCRIPT_SRC_DIR="$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)"
+
+# Fuchsia command common functions.
+# shellcheck disable=SC1090
+source "${SCRIPT_SRC_DIR}/fuchsia-common.sh" || exit $?
+
+FUCHSIA_SDK_PATH="$(get-fuchsia-sdk-dir)"
+FUCHSIA_IMAGE_WORK_DIR="$(get-fuchsia-sdk-data-dir)"
+FUCHSIA_BUCKET="$(get-fuchsia-property bucket)"
+if [[ "${FUCHSIA_BUCKET}" == "" ]]; then
+ FUCHSIA_BUCKET="${DEFAULT_FUCHSIA_BUCKET}"
+fi
+
+FUCHSIA_SERVER_PORT="8083"
+
+IMAGE_NAME="$(get-fuchsia-property image)"
+if [[ "${IMAGE_NAME}" == "" ]]; then
+ IMAGE_NAME="generic-x64"
+fi
+
+usage () {
+ echo "Usage: $0"
+ echo " [--work-dir <directory to store image assets>]"
+ echo " Defaults to ${FUCHSIA_IMAGE_WORK_DIR}"
+ echo " [--bucket <fuchsia gsutil bucket>]"
+ echo " Defaults to ${FUCHSIA_BUCKET}"
+ echo " [--image <image name>]"
+ echo " Defaults to ${IMAGE_NAME}. Use --image list to list all available images."
+ echo " [--private-key <identity file>]"
+ echo " Uses additional private key when using ssh to access the device."
+ echo " [--server-port <port>]"
+ echo " Port number to use when serving the packages. Defaults to ${FUCHSIA_SERVER_PORT}."
+ echo " [--device-name <device hostname>]"
+ echo " Only serves packages to a device with the given device hostname. Cannot be used with --device-ip."
+ echo " [--device-ip <device ip>]"
+ echo " Only serves packages to a device with the given device ip address. Cannot be used with --device-name."
+ echo " [--kill]"
+ echo " Kills any existing package manager server"
+ echo " [--prepare]"
+ echo " Downloads any dependencies but does not start the package server"
+ echo " [-x] Enable debug."
+}
+
+PRIVATE_KEY_FILE=""
+PREPARE_ONLY=""
+DEVICE_NAME_FILTER="$(get-fuchsia-property device-name)"
+DEVICE_IP_ADDR="$(get-fuchsia-property device-ip)"
+
+# Parse command line
+while (( "$#" )); do
+case $1 in
+ --work-dir)
+ shift
+ FUCHSIA_IMAGE_WORK_DIR="${1:-.}"
+ ;;
+ --bucket)
+ shift
+ FUCHSIA_BUCKET="${1}"
+ ;;
+ --image)
+ shift
+ IMAGE_NAME="${1}"
+ ;;
+ --private-key)
+ shift
+ PRIVATE_KEY_FILE="${1}"
+ ;;
+ --server-port)
+ shift
+ FUCHSIA_SERVER_PORT="${1}"
+ ;;
+ --device-name)
+ shift
+ DEVICE_NAME_FILTER="${1}"
+ ;;
+ --device-ip)
+ shift
+ DEVICE_IP_ADDR="${1}"
+ ;;
+ --kill)
+ kill-running-pm
+ exit 0
+ ;;
+ --prepare)
+ PREPARE_ONLY="yes"
+ ;;
+ -x)
+ set -x
+ ;;
+ *)
+ # unknown option
+ usage
+ exit 1
+ ;;
+esac
+shift
+done
+
+if [[ "${DEVICE_IP_ADDR}" != "" && "${DEVICE_NAME_FILTER}" != "" ]]; then
+ fx-error "Cannot use both --device-name and --device-ip".
+ exit 1
+fi
+
+if ! SDK_ID="$(get-sdk-version)"; then
+ fx-error "Could not get SDK version"
+ exit 1
+fi
+
+if [[ "${IMAGE_NAME}" == "list" ]]; then
+ if ! IMAGES="$(get-available-images "${SDK_ID}" "${FUCHSIA_BUCKET}")"; then
+ fx-error "Could not get list of available images for ${SDK_ID}"
+ exit 1
+ fi
+ echo "Valid images for this SDK version are: ${IMAGES}."
+ exit 1
+fi
+
+# The package tarball. We add the SDK ID to the filename to make them
+# unique.
+#
+# Consider cleaning up old tarballs when getting a new one?
+#
+
+FUCHSIA_TARGET_PACKAGES=$(get-package-src-path "${SDK_ID}" "${IMAGE_NAME}")
+# The package tarball, we add the SDK ID to make it unique, and note the
+# .tar.gz extension for packages vs .tgz extension for images.
+IMAGE_FILENAME="${SDK_ID}_${IMAGE_NAME}.tar.gz"
+
+# Validate the image is found
+if [[ ! -f "${FUCHSIA_IMAGE_WORK_DIR}/${IMAGE_FILENAME}" ]] ; then
+ if ! run-gsutil ls "${FUCHSIA_TARGET_PACKAGES}" >/dev/null 2>&1; then
+ echo "Packages for ${IMAGE_NAME} not found. Valid images for this SDK version are:"
+ if ! IMAGES="$(get-available-images "${SDK_ID}" "${FUCHSIA_BUCKET}")"; then
+ fx-error "Could not get list of available images for ${SDK_ID}"
+ exit 1
+ fi
+ echo "${IMAGES}"
+ exit 2
+ fi
+
+ if ! run-gsutil cp "${FUCHSIA_TARGET_PACKAGES}" "${FUCHSIA_IMAGE_WORK_DIR}/${IMAGE_FILENAME}"; then
+ fx-error "Could not copy image from ${FUCHSIA_TARGET_PACKAGES} to ${FUCHSIA_IMAGE_WORK_DIR}/${IMAGE_FILENAME}."
+ exit 2
+ fi
+else
+ echo "Skipping download, packages tarball exists"
+fi
+
+# The checksum file contains the output from `md5`. This is used to detect content
+# changes in the packages file.
+CHECKSUM_FILE="${FUCHSIA_IMAGE_WORK_DIR}/packages/packages.md5"
+
+# check that any existing contents of the image directory match the intended target device
+if [[ -f "${CHECKSUM_FILE}" ]]; then
+ if [[ "$(run-md5 "${FUCHSIA_IMAGE_WORK_DIR}/${IMAGE_FILENAME}")" != "$(cat "${CHECKSUM_FILE}")" ]]; then
+ fx-warn "Removing old package files."
+ if ! rm -f "$(cut -d ' ' -f3 "${CHECKSUM_FILE}")"; then
+ fx-error "Could not clean up old image archive."
+ exit 2
+ fi
+ if ! rm -rf "${FUCHSIA_IMAGE_WORK_DIR}/packages"; then
+ fx-error "Could not clean up old image."
+ exit 2
+ fi
+ fi
+else
+ # if the checksum file does not exist, something is inconsistent.
+ # so delete the entire directory to make sure we're starting clean.
+ # This also happens on a clean run, where the packages directory does not
+ # exist.
+ if ! rm -rf "${FUCHSIA_IMAGE_WORK_DIR}/packages"; then
+ fx-error "Could not clean up old packages."
+ exit 2
+ fi
+fi
+
+if ! mkdir -p "${FUCHSIA_IMAGE_WORK_DIR}/packages"; then
+ fx-error "Could not create packages directory."
+ exit 2
+fi
+
+# if the tarball is not untarred, do it.
+if [[ ! -d "${FUCHSIA_IMAGE_WORK_DIR}/packages/amber-files" ]]; then
+ if ! tar xzf "${FUCHSIA_IMAGE_WORK_DIR}/${IMAGE_FILENAME}" --directory "${FUCHSIA_IMAGE_WORK_DIR}/packages"; then
+ fx-error "Could not extract image from ${FUCHSIA_IMAGE_WORK_DIR}/${IMAGE_FILENAME}."
+ exit 1
+ fi
+ run-md5 "${FUCHSIA_IMAGE_WORK_DIR}/${IMAGE_FILENAME}" > "${CHECKSUM_FILE}"
+fi
+
+# Exit out if we only need to prepare the downloads
+if [[ "${PREPARE_ONLY}" == "yes" ]]; then
+ exit 0
+fi
+
+if [[ "${DEVICE_IP_ADDR}" != "" ]]; then
+ DEVICE_IP="${DEVICE_IP_ADDR}"
+else
+ DEVICE_IP=$(get-device-ip-by-name "$FUCHSIA_SDK_PATH" "$DEVICE_NAME_FILTER")
+fi
+
+if [[ ! "$?" || -z "$DEVICE_IP" ]]; then
+ fx-error "Could not get device IP address"
+ exit 2
+fi
+
+# get the host address as seen by the device.
+ssh_args=("${DEVICE_IP}" echo "\$SSH_CONNECTION")
+if ! connection_str="$(ssh-cmd "${ssh_args[@]}")"; then
+ fx-error "unable to determine host address as seen from the target. Is the target up?"
+ exit 1
+fi
+HOST_IP="$(echo "$connection_str" | cut -d ' ' -f 1)"
+
+if [[ ! "$?" || -z "$HOST_IP" ]]; then
+ fx-error "Could not get Host IP address"
+ exit 2
+fi
+
+# A simple heuristic for "is an ipv6 address", URL encase escape
+# the address.
+if [[ "${HOST_IP}" =~ : ]]; then
+ HOST_IP="${HOST_IP//%/%25}"
+ HOST_IP="[${HOST_IP}]"
+fi
+
+# kill existing pm if present
+kill-running-pm
+
+# Start the package server
+echo "** Starting package server in the background**"
+# `:port` syntax is valid for Go programs that intend to serve on every
+# interface on a given port. For example, if $FUCHSIA_SERVER_PORT is 54321,
+# this is similar to serving on [::]:54321 or 0.0.0.0:54321.
+"${FUCHSIA_SDK_PATH}/tools/pm" serve -repo "${FUCHSIA_IMAGE_WORK_DIR}/packages/amber-files" -l ":${FUCHSIA_SERVER_PORT}"&
+
+SSH_ARGS=()
+if [[ "${PRIVATE_KEY_FILE}" != "" ]]; then
+ SSH_ARGS+=( "-i" "${PRIVATE_KEY_FILE}")
+fi
+SSH_ARGS+=( "${DEVICE_IP}" amber_ctl add_src -f "http://${HOST_IP}:${FUCHSIA_SERVER_PORT}/config.json" )
+
+# Update the device to point to the server.
+# Because the URL to config.json contains an IPv6 address, the address needs
+# to be escaped in square brackets. This is not necessary for the ssh target,
+# since that's just an address and not a full URL.
+if ! ssh-cmd "${SSH_ARGS[@]}" ; then
+ fx-error "Error: could not update device"
+ exit 1
+fi
diff --git a/third_party/fuchsia-sdk/bin/fssh-meta.json b/third_party/fuchsia-sdk/bin/fssh-meta.json
new file mode 100644
index 0000000..89eb29b
--- /dev/null
+++ b/third_party/fuchsia-sdk/bin/fssh-meta.json
@@ -0,0 +1,10 @@
+{
+ "files": [
+ "bin/fssh.sh",
+ "bin/fuchsia-common.sh"
+ ],
+ "name": "fssh",
+ "root": "bin",
+ "target_files": {},
+ "type": "host_tool"
+}
diff --git a/third_party/fuchsia-sdk/bin/fssh.sh b/third_party/fuchsia-sdk/bin/fssh.sh
new file mode 100755
index 0000000..27020c6
--- /dev/null
+++ b/third_party/fuchsia-sdk/bin/fssh.sh
@@ -0,0 +1,98 @@
+#!/bin/bash
+# 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.
+#
+# Command to SSH to a Fuchsia device.
+set -eu
+
+# Source common functions
+readonly MY_SCRIPT_SRC_DIR="$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)"
+
+# Fuchsia command common functions.
+# shellcheck disable=SC1090
+source "${MY_SCRIPT_SRC_DIR}/fuchsia-common.sh" || exit $?
+
+readonly FUCHSIA_SDK_PATH="$(get-fuchsia-sdk-dir)"
+
+function usage {
+ echo "Usage: $0"
+ echo " [--device-name <device hostname>]"
+ echo " Connects to a device by looking up the given device hostname."
+ echo " [--device-ip <device ipaddr>]"
+ echo " Connects to a device by using the provided IP address, cannot use with --device-name"
+ echo " [--private-key <identity file>]"
+ echo " Uses additional private key when using ssh to access the device."
+}
+
+PRIVATE_KEY_FILE=""
+DEVICE_NAME_FILTER="$(get-fuchsia-property device-name)"
+DEVICE_IP="$(get-fuchsia-property device-ip)"
+POSITIONAL=()
+
+
+# Parse command line
+while (( "$#" )); do
+case $1 in
+ --device-name)
+ shift
+ DEVICE_NAME_FILTER="${1}"
+ ;;
+ --device-ip)
+ shift
+ DEVICE_IP="${1}"
+ ;;
+ --private-key)
+ shift
+ PRIVATE_KEY_FILE="${1}"
+ ;;
+ -*)
+ if [[ "${#POSITIONAL[@]}" -eq 0 ]]; then
+ echo "Unknown option ${1}"
+ usage
+ exit 1
+ else
+ POSITIONAL+=("${1}")
+ fi
+ ;;
+ *)
+ POSITIONAL+=("${1}")
+ ;;
+esac
+shift
+done
+
+readonly PRIVATE_KEY_FILE
+readonly DEVICE_NAME_FILTER
+readonly DEVICE_IP
+readonly POSITIONAL
+
+target_device_ip="${DEVICE_IP}"
+
+# Get the device IP address.
+if [[ "${DEVICE_IP}" == "" ]]; then
+ # explicitly pass the sdk dir here.
+ target_device_ip=$(get-device-ip-by-name "$FUCHSIA_SDK_PATH" "$DEVICE_NAME_FILTER")
+ if [[ ! "$?" || -z "$target_device_ip" ]]; then
+ fx-error "Error finding device"
+ exit 2
+ fi
+else
+ if [[ "${DEVICE_NAME_FILTER}" != "" ]]; then
+ fx-error "Cannot specify both --device-name and --device-ip"
+ exit 3
+ fi
+fi
+
+ssh_args=()
+# Build the command line
+if [[ "${PRIVATE_KEY_FILE}" != "" ]]; then
+ ssh_args+=( "-i" "${PRIVATE_KEY_FILE}")
+fi
+
+ssh_args+=( "${target_device_ip}" )
+if [[ "${#POSITIONAL[@]}" -ne 0 ]]; then
+ ssh_args+=( "${POSITIONAL[@]}" )
+fi
+
+ssh-cmd "${ssh_args[@]}"
diff --git a/third_party/fuchsia-sdk/bin/fuchsia-common.sh b/third_party/fuchsia-sdk/bin/fuchsia-common.sh
new file mode 100755
index 0000000..275ddc5
--- /dev/null
+++ b/third_party/fuchsia-sdk/bin/fuchsia-common.sh
@@ -0,0 +1,401 @@
+#!/bin/bash
+# Copyright 2020 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.
+#
+# Helper functions, no environment specific functions should be included below
+# this line.
+
+# Force all pipes to return any non-zero error code instead of just the last
+set -e -o pipefail
+
+SCRIPT_SRC_DIR="$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)"
+
+
+DEFAULT_FUCHSIA_BUCKET="fuchsia"
+SSH_BIN="$(command -v ssh)"
+FUCHSIA_PROPERTY_NAMES=(
+ "bucket" # Used as the default for --bucket
+ "device-ip" # Used as the default for --device-ip
+ "device-name" # Used as the default for --device-name
+ "image" # Used as the default for image
+)
+
+function is-mac {
+ [[ "$(uname -s)" == "Darwin" ]] && return 0
+ return 1
+}
+
+# Add Mac specific support
+if is-mac; then
+ # Fuchsia mac functions.
+
+ realpath() {
+ [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
+ }
+fi
+# Returns the fuchsia sdk root dir. Assuming this script is in ${FUCHSIA_SDK}/bin.
+function get-fuchsia-sdk-dir {
+ dirname "${SCRIPT_SRC_DIR}"
+}
+
+# Returns the data directory for the fuchsia sdk.
+# This directory is expected to be per-developer, not checked into source code revision systems,
+# and is used to store device images and packages and related data items.
+# The default is $HOME/.fuchsia. This can be overridden by setting the environment variable
+# FUCHSIA_SDK_DATA_DIR.
+function get-fuchsia-sdk-data-dir {
+ local data_dir="${FUCHSIA_SDK_DATA_DIR:-}"
+ if [[ -z "${data_dir}" ]]; then
+ data_dir="${HOME}/.fuchsia"
+ if [[ ! -d "${data_dir}" ]]; then
+ mkdir -p "${data_dir}"
+ fi
+ fi
+ echo "${data_dir}"
+}
+
+# fx-warn prints a line to stderr with a yellow WARNING: prefix.
+function fx-warn {
+ if [[ -t 2 ]]; then
+ echo -e >&2 "\033[1;33mWARNING:\033[0m $*"
+ else
+ echo -e >&2 "WARNING: $*"
+ fi
+}
+
+# fx-error prints a line to stderr with a red ERROR: prefix.
+function fx-error {
+ if [[ -t 2 ]]; then
+ echo -e >&2 "\033[1;31mERROR:\033[0m $*"
+ else
+ echo -e >&2 "ERROR: $*"
+ fi
+}
+
+function get-fuchsia-property-names {
+ echo "${FUCHSIA_PROPERTY_NAMES[@]}"
+}
+
+function is-valid-fuchsia-property {
+ [[ "${FUCHSIA_PROPERTY_NAMES[*]}" =~ $1 ]]
+}
+
+function set-fuchsia-property {
+ local prop_path
+ prop_path="$(get-fuchsia-sdk-data-dir)/.properties/$1.txt"
+ if ! mkdir -p "$(dirname "${prop_path}")"; then
+ fx-error "Cannot write property to $prop_path"
+ exit 1
+ fi
+ echo "$2" > "${prop_path}"
+}
+
+function get-fuchsia-property {
+ local prop_path
+ prop_path="$(get-fuchsia-sdk-data-dir)/.properties/$1.txt"
+ if [[ -e "${prop_path}" ]]; then
+ cat "${prop_path}"
+ else
+ echo ""
+ fi
+}
+
+function ssh-cmd {
+ check-fuchsia-ssh-config
+ "${SSH_BIN}" -F "$(get-fuchsia-sshconfig-file)" "$@"
+}
+
+function get-device-ip {
+ # $1 is the SDK_PATH (optional. defaults to get-fuchsia-sdk-dir)
+ # -ipv4 false: Disable IPv4. Fuchsia devices are IPv6-compatible, so
+ # forcing IPv6 allows for easier manipulation of the result.
+ local device_addr
+ device_addr="$(get-fuchsia-property device-addr)"
+ if [[ "${device_addr}" != "" ]]; then
+ echo "${device_addr}"
+ return 0
+ else
+ "${1-$(get-fuchsia-sdk-dir)}/tools/device-finder" list -netboot -device-limit 1 -ipv4=false
+ fi
+}
+
+function get-device-name {
+ # $1 is the SDK_PATH (optional. defaults to get-fuchsia-sdk-dir)
+ # Check for a device name being configured.
+ local device_name
+ if ! device_name="$(get-fuchsia-property device-name)"; then
+ return $?
+ fi
+ if [[ "${device_name}" != "" ]]; then
+ echo "${device_name}"
+ return 0
+ else
+ if device_name="$("${1-$(get-fuchsia-sdk-dir)}/tools/device-finder" list -netboot -device-limit 1 -full)"; then
+ echo "${device_name}" | cut -d' ' -f2
+ fi
+ fi
+}
+
+function get-device-ip-by-name {
+ # Writes the IP address of the device with the given name.
+ # If no such device is found, this function returns with a non-zero status
+ # code.
+
+ # $1 is the SDK_PATH, if specified else get-fuchsia-sdk-dir value is used.
+ # $2 is the hostname of the Fuchsia device. If $2 is empty, this function
+ # returns the IP address of an arbitrarily selected Fuchsia device.
+
+ if [[ "${#}" -ge 2 && -n "$2" ]]; then
+ # There should typically only be one device that matches the nodename
+ # but we add a device-limit to speed up resolution by exiting when the first
+ # candidate is found.
+ "${1-$(get-fuchsia-sdk-dir)}/tools/device-finder" resolve -device-limit 1 -ipv4=false -netboot "${2}"
+ else
+ if [[ "${#}" -ge 1 && -n "$1" ]]; then
+ get-device-ip "$1"
+ else
+ get-device-ip
+ fi
+ fi
+}
+
+function get-host-ip {
+ # $1 is the SDK_PATH, if specified else get-fuchsia-sdk-dir value is used.
+ # $2 is the hostname of the Fuchsia device. If $2 is empty, this function
+ # returns the IP address of an arbitrarily selected Fuchsia device.
+ local DEVICE_NAME
+ if [[ "${#}" -ge 2 && "${2}" != "" ]]; then
+ DEVICE_NAME="${2}"
+ else
+ DEVICE_NAME="$(get-device-name "${1-$(get-fuchsia-sdk-dir)}")"
+ fi
+ # -ipv4 false: Disable IPv4. Fuchsia devices are IPv6-compatible, so
+ # forcing IPv6 allows for easier manipulation of the result.
+ # cut: Remove the IPv6 scope, if present. For link-local addresses, the scope
+ # effectively describes which interface a device is connected on. Since
+ # this information is device-specific (i.e. the Fuchsia device refers to
+ # the development host with a different scope than vice versa), we can
+ # strip this from the IPv6 result. This is reliable as long as the Fuchsia
+ # device only needs link-local networking on one interface.
+ "${1-$(get-fuchsia-sdk-dir)}/tools/device-finder" resolve -local -ipv4=false "${DEVICE_NAME}" | head -1 | cut -d '%' -f1
+}
+
+function get-sdk-version {
+ # Get the Fuchsia SDK id
+ # $1 is the SDK_PATH, if specified else get-fuchsia-sdk-dir value is used.
+ local FUCHSIA_SDK_METADATA="${1-$(get-fuchsia-sdk-dir)}/meta/manifest.json"
+ if ! SDK_VERSION="$(grep \"id\": "${FUCHSIA_SDK_METADATA}" | cut -d\" -f4)"; then
+ return 1
+ fi
+ echo "${SDK_VERSION}"
+}
+
+function get-package-src-path {
+ # $1 is the SDK ID. See #get-sdk-version.
+ # $2 is the image name.
+ echo "gs://${FUCHSIA_BUCKET}/development/${1}/packages/${2}.tar.gz"
+}
+
+function get-image-src-path {
+ # $1 is the SDK ID. See #get-sdk-version.
+ # $2 is the image name.
+ echo "gs://${FUCHSIA_BUCKET}/development/${1}/images/${2}.tgz"
+}
+
+# Run gsutil from the directory of this script if it exists, otherwise
+# use the path.
+function run-gsutil {
+ GSUTIL_BIN="${SCRIPT_SRC_DIR}/gsutil"
+ if [[ ! -e "${GSUTIL_BIN}" ]]; then
+ GSUTIL_BIN="$(command -v gsutil)"
+ fi
+ if [[ ! -e "${GSUTIL_BIN}" ]]; then
+ GSUTIL_BIN="$(command -v gsutil.py)"
+ fi
+
+ if [[ "${GSUTIL_BIN}" == "" ]]; then
+ fx-error "Cannot find gsutil."
+ exit 2
+ fi
+
+ # Prevent gsutil prompting for updates by making stdin not a TTY
+ "${GSUTIL_BIN}" "$@" < /dev/null
+}
+
+# Run cipd from the directory of this script if it exists, otherwise
+# use the path.
+function run-cipd {
+ CIPD_BIN="${SCRIPT_SRC_DIR}/cipd"
+ if [[ ! -e "${CIPD_BIN}" ]]; then
+ CIPD_BIN="$(command -v cipd)"
+ fi
+
+ if [[ "${CIPD_BIN}" == "" ]]; then
+ fx-error "Cannot find cipd."
+ exit 2
+ fi
+ "${CIPD_BIN}" "$@"
+}
+
+# Runs md5sum or equivalent on mac.
+function run-md5 {
+ if is-mac; then
+ MD5_CMD=("/sbin/md5" "-r")
+ else
+ MD5_CMD=("md5sum")
+ fi
+
+ MD5_CMD+=("$@")
+
+ "${MD5_CMD[@]}"
+}
+
+function get-available-images {
+ # $1 is the SDK ID.
+ # $2 is the bucket, or uses the default.
+ local IMAGES=()
+ local BUCKET=""
+
+ BUCKET="${2:-${DEFAULT_FUCHSIA_BUCKET}}"
+ GSURL="gs://${BUCKET}/development/${1}/images"
+ if ! RESULTS=$(run-gsutil "ls" "${GSURL}" | cut -d/ -f7 | tr '\n' ' '); then
+ return 1
+ fi
+ if [[ "${RESULTS}" == "" ]]; then
+ return 2
+ fi
+ for f in ${RESULTS}; do
+ IMAGES+=("${f%.*}")
+ done
+ if [[ "${BUCKET}" != "${DEFAULT_FUCHSIA_BUCKET}" ]]; then
+ echo -n "${IMAGES[*]} "
+ get-available-images "${1}" "${DEFAULT_FUCHSIA_BUCKET}"
+ else
+ echo "${IMAGES[*]}"
+ fi
+}
+
+function kill-running-pm {
+ local PM_PROCESS=()
+ IFS=" " read -r -a PM_PROCESS <<< "$(pgrep -ax pm)"
+ if [[ ${#PM_PROCESS[@]} -gt 0 && -n "${PM_PROCESS[*]}" ]]; then
+ # mac only provides the pid, not the name
+ if is-mac; then
+ fx-warn "Killing existing pm process"
+ kill "${PM_PROCESS[0]}"
+ return $?
+ elif [[ ${#PM_PROCESS[@]} -gt 1 && "${PM_PROCESS[1]}" == *"tools/pm" ]]; then
+ fx-warn "Killing existing pm process"
+ kill "${PM_PROCESS[0]}"
+ return $?
+ fi
+ else
+ fx-warn "existing pm process not found"
+ fi
+ return 0
+}
+
+function check-fuchsia-ssh-config {
+ # This function creates the ssh keys needed to
+ # work with devices running Fuchsia. There are two parts, the keys and the config.
+ #
+ # The keys are stored in the Fuchsia SDK data directory in a directory named .ssh.
+ # This is the same structure as used "in-tree" for Fuchsia development. You can copy the
+ # keys from the other directory to make the keys identical, allowing SSH access using both
+ # SDK commands and in-tree "fx" commands.
+ #
+ # The authorized key file used for paving is in .ssh/authorized_keys.
+ # The private key used when ssh'ing to the device is in .ssh/pkey.
+ #
+ #
+ # The second part of is the sshconfig file used by the SDK when using SSH.
+ # This is stored in the Fuchsia SDK data directory named sshconfig.
+ # This script checks for the private key file being referenced in the sshconfig and
+ # the matching version tag. If they are not present, the sshconfig file is regenerated.
+ # The ssh configuration should not be modified.
+ local SSHCONFIG_TAG="Fuchsia SDK config version 2 tag"
+
+ local ssh_dir
+ ssh_dir="$(get-fuchsia-sdk-data-dir)/.ssh"
+ local authfile="${ssh_dir}/authorized_keys"
+ local keyfile="${ssh_dir}/pkey"
+ local sshconfig_file
+ sshconfig_file="$(get-fuchsia-sdk-data-dir)/sshconfig"
+
+ if [[ -e "${authfile}" && -e "${keyfile}" ]]; then
+ if grep "${keyfile}" "${sshconfig_file}" > /dev/null 2>&1; then
+ if grep "${SSHCONFIG_TAG}" "${sshconfig_file}" > /dev/null 2>&1; then
+ return 0
+ fi
+ fi
+ fi
+
+ mkdir -p "${ssh_dir}"
+ if [[ ! -f "${authfile}" ]]; then
+ if [[ ! -f "${keyfile}" ]]; then
+ if ! result="$(ssh-keygen -P "" -t ed25519 -f "${keyfile}" -C "${USER}@$(hostname -f)" 2>&1)"; then
+ fx-error "${result}"
+ return 1
+ fi
+ fi
+ if ! result="$(ssh-keygen -y -f "${keyfile}" > "${authfile}" 2>&1)"; then
+ fx-error "${result}"
+ return 1
+ fi
+ fi
+
+ cat >"${sshconfig_file}" <<EOF
+# ${SSHCONFIG_TAG}
+# Configure port 8022 for connecting to a device with the local address.
+# This makes it possible to forward 8022 to a device connected remotely.
+Host 127.0.0.1
+ Port 8022
+
+Host ::1
+ Port 8022
+
+Host *
+# Turn off refusing to connect to hosts whose key has changed
+StrictHostKeyChecking no
+CheckHostIP no
+
+# Disable recording the known hosts
+UserKnownHostsFile=/dev/null
+
+# Do not forward auth agent connection to remote, no X11
+ForwardAgent no
+ForwardX11 no
+
+# Connection timeout in seconds
+ConnectTimeout=10
+
+# Check for server alive in seconds, max count before disconnecting
+ServerAliveInterval 1
+ServerAliveCountMax 10
+
+# Try to keep the master connection open to speed reconnecting.
+ControlMaster auto
+ControlPersist yes
+ControlPath=/tmp/fuchsia--%r@%h:%p
+
+# Connect with user, use the identity specified.
+User fuchsia
+IdentitiesOnly yes
+IdentityFile "${keyfile}"
+GSSAPIDelegateCredentials no
+
+EOF
+
+ return 0
+}
+
+function get-fuchsia-auth-keys-file {
+ check-fuchsia-ssh-config
+ echo "$(get-fuchsia-sdk-data-dir)/.ssh/authorized_keys"
+}
+
+function get-fuchsia-sshconfig-file {
+ check-fuchsia-ssh-config
+ echo "$(get-fuchsia-sdk-data-dir)/sshconfig"
+}
diff --git a/third_party/fuchsia-sdk/bin/fx-image-common.sh b/third_party/fuchsia-sdk/bin/fx-image-common.sh
new file mode 100755
index 0000000..238670d
--- /dev/null
+++ b/third_party/fuchsia-sdk/bin/fx-image-common.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+# 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.
+
+# Requires FUCHSIA_IMAGE_WORK_DIR and FUCHSIA_SDK_PATH to be defined
+
+# fx commands require environment variables to be defined
+if [[ "${FUCHSIA_IMAGE_WORK_DIR}" == "" ]]; then
+ fx-error "FUCHSIA_IMAGE_WORK_DIR must be defined before sourcing this script"
+ exit 1
+fi
+if [[ "${FUCHSIA_SDK_PATH}" == "" ]]; then
+ fx-error "FUCHSIA_SDK_PATH must be defined before sourcing this script"
+ exit 1
+fi
+
+# Variables expected by fx emu
+ZIRCON_TOOLS_DIR="${FUCHSIA_SDK_PATH}/tools"
+# shellcheck disable=SC2034
+FUCHSIA_DIR="${FUCHSIA_SDK_PATH}/bin"
+# shellcheck disable=SC2034
+HOST_OUT_DIR="${FUCHSIA_SDK_PATH}/tools"
+# shellcheck disable=SC2034
+IMAGE_ZIRCONA_ZBI="zircon-a.zbi"
+# shellcheck disable=SC2034
+IMAGE_QEMU_KERNEL_RAW="qemu-kernel.kernel"
+# shellcheck disable=SC2034
+IMAGE_FVM_RAW="storage-full.blk"
+# TODO(fxb/43807): Replace FUCHSIA_ARCH with detecting the architecture, currently only tested with *-x64 images
+# shellcheck disable=SC2034
+FUCHSIA_ARCH="x64"
+
+# Provide fx-zbi functionality using the SDK zbi tool
+function fx-zbi {
+ "${ZIRCON_TOOLS_DIR}/zbi" "$@"
+}
diff --git a/third_party/fuchsia-sdk/bin/grpcwebproxy.version b/third_party/fuchsia-sdk/bin/grpcwebproxy.version
new file mode 100644
index 0000000..630d806
--- /dev/null
+++ b/third_party/fuchsia-sdk/bin/grpcwebproxy.version
@@ -0,0 +1 @@
+git_revision:c71ae8fa744867b49f83d4c128a8facb96c9c848
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/build/cmc.gni b/third_party/fuchsia-sdk/build/cmc.gni
new file mode 100644
index 0000000..c5cc735
--- /dev/null
+++ b/third_party/fuchsia-sdk/build/cmc.gni
@@ -0,0 +1,66 @@
+# Copyright 2020 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.
+
+import("config/config.gni")
+
+# Compiles a Components Framework v2 manifest (.cml) file to .cm
+#
+# The compiled manifest will be pretty-printed if is_debug is true.
+#
+# Parameters
+#
+# manifest
+# Required: The input Component Framework v2 manifest source (.cml) file.
+# The file must have the extension ".cml".
+#
+# output_name:
+# Optional: Name of the output file to generate. Defaults to $target_name.
+# This should not include a file extension (.cm)
+#
+# deps
+# public_deps
+# testonly
+# visibility
+# Optional: Standard GN meaning.
+template("cmc_compile") {
+ output_name = target_name
+ if (defined(invoker.output_name)) {
+ output_name = invoker.output_name
+ }
+
+ action(target_name) {
+ forward_variables_from(invoker,
+ [
+ "deps",
+ "manifest",
+ "public_deps",
+ "testonly",
+ "visibility",
+ ])
+ assert(defined(manifest), "manifest file required")
+
+ script = "${fuchsia_sdk}/build/gn_run_binary.py"
+
+ inputs = [
+ # Depend on the SDK hash, to ensure rebuild if the SDK tools change.
+ fuchsia_sdk_manifest_file,
+ manifest,
+ ]
+
+ output_file = "$target_out_dir/$output_name.cm"
+ outputs = [ output_file ]
+
+ args = [
+ rebase_path("${fuchsia_sdk}/tools/cmc", root_build_dir),
+ "compile",
+ "--output",
+ rebase_path(output_file, root_build_dir),
+ rebase_path(manifest, root_build_dir),
+ ]
+
+ if (is_debug) {
+ args += [ "--pretty" ]
+ }
+ }
+}
diff --git a/third_party/fuchsia-sdk/build/component.gni b/third_party/fuchsia-sdk/build/component.gni
new file mode 100644
index 0000000..30ccf33
--- /dev/null
+++ b/third_party/fuchsia-sdk/build/component.gni
@@ -0,0 +1,157 @@
+# 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.
+
+import("cmc.gni")
+
+# Define a Fuchsia component() target.
+#
+# The target generates a json file defining the component contents. This
+# component is used to assemble components into distributions, such as packages.
+#
+# Parameters
+#
+# deps
+# Optional: Dependencies for this component. These dependencies are external
+# to the component, such as other components that are used via FIDL.
+#
+# data_deps
+# Required: Dependencies examined for metadata. These dependencies define
+# the contents of the component. These are executables and libraries.
+#
+# manifest
+# Required: The source manifest file for this component. This can be
+# either a v1 (.cmx) or v2 (.cml) manifest. v2 manifests must have
+# the file extension ".cml".
+#
+# manifest_output_name
+# Optional: The name of the manifest file contained in the distribution
+# that this component is included in.
+#
+# By default, for v1 (.cmx) manifests, the output name is the same as
+# `manifest` with the extension ".cmx", and for v2 (.cml) manifests,
+# with the extension ".cm".
+#
+# The output name should have no extension or prefixes. The resulting
+# filename will have an extension that is determined by `manifest_version`.
+#
+# For example, if `manifest` is "foo.cmx" and `manifest_output_name` is
+# "bar", the filename will be "bar.cmx". If `manifest` is "foo.cml"
+# (a v2 manifest), the filename will be "bar.cm".
+#
+# manifest_version
+# Optional: The version of the source `manifest` file. This can be either
+# "v1" for .cmx manifests, or "v2" for .cml manifests.
+#
+# By default, the version is guessed from the `manifest` file extension.
+#
+# resources
+# Optional: Non-executable resources to include in the component.
+#
+template("fuchsia_component") {
+ forward_variables_from(invoker,
+ [
+ "manifest",
+ "manifest_output_name",
+ "manifest_version",
+ ])
+ assert(defined(manifest), "manifest file required for this component")
+
+ if (!defined(manifest_output_name)) {
+ manifest_output_name = get_path_info(manifest, "name")
+ }
+
+ # Guess `manifest_version` from the `manifest` file extension.
+ if (!defined(manifest_version)) {
+ manifest_extension = get_path_info(manifest, "extension")
+ if (manifest_extension == "cmx") {
+ manifest_version = "v1"
+ } else if (manifest_extension == "cml") {
+ manifest_version = "v2"
+ }
+ }
+
+ assert(
+ defined(manifest_version),
+ "manifest_version required and could not be determined from manifest file extension")
+ assert(manifest_version == "v1" || manifest_version == "v2",
+ "manifest_version must be one of: \"v1\", \"v2\"")
+
+ if (manifest_version == "v1") {
+ manifest_source = rebase_path(manifest)
+ } else if (manifest_version == "v2") {
+ compiled_manifest =
+ "compiled_" + target_name + "_" + get_path_info(manifest, "file")
+
+ cmc_compile(compiled_manifest) {
+ manifest = rebase_path(manifest)
+ }
+
+ compiled_manifest_outputs = get_target_outputs(":$compiled_manifest")
+ manifest_source = rebase_path(compiled_manifest_outputs[0])
+ }
+
+ group(target_name) {
+ forward_variables_from(invoker,
+ [
+ "deps",
+ "data_deps",
+ "friend",
+ "resources",
+ "testonly",
+ "visibility",
+ ])
+ assert(defined(data_deps),
+ "data_deps required to define contents of this component")
+
+ if (!defined(resources)) {
+ resources = []
+ }
+
+ if (!defined(deps)) {
+ deps = []
+ }
+
+ if (manifest_version == "v2") {
+ deps += [ ":$compiled_manifest" ]
+ }
+
+ component_contents = []
+
+ foreach(dep, data_deps) {
+ component_contents += [
+ {
+ type = "dep"
+ source = rebase_path(dep)
+ },
+ ]
+ }
+
+ foreach(resource, resources) {
+ component_contents += [
+ {
+ type = "resource"
+ source = rebase_path(resource.path)
+ },
+ ]
+ }
+
+ # TODO(fxb/42370): add cmx validation
+
+ component_contents += [
+ {
+ type = "manifest"
+ source = manifest_source
+ output_name = manifest_output_name
+ manifest_version = manifest_version
+ },
+ ]
+
+ # The contents of the component are enumerated in the
+ # metadata. The metadata is processed by the package
+ # template, or the distribution rule.
+ metadata = {
+ contents = [ component_contents ]
+ }
+ }
+}
diff --git a/third_party/fuchsia-sdk/build/config/BUILD.gn b/third_party/fuchsia-sdk/build/config/BUILD.gn
new file mode 100644
index 0000000..da51a33
--- /dev/null
+++ b/third_party/fuchsia-sdk/build/config/BUILD.gn
@@ -0,0 +1,84 @@
+# 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.
+
+import("config.gni")
+
+config("compiler") {
+ sdk_version = "${fuchsia_sdk_id}"
+ defines = [
+ # To force full builds after SDK updates in case of ABI changes.
+ "FUCHSIA_SDK_VERSION=$sdk_version",
+ ]
+ cflags = []
+ ldflags = []
+ if (current_cpu == "arm64") {
+ cflags += [ "--target=aarch64-fuchsia" ]
+ } else if (current_cpu == "x64") {
+ cflags += [ "--target=x86_64-fuchsia" ]
+ } else {
+ assert(false, "Unsupported architecture")
+ }
+
+ # Add libfdio by default. This may change in future versions
+ # in order to move away from POSIX applications and towards
+ # the Fuchsia programming model.
+ ldflags += [
+ # We always want fdio or else e.g. stdio wouldn't be initialized if fdio
+ # happens to not be directly referenced. The common POSIX-y compiler setup
+ # uses -Wl,--as-needed which drops it if it's simply "-lfdio" from a libs
+ # setting. Disable --as-needed, add fdio, and then set back to --as-needed.
+ "-Wl,--no-as-needed",
+ "-lfdio",
+ "-Wl,--as-needed",
+ ]
+
+ lib_dirs = [ "${fuchsia_sdk}/arch/${current_cpu}/lib" ]
+
+ libs = [ "zircon" ]
+
+ ldflags += cflags
+ asmflags = cflags
+}
+
+# This should be applied to all targets.
+config("runtime_library") {
+ asmflags = []
+ cflags = []
+ cflags_c = []
+ cflags_cc = []
+ cflags_objc = []
+ cflags_objcc = []
+ defines = []
+ ldflags = []
+
+ sysroot = "${fuchsia_sdk}/arch/$current_cpu/sysroot"
+
+ # Pass the sysroot to all C compiler variants, the assembler, and linker.
+ cflags = [ "--sysroot=" + rebase_path(sysroot, root_build_dir) ]
+ ldflags = cflags
+ asmflags = cflags
+}
+
+# Copy the loader to place it at the expected path in the final package.
+copy("sysroot_dist_libs") {
+ sources = [ "${fuchsia_sdk}/arch/${target_cpu}/sysroot/dist/lib/ld.so.1" ]
+ outputs = [ "${root_out_dir}/lib/{{source_file_part}}" ]
+}
+
+# This adds the runtime deps for //build/config/compiler:runtime_library
+# as that is a config target and thus cannot include data_deps.
+group("runtime_library_group") {
+ data_deps = [
+ ":sysroot_dist_libs",
+
+ # This is used directly from //build/config/fuchsia:compiler and thus
+ # also needs to be included by default.
+ "${fuchsia_sdk}/pkg/fdio",
+ ]
+}
+
+config("sdk_lib_dirs_config") {
+ visibility = [ ":*" ]
+ lib_dirs = [ "arch/${target_cpu}/lib" ]
+}
diff --git a/third_party/fuchsia-sdk/build/config/config.gni b/third_party/fuchsia-sdk/build/config/config.gni
new file mode 100644
index 0000000..2bd1af4
--- /dev/null
+++ b/third_party/fuchsia-sdk/build/config/config.gni
@@ -0,0 +1,29 @@
+# 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.
+
+declare_args() {
+ # Path to the fuchsia SDK. This is intended for use in other templates & rules
+ # to reference the contents of the fuchsia SDK.
+ fuchsia_sdk = get_path_info("../..", "abspath")
+
+ # Build ID uniquely identifying the Fuchsia IDK. This is exposed as a property so
+ # it can be used to locate images and packages on GCS and as a marker to indicate the
+ # "version" of the IDK. If it is empty, then it is most likely that something is fatally wrong.
+ fuchsia_sdk_id = ""
+}
+
+declare_args() {
+ # The SDK manifest file. This is useful to include as a dependency
+ # for some targets in order to cause a rebuild when the version of the
+ # SDK is changed.
+ fuchsia_sdk_manifest_file = "$fuchsia_sdk/meta/manifest.json"
+}
+
+if (fuchsia_sdk_id == "") {
+ # Note: If we need to expose more than just the id in the future,
+ # we should consider exposing the entire json object for the metadata vs.
+ # adding a bunch of variables.
+ _meta = read_file(fuchsia_sdk_manifest_file, "json")
+ fuchsia_sdk_id = _meta.id
+}
diff --git a/third_party/fuchsia-sdk/build/fidl_library.gni b/third_party/fuchsia-sdk/build/fidl_library.gni
new file mode 100644
index 0000000..1a28c45
--- /dev/null
+++ b/third_party/fuchsia-sdk/build/fidl_library.gni
@@ -0,0 +1,210 @@
+# 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.
+
+import("config/config.gni")
+
+# Define a Fuchsia FIDL library component() target.
+#
+# $namespace.$library_name must match the the library name specified in the FIDL
+# files.
+#
+# Parameters
+#
+# sources
+# Required: List of .fidl files.
+#
+# library_name
+# Optional: Name of the library. target_name is used if name
+# is not specified explicitly.
+#
+# namespace
+# Optional: Namespace for the library.
+#
+# deps
+# Optional: List of other fidl_library() targets that this
+# FIDL library depends on.
+#
+template("fidl_library") {
+ forward_variables_from(invoker, [ "namespace" ])
+
+ _library_basename = target_name
+ if (defined(invoker.library_name)) {
+ _library_basename = invoker.library_name
+ }
+
+ if (defined(namespace)) {
+ _library_name = "${namespace}.${_library_basename}"
+ _namespace_path = string_replace(namespace, ".", "/")
+ _library_path = "${_namespace_path}/${_library_basename}"
+ } else {
+ _library_name = _library_basename
+ _library_path = string_replace(_library_basename, ".", "/")
+ }
+
+ _response_file = "$target_gen_dir/$target_name.rsp"
+ _json_representation = "$target_gen_dir/${_library_name}.fidl.json"
+ _output_gen_dir = "$target_gen_dir/fidl"
+ _output_base = "$_output_gen_dir/${_library_path}/cpp/fidl"
+ _tables_file = "$_output_gen_dir/${_library_name}.fidl-tables.c"
+
+ action("${target_name}_response_file") {
+ script = "${fuchsia_sdk}/build/gen_fidl_response_file.py"
+
+ forward_variables_from(invoker,
+ [
+ "deps",
+ "public_deps",
+ "sources",
+ "testonly",
+ ])
+
+ _libraries_file = "$target_gen_dir/${invoker.target_name}.fidl_libraries"
+
+ outputs = [
+ _response_file,
+ _libraries_file,
+ ]
+
+ args = [
+ "--out-response-file",
+ rebase_path(_response_file, root_build_dir),
+ "--out-libraries",
+ rebase_path(_libraries_file, root_build_dir),
+ "--tables",
+ rebase_path(_tables_file, root_build_dir),
+ "--json",
+ rebase_path(_json_representation, root_build_dir),
+ "--name",
+ _library_name,
+ "--sources",
+ ] + rebase_path(sources, root_build_dir)
+
+ if (defined(invoker.deps) || defined(invoker.public_deps)) {
+ merged_deps = []
+
+ if (defined(invoker.deps)) {
+ merged_deps += invoker.deps
+ }
+
+ if (defined(invoker.public_deps)) {
+ merged_deps += invoker.public_deps
+ }
+
+ dep_libraries = []
+ deps = []
+
+ foreach(dep, merged_deps) {
+ gen_dir = get_label_info(dep, "target_gen_dir")
+ dep_toolchain = get_label_info(dep, "toolchain")
+ name = get_label_info(dep, "name")
+ dep_libraries += [ "$gen_dir/$name.fidl_libraries" ]
+ dep_dir =
+ get_label_info(get_label_info(dep, "label_no_toolchain"), "dir")
+ deps += [ "${dep_dir}:${name}_response_file($dep_toolchain)" ]
+ }
+
+ inputs = dep_libraries
+
+ args += [ "--dep-libraries" ] + rebase_path(dep_libraries, root_build_dir)
+ }
+ }
+
+ action("${target_name}_compile") {
+ forward_variables_from(invoker, [ "testonly" ])
+
+ visibility = [ ":*" ]
+
+ deps = [ ":${invoker.target_name}_response_file" ]
+
+ script = "${fuchsia_sdk}/build/gn_run_binary.py"
+
+ inputs = [
+ # Depend on the SDK hash, to ensure rebuild if the SDK tools change.
+ fuchsia_sdk_manifest_file,
+ _response_file,
+ ]
+
+ outputs = [
+ _json_representation,
+ _tables_file,
+ ]
+
+ rebased_response_file = rebase_path(_response_file, root_build_dir)
+ args = [
+ rebase_path("${fuchsia_sdk}/tools/fidlc", root_build_dir),
+ "@$rebased_response_file",
+ ]
+ }
+
+ action("${target_name}_cpp_gen") {
+ visibility = [ ":${invoker.target_name}" ]
+ forward_variables_from(invoker, [ "testonly" ])
+
+ deps = [ ":${invoker.target_name}_compile" ]
+
+ inputs = [
+ # Depend on the SDK hash, to ensure rebuild if the SDK tools change.
+ fuchsia_sdk_manifest_file,
+ _json_representation,
+ ]
+
+ outputs = [
+ "${_output_base}.h",
+ "${_output_base}.cc",
+ ]
+
+ script = "${fuchsia_sdk}/build/gn_run_binary.py"
+ args = [
+ rebase_path("${fuchsia_sdk}/tools/fidlgen", root_build_dir),
+ "-generators",
+ "cpp",
+ "-json",
+ rebase_path(_json_representation, root_build_dir),
+ "-include-base",
+ rebase_path(_output_gen_dir, root_build_dir),
+ "-output-base",
+ rebase_path("${_output_base}", root_build_dir),
+ ]
+ }
+
+ config("${target_name}_config") {
+ visibility = [ ":${invoker.target_name}" ]
+ include_dirs = [ _output_gen_dir ]
+ }
+
+ source_set(target_name) {
+ forward_variables_from(invoker,
+ [
+ "deps",
+ "public_deps",
+ "testonly",
+ "visibility",
+ ])
+
+ sources = [
+ "${_output_base}.cc",
+ "${_output_base}.h",
+ _tables_file,
+ ]
+
+ # Metadata to allow us to query all FIDL IR files.
+ metadata = {
+ fidl_json = [ rebase_path(_json_representation, root_build_dir) ]
+ }
+
+ if (!defined(deps)) {
+ deps = []
+ }
+ deps += [ ":${invoker.target_name}_compile" ]
+ deps += [ ":${invoker.target_name}_cpp_gen" ]
+
+ if (!defined(public_deps)) {
+ public_deps = []
+ }
+ public_deps += [ "${fuchsia_sdk}/pkg/fidl" ]
+ public_deps += [ "${fuchsia_sdk}/pkg/fidl_cpp" ]
+
+ public_configs = [ ":${invoker.target_name}_config" ]
+ }
+}
diff --git a/third_party/fuchsia-sdk/build/fuchsia_sdk_pkg.gni b/third_party/fuchsia-sdk/build/fuchsia_sdk_pkg.gni
new file mode 100644
index 0000000..b679760
--- /dev/null
+++ b/third_party/fuchsia-sdk/build/fuchsia_sdk_pkg.gni
@@ -0,0 +1,89 @@
+# 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.
+
+import("config/config.gni")
+
+# Defines a Fuchsia SDK library target from source or prebuilt.
+#
+# If this target has header files, they are exposed via a config
+# object specifying the include_dirs.
+#
+# Shared libraries are copied to ${root_out_dir/lib} for packaging.
+#
+#
+# Parameters
+#
+# package_name
+# Optional: Name of the library. Default is target_name.
+# sources
+# Required: List of source files.
+#
+# include_dirs
+# Optional: include_dirs to add to the configuration for the
+# target.
+# library_name
+# Optional: Name of the library. target_name is used if name
+# is not specified explicitly.
+#
+# shared_libs
+# Optional: List of shared libraries for this target.
+#
+# static_libs
+# Optional: List of static libraries for this target.
+#
+# sdk_dist_dir
+# Optional: Directory of libraries to distribute in the
+# target. Defaults to ${fuchsia_sdk}/arch/${target_cpu}/dist.
+# deps
+# Optional: List of other targets that this library depends on.
+#
+# Declares a package containing uncompiled code and/or precompiled libraries.
+#
+#
+template("fuchsia_sdk_pkg") {
+ config("${target_name}_config") {
+ forward_variables_from(invoker, [ "include_dirs" ])
+ visibility = [ ":${invoker.target_name}" ]
+ }
+
+ if (defined(invoker.shared_libs)) {
+ if (defined(invoker.sdk_dist_dir)) {
+ sdk_dist_dir = invoker.sdk_dist_dir
+ } else {
+ sdk_dist_dir = "${fuchsia_sdk}/arch/${target_cpu}/dist"
+ }
+
+ copy("${target_name}_dist_libs") {
+ sources = []
+ foreach(lib, invoker.shared_libs) {
+ sources += [ "${sdk_dist_dir}/lib${lib}.so" ]
+ }
+
+ outputs = [ "${root_out_dir}/lib/{{source_file_part}}" ]
+ visibility = [ ":${target_name}" ]
+ }
+ }
+
+ static_library(target_name) {
+ forward_variables_from(invoker,
+ [
+ "data",
+ "deps",
+ "public_deps",
+ "sources",
+ "testonly",
+ "visibility",
+ ])
+
+ public_configs = [ ":${invoker.target_name}_config" ]
+
+ if (defined(invoker.shared_libs)) {
+ configs += [ "${fuchsia_sdk}/build/config:sdk_lib_dirs_config" ]
+ libs = invoker.shared_libs
+ data_deps = [ ":${target_name}_dist_libs" ]
+ } else if (defined(invoker.static_libs)) {
+ libs = invoker.static_libs
+ }
+ }
+}
diff --git a/third_party/fuchsia-sdk/build/gen_fidl_response_file.py b/third_party/fuchsia-sdk/build/gen_fidl_response_file.py
new file mode 100755
index 0000000..a6c237d
--- /dev/null
+++ b/third_party/fuchsia-sdk/build/gen_fidl_response_file.py
@@ -0,0 +1,94 @@
+#!/usr/bin/env python2.7
+# 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.
+#
+# This file is a copy of
+# https://fuchsia.googlesource.com/garnet/+/731fec4559ba459b0d2567a2e68363a5d0021259/public/lib/fidl/build/fidl/gen_response_file.py
+
+import argparse
+import os
+import string
+import sys
+
+
+def read_libraries(libraries_path):
+ with open(libraries_path) as f:
+ lines = f.readlines()
+ return [l.rstrip("\n") for l in lines]
+
+
+def write_libraries(libraries_path, libraries):
+ directory = os.path.dirname(libraries_path)
+ if not os.path.exists(directory):
+ os.makedirs(directory)
+ with open(libraries_path, "w+") as f:
+ for library in libraries:
+ f.write(library)
+ f.write("\n")
+
+
+def main(args_list=None):
+ parser = argparse.ArgumentParser(
+ description="Generate response file for FIDL frontend")
+ parser.add_argument(
+ "--out-response-file",
+ help="The path for for the response file to generate",
+ required=True)
+ parser.add_argument(
+ "--out-libraries",
+ help="The path for for the libraries file to generate",
+ required=True)
+ parser.add_argument(
+ "--json", help="The path for the JSON file to generate, if any")
+ parser.add_argument(
+ "--tables", help="The path for the tables file to generate, if any")
+ parser.add_argument(
+ "--c-header",
+ help="The path for the C headers file to generate, if any")
+ parser.add_argument(
+ "--name", help="The name for the generated FIDL library, if any")
+ parser.add_argument(
+ "--sources", help="List of FIDL source files", nargs="*")
+ parser.add_argument(
+ "--dep-libraries", help="List of dependent libraries", nargs="*")
+ if args_list:
+ args = parser.parse_args(args_list)
+ else:
+ args = parser.parse_args()
+
+ target_libraries = []
+
+ for dep_libraries_path in args.dep_libraries or []:
+ dep_libraries = read_libraries(dep_libraries_path)
+ for library in dep_libraries:
+ if library in target_libraries:
+ continue
+ target_libraries.append(library)
+ target_libraries.append(" ".join(sorted(args.sources)))
+ write_libraries(args.out_libraries, target_libraries)
+
+ response_file = []
+
+ if args.json:
+ response_file.append("--json %s" % args.json)
+
+ if args.tables:
+ response_file.append("--tables %s" % args.tables)
+
+ if args.c_header:
+ response_file.append("--c-header %s" % args.c_header)
+
+ if args.name:
+ response_file.append("--name %s" % args.name)
+
+ response_file.extend(
+ ["--files %s" % library for library in target_libraries])
+
+ with open(args.out_response_file, "w+") as f:
+ f.write(" ".join(response_file))
+ f.write("\n")
+
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/third_party/fuchsia-sdk/build/gn-build-files-meta.json b/third_party/fuchsia-sdk/build/gn-build-files-meta.json
new file mode 100644
index 0000000..a262965
--- /dev/null
+++ b/third_party/fuchsia-sdk/build/gn-build-files-meta.json
@@ -0,0 +1,143 @@
+{
+ "docs": [
+ "fidl/fuchsia.accessibility.semantics/BUILD.gn",
+ "fidl/fuchsia.auth.oldtokens/BUILD.gn",
+ "fidl/fuchsia.auth/BUILD.gn",
+ "fidl/fuchsia.bluetooth.a2dp/BUILD.gn",
+ "fidl/fuchsia.bluetooth.control/BUILD.gn",
+ "fidl/fuchsia.bluetooth.gatt/BUILD.gn",
+ "fidl/fuchsia.bluetooth.le/BUILD.gn",
+ "fidl/fuchsia.bluetooth.sys/BUILD.gn",
+ "fidl/fuchsia.bluetooth/BUILD.gn",
+ "fidl/fuchsia.camera/BUILD.gn",
+ "fidl/fuchsia.camera2.hal/BUILD.gn",
+ "fidl/fuchsia.camera2/BUILD.gn",
+ "fidl/fuchsia.camera3/BUILD.gn",
+ "fidl/fuchsia.castauth/BUILD.gn",
+ "fidl/fuchsia.castconfig/BUILD.gn",
+ "fidl/fuchsia.castremotecontrol/BUILD.gn",
+ "fidl/fuchsia.castsetup/BUILD.gn",
+ "fidl/fuchsia.castsysteminfo/BUILD.gn",
+ "fidl/fuchsia.castwindow/BUILD.gn",
+ "fidl/fuchsia.cobalt/BUILD.gn",
+ "fidl/fuchsia.component.runner/BUILD.gn",
+ "fidl/fuchsia.component/BUILD.gn",
+ "fidl/fuchsia.data/BUILD.gn",
+ "fidl/fuchsia.deprecatedtimezone/BUILD.gn",
+ "fidl/fuchsia.developer.tiles/BUILD.gn",
+ "fidl/fuchsia.diagnostics/BUILD.gn",
+ "fidl/fuchsia.factory/BUILD.gn",
+ "fidl/fuchsia.feedback/BUILD.gn",
+ "fidl/fuchsia.fonts/BUILD.gn",
+ "fidl/fuchsia.hardware.ethernet/BUILD.gn",
+ "fidl/fuchsia.hardware.goldfish/BUILD.gn",
+ "fidl/fuchsia.hardware.light/BUILD.gn",
+ "fidl/fuchsia.hardware.power.statecontrol/BUILD.gn",
+ "fidl/fuchsia.hwinfo/BUILD.gn",
+ "fidl/fuchsia.images/BUILD.gn",
+ "fidl/fuchsia.input/BUILD.gn",
+ "fidl/fuchsia.inspect/BUILD.gn",
+ "fidl/fuchsia.intl/BUILD.gn",
+ "fidl/fuchsia.io/BUILD.gn",
+ "fidl/fuchsia.ldsvc/BUILD.gn",
+ "fidl/fuchsia.legacymetrics/BUILD.gn",
+ "fidl/fuchsia.location.namedplace/BUILD.gn",
+ "fidl/fuchsia.logger/BUILD.gn",
+ "fidl/fuchsia.math/BUILD.gn",
+ "fidl/fuchsia.media.audio/BUILD.gn",
+ "fidl/fuchsia.media.drm/BUILD.gn",
+ "fidl/fuchsia.media.playback/BUILD.gn",
+ "fidl/fuchsia.media.sessions2/BUILD.gn",
+ "fidl/fuchsia.media.sounds/BUILD.gn",
+ "fidl/fuchsia.media.target/BUILD.gn",
+ "fidl/fuchsia.media/BUILD.gn",
+ "fidl/fuchsia.mediacodec/BUILD.gn",
+ "fidl/fuchsia.mem/BUILD.gn",
+ "fidl/fuchsia.memorypressure/BUILD.gn",
+ "fidl/fuchsia.migration/BUILD.gn",
+ "fidl/fuchsia.modular.auth/BUILD.gn",
+ "fidl/fuchsia.modular.session/BUILD.gn",
+ "fidl/fuchsia.modular.testing/BUILD.gn",
+ "fidl/fuchsia.modular/BUILD.gn",
+ "fidl/fuchsia.net.dhcp/BUILD.gn",
+ "fidl/fuchsia.net.http/BUILD.gn",
+ "fidl/fuchsia.net.mdns/BUILD.gn",
+ "fidl/fuchsia.net.oldhttp/BUILD.gn",
+ "fidl/fuchsia.net/BUILD.gn",
+ "fidl/fuchsia.netstack/BUILD.gn",
+ "fidl/fuchsia.posix.socket/BUILD.gn",
+ "fidl/fuchsia.process/BUILD.gn",
+ "fidl/fuchsia.recovery.ui/BUILD.gn",
+ "fidl/fuchsia.recovery/BUILD.gn",
+ "fidl/fuchsia.scenic.scheduling/BUILD.gn",
+ "fidl/fuchsia.settings/BUILD.gn",
+ "fidl/fuchsia.sys.test/BUILD.gn",
+ "fidl/fuchsia.sys/BUILD.gn",
+ "fidl/fuchsia.sysinfo/BUILD.gn",
+ "fidl/fuchsia.sysmem/BUILD.gn",
+ "fidl/fuchsia.tracing.provider/BUILD.gn",
+ "fidl/fuchsia.ui.activity.control/BUILD.gn",
+ "fidl/fuchsia.ui.activity/BUILD.gn",
+ "fidl/fuchsia.ui.app/BUILD.gn",
+ "fidl/fuchsia.ui.brightness/BUILD.gn",
+ "fidl/fuchsia.ui.gfx/BUILD.gn",
+ "fidl/fuchsia.ui.input/BUILD.gn",
+ "fidl/fuchsia.ui.input2/BUILD.gn",
+ "fidl/fuchsia.ui.input3/BUILD.gn",
+ "fidl/fuchsia.ui.lifecycle/BUILD.gn",
+ "fidl/fuchsia.ui.policy/BUILD.gn",
+ "fidl/fuchsia.ui.scenic/BUILD.gn",
+ "fidl/fuchsia.ui.types/BUILD.gn",
+ "fidl/fuchsia.ui.views/BUILD.gn",
+ "fidl/fuchsia.update.channel/BUILD.gn",
+ "fidl/fuchsia.update.channelcontrol/BUILD.gn",
+ "fidl/fuchsia.update/BUILD.gn",
+ "fidl/fuchsia.url/BUILD.gn",
+ "fidl/fuchsia.weave/BUILD.gn",
+ "fidl/fuchsia.web/BUILD.gn",
+ "fidl/fuchsia.wlan.common/BUILD.gn",
+ "fidl/fuchsia.wlan.policy/BUILD.gn",
+ "fidl/fuchsia.wlan.service/BUILD.gn",
+ "fidl/fuchsia.wlan.stats/BUILD.gn",
+ "pkg/async-cpp/BUILD.gn",
+ "pkg/async-default/BUILD.gn",
+ "pkg/async-loop-cpp/BUILD.gn",
+ "pkg/async-loop-default/BUILD.gn",
+ "pkg/async-loop/BUILD.gn",
+ "pkg/async-testing/BUILD.gn",
+ "pkg/async/BUILD.gn",
+ "pkg/fdio/BUILD.gn",
+ "pkg/fidl-async/BUILD.gn",
+ "pkg/fidl/BUILD.gn",
+ "pkg/fidl_base/BUILD.gn",
+ "pkg/fidl_cpp/BUILD.gn",
+ "pkg/fidl_cpp_base/BUILD.gn",
+ "pkg/fidl_cpp_sync/BUILD.gn",
+ "pkg/fit/BUILD.gn",
+ "pkg/images_cpp/BUILD.gn",
+ "pkg/inspect/BUILD.gn",
+ "pkg/inspect_service_cpp/BUILD.gn",
+ "pkg/media_cpp/BUILD.gn",
+ "pkg/media_cpp_no_converters/BUILD.gn",
+ "pkg/memfs/BUILD.gn",
+ "pkg/modular_cpp/BUILD.gn",
+ "pkg/modular_testing_cpp/BUILD.gn",
+ "pkg/scenic_cpp/BUILD.gn",
+ "pkg/svc/BUILD.gn",
+ "pkg/sync/BUILD.gn",
+ "pkg/sys_cpp/BUILD.gn",
+ "pkg/sys_cpp_testing/BUILD.gn",
+ "pkg/sys_inspect_cpp/BUILD.gn",
+ "pkg/sys_service_cpp/BUILD.gn",
+ "pkg/syslog/BUILD.gn",
+ "pkg/trace-engine/BUILD.gn",
+ "pkg/trace-provider-so/BUILD.gn",
+ "pkg/trace/BUILD.gn",
+ "pkg/vfs_cpp/BUILD.gn",
+ "pkg/vulkan/BUILD.gn",
+ "pkg/vulkan_layers/BUILD.gn",
+ "pkg/zx/BUILD.gn"
+ ],
+ "name": "gn-build-files",
+ "type": "documentation"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/build/gn-rules-meta.json b/third_party/fuchsia-sdk/build/gn-rules-meta.json
new file mode 100644
index 0000000..c3ce338
--- /dev/null
+++ b/third_party/fuchsia-sdk/build/gn-rules-meta.json
@@ -0,0 +1,19 @@
+{
+ "docs": [
+ "build/cmc.gni",
+ "build/config/BUILD.gn",
+ "build/config/config.gni",
+ "build/fuchsia_sdk_pkg.gni",
+ "build/gn_run_binary.py",
+ "build/fidl_library.gni",
+ "build/gen_fidl_response_file.py",
+ "build/package.gni",
+ "build/component.gni",
+ "build/prepare_package_inputs.py",
+ "build/pm_tool.gni",
+ "build/test_targets.gni",
+ "build/test.gni"
+ ],
+ "name": "gn-rules",
+ "type": "documentation"
+}
diff --git a/third_party/fuchsia-sdk/build/gn_run_binary.py b/third_party/fuchsia-sdk/build/gn_run_binary.py
new file mode 100644
index 0000000..2377873
--- /dev/null
+++ b/third_party/fuchsia-sdk/build/gn_run_binary.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python2.7
+# 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.
+"""Helper script for GN to run an arbitrary binary.
+
+Run with:
+ python2.7 gn_run_binary.py <binary_name> [args ...]
+"""
+
+import os
+import subprocess
+import sys
+
+# This script is designed to run binaries produced by the current build. We
+# may prefix it with "./" to avoid picking up system versions that might
+# also be on the path.
+path = sys.argv[1]
+if not os.path.isabs(path):
+ path = './' + path
+
+# The rest of the arguments are passed directly to the executable.
+args = [path] + sys.argv[2:]
+
+sys.exit(subprocess.call(args))
diff --git a/third_party/fuchsia-sdk/build/package.gni b/third_party/fuchsia-sdk/build/package.gni
new file mode 100644
index 0000000..080522b
--- /dev/null
+++ b/third_party/fuchsia-sdk/build/package.gni
@@ -0,0 +1,140 @@
+# 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.
+
+import("config/config.gni")
+import("pm_tool.gni")
+
+# Define a Fuchsia component package target.
+#
+# Parameters
+#
+# package_name:
+# Optional: Name of the package. Defaults to target_name
+#
+# excluded_files
+# Optional: List of files to exclude from the package.
+#
+# deps
+# Required: List of fuchsia_component() targets that this
+# package contains.
+#
+template("fuchsia_package") {
+ if (!defined(invoker.package_name)) {
+ package_name = target_name
+ } else {
+ package_name = invoker.package_name
+ }
+ if (!defined(invoker.excluded_files)) {
+ excluded_files = []
+ } else {
+ excluded_files = invoker.excluded_files
+ }
+
+ _depfile = "${target_gen_dir}/${target_name}_stamp.d"
+
+ # target names
+ _manifest_target = "${target_name}__archive-manifest"
+ _metadata_target = "${target_name}__archive-metadata"
+
+ # output values
+ _pkg_out_dir = "${target_gen_dir}/${package_name}"
+ _runtime_deps_file = "$_pkg_out_dir/${package_name}.runtime_deps"
+ _archive_manifest = "$_pkg_out_dir/${package_name}.archive_manifest"
+ _build_ids_file = "$_pkg_out_dir/ids.txt"
+ _package_file = "$_pkg_out_dir/package"
+
+ _packaged_components_metadata =
+ "${target_gen_dir}/${package_name}_packaged_components_metadata.json"
+
+ _package_deps = []
+ if (defined(invoker.deps)) {
+ _package_deps += invoker.deps
+ }
+ if (defined(invoker.data_deps)) {
+ _package_deps += invoker.data_deps
+ }
+
+ # Generates a JSON file containing the contents of each of the
+ # components being included in this package.
+ generated_file("${package_name}_packaged_components_metadata") {
+ forward_variables_from(invoker, [ "testonly" ])
+ outputs = [ _packaged_components_metadata ]
+ data_keys = [ "contents" ]
+ output_conversion = "json"
+ deps = _package_deps
+ }
+
+ action(_manifest_target) {
+ forward_variables_from(invoker,
+ [
+ "deps",
+ "testonly",
+ ])
+ script = "${fuchsia_sdk}/build/prepare_package_inputs.py"
+
+ inputs = [ _runtime_deps_file ]
+
+ outputs = [
+ _archive_manifest,
+ _build_ids_file,
+ _package_file,
+ ]
+
+ if (!defined(deps)) {
+ deps = []
+ }
+ data_deps = _package_deps
+ deps += _package_deps
+
+ # Use a depfile to trigger package rebuilds if any of the files (static
+ # assets, shared libraries, etc.) included by the package have changed.
+ depfile = _depfile
+
+ args = [
+ "--root-dir",
+ rebase_path("//", root_build_dir),
+ "--out-dir",
+ rebase_path(root_out_dir, root_build_dir),
+ "--app-name",
+ package_name,
+ "--runtime-deps-file",
+ rebase_path(_runtime_deps_file, root_build_dir),
+ "--depfile-path",
+ rebase_path(_depfile, root_build_dir),
+ "--manifest-path",
+ rebase_path(_archive_manifest, root_build_dir),
+ "--build-ids-file",
+ rebase_path(_build_ids_file, root_build_dir),
+ "--json-file",
+ rebase_path(_packaged_components_metadata),
+ ]
+
+ if (defined(excluded_files)) {
+ foreach(filename, excluded_files) {
+ args += [
+ "--exclude-file",
+ filename,
+ ]
+ }
+ }
+ write_runtime_deps = _runtime_deps_file
+ }
+
+ # Creates a Fuchsia metadata package.
+ fuchsia_pm_tool(_metadata_target) {
+ forward_variables_from(invoker, [ "testonly" ])
+ package_name = package_name
+ command = "build"
+ archive_manifest = _archive_manifest
+ public_deps = [ ":$_manifest_target" ]
+ }
+
+ fuchsia_pm_tool(target_name) {
+ forward_variables_from(invoker, [ "testonly" ])
+ package_name = package_name
+ command = "archive"
+ archive_manifest = _archive_manifest
+ deps = [ ":$_metadata_target" ]
+ }
+}
diff --git a/third_party/fuchsia-sdk/build/pm_tool.gni b/third_party/fuchsia-sdk/build/pm_tool.gni
new file mode 100644
index 0000000..4a891f5
--- /dev/null
+++ b/third_party/fuchsia-sdk/build/pm_tool.gni
@@ -0,0 +1,98 @@
+# Copyright 2020 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.
+
+import("config/config.gni")
+
+# Template for running the pm tool for packaging fuchsia packages.
+#
+# Parameters
+# package_name - defaults to target_name
+# archive_manifest - required
+# command - the packaging step to perform valid steps are build, archive
+#
+# Forwarded parameters
+# testonly
+# deps
+# public_deps
+# visibility
+template("fuchsia_pm_tool") {
+ forward_variables_from(invoker, [ "*" ])
+ action(target_name) {
+ forward_variables_from(invoker,
+ [
+ "testonly",
+ "deps",
+ "public_deps",
+ "visibility"
+ ])
+ _valid_commands = [
+ "build",
+ "archive",
+ ]
+ assert(defined(invoker.archive_manifest), "archive_manifest is required.")
+ archive_manifest = invoker.archive_manifest
+
+ assert(defined(invoker.command), "command is required")
+ assert(invoker.command == "build" || invoker.command == "archive",
+ "invalid command. valid commands are ${_valid_commands}")
+ command = invoker.command
+
+ if (defined(invoker.package_name)) {
+ package_name = invoker.package_name
+ } else {
+ package_name = target_name
+ }
+
+ # tool path
+ _pm_tool_path = "${fuchsia_sdk}/tools/pm"
+ script = "${fuchsia_sdk}/build/gn_run_binary.py"
+
+ # output files
+ _pkg_out_dir = "${target_gen_dir}/${package_name}"
+ _meta_far_file = "${_pkg_out_dir}/meta.far"
+
+ inputs = [
+ # Depend on the SDK hash, to ensure rebuild if the SDK tools change.
+ fuchsia_sdk_manifest_file,
+ _pm_tool_path,
+ archive_manifest,
+ ]
+
+ if (command == "build") {
+ _pkg_output_manifest = "${_pkg_out_dir}/package_manifest.json"
+ outputs = [
+ _meta_far_file,
+ _pkg_output_manifest,
+ ]
+ depfile = "${_meta_far_file}.d"
+ } else {
+ inputs += [ _meta_far_file ]
+
+ _final_far_file = "$_pkg_out_dir/${package_name}.far"
+ outputs = [ _final_far_file ]
+ }
+
+ args = [
+ rebase_path(_pm_tool_path, root_build_dir),
+ "-o",
+ rebase_path(_pkg_out_dir, root_build_dir),
+ "-m",
+ rebase_path(archive_manifest, root_build_dir),
+ ]
+ if (command == "build") {
+ args += [
+ command,
+ "-depfile",
+ "-output-package-manifest",
+ rebase_path(_pkg_output_manifest, root_build_dir),
+ ]
+ } else if (command == "archive") {
+ args += [
+ command,
+ "--output",
+ rebase_path("${_pkg_out_dir}/${package_name}"),
+ ]
+ }
+ }
+}
diff --git a/third_party/fuchsia-sdk/build/prepare_package_inputs.py b/third_party/fuchsia-sdk/build/prepare_package_inputs.py
new file mode 100644
index 0000000..1b3e6de
--- /dev/null
+++ b/third_party/fuchsia-sdk/build/prepare_package_inputs.py
@@ -0,0 +1,303 @@
+#!/usr/bin/env python2.7
+# 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.
+
+#
+# Derivative work of https://chromium.googlesource.com/chromium/src/+/refs/heads/master/build/config/fuchsia/prepare_package_inputs.py
+#
+"""Creates a archive manifest used for Fuchsia package generation."""
+
+import argparse
+import json
+import os
+import re
+import shutil
+import subprocess
+import sys
+import tempfile
+
+# File extension of a component manifest for each Component Framework version
+MANIFEST_VERSION_EXTENSIONS = {"v1": ".cmx", "v2": ".cm"}
+
+
+def make_package_path(file_path, roots):
+ """Computes a path for |file_path| relative to one of the |roots|.
+
+ Args:
+ file_path: The file path to relativize.
+ roots: A list of directory paths which may serve as a relative root for
+ |file_path|.
+
+ For example:
+ * make_package_path('/foo/bar.txt', ['/foo/']) 'bar.txt'
+ * make_package_path('/foo/dir/bar.txt', ['/foo/']) 'dir/bar.txt'
+ * make_package_path('/foo/out/Debug/bar.exe', ['/foo/', '/foo/out/Debug/']) 'bar.exe'
+ """
+
+ # Prevents greedily matching against a shallow path when a deeper, better
+ # matching path exists.
+ roots.sort(key=len, reverse=True)
+
+ for next_root in roots:
+ if not next_root.endswith(os.sep):
+ next_root += os.sep
+
+ if file_path.startswith(next_root):
+ relative_path = file_path[len(next_root):]
+ return relative_path
+
+ return file_path
+
+
+def _get_stripped_path(bin_path):
+ """Finds the stripped version of |bin_path| in the build output directory.
+
+ returns |bin_path| if no stripped path is found.
+ """
+ stripped_path = bin_path.replace('lib.unstripped/',
+ 'lib/').replace('exe.unstripped/', '')
+ if os.path.exists(stripped_path):
+ return stripped_path
+ else:
+ return bin_path
+
+
+def _is_binary(path):
+ """Checks if the file at |path| is an ELF executable.
+
+ This is done by inspecting its FourCC header.
+ """
+
+ with open(path, 'rb') as f:
+ file_tag = f.read(4)
+ return file_tag == '\x7fELF'
+
+
+def _write_build_ids_txt(binary_paths, ids_txt_path):
+ """Writes an index text file mapping build IDs to unstripped binaries."""
+
+ READELF_FILE_PREFIX = 'File: '
+ READELF_BUILD_ID_PREFIX = 'Build ID: '
+
+ # List of binaries whose build IDs are awaiting processing by readelf.
+ # Entries are removed as readelf's output is parsed.
+ unprocessed_binary_paths = {os.path.basename(p): p for p in binary_paths}
+
+ with open(ids_txt_path, 'w') as ids_file:
+ # Create a set to dedupe stripped binary paths in case both the stripped and
+ # unstripped versions of a binary are specified.
+ stripped_binary_paths = set(map(_get_stripped_path, binary_paths))
+ readelf_stdout = subprocess.check_output(
+ ['readelf', '-n'] + list(stripped_binary_paths))
+
+ if len(binary_paths) == 1:
+ # Readelf won't report a binary's path if only one was provided to the
+ # tool.
+ binary_shortname = os.path.basename(binary_paths[0])
+ else:
+ binary_shortname = None
+
+ for line in readelf_stdout.split('\n'):
+ line = line.strip()
+
+ if line.startswith(READELF_FILE_PREFIX):
+ binary_shortname = os.path.basename(
+ line[len(READELF_FILE_PREFIX):])
+ assert binary_shortname in unprocessed_binary_paths
+
+ elif line.startswith(READELF_BUILD_ID_PREFIX):
+ # Paths to the unstripped executables listed in "ids.txt" are specified
+ # as relative paths to that file.
+ unstripped_rel_path = os.path.relpath(
+ os.path.abspath(unprocessed_binary_paths[binary_shortname]),
+ os.path.dirname(os.path.abspath(ids_txt_path)))
+
+ build_id = line[len(READELF_BUILD_ID_PREFIX):]
+ ids_file.write(build_id + ' ' + unstripped_rel_path + '\n')
+ del unprocessed_binary_paths[binary_shortname]
+
+ # Did readelf forget anything? Make sure that all binaries are accounted for.
+ assert not unprocessed_binary_paths
+
+
+def _parse_component(component_info_file):
+ component_info = json.load(open(component_info_file, 'r'))
+ return component_info
+
+
+def _get_app_filename(component_info):
+ for c in component_info:
+ if c.get('type') == 'dep':
+ pos = c.get('source').find(':')
+ return c.get('source')[pos + 1:]
+
+
+def _get_component_manifests(component_info):
+ return [c for c in component_info if c.get('type') == 'manifest']
+
+
+def _get_expanded_files(runtime_deps_file):
+ """ Process the runtime deps file for file paths, recursively walking
+ directories as needed.
+
+ Returns a set of expanded files referenced by the runtime deps file.
+ """
+
+ # runtime_deps may contain duplicate paths, so use a set for
+ # de-duplication.
+ expanded_files = set()
+ for next_path in open(runtime_deps_file, 'r'):
+ next_path = next_path.strip()
+ if os.path.isdir(next_path):
+ for root, _, files in os.walk(next_path):
+ for current_file in files:
+ if current_file.startswith('.'):
+ continue
+ expanded_files.add(
+ os.path.normpath(os.path.join(root, current_file)))
+ else:
+ expanded_files.add(os.path.normpath(next_path))
+ return expanded_files
+
+
+def _write_gn_deps_file(depfile_path, manifest_path, out_dir, expanded_files):
+ with open(depfile_path, 'w') as depfile:
+ manifest_path = os.path.relpath(manifest_path, out_dir)
+ deps_list = []
+ for f in expanded_files:
+ deps_list.append(os.path.relpath(f, out_dir))
+ deps_string = ' '.join(deps_list)
+ depfile.write('%s: %s' % (manifest_path, deps_string))
+
+
+def _write_meta_package_manifest(
+ manifest, manifest_path, app_name, out_dir, package_version):
+ # Write meta/package manifest file and add to archive manifest.
+ meta_package = os.path.join(os.path.dirname(manifest_path), 'package')
+ with open(meta_package, 'w') as package_json:
+ json_payload = {'version': package_version, 'name': app_name}
+ json.dump(json_payload, package_json)
+ package_json_filepath = os.path.relpath(package_json.name, out_dir)
+ manifest.write('meta/package=%s\n' % package_json_filepath)
+
+
+def _write_component_manifest(manifest, component_info, manifest_path, out_dir):
+ """Copy component manifest files and add to archive manifest.
+
+ Raises an exception if a component uses a unknown manifest version.
+ """
+
+ for component_manifest in _get_component_manifests(component_info):
+ manifest_version = component_manifest.get('manifest_version')
+
+ if manifest_version not in MANIFEST_VERSION_EXTENSIONS:
+ raise Exception(
+ 'Unknown manifest_version: {}'.format(manifest_version))
+
+ extension = MANIFEST_VERSION_EXTENSIONS.get(manifest_version)
+
+ manifest_dest_file_path = os.path.join(
+ os.path.dirname(manifest_path),
+ component_manifest.get('output_name') + extension)
+ shutil.copy(component_manifest.get('source'), manifest_dest_file_path)
+
+ manifest.write(
+ 'meta/%s=%s\n' % (
+ os.path.basename(manifest_dest_file_path),
+ os.path.relpath(manifest_dest_file_path, out_dir)))
+
+
+def _write_package_manifest(
+ manifest, expanded_files, out_dir, exclude_file, root_dir,
+ component_info, binaries):
+ """Writes the package manifest for a Fuchsia package
+
+ Returns a list of binaries in the package.
+
+ Raises an exception if the app filename does not match the package path.
+ Raises an exception if excluded files are not found."""
+ app_filename = _get_app_filename(component_info)
+ gen_dir = os.path.normpath(os.path.join(out_dir, 'gen'))
+ app_found = False
+ excluded_files_set = set(exclude_file)
+ for current_file in expanded_files:
+ if _is_binary(current_file):
+ binaries.append(current_file)
+ current_file = _get_stripped_path(current_file)
+ # make_package_path() may relativize to either the source root or
+ # output directory.
+ in_package_path = make_package_path(
+ current_file, [gen_dir, root_dir, out_dir])
+ if in_package_path == app_filename:
+ app_found = True
+
+ if in_package_path in excluded_files_set:
+ excluded_files_set.remove(in_package_path)
+ continue
+
+ manifest.write('%s=%s\n' % (in_package_path, current_file))
+
+ if len(excluded_files_set) > 0:
+ raise Exception(
+ 'Some files were excluded with --exclude-file, but '
+ 'not found in the deps list: %s' % ', '.join(excluded_files_set))
+
+ if not app_found:
+ raise Exception('Could not locate executable inside runtime_deps.')
+
+
+def _build_manifest(args):
+ expanded_files = _get_expanded_files(args.runtime_deps_file)
+ _write_gn_deps_file(
+ args.depfile_path, args.manifest_path, args.out_dir, expanded_files)
+ binaries = [] # keep track of binaries to write build IDs
+ with open(args.manifest_path, 'w') as manifest:
+ _write_meta_package_manifest(
+ manifest, args.manifest_path, args.app_name, args.out_dir,
+ args.package_version)
+ for component_info in _parse_component(args.json_file):
+ _write_package_manifest(
+ manifest, expanded_files, args.out_dir, args.exclude_file,
+ args.root_dir, component_info, binaries)
+ _write_component_manifest(
+ manifest, component_info, args.manifest_path, args.out_dir)
+
+ _write_build_ids_txt(binaries, args.build_ids_file)
+
+ return 0
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument(
+ '--root-dir', required=True, help='Build root directory')
+ parser.add_argument(
+ '--out-dir', required=True, help='Build output directory')
+ parser.add_argument('--app-name', required=True, help='Package name')
+ parser.add_argument(
+ '--runtime-deps-file',
+ required=True,
+ help='File with the list of runtime dependencies.')
+ parser.add_argument(
+ '--depfile-path', required=True, help='Path to write GN deps file.')
+ parser.add_argument(
+ '--exclude-file',
+ action='append',
+ default=[],
+ help='Package-relative file path to exclude from the package.')
+ parser.add_argument(
+ '--manifest-path', required=True, help='Manifest output path.')
+ parser.add_argument(
+ '--build-ids-file', required=True, help='Debug symbol index path.')
+ parser.add_argument('--json-file', required=True)
+ parser.add_argument(
+ '--package-version', default='0', help='Version of the package')
+
+ args = parser.parse_args()
+
+ return _build_manifest(args)
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/third_party/fuchsia-sdk/build/test.gni b/third_party/fuchsia-sdk/build/test.gni
new file mode 100644
index 0000000..2c7fe18
--- /dev/null
+++ b/third_party/fuchsia-sdk/build/test.gni
@@ -0,0 +1,92 @@
+# Copyright 2020 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.
+
+import("component.gni")
+import("config/config.gni")
+import("package.gni")
+
+# Define a test executable, which is packaged in a Fuchsia package.
+# Metadata is generated for the target to enable programmatic execution.
+#
+# Parameters
+#
+# deps
+# Optional: Dependencies for this component. These dependencies are external
+# to the component, such as other components that are used via FIDL. The deps
+# are added to the executable as well as a the component.
+#
+# data_deps
+# Required: Dependencies examined for metadata. These dependencies define
+# the contents of the component. These are executables and libraries. The
+# data_deps are added to the component.
+#
+# manifest
+# Required: The manifest file for this component. The executable name
+# must be of the form ${target_name}__exec
+#
+# resources
+# Optional: Non-executable resources to include in the component.
+#
+template("fuchsia_test") {
+ _output_name = invoker.target_name
+ _component_target = "${_output_name}_component"
+ _pkg_target = "${_output_name}_package"
+ _exec_target = "${_output_name}__exec"
+
+ # This is the executable for the test.
+ executable(_exec_target) {
+ visibility = [ ":*" ]
+ forward_variables_from(invoker,
+ [
+ "testonly",
+ "sources",
+ "deps",
+ ])
+ testonly = true
+ output_name = _exec_target
+ }
+
+ # The component encapsulates the executable,
+ # and all the dependencies and resources needed.
+ fuchsia_component(_component_target) {
+ visibility = [ ":*" ]
+ testonly = true
+ forward_variables_from(invoker,
+ [
+ "manifest",
+ "data_deps",
+ "deps",
+ "resources",
+ ])
+ if (!defined(data_deps)) {
+ data_deps = []
+ }
+ data_deps += [ ":$_exec_target" ]
+ }
+
+ # Package the component.
+ fuchsia_package(_pkg_target) {
+ testonly = true
+ data_deps = [ ":$_component_target" ]
+ package_name = _output_name
+ }
+
+ # Create metadata JSON which enables building the
+ # command line to execute the test.
+ group(target_name) {
+ testonly = true
+ metadata = {
+ test_metadata = [
+ {
+ package_name = _output_name
+ manifest_name = get_path_info(invoker.manifest, "file")
+ archive_file = rebase_path(
+ "${target_gen_dir}/${_output_name}/${_output_name}.far")
+ },
+ ]
+ }
+
+ deps = [ ":${_pkg_target}" ]
+ }
+}
diff --git a/third_party/fuchsia-sdk/build/test_targets.gni b/third_party/fuchsia-sdk/build/test_targets.gni
new file mode 100644
index 0000000..b72b6ed
--- /dev/null
+++ b/third_party/fuchsia-sdk/build/test_targets.gni
@@ -0,0 +1,209 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+assert(current_os == "fuchsia")
+
+import("fuchsia_sdk_pkg.gni")
+
+# These template is used to create build targets
+# that test the generated build targets. It does not
+# have any practical use outside testing.
+
+# All vulkan targets
+template("fuchsia_sdk_test_loadable_module_targets") {
+ not_needed(["invoker"])
+ group(target_name){
+ deps = [
+ "${fuchsia_sdk}/pkg/vulkan_layers:all",
+ ]
+ }
+}
+
+# All FIDL targets
+template("fuchsia_sdk_test_fidl_targets") {
+ not_needed(["invoker"])
+ group(target_name){
+ deps = [
+ "${fuchsia_sdk}/fidl/fuchsia.accessibility.semantics:all",
+ "${fuchsia_sdk}/fidl/fuchsia.auth:all",
+ "${fuchsia_sdk}/fidl/fuchsia.auth.oldtokens:all",
+ "${fuchsia_sdk}/fidl/fuchsia.bluetooth:all",
+ "${fuchsia_sdk}/fidl/fuchsia.bluetooth.a2dp:all",
+ "${fuchsia_sdk}/fidl/fuchsia.bluetooth.control:all",
+ "${fuchsia_sdk}/fidl/fuchsia.bluetooth.gatt:all",
+ "${fuchsia_sdk}/fidl/fuchsia.bluetooth.le:all",
+ "${fuchsia_sdk}/fidl/fuchsia.bluetooth.sys:all",
+ "${fuchsia_sdk}/fidl/fuchsia.camera:all",
+ "${fuchsia_sdk}/fidl/fuchsia.camera2:all",
+ "${fuchsia_sdk}/fidl/fuchsia.camera2.hal:all",
+ "${fuchsia_sdk}/fidl/fuchsia.camera3:all",
+ "${fuchsia_sdk}/fidl/fuchsia.castauth:all",
+ "${fuchsia_sdk}/fidl/fuchsia.castconfig:all",
+ "${fuchsia_sdk}/fidl/fuchsia.castremotecontrol:all",
+ "${fuchsia_sdk}/fidl/fuchsia.castsetup:all",
+ "${fuchsia_sdk}/fidl/fuchsia.castsysteminfo:all",
+ "${fuchsia_sdk}/fidl/fuchsia.castwindow:all",
+ "${fuchsia_sdk}/fidl/fuchsia.cobalt:all",
+ "${fuchsia_sdk}/fidl/fuchsia.component:all",
+ "${fuchsia_sdk}/fidl/fuchsia.component.runner:all",
+ "${fuchsia_sdk}/fidl/fuchsia.data:all",
+ "${fuchsia_sdk}/fidl/fuchsia.deprecatedtimezone:all",
+ "${fuchsia_sdk}/fidl/fuchsia.developer.tiles:all",
+ "${fuchsia_sdk}/fidl/fuchsia.diagnostics:all",
+ "${fuchsia_sdk}/fidl/fuchsia.factory:all",
+ "${fuchsia_sdk}/fidl/fuchsia.feedback:all",
+ "${fuchsia_sdk}/fidl/fuchsia.fonts:all",
+ "${fuchsia_sdk}/fidl/fuchsia.hardware.ethernet:all",
+ "${fuchsia_sdk}/fidl/fuchsia.hardware.goldfish:all",
+ "${fuchsia_sdk}/fidl/fuchsia.hardware.light:all",
+ "${fuchsia_sdk}/fidl/fuchsia.hardware.power.statecontrol:all",
+ "${fuchsia_sdk}/fidl/fuchsia.hwinfo:all",
+ "${fuchsia_sdk}/fidl/fuchsia.images:all",
+ "${fuchsia_sdk}/fidl/fuchsia.input:all",
+ "${fuchsia_sdk}/fidl/fuchsia.inspect:all",
+ "${fuchsia_sdk}/fidl/fuchsia.intl:all",
+ "${fuchsia_sdk}/fidl/fuchsia.io:all",
+ "${fuchsia_sdk}/fidl/fuchsia.ldsvc:all",
+ "${fuchsia_sdk}/fidl/fuchsia.legacymetrics:all",
+ "${fuchsia_sdk}/fidl/fuchsia.location.namedplace:all",
+ "${fuchsia_sdk}/fidl/fuchsia.logger:all",
+ "${fuchsia_sdk}/fidl/fuchsia.math:all",
+ "${fuchsia_sdk}/fidl/fuchsia.media:all",
+ "${fuchsia_sdk}/fidl/fuchsia.media.audio:all",
+ "${fuchsia_sdk}/fidl/fuchsia.media.drm:all",
+ "${fuchsia_sdk}/fidl/fuchsia.media.playback:all",
+ "${fuchsia_sdk}/fidl/fuchsia.media.sessions2:all",
+ "${fuchsia_sdk}/fidl/fuchsia.media.sounds:all",
+ "${fuchsia_sdk}/fidl/fuchsia.media.target:all",
+ "${fuchsia_sdk}/fidl/fuchsia.mediacodec:all",
+ "${fuchsia_sdk}/fidl/fuchsia.mem:all",
+ "${fuchsia_sdk}/fidl/fuchsia.memorypressure:all",
+ "${fuchsia_sdk}/fidl/fuchsia.migration:all",
+ "${fuchsia_sdk}/fidl/fuchsia.modular:all",
+ "${fuchsia_sdk}/fidl/fuchsia.modular.auth:all",
+ "${fuchsia_sdk}/fidl/fuchsia.modular.session:all",
+ "${fuchsia_sdk}/fidl/fuchsia.modular.testing:all",
+ "${fuchsia_sdk}/fidl/fuchsia.net:all",
+ "${fuchsia_sdk}/fidl/fuchsia.net.dhcp:all",
+ "${fuchsia_sdk}/fidl/fuchsia.net.http:all",
+ "${fuchsia_sdk}/fidl/fuchsia.net.mdns:all",
+ "${fuchsia_sdk}/fidl/fuchsia.net.oldhttp:all",
+ "${fuchsia_sdk}/fidl/fuchsia.netstack:all",
+ "${fuchsia_sdk}/fidl/fuchsia.posix.socket:all",
+ "${fuchsia_sdk}/fidl/fuchsia.process:all",
+ "${fuchsia_sdk}/fidl/fuchsia.recovery:all",
+ "${fuchsia_sdk}/fidl/fuchsia.recovery.ui:all",
+ "${fuchsia_sdk}/fidl/fuchsia.scenic.scheduling:all",
+ "${fuchsia_sdk}/fidl/fuchsia.settings:all",
+ "${fuchsia_sdk}/fidl/fuchsia.sys:all",
+ "${fuchsia_sdk}/fidl/fuchsia.sys.test:all",
+ "${fuchsia_sdk}/fidl/fuchsia.sysinfo:all",
+ "${fuchsia_sdk}/fidl/fuchsia.sysmem:all",
+ "${fuchsia_sdk}/fidl/fuchsia.tracing.provider:all",
+ "${fuchsia_sdk}/fidl/fuchsia.ui.activity:all",
+ "${fuchsia_sdk}/fidl/fuchsia.ui.activity.control:all",
+ "${fuchsia_sdk}/fidl/fuchsia.ui.app:all",
+ "${fuchsia_sdk}/fidl/fuchsia.ui.brightness:all",
+ "${fuchsia_sdk}/fidl/fuchsia.ui.gfx:all",
+ "${fuchsia_sdk}/fidl/fuchsia.ui.input:all",
+ "${fuchsia_sdk}/fidl/fuchsia.ui.input2:all",
+ "${fuchsia_sdk}/fidl/fuchsia.ui.input3:all",
+ "${fuchsia_sdk}/fidl/fuchsia.ui.lifecycle:all",
+ "${fuchsia_sdk}/fidl/fuchsia.ui.policy:all",
+ "${fuchsia_sdk}/fidl/fuchsia.ui.scenic:all",
+ "${fuchsia_sdk}/fidl/fuchsia.ui.types:all",
+ "${fuchsia_sdk}/fidl/fuchsia.ui.views:all",
+ "${fuchsia_sdk}/fidl/fuchsia.update:all",
+ "${fuchsia_sdk}/fidl/fuchsia.update.channel:all",
+ "${fuchsia_sdk}/fidl/fuchsia.update.channelcontrol:all",
+ "${fuchsia_sdk}/fidl/fuchsia.url:all",
+ "${fuchsia_sdk}/fidl/fuchsia.weave:all",
+ "${fuchsia_sdk}/fidl/fuchsia.web:all",
+ "${fuchsia_sdk}/fidl/fuchsia.wlan.common:all",
+ "${fuchsia_sdk}/fidl/fuchsia.wlan.policy:all",
+ "${fuchsia_sdk}/fidl/fuchsia.wlan.service:all",
+ "${fuchsia_sdk}/fidl/fuchsia.wlan.stats:all",
+ ]
+ }
+}
+
+# All CC source targets
+template("fuchsia_sdk_test_cc_source_targets") {
+ not_needed(["invoker"])
+ group(target_name){
+ deps = [
+ "${fuchsia_sdk}/pkg/async:all",
+ "${fuchsia_sdk}/pkg/async-cpp:all",
+ "${fuchsia_sdk}/pkg/async-loop:all",
+ "${fuchsia_sdk}/pkg/async-loop-cpp:all",
+ "${fuchsia_sdk}/pkg/async-testing:all",
+ "${fuchsia_sdk}/pkg/fidl:all",
+ "${fuchsia_sdk}/pkg/fidl-async:all",
+ "${fuchsia_sdk}/pkg/fidl_base:all",
+ "${fuchsia_sdk}/pkg/fidl_cpp:all",
+ "${fuchsia_sdk}/pkg/fidl_cpp_base:all",
+ "${fuchsia_sdk}/pkg/fidl_cpp_sync:all",
+ "${fuchsia_sdk}/pkg/fit:all",
+ "${fuchsia_sdk}/pkg/images_cpp:all",
+ "${fuchsia_sdk}/pkg/inspect:all",
+ "${fuchsia_sdk}/pkg/inspect_service_cpp:all",
+ "${fuchsia_sdk}/pkg/media_cpp:all",
+ "${fuchsia_sdk}/pkg/media_cpp_no_converters:all",
+ "${fuchsia_sdk}/pkg/modular_cpp:all",
+ "${fuchsia_sdk}/pkg/modular_testing_cpp:all",
+ "${fuchsia_sdk}/pkg/scenic_cpp:all",
+ "${fuchsia_sdk}/pkg/sys_cpp:all",
+ "${fuchsia_sdk}/pkg/sys_cpp_testing:all",
+ "${fuchsia_sdk}/pkg/sys_inspect_cpp:all",
+ "${fuchsia_sdk}/pkg/sys_service_cpp:all",
+ "${fuchsia_sdk}/pkg/trace:all",
+ "${fuchsia_sdk}/pkg/vfs_cpp:all",
+ "${fuchsia_sdk}/pkg/zx:all",
+ ]
+ }
+}
+
+# All CC prebuilt targets
+template("fuchsia_sdk_test_cc_prebuilt_targets") {
+ not_needed(["invoker"])
+ group(target_name){
+ deps = [
+ "${fuchsia_sdk}/pkg/async-default:all",
+ "${fuchsia_sdk}/pkg/async-loop-default:all",
+ "${fuchsia_sdk}/pkg/fdio:all",
+ "${fuchsia_sdk}/pkg/memfs:all",
+ "${fuchsia_sdk}/pkg/svc:all",
+ "${fuchsia_sdk}/pkg/sync:all",
+ "${fuchsia_sdk}/pkg/syslog:all",
+ "${fuchsia_sdk}/pkg/trace-engine:all",
+ "${fuchsia_sdk}/pkg/trace-provider-so:all",
+ "${fuchsia_sdk}/pkg/vulkan:all",
+ ]
+ }
+}
+
+# All test targets
+template("fuchsia_sdk_test_targets"){
+ not_needed(["invoker"])
+ fuchsia_sdk_test_loadable_module_targets("loadable_module_targets"){
+ }
+ fuchsia_sdk_test_fidl_targets("fidl_targets"){
+ }
+ fuchsia_sdk_test_cc_source_targets("cc_source_targets"){
+ }
+ fuchsia_sdk_test_cc_prebuilt_targets("cc_prebuilt_targets"){
+ }
+ group(target_name){
+ deps = [
+ ":loadable_module_targets",
+ ":fidl_targets",
+ ":cc_source_targets",
+ ":cc_prebuilt_targets",
+ ]
+ }
+}
diff --git a/third_party/fuchsia-sdk/docs/README.md b/third_party/fuchsia-sdk/docs/README.md
new file mode 100644
index 0000000..aa2e88c
--- /dev/null
+++ b/third_party/fuchsia-sdk/docs/README.md
@@ -0,0 +1,13 @@
+# Documentation
+
+## General
+
+For general information about this SDK, see the [root README](../README.md).
+
+
+## Workflows
+
+- [Creating and deploying Fuchsia packages](packages.md)
+- [Communicating with target devices](devices.md)
+- [Creating and consuming logs](logging.md)
+- [Debugging native code](debugger.md)
diff --git a/third_party/fuchsia-sdk/docs/bootserver.md b/third_party/fuchsia-sdk/docs/bootserver.md
new file mode 100644
index 0000000..fa201dd
--- /dev/null
+++ b/third_party/fuchsia-sdk/docs/bootserver.md
@@ -0,0 +1,46 @@
+# Bootserver
+
+The `bootserver` host tool can be used to pave, netboot or boot Fuchsia on a
+target device. This tool is very likely to go away in the short future with
+a replacement being currently implemented.
+
+## x64
+
+### Generic
+
+To pave and boot on a generic `x64` target, run:
+
+```
+bootserver \
+ --boot "$IMAGES_PATH/fuchsia.zbi" \
+ --bootloader "$IMAGES_PATH/fuchsia.esp.blk" \
+ --fvm "$IMAGES_PATH/obj/build/images/fvm.sparse.blk" \
+ --zircona "$IMAGES_PATH/fuchsia.zbi" \
+ --zirconr "$IMAGES_PATH/zedboot.zbi"
+```
+
+### Chromebook
+
+To pave and boot on a `chromebook` target, run:
+
+
+```
+bootserver \
+ --boot "$IMAGES_PATH/fuchsia.zbi" \
+ --fvm "$IMAGES_PATH/obj/build/images/fvm.sparse.blk" \
+ --zircona "$IMAGES_PATH/fuchsia.zbi.vboot" \
+ --zirconr "$IMAGES_PATH/zedboot.vboot"
+```
+
+
+## arm64
+
+To pave and boot on an `arm64` target, run:
+
+```
+bootserver \
+ --boot "$IMAGES_PATH/fuchsia.zbi" \
+ --fvm "$IMAGES_PATH/obj/build/images/fvm.sparse.blk" \
+ --zircona "$IMAGES_PATH/fuchsia.zbi" \
+ --zirconr "$IMAGES_PATH/zedboot.zbi"
+```
diff --git a/third_party/fuchsia-sdk/docs/compilation.md b/third_party/fuchsia-sdk/docs/compilation.md
new file mode 100644
index 0000000..dcf9c71
--- /dev/null
+++ b/third_party/fuchsia-sdk/docs/compilation.md
@@ -0,0 +1,41 @@
+# Compiling C/C++ code
+
+The present document compiles a list of guidelines, recommendations, and
+expectations around the topic of compiling C and C++ code against the Core SDK.
+
+
+## Sysroot
+
+The Fuchsia sysroot for a given target architecture is available under
+`//arch/<architecture>/sysroot`.
+That directory contains a complete sysroot and may be used with any tool that
+accepts a `--sysroot` flag.
+
+
+## Prebuilts
+
+All prebuilts have C linkage.
+
+### Debug symbols
+
+Debug symbols for all prebuilts are available under `//.build-id`, which follows
+a [standard convention][build-id].
+
+
+## Compilation parameters
+
+- C++ sources are compatible with both C++14 and C++17.
+
+### Warning flags
+
+The following flags are guaranteed to not generate any warning:
+- `-Wall`
+- `-Wextra-semi`
+- `-Wnewline-eof`
+- `-Wshadow`
+
+The following flags may generate warnings:
+- `-Wdeprecated-declarations`
+
+
+[build-id]: https://fedoraproject.org/wiki/Releases/FeatureBuildId#Find_files_by_build_ID
diff --git a/third_party/fuchsia-sdk/docs/debugger.md b/third_party/fuchsia-sdk/docs/debugger.md
new file mode 100644
index 0000000..d2c9aac
--- /dev/null
+++ b/third_party/fuchsia-sdk/docs/debugger.md
@@ -0,0 +1,67 @@
+# Debugger (zxdb)
+
+Zxdb is a console debugger for native code compiled with DWARF symbols (C, C++
+and Rust). The frontend runs on the host computer and connects to the on-device
+`debug_agent`. This document describes how to set up these processes.
+
+## Running the agent
+
+The `debug_agent` is run on the target device along with the port number that
+it should listen to for incoming client connections. Typically this command
+will be run from a console after [ssh-ing](ssh.md) in to the system:
+
+```
+run fuchsia-pkg://fuchsia.com/debug_agent#meta/debug_agent.cmx --port=2345
+```
+
+## Connecting the client
+
+The `zxdb` client program is run on the host computer. It can be connected to
+the `debug_agent` via the interactive `connect` debugger command or it can
+automatically connect based on a command-line flag. Both IPv4 and IPv6
+addresses are supported (see [device discovery](device_discovery.md) to find
+the address). The port should match the port number passed to the agent.
+
+```
+zxdb -c "[f370::5051:ff:1e53:589a%qemu]:2345"
+```
+
+### Connecting via a script
+
+Scripts may want to automatically launch the agent and client automatically.
+The script should wait for the port to be open on the target system before
+launching the client. Automatic retry is not yet implemented in the client.
+
+To clean up the debug agent gracefully when the client exits, pass the
+`--quit-agent-on-exit` command-line flag to the client.
+
+## Specifying symbol paths
+
+The debugger expects unstripped ELF files to be available on the local host
+system. Symbols on the target are not used. The location where the local build
+stores symbols must be passed to the `zxdb` client.
+
+Local symbols can be passed on the command line:
+
+```
+zxdb --symbol-path=/path-to-symbols
+```
+
+The path can be any of:
+
+ * An individual symbolized ELF file.
+ * An ids.txt file mapping build IDs to local files.
+ * A directory name. If the directory is a GNU-style symbol repo (see below),
+ symbols will be taken from the .build-id folder beneath it, otherwise the
+ directory will be searched (non-recursively) for symbolized ELF files.
+
+GNU-style symbol repos are directories of any layout which contain a folder at
+the root called .build-id. This folder contains the symbolized binaries
+indexed by the binaries' build IDs. Often these are symlinks pointing to
+various locations in the folder itself.
+```
+Multiple `--symbol-path` parameters may be specified if there are symbols in
+more than one location. All locations will be searched.
+
+Symbol locations can also be edited interactively in the client using the
+global "symbol-paths" setting (see the interactive "get" and "set" commands).
diff --git a/third_party/fuchsia-sdk/docs/device_discovery.md b/third_party/fuchsia-sdk/docs/device_discovery.md
new file mode 100644
index 0000000..39cc1f5
--- /dev/null
+++ b/third_party/fuchsia-sdk/docs/device_discovery.md
@@ -0,0 +1,57 @@
+# `device-finder`
+
+`device-finder` is the command line tool for device discovery. It uses mDNS to
+find Fuchsia devices.
+
+Currently only Linux is supported. For Mac users see the "For Mac Users"
+section.
+
+## For Linux Users
+
+### Finding all Devices
+
+The simplest way to get all the devices on the network by their address is to
+run
+
+```
+$ ./device-finder list
+192.168.42.156
+```
+
+This will give you the addresses of all Fuchsia devices on the network. If you'd
+like to get their hostnames as well as their addresses, you can include the
+`-full` flag.
+
+### Finding devices by hostname
+
+If you'd like to find your device by its unique hostname (e.g.
+`lunch-feta-stool-woozy`) you can use the `resolve` command:
+
+```
+$ ./device-finder resolve lunch-feta-stool-woozy
+192.168.42.156
+```
+
+### Finding the Interface Connected to the Device
+
+To find the interface connected to the device, include the `-local` flag to
+either the `list` command or the `resolve` command, which will give you the
+address that the Fuchsia device can use to connect to your host.
+
+## For Mac Users
+
+For those on Mac hosts, you can use the included `dns-sd` command to find your
+device. Here's an example command along with the output you should see when a
+device is on your network:
+
+```
+$ dns-sd -B _fuchsia._udp .
+Browsing for _fuchsia._udp
+DATE: ---Fri 14 Dec 2018---
+15:28:21.447 ...STARTING...
+Timestamp A/R Flags if Domain Service Type Instance Name
+15:28:21.448 Add 2 7 local. _fuchsia._udp. quake-agile-lurk-even
+```
+
+Mac does not support the equivalent of a `local` flag as described above in the
+`device-finder` docs.
diff --git a/third_party/fuchsia-sdk/docs/devices.md b/third_party/fuchsia-sdk/docs/devices.md
new file mode 100644
index 0000000..c28d982
--- /dev/null
+++ b/third_party/fuchsia-sdk/docs/devices.md
@@ -0,0 +1,29 @@
+# Working with target devices
+
+## Connecting to a device
+
+Fuchsia target devices must be connected to a host device via a network link.
+SSH is the protocol for communications over that link, as described in
+[this document](ssh.md).
+
+### Getting the device address
+
+Getting the Fuchsia device address can be done using mDNS. Methods for device
+discovery are outlined in [this document](device_discovery.md)
+
+## Flashing a device
+
+In order to flash a device, start a [bootserver](bootserver.md) on the host and
+restart the device into its bootloader.
+
+## Installing software onto a device
+
+The unit of installation on Fuchsia is a package.
+For information on how to push packages to a Fuchsia device, see the
+[this document](packages.md).
+
+## Getting logs from a device
+
+In order to retrieve logs from a device, open a shell on the device and run the
+`log_listener` command, which provides various filtering knobs. See
+[this page](logging.md) for more details.
diff --git a/third_party/fuchsia-sdk/docs/logging.md b/third_party/fuchsia-sdk/docs/logging.md
new file mode 100644
index 0000000..660e448
--- /dev/null
+++ b/third_party/fuchsia-sdk/docs/logging.md
@@ -0,0 +1,27 @@
+# Logging
+
+The preferred way to publish logs is to use the `syslog` API, currently
+available for C in `//pkg/syslog`.
+
+The library provides the ability to tag logs so that they can later be filtered
+upon retrieval.
+
+In order to get logs from a device, open a shell on the device as described in
+[this document](ssh.md) and run:
+```
+$ log_listener
+```
+
+To view specifics logs, add a tag specification:
+```
+$ log_listener --tag foobar
+```
+
+## Symbolization
+
+`//tools/symbolize` should be used to symbolize stack traces. It should be
+pointed to the `.build-id` directory at the root of the SDK, where debug symbols
+are hosted:
+```
+tools/symbolize --build-id-dir .build-id
+```
diff --git a/third_party/fuchsia-sdk/docs/low_level.json b/third_party/fuchsia-sdk/docs/low_level.json
new file mode 100644
index 0000000..4f48575
--- /dev/null
+++ b/third_party/fuchsia-sdk/docs/low_level.json
@@ -0,0 +1,16 @@
+{
+ "docs": [
+ "README.md",
+ "docs/README.md",
+ "docs/bootserver.md",
+ "docs/compilation.md",
+ "docs/debugger.md",
+ "docs/device_discovery.md",
+ "docs/devices.md",
+ "docs/logging.md",
+ "docs/packages.md",
+ "docs/ssh.md"
+ ],
+ "name": "low_level",
+ "type": "documentation"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/docs/metadata_schemas.json b/third_party/fuchsia-sdk/docs/metadata_schemas.json
new file mode 100644
index 0000000..ce1f62e
--- /dev/null
+++ b/third_party/fuchsia-sdk/docs/metadata_schemas.json
@@ -0,0 +1,17 @@
+{
+ "docs": [
+ "meta/schemas/cc_prebuilt_library.json",
+ "meta/schemas/cc_source_library.json",
+ "meta/schemas/common.json",
+ "meta/schemas/dart_library.json",
+ "meta/schemas/device_profile.json",
+ "meta/schemas/documentation.json",
+ "meta/schemas/fidl_library.json",
+ "meta/schemas/host_tool.json",
+ "meta/schemas/loadable_module.json",
+ "meta/schemas/manifest.json",
+ "meta/schemas/sysroot.json"
+ ],
+ "name": "metadata_schemas",
+ "type": "documentation"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/docs/modular/modular_config_schema.json b/third_party/fuchsia-sdk/docs/modular/modular_config_schema.json
new file mode 100644
index 0000000..01e18fc
--- /dev/null
+++ b/third_party/fuchsia-sdk/docs/modular/modular_config_schema.json
@@ -0,0 +1,145 @@
+{
+ "$schema": "http://json-schema.org/schema#",
+ "title": "Schema for modular framework configuration",
+ "definitions": {
+ "basemgr": {
+ "type": "object",
+ "properties": {
+ "enable_cobalt": { "type": "boolean", "default": true },
+ "enable_presenter": { "type": "boolean", "default": false },
+ "test": { "type": "boolean", "default": false },
+ "use_minfs": { "type": "boolean", "default": true },
+ "use_session_shell_for_story_shell_factory": {
+ "type": "boolean",
+ "default": false
+ },
+ "base_shell": { "$ref": "#definitions/base_shell" },
+ "session_shells": {
+ "type": "array",
+ "items": { "$ref": "#/definitions/session_shell" }
+ },
+ "story_shell_url": {
+ "type": "string",
+ "pattern": "^fuchsia-pkg://([^/]+)/([^/#]+)(/([^/#]+))?(#(.+))?$",
+ "default": "fuchsia-pkg://fuchsia.com/mondrian#meta/mondrian.cmx"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["base_shell", "session_shells"]
+ },
+ "base_shell": {
+ "type": "object",
+ "properties": {
+ "url": {
+ "type": "string",
+ "pattern": "^fuchsia-pkg://([^/]+)/([^/#]+)(/([^/#]+))?(#(.+))?$",
+ "default": "fuchsia-pkg://fuchsia.com/dev_base_shell#meta/dev_base_shell.cmx"
+ },
+ "keep_alive_after_login": { "type": "boolean", "default": false },
+ "args": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false,
+ "required": ["url"]
+ },
+ "session_shell": {
+ "type": "object",
+ "properties": {
+ "url": {
+ "type": "string",
+ "pattern": "^fuchsia-pkg://([^/]+)/([^/#]+)(/([^/#]+))?(#(.+))?$",
+ "default": "fuchsia-pkg://fuchsia.com/ermine_session_shell#meta/ermine_session_shell.cmx"
+ },
+ "display_usage": { "type": "string" },
+ "screen_height": { "type": "number" },
+ "screen_width": { "type": "number" }
+ },
+ "additionalProperties": false,
+ "required": ["url"]
+ },
+ "sessionmgr": {
+ "type": "object",
+ "properties": {
+ "cloud_provider": {
+ "type": "string",
+ "enum": ["LET_LEDGER_DECIDE", "FROM_ENVIRONMENT", "NONE"],
+ "default": "LET_LEDGER_DECIDE"
+ },
+ "enable_cobalt": { "type": "boolean", "default": true },
+ "enable_story_shell_preload": { "type": "boolean", "default": true },
+ "use_memfs_for_ledger": { "type": "boolean", "default": false },
+ "startup_agents": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "pattern": "^fuchsia-pkg://([^/]+)/([^/#]+)(/([^/#]+))?(#(.+))?$"
+ },
+ "uniqueItems": true
+ },
+ "session_agents": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "pattern": "^fuchsia-pkg://([^/]+)/([^/#]+)(/([^/#]+))?(#(.+))?$"
+ },
+ "uniqueItems": true
+ },
+ "component_args": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "$ref": "#/definitions/component_args"
+ }
+ },
+ "agent_service_index": {
+ "type": "array",
+ "items": { "$ref": "#/definitions/agent_service_index_entry" },
+ "uniqueItems": true
+ }
+ },
+ "additionalProperties": false
+ },
+ "component_args": {
+ "type": "object",
+ "properties": {
+ "uri": {
+ "type": "string",
+ "pattern": "^[a-z|-]+://.+"
+ },
+ "args": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "required": ["uri", "args"]
+ }
+ },
+ "agent_service_index_entry": {
+ "type": "object",
+ "properties": {
+ "service_name": {
+ "type": "string",
+ "pattern": "^[^.]+[.][^.]+([.][^.]+)*$"
+ },
+ "agent_url": {
+ "type": "string",
+ "pattern": "^fuchsia-pkg://([^/]+)/([^/#]+)(/([^/#]+))?(#(.+))?$"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["service_name", "agent_url"]
+ }
+ },
+ "type": "object",
+ "properties": {
+ "basemgr": { "$ref": "#/definitions/basemgr" },
+ "sessionmgr": { "$ref": "#/definitions/sessionmgr" }
+ },
+ "required": ["basemgr", "sessionmgr"],
+ "additionalProperties": false
+}
diff --git a/third_party/fuchsia-sdk/docs/modular_config_schema.json b/third_party/fuchsia-sdk/docs/modular_config_schema.json
new file mode 100644
index 0000000..39e11eb
--- /dev/null
+++ b/third_party/fuchsia-sdk/docs/modular_config_schema.json
@@ -0,0 +1,7 @@
+{
+ "docs": [
+ "docs/modular/modular_config_schema.json"
+ ],
+ "name": "modular_config_schema",
+ "type": "documentation"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/docs/musl_license.json b/third_party/fuchsia-sdk/docs/musl_license.json
new file mode 100644
index 0000000..e2121e9
--- /dev/null
+++ b/third_party/fuchsia-sdk/docs/musl_license.json
@@ -0,0 +1,7 @@
+{
+ "docs": [
+ "COPYRIGHT.musl"
+ ],
+ "name": "musl_license",
+ "type": "documentation"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/docs/open_source.json b/third_party/fuchsia-sdk/docs/open_source.json
new file mode 100644
index 0000000..376bda4
--- /dev/null
+++ b/third_party/fuchsia-sdk/docs/open_source.json
@@ -0,0 +1,9 @@
+{
+ "docs": [
+ "AUTHORS",
+ "LICENSE",
+ "PATENTS"
+ ],
+ "name": "open_source",
+ "type": "documentation"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/docs/packages.md b/third_party/fuchsia-sdk/docs/packages.md
new file mode 100644
index 0000000..b230a7f
--- /dev/null
+++ b/third_party/fuchsia-sdk/docs/packages.md
@@ -0,0 +1,161 @@
+# Packages
+
+A package is the unit of installation on a Fuchsia system.
+
+## Anatomy
+
+_To be added..._
+
+## Working with packages
+
+The majority of these instructions rely on the `pm` tool which is available
+in `//tools`.
+
+This document describes the various steps to build and install a package:
+
+* [Build a package](#build-package)
+* [Publish a package](#publish-package)
+* [Install a package](#install-package)
+* [Run a component from an installed package](#run-component)
+
+For more details about each step, see `pm`'s help messages.
+
+### Build a package {#build-package}
+
+To build a package:
+
+1. Create the package ID file:
+
+ Note: `$PACKAGE_DIR` is a staging directory where the package
+ is built.
+
+ ```
+ pm -o $PACKAGE_DIR -n $PACKAGE_NAME init
+ ```
+
+ This generates the package ID file implicitly as
+ `$PACKAGE_DIR/meta/package`. Set `$PACKAGE_ID_FILE` accordingly
+ for use in subsequent steps:
+
+ ```
+ export PACKAGE_ID_FILE=${PACKAGE_DIR}/meta/package
+ ```
+
+ `$PACKAGE_ID_FILE` will contain the following data:
+
+ ```
+ {
+ "name": "<package name>",
+ "version": "<package version>"
+ }
+ ```
+
+2. Create the manifest file, `$MANIFEST_FILE`, that provides the path to
+ the package ID file. Each line of a manifest file maps a single file that
+ is contained in the package and is in the form of `destination=source` where:
+
+ * `destination` is the path to the file in the final package
+ * `source` is the path to the file on the host machine
+
+ The manifest file must include at least one line for the package ID file like
+ this:
+
+ ```
+ meta/package=<package ID file>
+ ```
+
+3. Generate the package metadata archive:
+
+ ```
+ pm -o $PACKAGE_DIR -m $MANIFEST_FILE build
+ ```
+
+ This creates the metadata archive at `$PACKAGE_DIR/meta.far`.
+
+4. Create the package archive `$PACKAGE_ARCHIVE`:
+
+ ```
+ pm -o $PACKAGE_DIR -m $MANIFEST_FILE archive
+ ```
+
+ This command creates the package archive implicitly as
+ `$PACKAGE_DIR/$PACKAGE_NAME-0.far`. Set `$PACKAGE_ARCHIVE` accordingly
+ for use in subsequent steps:
+
+ ```
+ export PACKAGE_ARCHIVE=${PACKAGE_DIR}/${PACKAGE_NAME}-0.far
+ ```
+
+ If the contents of the package change, you need to re-run the
+ `pm -o $PACKAGE_DIR -m $MANIFEST_FILE archive` command.
+
+You have successfully built a package. You are now ready to publish the package.
+
+### Publish a package {#publish-package}
+
+To publish a package:
+
+1. Initialize a directory, `$REPO`, that serves as a packages repository:
+
+ ```
+ pm newrepo -repo $REPO
+ ```
+
+ This creates a directory structure named `$REPO` that is ready for
+ publishing packages.
+
+2. Publish packages to the repository `$REPO`:
+
+ ```
+ pm publish -a -r $REPO -f $PACKAGE_ARCHIVE
+ ```
+
+ `pm publish` parses `$PACKAGE_ARCHIVE` and publishes the package in the
+ provided `$REPO` directory. If you run this command multiple times with
+ different package archives, `pm publish` publishes the packages to the same
+ repository. New versions of a same package can be published using the same
+ command.
+
+You have successfully published a package. You are now ready to install a
+package.
+
+### Install a package {#install-package}
+
+To install a package:
+
+1. Start the package server:
+
+ ```
+ pm serve -repo $REPO
+ ```
+
+ By default, this starts an amber server on the host machine at port `8083`.
+
+2. (On the target device) Add the new repository as an update source with
+ `amberctl`:
+
+ ```
+ amberctl add_repo_cfg -n $REPO -f http://$HOST_ADDRESS:8083/config.json
+ ```
+
+ If the component is not already on the system, `amberctl` installs the package.
+ If the package already exists, `amberctl` installs any package updates.
+
+You have successfully installed or updated the package. You are now ready to
+run a component from the installed package.
+
+### Run a component from an installed package {#run-component}
+
+To run a component published in a package:
+
+1. (On the target device) Run:
+
+ Note: `$COMPONENT_URI` is in this form
+ `fuchsia-pkg://${REPO}/${PACKAGE_NAME}#meta/<component name>.cmx`.
+
+ ```
+ run $COMPONENT_URI
+ ```
+
+You have successfully run a component from the installed package.
+
diff --git a/third_party/fuchsia-sdk/docs/ssh.md b/third_party/fuchsia-sdk/docs/ssh.md
new file mode 100644
index 0000000..3426c5b
--- /dev/null
+++ b/third_party/fuchsia-sdk/docs/ssh.md
@@ -0,0 +1,59 @@
+# SSH
+
+SSH is the supported protocol for communication between a Fuchsia target device
+and a host device.
+This document describes how to properly set up an SSH connection between these
+devices.
+
+## Prerequisites
+
+On the host side, a proper SSH distribution is required.
+
+A public/private keypair is also needed.
+It may be generated via the `ssh-keygen` command, or extracted from the running
+SSH agent via `ssh-add -L`.
+
+## Provisioning a device
+
+There are two options for installing the public key onto the target.
+
+### By installing it during paving (preferred)
+
+Follow the instruction for [paving](bootserver.md) the target device, and add an
+extra argument to the `bootserver` call pointing to the public key:
+```
+$ bootserver --authorized-keys $PUBLIC_KEY <other args>
+```
+
+### By modifying the Fuchsia image directly
+
+The `fuchsia.zbi` image may be modified to include the public key using the
+`zbi` tool:
+```
+$ zbi -o $FUCHSIA_DOT_ZBI -e data/ssh/authorized_keys=$PUBLIC_KEY
+```
+
+Note that this method is mainly designed for situations where paving is not
+necessarily an efficient option (e.g. testing on an emulator).
+Use with care.
+
+## Connecting to a device
+
+Provided that the address of the target device is known as `$TARGET_ADDRESS`,
+open a shell on that device with:
+```
+$ ssh -i $PRIVATE_KEY fuchsia@$TARGET_ADDRESS
+```
+
+Note that if you got the key from your SSH agent, or if the key is in a well
+known location (`$SSH_HOME`) under a well known name (`id_*`), you may omit the
+`-i` argument.
+
+Note also that the host keys for a Fuchsia target device are generated at first
+boot, meaning that every time the device gets paved the keys are going to
+change.
+You may want to disable host key checking when connecting to a Fuchsia device to
+avoid running into errors by adding the following flags:
+```
+-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null
+```
diff --git a/third_party/fuchsia-sdk/docs/vulkan_license.json b/third_party/fuchsia-sdk/docs/vulkan_license.json
new file mode 100644
index 0000000..0ee5ef9
--- /dev/null
+++ b/third_party/fuchsia-sdk/docs/vulkan_license.json
@@ -0,0 +1,7 @@
+{
+ "docs": [
+ "LICENSE.vulkan"
+ ],
+ "name": "vulkan_license",
+ "type": "documentation"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.accessibility.semantics/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.accessibility.semantics/BUILD.gn
new file mode 100644
index 0000000..fb8ef57
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.accessibility.semantics/BUILD.gn
@@ -0,0 +1,29 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.accessibility.semantics") {
+ library_name = "semantics"
+ namespace = "fuchsia.accessibility"
+ public_deps = [
+ "../fuchsia.math",
+ "../fuchsia.ui.gfx",
+ "../fuchsia.ui.views",
+ ]
+ sources = [
+ "node.fidl",
+ "semantics_manager.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.accessibility.semantics",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.accessibility.semantics/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.accessibility.semantics/meta.json
new file mode 100644
index 0000000..abcf651
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.accessibility.semantics/meta.json
@@ -0,0 +1,14 @@
+{
+ "deps": [
+ "fuchsia.math",
+ "fuchsia.ui.gfx",
+ "fuchsia.ui.views"
+ ],
+ "name": "fuchsia.accessibility.semantics",
+ "root": "fidl/fuchsia.accessibility.semantics",
+ "sources": [
+ "fidl/fuchsia.accessibility.semantics/node.fidl",
+ "fidl/fuchsia.accessibility.semantics/semantics_manager.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.accessibility.semantics/node.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.accessibility.semantics/node.fidl
new file mode 100644
index 0000000..e17da74
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.accessibility.semantics/node.fidl
@@ -0,0 +1,119 @@
+// 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.
+
+library fuchsia.accessibility.semantics;
+
+using fuchsia.ui.gfx;
+
+/// Represents actions that can be applied to Nodes.
+enum Action {
+ /// The default action associated with the element.
+ DEFAULT = 1;
+ /// The secondary action associated with the element. This may correspond to a long press
+ /// (touchscreens) or right click (mouse).
+ SECONDARY = 2;
+ /// Set (input/non-accessibility) focus on this element.
+ SET_FOCUS = 3;
+ /// Set the element's value.
+ SET_VALUE = 4;
+ /// Scroll node to make it visible.
+ SHOW_ON_SCREEN = 5;
+};
+
+/// Represents a role of an element on a UI.
+enum Role {
+ /// Role used to represent elements which role is not currently supported.
+ UNKNOWN = 1;
+ /// Something on screen that can be clicked/activated, that has a single function.
+ BUTTON = 2;
+ /// Header text, e.g. something tagged <h1> in HTML.
+ HEADER = 3;
+ /// An image or graphic.
+ IMAGE = 4;
+ /// A field containing text that is not a header.
+ TEXT_FIELD = 5;
+};
+
+/// An attribute is an essential property to describe an element. Unlike states, attributes do not
+/// change over the life of an element.
+/// Example: A button with a label attribute 'ok' should never change to 'cancel', as this is not
+/// the same element.
+table Attributes {
+ /// The primary label for an element. If longer than MAX_LABEL_SIZE the client is responsible
+ /// for truncating the label.
+ 1: string:MAX_LABEL_SIZE label;
+
+ /// The secondary label for an element. If longer than MAX_LABEL_SIZE the client is responsible
+ /// for truncating the label.
+ 2: string:MAX_LABEL_SIZE secondary_label;
+
+ /// A description of what the secondary action on a node (equivalent to long press or right click) should do.
+ 3: string:MAX_LABEL_SIZE secondary_action_description;
+};
+
+/// Represents the state of a UI checkbox.
+enum CheckedState {
+ /// Used when no data is entered or the element is not a check box.
+ NONE = 1;
+ /// Checked
+ CHECKED = 2;
+ /// Unchecked
+ UNCHECKED = 3;
+ /// Indeterminate state
+ MIXED = 4;
+};
+
+/// A state is a dynamic property of an element that may change in response to
+/// user action or automated processes. Thus, they are different from attributes
+/// in an important point, which is frequency of change.
+table States {
+ /// DEPRECATED
+ 1: bool checked;
+
+ /// State of a checkbox.
+ 2: CheckedState checked_state;
+
+ /// Whether the element is currently selected.
+ 3: bool selected;
+
+ /// Whether the element is currently hidden or marked invisible by the framework.
+ 4: bool hidden;
+
+ /// The user-entered value of the element, if applicable. If longer than MAX_VALUE_SIZE the
+ /// client is responsible for truncating.
+ 5: string:MAX_VALUE_SIZE value;
+};
+
+/// The Node represents a semantic element on an interface. This may
+/// be a button, a text field, a checkbox or any element that has a relevant
+/// semantic meaning so that assistive technology can understand the current UI.
+table Node {
+ /// Unique ID that represents a node in a particular UI.
+ /// Zero is assumed to be the root node and the only entry point to the tree.
+ /// No forest is allowed.
+ 1: uint32 node_id;
+
+ /// Role of this element, e.g. button, checkbox, etc.
+ 2: Role role;
+
+ /// A table of states of this object, e.g. checked, editable, etc.
+ 3: States states;
+
+ /// A table of attributes of this node.
+ 4: Attributes attributes;
+
+ /// A list of actions that can be performed on this node.
+ 5: vector<Action>:100 actions;
+
+ /// The list of child IDs of this node, in traversal order. Runtimes supplying semantic tree
+ /// information are responsible for ensuring the tree does not contain cycles. Each node may
+ /// have only one parent.
+ 6: vector<uint32>:MAX_FAN_OUT child_ids;
+
+ /// Local bounding box of this element.
+ 7: fuchsia.ui.gfx.BoundingBox location;
+
+ /// Transform from parent coordinate space to local space. 4x4 for compatibility with scenic.
+ 8: fuchsia.ui.gfx.mat4 transform;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.accessibility.semantics/semantics_manager.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.accessibility.semantics/semantics_manager.fidl
new file mode 100644
index 0000000..050b2ae
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.accessibility.semantics/semantics_manager.fidl
@@ -0,0 +1,97 @@
+// 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.
+
+library fuchsia.accessibility.semantics;
+
+using fuchsia.math;
+using fuchsia.ui.views;
+
+/// Maximum depth of the semantic tree.
+const uint64 MAX_TREE_DEPTH = 256;
+
+/// Maximum number of children for a node in the semantic tree.
+const uint64 MAX_FAN_OUT = 20000;
+
+/// Maximum number of semantic nodes that may be sent in a single update.
+const uint64 MAX_NODES_PER_UPDATE = 2048;
+
+/// Maximum size of a label string, in bytes.
+const uint64 MAX_LABEL_SIZE = 16384;
+
+/// Maximum size of a value string, in bytes.
+const uint64 MAX_VALUE_SIZE = 16384;
+
+/// An interface to manage connections with views for the purposes of gathering semantic information
+/// about their current UI state.
+///
+/// The manager allows clients to register as a semantic provider for their view(s). In return the
+/// semantics manager supplies an interface to update, commit and delete information from the
+/// semantic tree for that view. If the semantic manager encounters an error, it will close the
+/// channel, delete any associated data and rely on the client to re-register.
+[Discoverable]
+protocol SemanticsManager {
+ RegisterViewForSemantics(fuchsia.ui.views.ViewRef view_ref,
+ SemanticListener listener,
+ request<SemanticTree> semantic_tree_request);
+};
+
+/// Interface to update the semantic tree for a particular view. Nodes can be added, updated or
+/// deleted. Because the size of an update may exceed FIDL transfer limits, clients are responsible
+/// for breaking up changes into multiple update and delete calls that conform to these limits. The
+/// commit function must always be called at the end of a full update push to signal the end of an
+/// update.
+///
+/// The client may make several calls to UpdateSemanticNodes(...) or DeleteSemanticNodes(...)
+/// before calling CommitUpdates(), and must wait for the semantics manager to reply to the
+/// CommitUpdates() method to know whether an update has been processed. This allows the client to
+/// break up a set of changes (e.g. a re-computed semantic tree) to the semantic tree into
+/// FIDL-compatible chunks, but commit them all at once.
+///
+/// If the semantics manager ever receives inconsistent state from the client, such as an
+/// invalid tree or unrecognized parent node id, the server will close the channel. The client is
+/// responsible for reconnecting and re-sending its state from scratch.
+protocol SemanticTree {
+
+ /// Sends new/updated nodes to the root to add to the cache on the next commit.
+ UpdateSemanticNodes(vector<Node>:MAX_NODES_PER_UPDATE nodes);
+
+ /// Tells the root to remove nodes with node_ids from the semantic tree on the next commit.
+ DeleteSemanticNodes(vector<uint32>:MAX_NODES_PER_UPDATE node_ids);
+
+ /// Commits pending changes to node tree associated with the view using UpdateSemanticNodes and
+ /// DeleteSemanticNodes. Updates are processed in the order in which they are received. If the
+ /// committed updates result in an ill-formed tree (for example a missing root node or a cycle)
+ /// the semantic manager will close the channel.
+ CommitUpdates() -> ();
+};
+
+/// Results of hit testing on a view's semantic tree which is implemented by
+/// Runtimes(like Flutter/Chrome) and sent to Accessibility.
+table Hit {
+ /// Unique ID that represents a node in a particular UI.
+ /// Zero is assumed to be the root node and the only entry point to the tree.
+ /// node_id will not be filled when there is no hit.
+ 1: uint32 node_id;
+
+ /// The ordered list of node ids which represent path from root node to the hit node.
+ 2: vector<uint32>:MAX_TREE_DEPTH path_from_root;
+};
+
+/// A semantic provider is the client-side interface that the manager can use to enable or disable
+/// semantic updates, and to ask clients to perform accessibility actions.
+protocol SemanticListener {
+ /// Asks the semantics provider to perform an accessibility action on the
+ /// node with node id in the front-end.
+ OnAccessibilityActionRequested(uint32 node_id, Action action) -> (bool handled);
+
+ /// Asks the semantics provider to perform hit testing and return the result.
+ [Transitional]
+ HitTest(fuchsia.math.PointF local_point) -> (Hit result);
+
+ /// Callback telling the client whether or not to send updates to the semantic tree.
+ /// The semantics manager will clear all state when this is called with updates_enabled = false.
+ /// When called with updates_enabled = true, the client should sent the full state of the
+ /// current semantic tree.
+ OnSemanticsModeChanged(bool updates_enabled) -> ();
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.auth.oldtokens/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.auth.oldtokens/BUILD.gn
new file mode 100644
index 0000000..3c42caf
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.auth.oldtokens/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.auth.oldtokens") {
+ library_name = "oldtokens"
+ namespace = "fuchsia.auth"
+ public_deps = [
+ ]
+ sources = [
+ "credentials_producer.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.auth.oldtokens",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.auth.oldtokens/credentials_producer.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.auth.oldtokens/credentials_producer.fidl
new file mode 100644
index 0000000..30c33bf
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.auth.oldtokens/credentials_producer.fidl
@@ -0,0 +1,33 @@
+// 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.
+
+library fuchsia.auth.oldtokens;
+
+/// The id of a user linked to this device, alongside the current access token
+/// to make requests on the user's behalf.
+table Credential {
+ /// Opaque id for the user with which this credential is associated. It is
+ /// stable across reconnections to the CredentialsProducer protocol.
+ 1: string user_id;
+
+ /// OAuth2 access token for this user.
+ 2: string access_token;
+};
+
+/// Clients can connect to this protocol to subscribe to changes in the set of
+/// users linked to this device, as well as the OAuth2 access token associated
+/// with each.
+///
+/// This protocol won't be supported on the majority of devices, and shouldn't
+/// be used without permission from its maintainers.
+[Discoverable]
+protocol CredentialsProducer {
+ /// Get the set of users linked to this device, and their corresponding access
+ /// tokens. While the connection to the service remains uninterrumpted, the
+ /// method call hangs if it would return the same response as the previous
+ /// time it was called by this client. In other words, if the client already
+ /// has the most up-to-date credentials, the method acts as a hanging get and
+ /// only returns when there's an update to report.
+ GetUpdatedCredentials() -> (vector<Credential> credentials);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.auth.oldtokens/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.auth.oldtokens/meta.json
new file mode 100644
index 0000000..2ddace2
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.auth.oldtokens/meta.json
@@ -0,0 +1,9 @@
+{
+ "deps": [],
+ "name": "fuchsia.auth.oldtokens",
+ "root": "fidl/fuchsia.auth.oldtokens",
+ "sources": [
+ "fidl/fuchsia.auth.oldtokens/credentials_producer.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.auth/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.auth/BUILD.gn
new file mode 100644
index 0000000..dc93166
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.auth/BUILD.gn
@@ -0,0 +1,29 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.auth") {
+ library_name = "auth"
+ namespace = "fuchsia"
+ public_deps = [
+ "../fuchsia.ui.views",
+ ]
+ sources = [
+ "attestation_signer.fidl",
+ "auth_provider.fidl",
+ "common.fidl",
+ "token_manager.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.auth",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.auth/attestation_signer.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.auth/attestation_signer.fidl
new file mode 100644
index 0000000..c630e9f
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.auth/attestation_signer.fidl
@@ -0,0 +1,31 @@
+// Copyright 2018 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.
+
+library fuchsia.auth;
+
+/// This file contains an interface to cryptographically sign any plain text data
+/// using any crypto key. This interface is useful for signing JWT's in device
+/// attestation based authentication.
+///
+/// Specifies the success/failure status from the attestation signer.
+enum AttestationSignerStatus {
+ /// The command completed successfully
+ OK = 0;
+ /// The command referred to a missing, or an invalid argument.
+ INVALID_ARGUMENT = 1;
+ /// There was an error in generating crypto signatures for the given
+ /// plaintext. This usually indicates errors for misconfigured keys or
+ /// signature algorithms from the underlying crypto library.
+ SIGNING_ERROR = 2;
+};
+
+protocol AttestationSigner {
+ /// Cryptographically signs the `plaintext` data sent in request using a
+ /// crypto key configured at initialization.
+ ///
+ /// Returns the raw bytes of the `signature` string on success. Otherwise,
+ /// an error status is returned.
+ SignData(bytes plaintext)
+ -> (AttestationSignerStatus status, bytes? signature);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.auth/auth_provider.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.auth/auth_provider.fidl
new file mode 100644
index 0000000..09f969e
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.auth/auth_provider.fidl
@@ -0,0 +1,45 @@
+// Copyright 2017 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.
+
+library fuchsia.auth;
+
+using fuchsia.ui.views;
+
+/// User attributes returned to callers on authorizing a new user at any auth
+/// provider. These attributes are generated by calling the auth provider's
+/// user profile apis.
+struct UserProfileInfo {
+ /// User identifier returned by the backend identity provider server to
+ /// identify the user after successful authorization. Some identity providers
+ /// send verified email address as the identifier, and some send an opaque
+ /// string as the user identifier.
+ string id;
+
+ /// The name that is displayed on the base shell while logging in. Display
+ /// name is fetched from user profile attributes as configured by the user at
+ /// the given identity provider.
+ string? display_name;
+
+ /// User's profile url that is used by the base shell while logging in.
+ /// Profile url is fetched from user profile attributes as configured by the
+ /// user at the given identity provider.
+ string? url;
+
+ /// User's profile image url that is used by the base shell while logging in.
+ /// Profile image url is fetched from user profile attributes as configured by
+ /// the user at the given identity provider.
+ string? image_url;
+};
+
+/// This interface is implemented by base shell. It is used to notify the
+/// base shell that a view for login needs to be started / stopped.
+protocol AuthenticationUIContext {
+ /// Requests base shell to display `view_holder_token` for authentication.
+ /// Another call to StartOverlay() will not be made until StopOverlay()
+ /// has been called.
+ StartOverlay(fuchsia.ui.views.ViewHolderToken view_holder_token);
+
+ /// Requests base shell to stop displaying the auth view.
+ StopOverlay();
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.auth/common.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.auth/common.fidl
new file mode 100644
index 0000000..2385757
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.auth/common.fidl
@@ -0,0 +1,22 @@
+// Copyright 2018 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.
+
+library fuchsia.auth;
+
+/// A unique identifier for an account with some service provider, comprised of
+/// the identity of the service provider and an account identity supplied by that
+/// service provider.
+///
+// TODO(jsankey): Integrate other parts of the AuthProvider API with this
+// domain-based identity. In general multiple auth_provider_types may exist for
+// the same identity_provider_domain.
+struct ServiceProviderAccount {
+ /// The primary domain of the identity provider, such as "www.google.com".
+ string identity_provider_domain;
+
+ /// User identifier as supplied by the identity provider. Some identity
+ /// providers send verified email address as the identifier, some send an
+ /// opaque string.
+ string user_profile_id;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.auth/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.auth/meta.json
new file mode 100644
index 0000000..c2d641a
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.auth/meta.json
@@ -0,0 +1,14 @@
+{
+ "deps": [
+ "fuchsia.ui.views"
+ ],
+ "name": "fuchsia.auth",
+ "root": "fidl/fuchsia.auth",
+ "sources": [
+ "fidl/fuchsia.auth/attestation_signer.fidl",
+ "fidl/fuchsia.auth/auth_provider.fidl",
+ "fidl/fuchsia.auth/common.fidl",
+ "fidl/fuchsia.auth/token_manager.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.auth/token_manager.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.auth/token_manager.fidl
new file mode 100644
index 0000000..533a09b
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.auth/token_manager.fidl
@@ -0,0 +1,210 @@
+// Copyright 2017 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.
+
+library fuchsia.auth;
+
+/// Specifies the success/failure status of TokenManager calls.
+enum Status {
+ /// The command completed successfully
+ OK = 0;
+ /// The command referred to a missing, misconfigured, or failed auth provider.
+ /// Retrying is not recommended.
+ AUTH_PROVIDER_SERVICE_UNAVAILABLE = 1;
+ /// The auth server was reachable but responded with an error. These errors
+ /// are typically caused by a configuration problem or a revoked token and so
+ /// should not be retried.
+ AUTH_PROVIDER_SERVER_ERROR = 2;
+ /// An internal error occurred. This usually indicates a bug within the Token
+ /// Manager itself. Retry is optional.
+ INTERNAL_ERROR = 3;
+ /// An invalid or non-functional AuthContextProvider was provided. Retrying is
+ /// unlikely to correct this error.
+ INVALID_AUTH_CONTEXT = 4;
+ /// The request was malformed in some way, such as using an empty string for
+ /// the user_profile_id. The request should not be retried.
+ INVALID_REQUEST = 5;
+ /// The requested user profile could not be found in the database. The request
+ /// should not be retried.
+ USER_NOT_FOUND = 6;
+ /// A local error occurred such as disk I/O or memory allocation. Retry, after
+ /// a delay, is recommended.
+ IO_ERROR = 7;
+ /// Some other problem occurred that cannot be classified using one of the more
+ /// specific statuses. Retry is optional.
+ UNKNOWN_ERROR = 8;
+ /// The auth server requires that the user reauthenticate. The client should
+ /// call the Authorize method.
+ REAUTH_REQUIRED = 9;
+ /// The user cancelled the flow. User consent is required before any retry.
+ USER_CANCELLED = 10;
+ /// A network error occurred while communicating with the auth server. Retry,
+ /// after a delay, is recommended.
+ NETWORK_ERROR = 11;
+};
+
+/// Stores configuration parameters required to connect to available
+/// `AuthProvider`s. It is used by TokenManager to instantiate all auth providers
+/// during startup.
+struct AuthProviderConfig {
+ /// Type of OAuth Identity provider. An identity provider authenticates and
+ /// authorizes users for accessing their services. They also provide unique
+ /// identifiers for users to interact with the system and may provide
+ /// information about the user that is known to the provider.
+ ///
+ /// Sample auth provider types include:
+ /// Dev : An identity provider that's used for development and testing.
+ /// Google: Uses Google as the identity provider. Authorization from Google
+ /// requires a working network connection and a web view.
+ /// Spotify: Uses Spotify as an identity provider.
+ string auth_provider_type;
+
+ /// Url of the Fuchsia component implementing the AuthProvider.
+ string url;
+
+ /// Optional parameters specified during AuthProvider startup.
+ vector<string>? params;
+};
+
+/// Stores OAuth configuration details for a given client application. These
+/// details are used in the OAuth authorization step.
+struct AppConfig {
+ /// An OAuth identity provider matching a configuration set in
+ /// AuthProviderConfig.auth_provider_type.
+ string auth_provider_type;
+
+ /// OAuth client id.
+ string? client_id;
+
+ /// OAuth client secret.
+ /// This field is optional and will only be used on calls to Authorize.
+ string? client_secret;
+
+ /// OAuth application's redirect uri.
+ /// This field is optional and will only be used on calls to Authorize.
+ string? redirect_uri;
+};
+
+/// Implemented by a privileged system component with the ability to display UI
+/// to the end user.
+///
+/// This is provided during the initialization of TokenManager service and is
+/// used for any subsequent authorize calls. The UI contexts created by this
+/// interface are used to display OAuth login and permission screens to the end
+/// user.
+protocol AuthenticationContextProvider {
+ GetAuthenticationUIContext(request<AuthenticationUIContext> request);
+};
+
+/// This interface provides a discoverable mechanism to create TokenManager
+/// instances for each user, and to supply auth provider configuration
+/// information using the structs defined in `auth_provider.fidl`.
+[Discoverable]
+protocol TokenManagerFactory {
+ /// Creates an OAuth TokenManager instance scoped for the component specified
+ /// by `application_url`, the Fuchsia user specified by `user_id`, and the list
+ /// of auth providers specified in `auth_provider_configs`.
+ ///
+ /// `auth_context_provider` is used to generate AuthenticationUIContexts during
+ /// TokenManager methods that require UI, unless the caller of those methods
+ /// supplies an alternative AuthenticationUIContext.
+ GetTokenManager(string user_id, string application_url,
+ vector<AuthProviderConfig> auth_provider_configs,
+ AuthenticationContextProvider auth_context_provider,
+ request<TokenManager> token_manager);
+};
+
+/// This interface manages OAuth tokens at the Fuchsia system level for different
+/// auth identity providers.
+///
+/// If user authorization is required for minting tokens, TokenManager uses the
+/// `auth_context_provider's` UI context for displaying OAuth UI to the end user.
+///
+/// After initialization, TokenManager handles are typically handed out by
+/// Framework to components like Ledger and Agents. These components fetch
+/// OAuth tokens from any configured auth provider, and use the
+/// `auth_context_provider` initialized above for new authorizations.
+protocol TokenManager {
+ /// The first step of OAuth is to get authorization from the user. For Fuchsia
+ /// components, this is accomplished by displaying OAuth permissions in a view
+ /// provided by the caller. This view will use `auth_ui_context` if supplied,
+ /// or the `auth_context_provider` supplied at TokenManager creation if not.
+ /// The component's OAuth configuration is provided in `app_config` and
+ /// `app_scopes`. An optional `user_profile_id` that uniquely identifies an
+ /// account for a given auth provider may be provided to identify an existing
+ /// account during a re-auth flow.
+ ///
+ /// IoT ID authorization includes a mode where the user authorizes on a second
+ /// device and that device acquires an auth code from the auth provider.
+ /// In this mode, the auth code may be supplied in `auth_code` and no local
+ /// user interface will be displayed.
+ ///
+ /// After the user has successfully authorized, Token manager receives and
+ /// securely stores a persistent credential, such as an OAuth refresh token,
+ /// for the intended scopes. TokenManager later uses this credential for
+ /// minting short lived tokens.
+ ///
+ /// If the operation is successful, an OK status is returned along with user
+ /// profile information in `user_profile_info` such as the user's email,
+ /// image_url, profile_url, and first and last names as configured on the auth
+ /// provider backend system.
+ Authorize(AppConfig app_config, AuthenticationUIContext? auth_ui_context,
+ vector<string> app_scopes, string? user_profile_id, string? auth_code)
+ -> (Status status, UserProfileInfo? user_profile_info);
+
+ /// Returns a downscoped access token from an auth provider for the given user
+ /// `user_profile_id` and `scopes` to a Fuchsia component. The component's
+ /// OAuth configuration is provided in `app_config` and the `user_profile_id`
+ /// is the unique user identifier returned by the Authorize() call.
+ ///
+ /// In the interests of performance, Token Manager does not place the supplied
+ /// scopes in a canonical order during caching. To benefit from caching of
+ /// tokens, clients must request the same scopes in the same order across
+ /// calls.
+ ///
+ /// The access token is returned from cache if possible, otherwise the auth
+ /// provider is used to exchange the persistent credential for a new access
+ /// token.
+ GetAccessToken(AppConfig app_config, string user_profile_id,
+ vector<string> app_scopes) -> (Status status, string? access_token);
+
+ /// Returns a JWT identity token from an auth provider to a Fuchsia component
+ /// intended for the given `audience`. The component's OAuth configuration is
+ /// supplied in `app_config`, the intended recipient of the id_token is
+ /// supplied in `audience`, and `user_profile_id` is a unique account
+ /// identifier returned by the Authorize() or ListProfileIds() calls.
+ ///
+ /// `user_profile_id` is the unique user identifier returned by the
+ /// Authorize() call.
+ ///
+ /// The identity token is returned from cache if possible, otherwise the auth
+ /// provider is used to exchange the persistant credential for a new identity
+ /// token.
+ GetIdToken(AppConfig app_config, string user_profile_id, string? audience)
+ -> (Status status, string? id_token);
+
+ /// Deletes and revokes all long lived and short lived tokens generated for
+ /// an account and on behalf of a Fuchsia component. The component's OAuth
+ /// configuration is provided in `app_config` and `user_profile_id`
+ /// is a unique account identifier returned by the Authorize() or
+ /// ListProfileIds() calls.
+ ///
+ /// Deletion of tokens involves three steps:
+ ///
+ /// 1. Revoking credentials remotely at the auth provider.
+ /// 2. Deleting short lived tokens from the in-memory cache.
+ /// 3. Deleting persistent credentials stored locally on disk.
+ ///
+ /// If `force` is false then a failure at step 1 will terminate the method,
+ /// ensuring client and server state remain consistent. If `force` is true
+ /// then steps 2&3 will be performed and the method will return OK even if
+ /// step 1 fails, ensuring the local credentials are wiped in all
+ /// circumstances.
+ DeleteAllTokens(AppConfig app_config, string user_profile_id, bool force)
+ -> (Status status);
+
+ /// Returns a vector of all currently authorized user_profile_ids for a
+ /// component's OAuth configuration provided in `app_config`.
+ ListProfileIds(AppConfig app_config)
+ -> (Status status, vector<string> user_profile_ids);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.a2dp/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.a2dp/BUILD.gn
new file mode 100644
index 0000000..0642034
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.a2dp/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.bluetooth.a2dp") {
+ library_name = "a2dp"
+ namespace = "fuchsia.bluetooth"
+ public_deps = [
+ ]
+ sources = [
+ "audio_mode.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.bluetooth.a2dp",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.a2dp/audio_mode.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.a2dp/audio_mode.fidl
new file mode 100644
index 0000000..7dba806
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.a2dp/audio_mode.fidl
@@ -0,0 +1,31 @@
+// Copyright 2020 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.
+
+library fuchsia.bluetooth.a2dp;
+
+/// Enum corresponding to the A2DP SRC/SNK roles as defined in the
+/// A2DP v1.3.2 profile specification, section 2.2.
+enum Role {
+ /// Act as a source of digital audio streams, sending audio to peers.
+ SOURCE = 1;
+ /// Act as a sink of digital audio streams and play audio sent from peers.
+ SINK = 2;
+};
+
+/// A protocol for specifying which A2DP role this device should operate.
+[Discoverable]
+protocol AudioMode {
+ /// Switch the device to act as the specified A2DP Role. If the device is already
+ /// set to the requested role, calling this method is a no-op.
+ ///
+ /// When this method returns, a client can depend on the following:
+ /// 1. If the role was switched, the previous profile has requested removal
+ /// from the hosts' SDP databases, and all L2CAP channels associated with
+ /// the previous profile have initiated or completed the process of closing.
+ /// 2. The device is in the requested A2DP role.
+ ///
+ /// If the role cannot be set due to an internal error, the server will close
+ /// the channel.
+ SetRole(Role role) -> ();
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.a2dp/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.a2dp/meta.json
new file mode 100644
index 0000000..7a3400e
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.a2dp/meta.json
@@ -0,0 +1,9 @@
+{
+ "deps": [],
+ "name": "fuchsia.bluetooth.a2dp",
+ "root": "fidl/fuchsia.bluetooth.a2dp",
+ "sources": [
+ "fidl/fuchsia.bluetooth.a2dp/audio_mode.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.control/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.control/BUILD.gn
new file mode 100644
index 0000000..cda52a3
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.control/BUILD.gn
@@ -0,0 +1,30 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.bluetooth.control") {
+ library_name = "control"
+ namespace = "fuchsia.bluetooth"
+ public_deps = [
+ "../fuchsia.bluetooth",
+ ]
+ sources = [
+ "bonding.fidl",
+ "control.fidl",
+ "pairing_delegate.fidl",
+ "pairing_options.fidl",
+ "remote_device.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.bluetooth.control",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.control/bonding.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.control/bonding.fidl
new file mode 100644
index 0000000..ccc5f0c
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.control/bonding.fidl
@@ -0,0 +1,116 @@
+// Copyright 2018 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.
+
+library fuchsia.bluetooth.control;
+
+struct SecurityProperties {
+ bool authenticated;
+ bool secure_connections;
+ uint8 encryption_key_size;
+};
+
+// Represents a key that was received from a peer.
+struct RemoteKey {
+ // The security properties of this link under which this key was received.
+ SecurityProperties security_properties;
+
+ // 128 bit key
+ array<uint8>:16 value;
+};
+
+// Represents a locally assigned key that is reused across bonds.
+struct LocalKey {
+ array<uint8>:16 value;
+};
+
+// Represents a LE Long-Term RemoteKey. The `ediv` and `rand` fields are zero if
+// distributed using LE Secure Connections pairing.
+struct LTK {
+ RemoteKey key;
+ uint8 key_size;
+ uint16 ediv;
+ uint64 rand;
+};
+
+// The preferred LE connection parameters of the peer.
+struct LEConnectionParameters {
+ uint16 connection_interval;
+ uint16 connection_latency;
+ uint16 supervision_timeout;
+};
+
+enum AddressType : uint8 {
+ LE_PUBLIC = 0;
+ LE_RANDOM = 1;
+ BREDR = 2;
+};
+
+struct LEData {
+ // The identity address of the peer. If `resolvable` is true, then this is the
+ // resolved private address (and the `irk` is present).
+ string address;
+ AddressType address_type;
+
+ // The peer’s preferred connection parameters, if known.
+ LEConnectionParameters? connection_parameters;
+
+ // Known GATT service UUIDs.
+ vector<string:36> services;
+
+ // The LE long-term key. Present if the link was encrypted.
+ LTK? ltk;
+
+ // Identity Resolving RemoteKey used to generate and resolve random addresses.
+ RemoteKey? irk;
+
+ // Connection Signature Resolving RemoteKey used for data signing without encryption.
+ RemoteKey? csrk;
+};
+
+struct BREDRData {
+ // The public device address of the peer.
+ string address;
+
+ // True if the peer prefers to lead the piconet. This is determined by role
+ // switch procedures. Paging and connecting from a peer does not automatically
+ // set this flag.
+ bool piconet_leader;
+
+ // Known SDP service UUIDs.
+ vector<string:36> services;
+
+ // The semi-permanent BR/EDR key. Present if link was paired with Secure
+ // Simple Pairing or stronger.
+ LTK? link_key;
+};
+
+// Represents the bonding data for a single peer.
+struct BondingData {
+ // The identifier that uniquely identifies this device.
+ string identifier;
+
+ // The local Bluetooth identity address that this bond is associated with.
+ string local_address;
+
+ // The name of the device, if any.
+ string? name;
+
+ // Bonding data that is present when this device is paired on the LE transport.
+ LEData? le;
+
+ // Bonding data that is present when this device is paired on the BR/EDR transport.
+ BREDRData? bredr;
+};
+
+/// Represents persistent local host data.
+// TODO(BT-813): Consider using a table instead of struct.
+struct HostData {
+ /// The local Identity Resolving Key used by a bt-host device to generate Resolvable Private
+ /// Addresses when privacy is enabled.
+ ///
+ /// NOTE: This key is distributed to LE peers during pairing procedures. The client must take
+ /// care to assign an IRK that consistent with the local bt-host identity.
+ // TODO(BT-815): Document behavior once there is a better privacy policy when `irk` is null.
+ LocalKey? irk;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.control/control.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.control/control.fidl
new file mode 100644
index 0000000..02091fb
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.control/control.fidl
@@ -0,0 +1,142 @@
+// Copyright 2017 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.
+
+library fuchsia.bluetooth.control;
+
+using fuchsia.bluetooth;
+
+/// Bluetooth controller and its associated host-subsystem state that is present
+/// on the current platform.
+struct AdapterInfo {
+ /// UUID that uniquely identifies this adapter on the current system.
+ string identifier;
+
+ /// The Bluetooth technologies that are supported by this adapter.
+ TechnologyType technology;
+
+ /// Public Bluetooth device address which can be displayed to the user.
+ string address;
+
+ /// The current adapter state. This field is only present when an AdapterInfo
+ /// is obtained via the Control and ControlDelegate interfaces. If present,
+ /// all optional members of `state` will also be present.
+ AdapterState? state;
+};
+
+/// Contains static global information about a local Bluetooth adapter,
+/// including its current state. Each adapter instance represents a physical
+struct AdapterState {
+ // The local name of the local adapter, visible to other devices when
+ // discoverable.
+ string? local_name;
+
+ // Whether or not the local adapter is currently discoverable over BR/EDR and
+ // LE physical channels.
+ fuchsia.bluetooth.Bool? discoverable;
+
+ // Whether or not device discovery is currently being performed.
+ fuchsia.bluetooth.Bool? discovering;
+
+ // Service UUIDs of all local services that are published and available to
+ // other devices via this adapter. These services are usually registered
+ // using the GATT and the classic profile APIs.
+ vector<string>? local_service_uuids;
+};
+
+/// Device Class represents the Major and Minor Device Class and Service Class of an adapter
+/// Values are defined in https://www.bluetooth.com/specifications/assigned-numbers/baseband
+[MaxHandles = "0"]
+struct DeviceClass {
+ uint32 value;
+};
+
+/// Primary Bluetooth control service to access bluetooth
+[Discoverable]
+protocol Control {
+ /// Returns whether or not Bluetooth is currently available on the system.
+ IsBluetoothAvailable() -> (bool available);
+
+ /// Registers a delegate to handle pairing requests.
+ /// Indicate the capability type of the PairingDelegate using `in` and `out`.
+ /// If your input/output capability is variable, call this function when it
+ /// changes to update.
+ /// Setting a pairing delegate closes the previously assigned pairing Delegate.
+ ///
+ /// To disable pairing, set `delegate` to null.
+ SetPairingDelegate(PairingDelegate? delegate) -> (bool success);
+
+ /// Returns information about all local adapters that are known to the system.
+ GetAdapters() -> (vector<AdapterInfo>? adapters);
+
+ /// Sets the local adapter with the given `identifier` to act as the backing
+ /// adapter for all Bluetooth interfaces.
+ SetActiveAdapter(string identifier) -> (fuchsia.bluetooth.Status status);
+
+ /// Returns information on the current active adapter, if it exists.
+ GetActiveAdapterInfo() -> (AdapterInfo? adapter);
+
+ /// If `discovery` is true, active discovery is requested.
+ /// When requesting discovery, general discovery for BR/EDR and LE will be
+ /// active and newly discovered devices will be reported via
+ /// RemoteDeviceDelegate.OnDeviceUpdate().
+ ///
+ /// Discovery may be active when not reqested.
+ /// If an error occurs when starting discovery, it is reflected in `status`.
+ RequestDiscovery(bool discovery) -> (fuchsia.bluetooth.Status status);
+
+ /// Retrieve the set of known remote devices.
+ /// Note: These devices are not guaranteed to still be reachable.
+ GetKnownRemoteDevices() -> (vector<RemoteDevice> devices);
+
+ /// Sets the public Bluetooth name for this device, or resets to the default
+ /// name if `name` is not present.
+ SetName(string? name) -> (fuchsia.bluetooth.Status status);
+
+ /// Set the Device Class for the active Bluetooth adapter.
+ /// Values are defined in https://www.bluetooth.com/specifications/assigned-numbers/baseband
+ [Transitional]
+ SetDeviceClass(DeviceClass device_class) -> (fuchsia.bluetooth.Status status);
+
+ /// Set the discoverability of this device.
+ SetDiscoverable(bool discoverable) -> (fuchsia.bluetooth.Status status);
+
+ /// Attempt to connect to the remote `device_id`.
+ Connect(string device_id) -> (fuchsia.bluetooth.Status status);
+
+ /// Disconnect a previously-connected device.
+ /// Note: This does not remove a device bond, see Control::Forget.
+ Disconnect(string device_id) -> (fuchsia.bluetooth.Status status);
+
+ /// Initiate a pairing to the remote `id` with the given `options`. Returns an error
+ /// variant of fuchsia.bluetooth.Status if no connected peer with `id` is found or the pairing
+ /// procedure fails. If already paired, this will do nothing unless the pairing is over LE and
+ /// the PairingOptions.le_security_level is more secure than the current security level.
+ Pair(fuchsia.bluetooth.PeerId id, PairingOptions options) -> (fuchsia.bluetooth.Status status);
+
+ /// Forget `device_id` completely, removing all bonding information.
+ /// This will disconnect a device if it is connected.
+ Forget(string device_id) -> (fuchsia.bluetooth.Status status);
+
+ /// Set local IO Capabilities to use during pairing.
+ SetIOCapabilities(InputCapabilityType input, OutputCapabilityType output);
+
+ // Events
+
+ /// Sent when the active adapter has been updated. If `active_adapter` is
+ /// null, then no adapter is currently active.
+ -> OnActiveAdapterChanged(AdapterInfo? adapter);
+
+ /// Sent when an adapter has been updated.
+ -> OnAdapterUpdated(AdapterInfo adapter);
+
+ /// Sent when an adapter with the given `identifier` has been removed from
+ /// the system.
+ -> OnAdapterRemoved(string identifier);
+
+ /// Sent when a peer is updated.
+ -> OnDeviceUpdated(RemoteDevice device);
+
+ /// Sent when a peer is removed.
+ -> OnDeviceRemoved(string identifier);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.control/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.control/meta.json
new file mode 100644
index 0000000..744a86f
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.control/meta.json
@@ -0,0 +1,15 @@
+{
+ "deps": [
+ "fuchsia.bluetooth"
+ ],
+ "name": "fuchsia.bluetooth.control",
+ "root": "fidl/fuchsia.bluetooth.control",
+ "sources": [
+ "fidl/fuchsia.bluetooth.control/bonding.fidl",
+ "fidl/fuchsia.bluetooth.control/control.fidl",
+ "fidl/fuchsia.bluetooth.control/pairing_delegate.fidl",
+ "fidl/fuchsia.bluetooth.control/pairing_options.fidl",
+ "fidl/fuchsia.bluetooth.control/remote_device.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.control/pairing_delegate.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.control/pairing_delegate.fidl
new file mode 100644
index 0000000..69db6c3
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.control/pairing_delegate.fidl
@@ -0,0 +1,81 @@
+// Copyright 2018 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.
+
+library fuchsia.bluetooth.control;
+
+using fuchsia.bluetooth;
+
+/// Input and Output Capabilities for pairing exchanges.
+/// See Volume 3, Part C, Table 5.3 and 5.4
+enum InputCapabilityType {
+ NONE = 0;
+ CONFIRMATION = 1;
+ KEYBOARD = 2;
+};
+
+enum OutputCapabilityType {
+ NONE = 0;
+ DISPLAY = 1;
+};
+
+/// Different types required by the Security Manager for pairing methods.
+/// Bluetooth SIG has different requirements for different device capabilities.
+enum PairingMethod {
+ /// The user is asked to accept or reject pairing.
+ CONSENT = 0;
+
+ /// The user is shown a 6-digit numerical passkey which they must enter on the
+ /// peer device.
+ PASSKEY_DISPLAY = 1;
+
+ /// The user is shown a 6-digit numerical passkey which will also shown on the
+ /// peer device. The user must compare the passkeys and accept the pairing if
+ /// the passkeys match.
+ PASSKEY_COMPARISON = 2;
+
+ /// The user is asked to enter a 6-digit passkey.
+ PASSKEY_ENTRY = 3;
+};
+
+enum PairingKeypressType {
+ /// The user has entered a single digit.
+ DIGIT_ENTERED = 0;
+
+ /// The user has erased a single digit.
+ DIGIT_ERASED = 1;
+
+ /// The user has cleared the entire passkey.
+ PASSKEY_CLEARED = 2;
+
+ /// The user has finished entering the passkey.
+ PASSKEY_ENTERED = 3;
+};
+
+protocol PairingDelegate {
+ /// Called for most pairing requests. The delegate must respond with “true” or “false” to
+ /// either accept or reject the pairing request. If the pairing method requires a passkey
+ /// this is returned as well.
+ ///
+ /// Any response from this method will be ignored if the OnPairingComplete
+ /// event has already been sent for `device`.
+ OnPairingRequest(RemoteDevice device, PairingMethod method, string? displayed_passkey)
+ -> (bool accept, string? entered_passkey);
+
+ /// Called if the pairing procedure for the device with the given ID is completed.
+ /// This can be due to successful completion or an error (e.g. due to cancellation
+ /// by the peer, a timeout, or disconnection) which is indicated by `status`.
+ OnPairingComplete(string device_id, fuchsia.bluetooth.Status status);
+
+ /// Called to notify keypresses from the peer device during pairing using
+ /// PairingMethod.PASSKEY_DISPLAY.
+ ///
+ /// This event is used to provide key press events to the delegate for a responsive user
+ /// experience as the user types the passkey on the peer device. This event will be called
+ /// once for each key-press.
+ OnRemoteKeypress(string device_id, PairingKeypressType keypress);
+
+ /// The delegate can send this event to notify the peer of local keypresses
+ /// during pairing using PairingMethod.PASSKEY_ENTRY.
+ -> OnLocalKeypress(string device_id, PairingKeypressType keypress);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.control/pairing_options.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.control/pairing_options.fidl
new file mode 100644
index 0000000..ba45032
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.control/pairing_options.fidl
@@ -0,0 +1,36 @@
+// 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.
+
+library fuchsia.bluetooth.control;
+
+/// The security level required for this pairing - corresponds to the security
+/// levels defined in the Security Manager Protocol in Vol 3, Part H, Section 2.3.1
+enum PairingSecurityLevel {
+ /// Encrypted without MITM protection (unauthenticated)
+ ENCRYPTED = 1;
+
+ /// Encrypted with MITM protection (authenticated), although this level of security does not
+ /// fully protect against passive eavesdroppers
+ AUTHENTICATED = 2;
+};
+
+/// Parameters that give a caller more fine-grained control over the pairing process. All of the
+/// fields of this table are optional and pairing can still succeed if none of them are set.
+table PairingOptions {
+ /// Only relevant for LE. If present, determines the Security Manager security level to pair
+ /// with. If not present, defaults to PairingSecurityLevel.AUTHENTICATED.
+ 1: PairingSecurityLevel le_security_level;
+
+ /// If not present or false, the pairing will default to bondable mode. Otherwise, setting this
+ /// parameter to true will initiate a non-bondable pairing.
+ ///
+ /// TODO(fxb/42403): Only implemented for LE transport. Support this for BR/EDR.
+ 2: bool non_bondable;
+
+ /// If transport is LOW_ENERGY or CLASSIC, pairing will be performed over the transport
+ /// corresponding to the specified technology, which must already be connected. If transport
+ /// is not present or DUAL_MODE, the pairing will be performed over whichever transport is
+ /// connected, and defaults to LE for dual-mode connections.
+ 3: TechnologyType transport;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.control/remote_device.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.control/remote_device.fidl
new file mode 100644
index 0000000..34dbc36
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.control/remote_device.fidl
@@ -0,0 +1,113 @@
+// Copyright 2018 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.
+
+library fuchsia.bluetooth.control;
+
+using fuchsia.bluetooth;
+
+/// Possible values for the LE Appearance property which describes the external
+/// appearance of a
+/// device at a high level.
+/// (See the Bluetooth assigned-numbers document:
+/// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.gap.appearance.xml)
+enum Appearance : uint16 {
+ UNKNOWN = 0;
+ PHONE = 64;
+ COMPUTER = 128;
+ WATCH = 192;
+ WATCH_SPORTS = 193;
+ CLOCK = 256;
+ DISPLAY = 320;
+ REMOTE_CONTROL = 384;
+ EYE_GLASSES = 448;
+ TAG = 512;
+ KEYRING = 576;
+ MEDIA_PLAYER = 640;
+ BARCODE_SCANNER = 704;
+ THERMOMETER = 768;
+ THERMOMETER_EAR = 769;
+ HEART_RATE_SENSOR = 832;
+ HEART_RATE_SENSOR_BELT = 833;
+ BLOOD_PRESSURE = 896;
+ BLOOD_PRESSURE_ARM = 897;
+ BLOOD_PRESSURE_WRIST = 898;
+ HID = 960;
+ HID_KEYBOARD = 961;
+ HID_MOUSE = 962;
+ HID_JOYSTICK = 963;
+ HID_GAMEPAD = 964;
+ HID_DIGITIZER_TABLET = 965;
+ HID_CARD_READER = 966;
+ HID_DIGITAL_PEN = 967;
+ HID_BARCODE_SCANNER = 968;
+ GLUCOSE_METER = 1024;
+ RUNNING_WALKING_SENSOR = 1088;
+ RUNNING_WALKING_SENSOR_IN_SHOE = 1089;
+ RUNNING_WALKING_SENSOR_ON_SHOE = 1090;
+ RUNNING_WALKING_SENSOR_ON_HIP = 1091;
+ CYCLING = 1152;
+ CYCLING_COMPUTER = 1153;
+ CYCLING_SPEED_SENSOR = 1154;
+ CYCLING_CADENCE_SENSOR = 1155;
+ CYCLING_POWER_SENSOR = 1156;
+ CYCLING_SPEED_AND_CADENCE_SENSOR = 1157;
+ PULSE_OXIMETER = 3136;
+ PULSE_OXIMETER_FINGERTIP = 3137;
+ PULSE_OXIMETER_WRIST = 3138;
+ WEIGHT_SCALE = 3200;
+ PERSONAL_MOBILITY = 3264;
+ PERSONAL_MOBILITY_WHEELCHAIR = 3265;
+ PERSONAL_MOBILITY_SCOOTER = 3266;
+ GLUCOSE_MONITOR = 3328;
+ SPORTS_ACTIVITY = 5184;
+ SPORTS_ACTIVITY_LOCATION_DISPLAY = 5185;
+ SPORTS_ACTIVITY_LOCATION_AND_NAV_DISPLAY = 5186;
+ SPORTS_ACTIVITY_LOCATION_POD = 5187;
+ SPORTS_ACTIVITY_LOCATION_AND_NAV_POD = 5188;
+};
+
+enum TechnologyType {
+ LOW_ENERGY = 0;
+ CLASSIC = 1;
+ DUAL_MODE = 2;
+};
+
+/// Represents a remote BR/EDR, LE, or dual-mode BR/EDR/LE device.
+struct RemoteDevice {
+ /// Uniquely identifies this device on the current system.
+ string identifier;
+
+ /// Bluetooth device address that identifies this remote device. Clients
+ /// should display this field to the user when `name` is not available.
+ ///
+ /// NOTE: Clients should use the `identifier` field to distinguish between
+ /// remote devices instead of using their address.
+ string address;
+
+ /// The Bluetooth technologies that are supported by this device.
+ TechnologyType technology;
+
+ /// The name of the remote device if present or known.
+ string? name;
+
+ /// The LE appearance property. Present if this is a LE device and the
+ /// appearance information was obtained over advertising and/or GATT.
+ Appearance appearance;
+
+ /// The most recently obtained advertising signal strength for this device.
+ fuchsia.bluetooth.Int8? rssi;
+
+ /// The most recently obtained transmission power for this device.
+ fuchsia.bluetooth.Int8? tx_power;
+
+ /// Whether or not a BR/EDR and/or LE connection exists between the local
+ /// adapter and this device.
+ bool connected;
+
+ /// Whether or not a bond exists between the local adapter and this device.
+ bool bonded;
+
+ /// The list of service UUIDs known to be published on this remote device.
+ vector<string> service_uuids;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.gatt/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.gatt/BUILD.gn
new file mode 100644
index 0000000..b8f6bd0
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.gatt/BUILD.gn
@@ -0,0 +1,29 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.bluetooth.gatt") {
+ library_name = "gatt"
+ namespace = "fuchsia.bluetooth"
+ public_deps = [
+ "../fuchsia.bluetooth",
+ ]
+ sources = [
+ "client.fidl",
+ "constants.fidl",
+ "server.fidl",
+ "types.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.bluetooth.gatt",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.gatt/client.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.gatt/client.fidl
new file mode 100644
index 0000000..28ba1c7
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.gatt/client.fidl
@@ -0,0 +1,146 @@
+// Copyright 2017 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.
+
+library fuchsia.bluetooth.gatt;
+
+using fuchsia.bluetooth;
+
+protocol RemoteService {
+ /// Returns the characteristics and characteristic descriptors that belong to
+ /// this service.
+ DiscoverCharacteristics() -> (fuchsia.bluetooth.Status status, vector<Characteristic> characteristics);
+
+ /// Reads the value of the characteristic with `id` and returns it in the
+ /// reply. If `status` indicates an error `value` will be empty.
+ ///
+ /// If the characteristic has a long value (i.e. larger than the current MTU)
+ /// this method will return only the first (MTU - 1) bytes of the value. Use
+ /// ReadLongCharacteristic() to read larger values or starting at a non-zero
+ /// offset.
+ ReadCharacteristic(uint64 id) -> (fuchsia.bluetooth.Status status, bytes value);
+
+ /// Reads the complete value of a characteristic with the given `id`. This
+ /// procedure should be used if the characteristic is known to have a value
+ /// that can not be read in a single request.
+ ///
+ /// Returns up to `max_bytes` octets of the characteristic value starting at
+ /// the given `offset`.
+ ///
+ /// This may return an error if:
+ /// a. `max_bytes` is 0;
+ /// b. The `offset` is invalid;
+ /// c. The characteristic does not have a long value;
+ /// d. The server does not support the long read procedure.
+ ReadLongCharacteristic(uint64 id, uint16 offset, uint16 max_bytes) -> (fuchsia.bluetooth.Status status, bytes:MAX_VALUE_LENGTH value);
+
+ /// Writes `value` to the characteristic with `id`. This operation may return
+ /// an error if:
+ /// a. The size of `value` exceeds the current MTU.
+ /// b. The characteristic referred to by `id` does not have the 'write'
+ /// property.
+ WriteCharacteristic(uint64 id, bytes value) -> (fuchsia.bluetooth.Status status);
+
+ /// Writes `value` to the characteristic with `id`, beginning at `offset` using
+ /// the provided `write_options`.
+ ///
+ /// This procedure should be used if the value to be written is too long to
+ /// fit in a single request or needs to be written at an offset. This may
+ /// return an error if:
+ /// a. The `offset` is invalid;
+ /// b. The server does not support the long write procedure.
+ ///
+ /// Long Writes require multiple messages to the remote service and take longer
+ /// to execute than Short Writes. It is not recommended to send a short write
+ /// while a long write is in process to the same id and data range. The order
+ /// of the responses from this function signify the order in which the remote
+ /// service received them, not necessarily the order in which it is called.
+ WriteLongCharacteristic(uint64 id, uint16 offset, bytes:MAX_VALUE_LENGTH value, WriteOptions write_options)
+ -> (fuchsia.bluetooth.Status status);
+
+ /// Writes `value` to the characteristic with `id` without soliciting an
+ /// acknowledgement from the peer. This method has no response and its delivery
+ /// cannot be confirmed.
+ WriteCharacteristicWithoutResponse(uint64 id, bytes value);
+
+ /// Reads the value of the characteristic descriptor with `id` and returns it
+ /// in the reply. If `status` indicates an error, `value` can be ignored.
+ ///
+ /// If the descriptor has a long value (i.e. larger than the current MTU)
+ /// this method will return only the first (MTU - 1) bytes of the value. Use
+ /// ReadLongDescriptor() to read larger values or starting at a non-zero
+ /// offset.
+ ReadDescriptor(uint64 id) -> (fuchsia.bluetooth.Status status, bytes value);
+
+ /// Reads the complete value of a characteristic descriptor with the given `id`.
+ /// This procedure should be used if the descriptor is known to have a value
+ /// that can not be read in a single request.
+ ///
+ /// Returns up to `max_bytes` octets of the characteristic value starting at
+ /// the given `offset`.
+ ///
+ /// This may return an error if:
+ /// a. `max_bytes` is 0;
+ /// b. The `offset` is invalid;
+ /// c. The server does not support the long read procedure.
+ ReadLongDescriptor(uint64 id, uint16 offset, uint16 max_bytes) -> (fuchsia.bluetooth.Status status, bytes value);
+
+ /// Writes `value` to the characteristic descriptor with `id`. This operation
+ /// may return an error if:
+ /// a. The size of `value` exceeds the current MTU.
+ /// b. `id` refers to an internally reserved descriptor type (e.g. the Client
+ /// Characteristic Configuration descriptor).
+ WriteDescriptor(uint64 id, bytes value) -> (fuchsia.bluetooth.Status status);
+
+ /// Writes `value` to the characteristic descriptor with `id`, beginning at
+ /// `offset`. This procedure should be used if the value to be written is too
+ /// long to fit in a single request or needs to be written at an offset. This
+ /// may return an error if:
+ /// a. The `offset` is invalid;
+ /// b. The server does not support the long write procedure.
+ /// c. `id` refers to an internally reserved descriptor type (e.g. the Client
+ /// Characteristic Configuration descriptor).
+ ///
+ /// Long Writes require multiple messages to the remote service and take longer
+ /// to execute than Short Writes. It is not recommended to send a short write
+ /// while a long write is in process to the same id and data range. The order
+ /// of the responses from this function signify the order in which the remote
+ /// service received them, not necessarily the order in which it is called.
+ WriteLongDescriptor(uint64 id, uint16 offset, bytes:MAX_VALUE_LENGTH value) -> (fuchsia.bluetooth.Status status);
+
+ /// Subscribe or unsubscribe to notifications/indications from the characteristic with
+ /// the given `id`. Notifications or indications will be enabled if `enable` is
+ /// true or disabled if `enable` is false and they have been enabled for this
+ /// client.
+ ///
+ /// Either notifications or indications will be enabled depending on
+ /// characteristic properties. Indications will be preferred if they are
+ /// supported.
+ ///
+ /// This operation fails if the characteristic does not have the "notify" or
+ /// "indicate" property or does not contain a Client Characteristic
+ /// Configuration descriptor.
+ ///
+ /// On success, the OnCharacteristicValueUpdated event will be sent whenever
+ /// the peer sends a notification or indication. The local host will
+ /// automically confirm indications.
+ NotifyCharacteristic(uint64 id, bool enable) -> (fuchsia.bluetooth.Status status);
+
+ /// Events:
+ /// Called when a characteristic value notification or indication is received.
+ -> OnCharacteristicValueUpdated(uint64 id, bytes value);
+};
+
+protocol Client {
+ /// Enumerates services found on the peer that this Client represents. Results
+ /// can be restricted by specifying a list of UUIDs in `uuids`. The returned
+ /// ServiceInfo structures will contain only basic information about each
+ /// service and the `characteristics` and `includes` fields will be null.
+ ///
+ /// To further interact with services, clients must obtain a RemoteService
+ /// handle by calling ConnectToService().
+ ListServices(vector<string>? uuids) -> (fuchsia.bluetooth.Status status, vector<ServiceInfo> services);
+
+ /// Connects the RemoteService with the given identifier.
+ ConnectToService(uint64 id, request<RemoteService> service);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.gatt/constants.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.gatt/constants.fidl
new file mode 100644
index 0000000..38af827
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.gatt/constants.fidl
@@ -0,0 +1,7 @@
+// 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.
+
+library fuchsia.bluetooth.gatt;
+
+const uint16 MAX_VALUE_LENGTH = 512;
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.gatt/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.gatt/meta.json
new file mode 100644
index 0000000..7b6f4c7
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.gatt/meta.json
@@ -0,0 +1,14 @@
+{
+ "deps": [
+ "fuchsia.bluetooth"
+ ],
+ "name": "fuchsia.bluetooth.gatt",
+ "root": "fidl/fuchsia.bluetooth.gatt",
+ "sources": [
+ "fidl/fuchsia.bluetooth.gatt/client.fidl",
+ "fidl/fuchsia.bluetooth.gatt/constants.fidl",
+ "fidl/fuchsia.bluetooth.gatt/server.fidl",
+ "fidl/fuchsia.bluetooth.gatt/types.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.gatt/server.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.gatt/server.fidl
new file mode 100644
index 0000000..4ea6794
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.gatt/server.fidl
@@ -0,0 +1,68 @@
+// Copyright 2017 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.
+
+library fuchsia.bluetooth.gatt;
+
+using fuchsia.bluetooth;
+
+/// Interface for responding to requests on a local service.
+protocol LocalServiceDelegate {
+ /// Notifies the delegate when a remote device with `peer_id` enables or
+ /// disables notifications or indications on the characteristic with the given
+ /// `characteristic_id`.
+ OnCharacteristicConfiguration(uint64 characteristic_id, string peer_id,
+ bool notify, bool indicate);
+
+ /// Called when a remote device issues a request to read the value of the
+ /// of the characteristic or descriptor with given identifier. The delegate
+ /// must respond to the request by returning the characteristic value. If the
+ /// read request resulted in an error it should be returned in `error_code`.
+ /// On success, `error_code` should be set to NO_ERROR and a `value` should be
+ /// provided.
+ OnReadValue(uint64 id, int32 offset) -> (bytes? value, ErrorCode status);
+
+ /// Called when a remote device issues a request to write the value of the
+ /// characteristic or descriptor with the given identifier.
+ OnWriteValue(uint64 id, uint16 offset, bytes value) -> (ErrorCode status);
+
+ /// Called when a remote device issues a request to write the value of the
+ /// characteristic with the given identifier. This can be called on a
+ /// characteristic with the WRITE_WITHOUT_RESPONSE property.
+ OnWriteWithoutResponse(uint64 id, uint16 offset, bytes value);
+};
+
+/// Interface for communicating with a published service.
+protocol LocalService {
+ /// Removes the service that this interface instance corresponds to. Does
+ /// nothing if the service is already removed.
+ RemoveService();
+
+ /// Sends a notification carrying the `value` of the characteristic with the
+ /// given `characteristic_id` to the device with `peer_id`.
+ ///
+ /// If `confirm` is true, then this method sends an indication instead. If the
+ /// peer fails to confirm the indication, the link between the peer and the
+ /// local adapter will be closed.
+ ///
+ /// This method has no effect if the peer has not enabled notifications or
+ /// indications on the requested characteristic.
+ NotifyValue(uint64 characteristic_id, string peer_id, bytes value, bool confirm);
+};
+
+[Discoverable]
+protocol Server {
+ /// Publishes the given service so that it is available to all remote peers.
+ /// A LocalServiceDelegate must be provided over which to receive service requests.
+ ///
+ /// The caller must assign distinct identifiers to the characteristics and
+ /// descriptors listed in `info`. These identifiers will be used in requests
+ /// sent to `delegate`.
+ ///
+ /// `service` can be used to interact with the pubished service. If this
+ /// service cannot be published then the handle for `service` will be closed.
+ ///
+ /// Returns the success or failure status of the call and a unique identifier
+ /// that can be used to unregister the service.
+ PublishService(ServiceInfo info, LocalServiceDelegate delegate, request<LocalService> service) -> (fuchsia.bluetooth.Status status);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.gatt/types.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.gatt/types.fidl
new file mode 100644
index 0000000..54a6344
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.gatt/types.fidl
@@ -0,0 +1,152 @@
+// Copyright 2018 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.
+
+library fuchsia.bluetooth.gatt;
+
+/// Codes that can be returned in the `protocol_error_code` field of a
+/// bluetooth.Error.
+enum ErrorCode {
+ /// Indicates that the operation was successful.
+ NO_ERROR = 0;
+
+ /// Indicates that the offset used in a read or write request exceeds the
+ /// bounds of the value.
+ INVALID_OFFSET = 1;
+
+ /// Indicates that the value given in a write request would exceed the maximum
+ /// length allowed for the destionation characteristic or descriptor.
+ INVALID_VALUE_LENGTH = 2;
+
+ /// Indicates that a read or write request is not permitted.
+ NOT_PERMITTED = 3;
+};
+
+/// Represents encryption, authentication, and authorization permissions that can
+/// be assigned to a specific access permission.
+struct SecurityRequirements {
+ /// If true, the physical link must be encrypted to access this attribute.
+ bool encryption_required;
+
+ /// If true, the physical link must be authenticated to access this
+ /// attribute.
+ bool authentication_required;
+
+ /// If true, the client needs to be authorized before accessing this
+ /// attribute.
+ bool authorization_required;
+};
+
+/// Specifies the access permissions for a specific attribute value.
+struct AttributePermissions {
+ /// Specifies whether or not an attribute has the read permission. If null,
+ /// then the attribute value cannot be read. Otherwise, it can be read only if
+ /// the permissions specified in the Permissions struct are satisfied.
+ SecurityRequirements? read;
+
+ /// Specifies whether or not an attribute has the write permission. If null,
+ /// then the attribute value cannot be written. Otherwise, it be written only
+ /// if the permissions specified in the Permissions struct are satisfied.
+ SecurityRequirements? write;
+
+ /// Specifies the security requirements for a client to subscribe to
+ /// notifications or indications on a characteristic. A characteristic's
+ /// support for notifications or indiciations is specified using the NOTIFY and
+ /// INDICATE characteristic properties. If a local characteristic has one of
+ /// these properties then this field can not be null. Otherwise, this field
+ /// must be left as null.
+ ///
+ /// This field is ignored for Descriptors.
+ SecurityRequirements? update;
+};
+
+/// Possible values for the characteristic properties bitfield. These specify the
+/// GATT procedures that are allowed for a particular characteristic.
+const uint32 kPropertyBroadcast = 1;
+const uint32 kPropertyRead = 2;
+const uint32 kPropertyWriteWithoutResponse = 4;
+const uint32 kPropertyWrite = 8;
+const uint32 kPropertyNotify = 16;
+const uint32 kPropertyIndicate = 32;
+const uint32 kPropertyAuthenticatedSignedWrites = 64;
+const uint32 kPropertyReliableWrite = 256;
+const uint32 kPropertyWritableAuxiliaries = 512;
+
+/// Represents a local or remote GATT service.
+struct ServiceInfo {
+ /// Uniquely identifies this GATT service. This value will be ignored for local
+ /// services. Remote services will always have an identifier.
+ uint64 id;
+
+ /// Indicates whether this is a primary or secondary service.
+ bool primary;
+
+ /// The 128-bit UUID that identifies the type of this service. This is a string
+ /// in the canonical 8-4-4-4-12 format.
+ string type;
+
+ /// The characteristics of this service.
+ vector<Characteristic>? characteristics;
+
+ /// Ids of other services that are included by this service.
+ vector<uint64>? includes;
+};
+
+/// Represents a local or remote GATT characteristic.
+struct Characteristic {
+ /// Uniquely identifies this characteristic within a service.
+ uint64 id;
+
+ /// The 128-bit UUID that identifies the type of this characteristic. This is a
+ /// string in the canonical 8-4-4-4-12 format.
+ string type;
+
+ /// The characteristic properties bitfield. See kProperty* above for possible
+ /// values.
+ uint32 properties;
+
+ /// The attribute permissions of this characteristic. For remote
+ /// characteristics, this value will be null until the permissions are
+ /// discovered via read and write requests.
+ ///
+ /// For local characteristics, this value is mandatory.
+ AttributePermissions? permissions;
+
+ /// The descriptors of this characteristic.
+ vector<Descriptor>? descriptors;
+};
+
+/// Represents a local or remote GATT characteristic descriptor.
+struct Descriptor {
+ /// Uniquely identifies this descriptor within the characteristic that it
+ /// belongs to.
+ uint64 id;
+
+ /// The 128-bit UUID that identifies the type of this descriptor. This is a
+ /// string in the canonical 8-4-4-4-12 format.
+ string type;
+
+ /// The attribute permissions of this descriptor. For remote
+ /// descriptors, this value will be null until the permissions are
+ /// discovered via read and write requests.
+ ///
+ /// For local descriptors, this value is mandatory.
+ AttributePermissions? permissions;
+};
+
+/// Represents the reliability mode during long and prepared write operations.
+///
+/// If enabled, every value blob is verified against an echo response from the server.
+/// The procedure is aborted if a value blob has not been reliably delivered to the peer.
+enum ReliableMode {
+ DISABLED = 1;
+ ENABLED = 2;
+};
+
+/// Represents the supported options to write a characteristic value to a server.
+table WriteOptions {
+ /// The reliable mode of the write operation.
+ ///
+ /// Defaults to [`fuchsia.bluetooth.gatt/ReliableMode.DISABLED`] if not present.
+ 1: ReliableMode reliable_mode;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.le/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.le/BUILD.gn
new file mode 100644
index 0000000..e674001
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.le/BUILD.gn
@@ -0,0 +1,32 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.bluetooth.le") {
+ library_name = "le"
+ namespace = "fuchsia.bluetooth"
+ public_deps = [
+ "../fuchsia.bluetooth",
+ "../fuchsia.bluetooth.gatt",
+ ]
+ sources = [
+ "advertising_data.fidl",
+ "central.fidl",
+ "connection_options.fidl",
+ "peer.fidl",
+ "peripheral.fidl",
+ "types_deprecated.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.bluetooth.le",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.le/advertising_data.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.le/advertising_data.fidl
new file mode 100644
index 0000000..52fc763
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.le/advertising_data.fidl
@@ -0,0 +1,49 @@
+// 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.
+
+library fuchsia.bluetooth.le;
+
+using fuchsia.bluetooth as bt;
+
+/// Entry in the `service_data` field of a [`fuchsia.bluetooth.le/AdvertisingData`].
+struct ServiceData {
+ bt.Uuid uuid;
+ bytes data;
+};
+
+/// Entry in the `manufacturer_data` field of a [`fuchsia.bluetooth.le/AdvertisingData`].
+struct ManufacturerData {
+ uint16 company_id;
+ bytes data;
+};
+
+/// Represents advertising and scan response data that are transmitted by a LE peripheral or
+/// broadcaster.
+table AdvertisingData {
+ /// Long or short name of the device.
+ 1: string name;
+
+ /// The appearance of the device.
+ 2: bt.Appearance appearance;
+
+ /// The radio transmit power level reported by an advertising peer. This field is disallowed
+ /// when used with the Peripheral API.
+ 3: int8 tx_power_level;
+
+ /// Service UUIDs.
+ 4: vector<bt.Uuid> service_uuids;
+
+ /// Service data entries.
+ 5: vector<ServiceData> service_data;
+
+ /// Manufacturer-specific data entries.
+ 6: vector<ManufacturerData> manufacturer_data;
+
+ /// String representing a URI to be advertised, as defined in [IETF STD 66](https://tools.ietf.org/html/std66).
+ /// Each entry should be a UTF-8 string including the scheme. For more information, see:
+ /// - https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml for allowed schemes;
+ /// - https://www.bluetooth.com/specifications/assigned-numbers/uri-scheme-name-string-mapping
+ /// for code-points used by the system to compress the scheme to save space in the payload.
+ 7: vector<string> uris;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.le/central.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.le/central.fidl
new file mode 100644
index 0000000..51c4bdf
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.le/central.fidl
@@ -0,0 +1,61 @@
+// Copyright 2018 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.
+
+library fuchsia.bluetooth.le;
+
+using fuchsia.bluetooth;
+using fuchsia.bluetooth.gatt;
+
+[Discoverable]
+protocol Central {
+ /// Returns the list of peripherals that are known to the system from previous scan, connection,
+ /// and/or bonding procedures. The results can be filtered based on service UUIDs that are known to
+ /// be present on the peripheral.
+ ///
+ /// This method only returns peripherals (i.e. connectable devices).
+ GetPeripherals(vector<string>? service_uuids) -> (vector<RemoteDevice> peripherals);
+
+ /// Returns information about a single peripheral that is known to the system from previous scan,
+ /// connection, and/or bonding procedures based on its unique identifier. Returns null if
+ /// `identifier` is not recognized.
+ GetPeripheral(string identifier) -> (RemoteDevice? peripheral);
+
+ /// Initiates a scan session for nearby peripherals and broadcasters. Discovered devices will be
+ /// reported via CentralDelegate.OnDeviceDiscovered(). If a scan session is already in progress,
+ /// `filter` will replace the existing session's filter.
+ ///
+ /// If `filter` is null or empty (i.e. none of its fields has been populated) then the delegate
+ /// will be notified for all discoverable devices that are found. This is not recommended; clients
+ /// should generally filter results by at least one of `filter.service_uuids`,
+ /// `filter.service_data`, and/or `filter.manufacturer_identifier`.
+ StartScan(ScanFilter? filter) -> (fuchsia.bluetooth.Status status);
+
+ /// Terminate a previously started scan session.
+ StopScan();
+
+ /// Creates a connection to the peripheral device with the given identifier.
+ /// Returns the status of the operation in `status`.
+ ///
+ /// On success, `gatt_client` will be bound and can be used for GATT client
+ /// role procedures. On failure, `gatt_client` will be closed and `status` will
+ /// indicate an error.
+ ConnectPeripheral(string identifier, ConnectionOptions options,
+ request<fuchsia.bluetooth.gatt.Client> gatt_client)
+ -> (fuchsia.bluetooth.Status status);
+
+ /// Disconnects this Central's connection to the peripheral with the given identifier.
+ DisconnectPeripheral(string identifier) -> (fuchsia.bluetooth.Status status);
+
+ /// Called when the scan state changes, e.g. when a scan session terminates due to a call to
+ /// Central.StopScan() or another unexpected condition.
+ -> OnScanStateChanged(bool scanning);
+
+ /// Called for each peripheral/broadcaster that is discovered during a scan session. `rssi`
+ /// contains the received signal strength of the advertising packet that generated this event, if
+ /// available.
+ -> OnDeviceDiscovered(RemoteDevice device);
+
+ /// Called when this Central's connection to a peripheral with the given identifier is terminated.
+ -> OnPeripheralDisconnected(string identifier);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.le/connection_options.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.le/connection_options.fidl
new file mode 100644
index 0000000..51972ca
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.le/connection_options.fidl
@@ -0,0 +1,15 @@
+// Copyright 2020 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.
+
+library fuchsia.bluetooth.le;
+
+/// Represents parameters that are set on a per-connection basis by FIDL protocols that create
+/// Low Energy connections.
+table ConnectionOptions {
+ /// When true, the connection operates in bondable mode. This means pairing will form a bond,
+ /// or persist across disconnections, if the peer is also in bondable mode. When not present,
+ /// the connection defaults to bondable mode. When false, the connection operates in non-
+ /// bondable mode, which means the local device only allows pairing that does not form a bond.
+ 1: bool bondable_mode;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.le/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.le/meta.json
new file mode 100644
index 0000000..ef6573f
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.le/meta.json
@@ -0,0 +1,17 @@
+{
+ "deps": [
+ "fuchsia.bluetooth",
+ "fuchsia.bluetooth.gatt"
+ ],
+ "name": "fuchsia.bluetooth.le",
+ "root": "fidl/fuchsia.bluetooth.le",
+ "sources": [
+ "fidl/fuchsia.bluetooth.le/advertising_data.fidl",
+ "fidl/fuchsia.bluetooth.le/central.fidl",
+ "fidl/fuchsia.bluetooth.le/connection_options.fidl",
+ "fidl/fuchsia.bluetooth.le/peer.fidl",
+ "fidl/fuchsia.bluetooth.le/peripheral.fidl",
+ "fidl/fuchsia.bluetooth.le/types_deprecated.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.le/peer.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.le/peer.fidl
new file mode 100644
index 0000000..3d83107
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.le/peer.fidl
@@ -0,0 +1,36 @@
+// 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.
+
+library fuchsia.bluetooth.le;
+
+using fuchsia.bluetooth as bt;
+
+/// Represents a Bluetooth Low Energy peer that may act in the broadcaster, peripheral, or central
+/// role. The peer's role depends on whether it is obtained from the Central or Peripheral protocol.
+table Peer {
+ /// Uniquely identifies this peer on the current system.
+ ///
+ /// This field is always present.
+ 1: bt.PeerId id;
+
+ /// Whether or not this peer is connectable. Non-connectable peers are typically in the LE
+ /// broadcaster role.
+ ///
+ /// This field is always present.
+ 2: bool connectable;
+
+ /// The last observed RSSI of this peer.
+ 3: int8 rssi;
+
+ /// Advertising and scan response data broadcast by this peer. Present in broadcasters and
+ /// peripherals.
+ 4: AdvertisingData advertising_data;
+};
+
+/// Protocol that represents the connection to a peer. This can be used to interact with GATT
+/// services and establish L2CAP channels.
+protocol Connection {
+ // TODO(armansito): Introduce function to obtain gatt.Client handle when transitioning the
+ // Central protocol.
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.le/peripheral.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.le/peripheral.fidl
new file mode 100644
index 0000000..7879508
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.le/peripheral.fidl
@@ -0,0 +1,122 @@
+// Copyright 2017 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.
+
+library fuchsia.bluetooth.le;
+
+enum PeripheralError {
+ /// The operation or parameters requested are not supported on the current hardware.
+ NOT_SUPPORTED = 1;
+
+ /// The provided advertising data exceeds the maximum allowed length when encoded.
+ ADVERTISING_DATA_TOO_LONG = 2;
+
+ /// The provided scan response data exceeds the maximum allowed length when encoded.
+ SCAN_RESPONSE_DATA_TOO_LONG = 3;
+
+ /// The requested parameters are invalid.
+ INVALID_PARAMETERS = 4;
+
+ /// The request to start advertising was aborted, for example by issuing a new request with new
+ /// parameters.
+ ABORTED = 5;
+
+ /// Advertising could not be initiated due to a hardware or system error.
+ FAILED = 6;
+};
+
+/// A client can indicate the transmission rate of advertising packets by specifying a mode. The
+/// mode provides a hint to the system when configuring the controller with advertising interval and
+/// window parameters.
+///
+/// The mode affects how quickly a scanner or central is able to discover the peripheral; however it
+/// can have an adverse effect on power consumption. While the system will try to honor a client's
+/// request, it is not guaranteed to do so.
+enum AdvertisingModeHint : uint8 {
+ /// Advertise with a very short interval and window for fast discovery at the cost of higher
+ /// power consumption. This corresponds to a 30-60ms interval on the 1M PHYs and 90-180ms on the
+ /// coded PHY.
+ VERY_FAST = 1;
+
+ /// Advertise with a short interval and window that uses less power than `VERY_FAST`.
+ /// This corresponds to a 100-150ms interval on the 1M PHYs and 300-450ms on the coded PHY.
+ FAST = 2;
+
+ /// Advertise with a moderate interval and window. This corresponds to 1-1.2s on the 1M PHYs and 3s
+ /// on the coded PHY.
+ SLOW = 3;
+};
+
+/// Represents the parameters for configuring advertisements.
+table AdvertisingParameters {
+ /// The fields that will be encoded in the data section of advertising packets.
+ ///
+ /// This field is required.
+ 1: AdvertisingData data;
+
+ /// The fields that are to be sent in a scan response packet. Clients may use this to send
+ /// additional data that does not fit inside an advertising packet on platforms that do not
+ /// support the advertising data length extensions.
+ ///
+ /// If present advertisements will be configured to be scannable.
+ 2: AdvertisingData scan_response;
+
+ /// The desired advertising frequency. See [`fuchsia.bluetooth.le/AdvertisingModeHint`].
+ /// Defaults to [`fuchsia.bluetooth.le/AdvertisingModeHint.SLOW`] if not present.
+ 3: AdvertisingModeHint mode_hint;
+
+ /// [[DEPRECATED]]: Prefer to use the ConnectionOptions field for new code.
+ /// If present and true then the controller will broadcast connectable advertisements which
+ /// allows remote LE centrals to initiate a connection to the Peripheral. If false or otherwise
+ /// not present then the advertisements will be non-connectable.
+ 4: bool connectable;
+
+ /// If present, the controller will broadcast connectable advertisements which allow remote LE
+ /// centrals to initiate connections to the Peripheral. The fields of ConnectionOptions will
+ /// configure any connections set up from advertising.
+ 5: ConnectionOptions connection_options;
+};
+
+/// Capability that is valid for the duration of advertising. The caller can close the handle to
+/// stop advertising. If the system internally stops advertising for any reason, the handle will be
+/// closed to communicate this to the client.
+protocol AdvertisingHandle {
+};
+
+[Discoverable]
+protocol Peripheral {
+ /// Start advertising as a LE peripheral. An empty response is sent to indicate when advertising
+ /// has successfully initiated. If advertising cannot be initiated, then the response will
+ /// contain a [`fuchsia.bluetooth.le/PeripheralError`].
+ ///
+ /// This method can get called any number of times and successive calls can be made to
+ /// reconfigure the advertising parameters. However only the most recent
+ /// [`fuchsia.bluetooth.le/AdvertisingHandle`] will remain valid.
+ ///
+ /// An instance of [`fuchsia.bluetooth.le/Peripheral`] can only have one active advertisement at
+ /// a time. Clients must obtain multiple Peripheral instances for multiple simultaneous
+ /// advertisements.
+ ///
+ /// If the client closes its end of the [`fuchsia.bluetooth.le/AdvertisingHandle`] channel,
+ /// advertising will be stopped. If the handle is closed before the request is fulfilled,
+ /// advertising will be briefly enabled before it is terminated.
+ ///
+ /// + request `parameters` Parameters used while configuring the advertising instance.
+ /// + request `handle` Handle that remains valid for the duration of this advertising session.
+ /// * error Returns a [`fuchsia.bluetooth.le/PeripheralError`] if advertising cannot be
+ /// initiated. In this case the `handle` will be closed.
+ StartAdvertising(AdvertisingParameters parameters, request<AdvertisingHandle> handle) -> () error PeripheralError;
+
+ /// Event delivered when a remote LE central initiates a connection to this Peripheral when
+ /// connectable advertising is enabled via
+ /// [`fuchsia.bluetooth.le/Peripheral.StartAdvertising`].
+ ///
+ /// The returned [`fuchsia.bluetooth.le/Connection`] handle can be used to interact with the
+ /// peer. It also represents a peripheral's ownership over the connection: the client can drop
+ /// the handle to request a disconnection. Similarly, the handle is closed by the system to
+ /// indicate that the connection to the peer has been lost.
+ ///
+ /// + request `peer` Information about the central that initiated the connection.
+ /// + request `handle` Represents the connection.
+ -> OnPeerConnected(Peer peer, Connection connection);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.le/types_deprecated.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.le/types_deprecated.fidl
new file mode 100644
index 0000000..6bc8fb9
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.le/types_deprecated.fidl
@@ -0,0 +1,100 @@
+// Copyright 2017 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.
+
+library fuchsia.bluetooth.le;
+
+using fuchsia.bluetooth;
+
+/// [[DEPRECATED]]
+struct ServiceDataEntry {
+ string uuid;
+ bytes data;
+};
+
+/// [[DEPRECATED]]
+struct ManufacturerSpecificDataEntry {
+ uint16 company_id;
+ bytes data;
+};
+
+/// Represents advertising and scan response data advertised by a broadcaster or peripheral.
+/// [[DEPRECATED]]
+struct AdvertisingDataDeprecated {
+ /// Name of the device.
+ string? name;
+
+ /// The radio transmission power level reported in the advertisement.
+ fuchsia.bluetooth.Int8? tx_power_level;
+
+ /// The appearance reported in the advertisemet.
+ fuchsia.bluetooth.UInt16? appearance;
+
+ /// List of service UUIDs reported in the advertisement.
+ vector<string>? service_uuids;
+
+ /// Service data included in the advertisement.
+ vector<ServiceDataEntry>? service_data;
+
+ /// Manufacturer specific data entries.
+ vector<ManufacturerSpecificDataEntry>? manufacturer_specific_data;
+
+ /// Service UUIDs that were solicited in the advertisement. Peripherals can invite centrals that
+ /// expose certain services to connect to them using service solicitation.
+ vector<string>? solicited_service_uuids;
+
+ /// URIs included in the advertising packet.
+ /// These are full URIs (they are encoded/decoded automatically)
+ vector<string>? uris;
+};
+
+/// Represents a remote Bluetooth Low Energy device. A RemoteDevice can represent a central,
+/// broadcaster, or peripheral based on the API from which it was received.
+/// [[DEPRECATED]]
+struct RemoteDevice {
+ /// Identifier that uniquely identifies this device on the current system.
+ string identifier;
+
+ /// Whether or not this device is connectable. Non-connectable devices are typically acting in the
+ /// LE broadcaster role.
+ bool connectable;
+
+ /// The last known RSSI of this device, if known.
+ fuchsia.bluetooth.Int8? rssi;
+
+ /// Advertising data broadcast by this device if this device is a broadcaster or peripheral.
+ AdvertisingDataDeprecated? advertising_data;
+};
+
+/// Filter parameters for use during a scan. A discovered peripheral or broadcaster will be reported
+/// to applications only if it satisfies all of the provided filter parameters. Null fields will be
+/// ignored.
+/// [[DEPRECATED]]
+struct ScanFilter {
+ /// Filter based on advertised service UUIDs. A peripheral that advertises at least one of the
+ /// entries in `service_uuids` will satisfy this filter.
+ vector<string>? service_uuids;
+
+ /// Filter based on service data containing one of the given UUIDs.
+ vector<string>? service_data_uuids;
+
+ /// Filter based on a company identifier present in the manufacturer data. If this filter parameter
+ /// is set, then the advertising payload must contain manufacturer specific data with the provided
+ /// company identifier to satisfy this filter.
+ fuchsia.bluetooth.UInt16? manufacturer_identifier;
+
+ /// Filter based on whether or not a device is connectable. For example, a client that is only
+ /// interested in peripherals that it can connect to can set this to true. Similarly a client can
+ /// scan only for braodcasters by setting this to false.
+ fuchsia.bluetooth.Bool? connectable;
+
+ /// Filter results based on a portion of the advertised device name.
+ string? name_substring;
+
+ /// Filter results based on the path loss of the radio wave. A device that matches this filter must
+ /// satisfy the following:
+ /// 1. Radio transmission power level and received signal strength must be available for the path
+ /// loss calculation;
+ /// 2. The calculated path loss value must be less than, or equal to, `max_path_loss`.
+ fuchsia.bluetooth.Int8? max_path_loss;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.sys/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.sys/BUILD.gn
new file mode 100644
index 0000000..49ded32
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.sys/BUILD.gn
@@ -0,0 +1,31 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.bluetooth.sys") {
+ library_name = "sys"
+ namespace = "fuchsia.bluetooth"
+ public_deps = [
+ "../fuchsia.bluetooth",
+ ]
+ sources = [
+ "access.fidl",
+ "bootstrap.fidl",
+ "host_watcher.fidl",
+ "identity.fidl",
+ "pairing_delegate.fidl",
+ "peer.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.bluetooth.sys",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.sys/access.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.sys/access.fidl
new file mode 100644
index 0000000..e2f12cb
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.sys/access.fidl
@@ -0,0 +1,124 @@
+// 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.
+
+library fuchsia.bluetooth.sys;
+
+using fuchsia.bluetooth as bt;
+
+enum Error {
+ /// Operation could not be performed.
+ FAILED = 1;
+
+ /// The peer designated for the operation was not found.
+ PEER_NOT_FOUND = 2;
+
+ /// The time limit for the operation has expired.
+ TIMED_OUT = 3;
+
+ /// The operation was canceled.
+ CANCELED = 4;
+
+ /// Operation already in progress.
+ IN_PROGRESS = 5;
+
+ /// Operation not supported.
+ NOT_SUPPORTED = 6;
+
+ /// The operation was given an invalid set of arguments.
+ INVALID_ARGUMENTS = 7;
+};
+
+/// Represents an active procedure. The validity of a handle that supports this protocol is tied to
+/// the activity of the procedure that it is attached to. To elaborate:
+///
+/// 1. Closing a token handle ends the procedure that it is attached to.
+/// 2. The system closes a token handle to communicate that a procedure was internally terminated.
+protocol ProcedureToken {
+};
+
+/// Protocol that abstracts the operational modes and procedures defined in the Bluetooth Generic
+/// Access Profile (see Core Specification v5.1, Vol 3, Part C).
+///
+/// The procedures under this protocol apply to the system as a whole. The Bluetooth controller that
+/// plays an active role in these procedures can be managed using the HostWatcher protocol.
+///
+/// The procedures initiated by an Access protocol instance are terminated when the underlying
+/// channel is closed.
+[Discoverable]
+protocol Access {
+ /// Assign a PairingDelegate to respond to drive pairing procedures. The delegate will be
+ /// configured to use the provided I/O capabilities to determine the pairing method.
+ ///
+ /// Only one PairingDelegate can be registered at a time. Closing a PairingDelegate aborts all
+ /// on-going pairing procedures associated with a delegate and closes the PairingDelegate
+ /// previously assigned for this Access instance.
+ ///
+ /// + request `input` Bluetooth input capability
+ /// + request `output` Bluetooth output capability
+ /// + request `delegate` The client end of a PairingDelegate channel.
+ SetPairingDelegate(InputCapability input, OutputCapability output, PairingDelegate delegate);
+
+ /// Assign a local name for the Bluetooth system. This name will be visible to nearby peers
+ /// when the system is in discoverable mode and during name discovery procedures.
+ ///
+ /// + request `name` The complete local name to assign to the system.
+ SetLocalName(string name);
+
+ /// Set the local device class that will be visible to nearby peers when the system is in
+ /// discoverable mode.
+ ///
+ /// + request `device_class` The device class to assign to the system.
+ SetDeviceClass(bt.DeviceClass device_class);
+
+ /// Put the system into the "General Discoverable" mode on the BR/EDR transport. The active
+ /// host will respond to general inquiry (by regularly entering the inquiry scan mode).
+ ///
+ /// + request `token` [`fuchsia.bluetooth.sys/ProcedureToken`] that will remain valid while a
+ /// discoverable mode session is active. NOTE: The system may remain discoverable until all
+ /// [`fuchsia.bluetooth.sys/Access`] clients drop their tokens.
+ /// * error Reports Error.FAILED if inquiry mode cannot be entered.
+ MakeDiscoverable(request<ProcedureToken> token) -> () error Error;
+
+ /// Start a general discovery procedure. All general discoverable BR/EDR, LE,
+ /// and BR/EDR/LE devices will appear in the peer list, which can be observed by calling
+ /// [`fuchsia.bluetooth.sys/Access.WatchPeers`].
+ ///
+ /// + request `token` [`fuchsia.bluetooth.sys/ProcedureToken`] that will remain valid while
+ /// discovery is in progress. NOTE: The radio will continue performing discovery until all
+ /// [`fuchsia.bluetooth.sys/Access`] drop their tokens.
+ /// * error Reports Error.FAILED if discovery on either transport cannot be initiated.
+ StartDiscovery(request<ProcedureToken> token) -> () error Error;
+
+ /// Returns a list of all peers (connectable Bluetooth devices) known to the system. The first
+ /// call results in a snapshot of all known peers to be sent immediately in the `updated` return
+ /// paremeter. Subsequent calls receive a response only when one or more entries have been
+ /// added, modified, or removed from the entries reported since the most recent call.
+ ///
+ /// - response `updated` Peers that were added or updated since the last call to WatchPeers().
+ /// - response `removed` Ids of peers that were removed since the last call to WatchPeers().
+ WatchPeers() -> (vector<Peer> updated, vector<bt.PeerId> removed);
+
+ /// Initiate a connection to the peer with the given `id`. This method connects both BR/EDR and
+ /// LE transports depending on the technologies that the peer is known to support.
+ ///
+ /// + request `id` The id of the peer to connect.
+ /// * error Reports `Error.FAILED` if a connection to the peer cannot be initiated.
+ /// * error Reports `Error.PEER_NOT_FOUND` if `id` is not recognized.
+ Connect(bt.PeerId id) -> () error Error;
+
+ /// Disconnect all logical links to the peer with the given `id`. This includes LE and
+ /// BR/EDR links that have been initiated using all Access and fuchsia.bluetooth.le protocol
+ /// instances.
+ ///
+ /// + request `id` The id of the peer to disconnect.
+ /// * error Reports `Error.PEER_NOT_FOUND` if `id` is not recognized.
+ Disconnect(bt.PeerId id) -> () error Error;
+
+ /// Removes all bonding information and disconnects any existing links with the peer with the
+ /// given `id`.
+ ///
+ /// + request `id` The id of the peer to forget.
+ /// * error Reports `Error.PEER_NOT_FOUND` if `id` is not recognized.
+ Forget(bt.PeerId id) -> () error Error;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.sys/bootstrap.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.sys/bootstrap.fidl
new file mode 100644
index 0000000..664eed1
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.sys/bootstrap.fidl
@@ -0,0 +1,37 @@
+// 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.
+
+library fuchsia.bluetooth.sys;
+
+enum BootstrapError : uint32 {
+ INVALID_HOST_IDENTITY = 1;
+ WRITE_FAILURE = 2;
+};
+
+/// Protocol used to initialize persistent core Bluetooth data. This protocol populates data that
+/// determine the identity of this device as perceived by other Bluetooth devices.
+///
+/// This protocol can be obtained only before the core Bluetooth host subsystem has generated its
+/// own identity. Once initial data is committed, this capability becomes unavailable and remains
+/// unavailable even if new Bluetooth adapters are attached.
+///
+/// Due to the privacy and bonding secrets involved, as well as the capability to make this device
+/// assume the Bluetooth identity of another device, this protocol should only be exposed to
+/// privileged components that can vouchsafe the origin of the data.
+[Discoverable]
+protocol Bootstrap {
+ /// Adds identities to be added to the unpopulated Bluetooth stack.
+ ///
+ /// Repeated calls will append identities.
+ // TODO(BT-711): If necessary, paginate bonding data to allow an arbitrary number of bonds for
+ // each identity, e.g. AddBonds(adapter_id, bonds).
+ AddIdentities(vector<Identity> identities);
+
+ /// Writes all added bootstrapping data to the Bluetooth core stack. The server will close the
+ /// channel regardless of success. Returns without error if successful and the stack will be
+ /// considered initialized even if no bootstrapping data was written. Returns
+ /// INVALID_HOST_IDENTITY if any host or bonded peer data is insufficient or inconsistent, with
+ /// no effect (the client may retry by obtaining another protocol handle).
+ Commit() -> () error BootstrapError;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.sys/host_watcher.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.sys/host_watcher.fidl
new file mode 100644
index 0000000..dc3a0de
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.sys/host_watcher.fidl
@@ -0,0 +1,56 @@
+// 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.
+
+library fuchsia.bluetooth.sys;
+
+using fuchsia.bluetooth as bt;
+using zx;
+
+/// Information about a Bluetooth controller and its associated host-subsystem state.
+table HostInfo {
+ /// Uniquely identifies a host on the current system.
+ ///
+ /// This field is always present.
+ 1: bt.HostId id;
+
+ /// The Bluetooth technologies that are supported by this adapter.
+ ///
+ /// This field is always present.
+ 2: TechnologyType technology;
+
+ /// The identity address.
+ ///
+ /// This field is always present.
+ 3: bt.Address address;
+
+ /// Indicates whether or not this is the active host. The system has one active host which
+ /// handles all Bluetooth procedures.
+ 4: bool active;
+
+ /// The local name of this host. This is the name that is visible to other devices when this
+ /// host is in the discoverable mode.
+ 5: string local_name;
+
+ /// Whether or not the local adapter is currently discoverable over BR/EDR and
+ /// LE physical channels.
+ 6: bool discoverable;
+
+ /// Whether or not device discovery is currently being performed.
+ 7: bool discovering;
+};
+
+/// Protocol used to observe and manage the Bluetooth controllers on the system.
+[Discoverable]
+protocol HostWatcher {
+ /// Obtain a list of all available Bluetooth controllers and their state. A response is sent
+ /// only if this list has changed since the last time the client has sent this message.
+ Watch() -> (vector<HostInfo> hosts);
+
+ /// Designates the host with the given `id` as active. All Bluetooth procedures will be routed
+ /// over this host. Any previously assigned active host will be disabled and all of its pending
+ /// procedures will be terminated.
+ ///
+ /// * error This can fail if a host with `id` was not found.
+ SetActive(bt.HostId id) -> () error zx.status;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.sys/identity.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.sys/identity.fidl
new file mode 100644
index 0000000..54aadb7
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.sys/identity.fidl
@@ -0,0 +1,130 @@
+// 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.
+
+library fuchsia.bluetooth.sys;
+
+using fuchsia.bluetooth as bt;
+
+struct SecurityProperties {
+ bool authenticated;
+ bool secure_connections;
+ uint8 encryption_key_size;
+};
+
+/// Represents a 128-bit secret key.
+struct Key {
+ array<uint8>:16 value;
+};
+
+/// Represents a key that was received from a peer.
+struct PeerKey {
+ /// The security properties of this link under which this key was received.
+ SecurityProperties security;
+
+ /// The contents of the key.
+ Key data;
+};
+
+/// Represents a locally generated key that is distributed across one or more bonds.
+using LocalKey = Key;
+
+/// Represents a LE Long-Term peer key used for link encyrption. The `ediv` and `rand`
+/// fields are zero if distributed using LE Secure Connections pairing.
+struct Ltk {
+ PeerKey key;
+ uint16 ediv;
+ uint64 rand;
+};
+
+/// The preferred LE connection parameters of the peer.
+struct LeConnectionParameters {
+ uint16 connection_interval;
+ uint16 connection_latency;
+ uint16 supervision_timeout;
+};
+
+table LeData {
+ /// The identity address of the peer.
+ 1: bt.Address address;
+
+ /// The peer's preferred connection parameters, if known.
+ 2: LeConnectionParameters connection_parameters;
+
+ /// Known GATT service UUIDs.
+ 3: vector<bt.Uuid> services;
+
+ /// The LE long-term key. Present if the link was encrypted.
+ 4: Ltk ltk;
+
+ /// Identity Resolving RemoteKey used to generate and resolve random addresses.
+ 5: PeerKey irk;
+
+ /// Connection Signature Resolving RemoteKey used for data signing without encryption.
+ 6: PeerKey csrk;
+};
+
+table BredrData {
+ /// The public device address of the peer.
+ 1: bt.Address address;
+
+ /// The peer's preferred piconet role. This is determined by role switch procedures. Paging and
+ /// connecting from a peer does not automatically set this flag. If absent, the peer has not
+ /// expressed a preference.
+ 2: bt.ConnectionRole role_preference;
+
+ /// Known service UUIDs obtained from EIR data or SDP.
+ 3: vector<bt.Uuid> services;
+
+ /// The semi-permanent BR/EDR key. Present if link was paired with Secure
+ /// Simple Pairing or stronger.
+ 4: PeerKey link_key;
+};
+
+/// Represents the bonding data for a single peer.
+table BondingData {
+ /// The identifier that uniquely identifies this peer.
+ 1: bt.PeerId identifier;
+
+ /// The local Bluetooth identity address that this bond is associated with.
+ 2: bt.Address local_address;
+
+ /// The name of the peer, if known.
+ 3: string name;
+
+ /// Bonding data that is present when this peer is paired on the LE transport.
+ 4: LeData le;
+
+ /// Bonding data that is present when this peer is paired on the BR/EDR transport.
+ 5: BredrData bredr;
+};
+
+/// Represents persistent local host data.
+table HostData {
+ /// The local Identity Resolving Key used by a bt-host device to generate Resolvable Private
+ /// Addresses when privacy is enabled.
+ ///
+ /// May be absent for hosts that do not use LE privacy, or that only use Non-Resolvable Private
+ /// Addresses.
+ ///
+ /// NOTE: This key is distributed to LE peers during pairing procedures. The client must take
+ /// care to assign an IRK that consistent with the local bt-host identity.
+ // TODO(BT-815): Document behavior once there is a better privacy policy when `irk` is null.
+ 1: LocalKey irk;
+};
+
+/// Represents the persistent configuration of a single host-subsystem instance. This is used for
+/// identity presentation (inquiry, inquiry response, and advertisement) and for bonding secrets
+/// recall (encrypting link data to peers associated with this identity).
+///
+/// Each BR/EDR BD_ADDR and Low Energy public identity address used to bond should have its own
+/// Identity instance containing corresponding peers.
+///
+/// Each Identity instance that supports LE privacy should have an Identity Resolving Key (IRK) that
+/// is consistent with that distributed to its bonded peers.
+table Identity {
+ 1: HostData host;
+
+ /// All bonds that use a public identity address must contain the same local address.
+ 2: vector<BondingData> bonds;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.sys/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.sys/meta.json
new file mode 100644
index 0000000..e62a160
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.sys/meta.json
@@ -0,0 +1,16 @@
+{
+ "deps": [
+ "fuchsia.bluetooth"
+ ],
+ "name": "fuchsia.bluetooth.sys",
+ "root": "fidl/fuchsia.bluetooth.sys",
+ "sources": [
+ "fidl/fuchsia.bluetooth.sys/access.fidl",
+ "fidl/fuchsia.bluetooth.sys/bootstrap.fidl",
+ "fidl/fuchsia.bluetooth.sys/host_watcher.fidl",
+ "fidl/fuchsia.bluetooth.sys/identity.fidl",
+ "fidl/fuchsia.bluetooth.sys/pairing_delegate.fidl",
+ "fidl/fuchsia.bluetooth.sys/peer.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.sys/pairing_delegate.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.sys/pairing_delegate.fidl
new file mode 100644
index 0000000..b5df787
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.sys/pairing_delegate.fidl
@@ -0,0 +1,88 @@
+// 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.
+
+library fuchsia.bluetooth.sys;
+
+using fuchsia.bluetooth as bt;
+
+/// Input and Output Capabilities for pairing exchanges.
+/// See Volume 3, Part C, Table 5.3 and 5.4
+enum InputCapability {
+ NONE = 1;
+ CONFIRMATION = 2;
+ KEYBOARD = 3;
+};
+
+enum OutputCapability {
+ NONE = 1;
+ DISPLAY = 2;
+};
+
+/// Different types required by the Security Manager for pairing methods.
+/// Bluetooth SIG has different requirements for different device capabilities.
+enum PairingMethod {
+ /// The user is asked to accept or reject pairing.
+ CONSENT = 1;
+
+ /// The user is shown a 6-digit numerical passkey which they must enter on the
+ /// peer device.
+ PASSKEY_DISPLAY = 2;
+
+ /// The user is shown a 6-digit numerical passkey which will also shown on the
+ /// peer device. The user must compare the passkeys and accept the pairing if
+ /// the passkeys match.
+ PASSKEY_COMPARISON = 3;
+
+ /// The user is asked to enter a 6-digit passkey.
+ PASSKEY_ENTRY = 4;
+};
+
+enum PairingKeypress {
+ /// The user has entered a single digit.
+ DIGIT_ENTERED = 1;
+
+ /// The user has erased a single digit.
+ DIGIT_ERASED = 2;
+
+ /// The user has cleared the entire passkey.
+ PASSKEY_CLEARED = 3;
+
+ /// The user has finished entering the passkey.
+ PASSKEY_ENTERED = 4;
+};
+
+protocol PairingDelegate {
+ /// Called to initiate a pairing request. The delegate must respond with “true” or “false” to
+ /// either accept or reject the pairing request. If the pairing method requires a passkey
+ /// this is returned as well.
+ ///
+ /// Any response from this method will be ignored if the OnPairingComplete
+ /// event has already been sent for `peer`.
+ ///
+ /// The `displayed_passkey` parameter should be displayed to the user if `method` equals
+ /// `PairingMethod.PASSKEY_DISPLAY` or `PairingMethod.PASSKEY_COMPARISON`. Otherwise, this parameter
+ /// has no meaning and should be ignored.
+ ///
+ /// The `entered_passkey` parameter only has meaning if `method` equals
+ /// `PairingMethod.PASSKEY_ENTRY`. It will be ignored otherwise.
+ OnPairingRequest(Peer peer, PairingMethod method, uint32 displayed_passkey)
+ -> (bool accept, uint32 entered_passkey);
+
+ /// Called if the pairing procedure for the device with the given ID is completed.
+ /// This can be due to successful completion or an error (e.g. due to cancellation
+ /// by the peer, a timeout, or disconnection) which is indicated by `success`.
+ OnPairingComplete(bt.PeerId id, bool success);
+
+ /// Called to notify keypresses from the peer device during pairing using
+ /// `PairingMethod.PASSKEY_DISPLAY`.
+ ///
+ /// This event is used to provide key press events to the delegate for a responsive user
+ /// experience as the user types the passkey on the peer device. This event will be called
+ /// once for each key-press.
+ OnRemoteKeypress(bt.PeerId id, PairingKeypress keypress);
+
+ /// The delegate can send this event to notify the peer of local keypresses
+ /// during pairing using `PairingMethod.PASSKEY_ENTRY`.
+ -> OnLocalKeypress(bt.PeerId id, PairingKeypress keypress);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.sys/peer.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.sys/peer.fidl
new file mode 100644
index 0000000..33c889b
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth.sys/peer.fidl
@@ -0,0 +1,64 @@
+// 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.
+
+library fuchsia.bluetooth.sys;
+
+using fuchsia.bluetooth as bt;
+
+enum TechnologyType {
+ LOW_ENERGY = 1;
+ CLASSIC = 2;
+ DUAL_MODE = 3;
+};
+
+/// Represents a remote BR/EDR, LE, or dual-mode BR/EDR/LE peer.
+table Peer {
+ /// Uniquely identifies this peer on the current system.
+ ///
+ /// This field is always present.
+ 1: bt.PeerId id;
+
+ /// Bluetooth device address that identifies this peer. Clients
+ /// should display this field to the user when `name` is not available.
+ ///
+ /// This field is always present.
+ ///
+ /// NOTE: Clients should use the `identifier` field to keep track of peers instead of their
+ /// address.
+ 2: bt.Address address;
+
+ /// The Bluetooth technologies that are supported by this peer.
+ ///
+ /// This field is always present.
+ 3: TechnologyType technology;
+
+ /// Whether or not a BR/EDR and/or LE connection exists to this peer.
+ ///
+ /// This field is always present.
+ 4: bool connected;
+
+ /// Whether or not this peer is bonded.
+ ///
+ /// This field is always present.
+ 5: bool bonded;
+
+ /// The name of the peer, if known.
+ 6: string name;
+
+ /// The LE appearance property. Present if this peer supports LE and the
+ /// appearance information was obtained over advertising and/or GATT.
+ 7: bt.Appearance appearance;
+
+ /// The class of device for this device, if known.
+ 8: bt.DeviceClass device_class;
+
+ /// The most recently obtained advertising signal strength for this peer. Present if known.
+ 9: int8 rssi;
+
+ /// The most recently obtained transmission power for this peer. Present if known.
+ 10: int8 tx_power;
+
+ /// The list of service UUIDs known to be available on this peer.
+ 11: vector<bt.Uuid> services;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth/BUILD.gn
new file mode 100644
index 0000000..5aca079
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth/BUILD.gn
@@ -0,0 +1,32 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.bluetooth") {
+ library_name = "bluetooth"
+ namespace = "fuchsia"
+ public_deps = [
+ ]
+ sources = [
+ "address.fidl",
+ "appearance.fidl",
+ "connection_role.fidl",
+ "device_class.fidl",
+ "id.fidl",
+ "nullables.fidl",
+ "status.fidl",
+ "uuid.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.bluetooth",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth/address.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth/address.fidl
new file mode 100644
index 0000000..65daf08
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth/address.fidl
@@ -0,0 +1,22 @@
+// 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.
+
+library fuchsia.bluetooth;
+
+enum AddressType : uint8 {
+ /// LE public device address or `BR/EDR` `BD_ADDR`.
+ PUBLIC = 1;
+
+ /// LE private or static random device address.
+ RANDOM = 2;
+};
+
+/// Represents a 48-bit Bluetooth Device Address.
+struct Address {
+ /// Type of the device address.
+ AddressType type;
+
+ /// The device address bytes in little-endian order.
+ array<uint8>:6 bytes;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth/appearance.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth/appearance.fidl
new file mode 100644
index 0000000..f6844e1
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth/appearance.fidl
@@ -0,0 +1,65 @@
+// 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.
+
+library fuchsia.bluetooth;
+
+/// Possible values for the LE Appearance property which describes the external
+/// appearance of a peer at a high level.
+/// (See the Bluetooth assigned-numbers document:
+/// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.gap.appearance.xml)
+enum Appearance : uint16 {
+ UNKNOWN = 0;
+ PHONE = 64;
+ COMPUTER = 128;
+ WATCH = 192;
+ WATCH_SPORTS = 193;
+ CLOCK = 256;
+ DISPLAY = 320;
+ REMOTE_CONTROL = 384;
+ EYE_GLASSES = 448;
+ TAG = 512;
+ KEYRING = 576;
+ MEDIA_PLAYER = 640;
+ BARCODE_SCANNER = 704;
+ THERMOMETER = 768;
+ THERMOMETER_EAR = 769;
+ HEART_RATE_SENSOR = 832;
+ HEART_RATE_SENSOR_BELT = 833;
+ BLOOD_PRESSURE = 896;
+ BLOOD_PRESSURE_ARM = 897;
+ BLOOD_PRESSURE_WRIST = 898;
+ HID = 960;
+ HID_KEYBOARD = 961;
+ HID_MOUSE = 962;
+ HID_JOYSTICK = 963;
+ HID_GAMEPAD = 964;
+ HID_DIGITIZER_TABLET = 965;
+ HID_CARD_READER = 966;
+ HID_DIGITAL_PEN = 967;
+ HID_BARCODE_SCANNER = 968;
+ GLUCOSE_METER = 1024;
+ RUNNING_WALKING_SENSOR = 1088;
+ RUNNING_WALKING_SENSOR_IN_SHOE = 1089;
+ RUNNING_WALKING_SENSOR_ON_SHOE = 1090;
+ RUNNING_WALKING_SENSOR_ON_HIP = 1091;
+ CYCLING = 1152;
+ CYCLING_COMPUTER = 1153;
+ CYCLING_SPEED_SENSOR = 1154;
+ CYCLING_CADENCE_SENSOR = 1155;
+ CYCLING_POWER_SENSOR = 1156;
+ CYCLING_SPEED_AND_CADENCE_SENSOR = 1157;
+ PULSE_OXIMETER = 3136;
+ PULSE_OXIMETER_FINGERTIP = 3137;
+ PULSE_OXIMETER_WRIST = 3138;
+ WEIGHT_SCALE = 3200;
+ PERSONAL_MOBILITY = 3264;
+ PERSONAL_MOBILITY_WHEELCHAIR = 3265;
+ PERSONAL_MOBILITY_SCOOTER = 3266;
+ GLUCOSE_MONITOR = 3328;
+ SPORTS_ACTIVITY = 5184;
+ SPORTS_ACTIVITY_LOCATION_DISPLAY = 5185;
+ SPORTS_ACTIVITY_LOCATION_AND_NAV_DISPLAY = 5186;
+ SPORTS_ACTIVITY_LOCATION_POD = 5187;
+ SPORTS_ACTIVITY_LOCATION_AND_NAV_POD = 5188;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth/connection_role.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth/connection_role.fidl
new file mode 100644
index 0000000..827f0ab
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth/connection_role.fidl
@@ -0,0 +1,18 @@
+// 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.
+
+library fuchsia.bluetooth;
+
+/// Refers to the role of a Bluetooth device (local or peer) in a physical channel piconet. See
+/// [Bluetooth Vocabulary Guide](/src/connectivity/bluetooth/docs/vocabulary.md) for more
+/// information.
+enum ConnectionRole {
+ /// The role of the device that defines the piconet physical channel in BR/EDR or the
+ /// "initiating" device in LE.
+ LEADER = 1;
+
+ /// The role of a device that synchronizes to the piconet physical channel in BR/EDR or the
+ /// "advertising" device in LE.
+ FOLLOWER = 2;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth/device_class.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth/device_class.fidl
new file mode 100644
index 0000000..5071822
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth/device_class.fidl
@@ -0,0 +1,31 @@
+// 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.
+
+library fuchsia.bluetooth;
+
+/// The "Class of Device/Service" is a variable-format field that defines the category of a
+/// Bluetooth device. The bitfield is divided into segments called "major service class",
+/// "major device class", and "minor device class".
+///
+/// No assumptions about the specific functionality or characteristics of any application should be
+/// based solely on its inclusion within a Major or Minor device class. For more information, see
+/// https://www.bluetooth.com/specifications/assigned-numbers/baseband.
+struct DeviceClass {
+ uint32 value;
+};
+
+/// Constants for the major device class field. The major device class is defined by bits 12-8.
+const uint32 MAJOR_DEVICE_CLASS_MASK = 0x1f00;
+
+const uint32 MAJOR_DEVICE_CLASS_MISCELLANEOUS = 0x0000;
+const uint32 MAJOR_DEVICE_CLASS_COMPUTER = 0x0100;
+const uint32 MAJOR_DEVICE_CLASS_PHONE = 0x0200;
+const uint32 MAJOR_DEVICE_CLASS_LAN = 0x0300;
+const uint32 MAJOR_DEVICE_CLASS_AUDIO_VIDEO = 0x0400;
+const uint32 MAJOR_DEVICE_CLASS_PERIPHERAL = 0x0500;
+const uint32 MAJOR_DEVICE_CLASS_IMAGING = 0x0600;
+const uint32 MAJOR_DEVICE_CLASS_WEARABLE = 0x0700;
+const uint32 MAJOR_DEVICE_CLASS_TOY = 0x0800;
+const uint32 MAJOR_DEVICE_CLASS_HEALTH = 0x0900;
+const uint32 MAJOR_DEVICE_CLASS_UNCATEGORIZED = 0x1f00;
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth/id.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth/id.fidl
new file mode 100644
index 0000000..26255a0
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth/id.fidl
@@ -0,0 +1,15 @@
+// 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.
+
+library fuchsia.bluetooth;
+
+/// 64-bit unique value used by the system to identify host adapters.
+struct HostId {
+ uint64 value;
+};
+
+/// 64-bit unique value used by the system to identify peer devices.
+struct PeerId {
+ uint64 value;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth/meta.json
new file mode 100644
index 0000000..f34661e
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth/meta.json
@@ -0,0 +1,16 @@
+{
+ "deps": [],
+ "name": "fuchsia.bluetooth",
+ "root": "fidl/fuchsia.bluetooth",
+ "sources": [
+ "fidl/fuchsia.bluetooth/address.fidl",
+ "fidl/fuchsia.bluetooth/appearance.fidl",
+ "fidl/fuchsia.bluetooth/connection_role.fidl",
+ "fidl/fuchsia.bluetooth/device_class.fidl",
+ "fidl/fuchsia.bluetooth/id.fidl",
+ "fidl/fuchsia.bluetooth/nullables.fidl",
+ "fidl/fuchsia.bluetooth/status.fidl",
+ "fidl/fuchsia.bluetooth/uuid.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth/nullables.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth/nullables.fidl
new file mode 100644
index 0000000..08e7a5b
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth/nullables.fidl
@@ -0,0 +1,20 @@
+// Copyright 2018 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.
+
+library fuchsia.bluetooth;
+
+// DEPRECATED: Do not use these types in new code. Prefer tables to group optional primitive
+// fields.
+
+struct Bool {
+ bool value;
+};
+
+struct Int8 {
+ int8 value;
+};
+
+struct UInt16 {
+ uint16 value;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth/status.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth/status.fidl
new file mode 100644
index 0000000..6d923ad
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth/status.fidl
@@ -0,0 +1,46 @@
+// Copyright 2017 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.
+
+library fuchsia.bluetooth;
+
+/// DEPRECATED. Do not use these types in new code. Prefer the "error" syntax, protocol-specific
+/// enums and zx.status instead.
+
+enum ErrorCode {
+ UNKNOWN = 0;
+ FAILED = 1;
+ CANCELED = 2;
+ IN_PROGRESS = 3;
+ TIMED_OUT = 4;
+ NOT_FOUND = 5;
+ NOT_SUPPORTED = 6;
+ BLUETOOTH_NOT_AVAILABLE = 7;
+ BAD_STATE = 8;
+ INVALID_ARGUMENTS = 9;
+ ALREADY = 10;
+ PROTOCOL_ERROR = 11;
+};
+
+// Represents an error result returned from an asynchronous operation.
+struct Error {
+ // Represents a high-level error code. If this is set to ErrorCode.PROTOCOL_ERROR, then
+ // `protocol_error_code` will represent a Bluetooth protocol error code. The specific
+ // protocol that caused the error will be context-specific, e.g. GATT interfaces will
+ // return ATT protocol error codes.
+ ErrorCode error_code;
+
+ // Protocol error code. The value of this field is relevant only if `error_code` is set to
+ // ErrorCode.PROTOCOL_ERROR.
+ uint32 protocol_error_code;
+
+ // Debug descriptioon of an error. This provides additional debugging information for an error
+ // and is not intended to be displayed in user interfaces.
+ string? description;
+};
+
+// Represents the result of an asynchronous operation.
+struct Status {
+ // `error` will be null if this represents a "success" status, i.e. no error has occurred.
+ Error? error;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth/uuid.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth/uuid.fidl
new file mode 100644
index 0000000..66b0bd6
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.bluetooth/uuid.fidl
@@ -0,0 +1,13 @@
+// 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.
+
+library fuchsia.bluetooth;
+
+/// Represents a Bluetooth UUID in its 128-bit canonical form. While the Bluetooth standard supports
+/// 16- and 32-bit short form UUIDs over the wire, the Fuchsia FIDL libraries require all UUIDs to
+/// be represented in their canonical 128-bit form.
+struct Uuid {
+ /// The UUID bytes in little-endian order.
+ array<uint8>:16 value;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.camera/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.camera/BUILD.gn
new file mode 100644
index 0000000..9570738
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.camera/BUILD.gn
@@ -0,0 +1,27 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.camera") {
+ library_name = "camera"
+ namespace = "fuchsia"
+ public_deps = [
+ "../fuchsia.sysmem",
+ ]
+ sources = [
+ "camera.fidl",
+ "manager.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.camera",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.camera/camera.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.camera/camera.fidl
new file mode 100644
index 0000000..a2c9796
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.camera/camera.fidl
@@ -0,0 +1,116 @@
+// Copyright 2018 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.
+
+// This file is being deprecated - please do not rely on any of the structs or
+// protocols here moving forward.
+
+library fuchsia.camera;
+
+using fuchsia.sysmem;
+using zx;
+
+const uint32 MAX_FORMATS_PER_RESPONSE = 16;
+
+/// A coarse set of capabilities. This struct is used in the camera description
+/// to help filter out cameras which will not have the needed capabilities.
+/// This set of declarations would be the bitfield: CameraOutputCapabilities.
+const uint32 CAMERA_OUTPUT_UNKNOWN = 0;
+const uint32 CAMERA_OUTPUT_STILL_IMAGE = 0x01;
+const uint32 CAMERA_OUTPUT_BURST = 0x02;
+const uint32 CAMERA_OUTPUT_STREAM = 0x04;
+const uint32 CAMERA_OUTPUT_HDR = 0x08;
+const uint32 CAMERA_OUTPUT_DEPTH = 0x10;
+const uint32 CAMERA_OUTPUT_STEREO = 0x20;
+
+/// Identifying information about the device.
+struct DeviceInfo {
+ uint64 camera_id; // Currently populated by the camera manager
+ uint16 vendor_id;
+ string vendor_name;
+ uint16 product_id;
+ string product_name;
+ /// The maximum number of stream interfaces that the device can support
+ /// simultaneously.
+ uint16 max_stream_count;
+ uint32 output_capabilities; // CameraOutputCapabilities
+ // TODO(CAM-12): Add CameraPose, when we can actually use it.
+};
+
+/// Status to be set when a frame is signalled available.
+enum FrameStatus {
+ OK = 0;
+ /// An error occurred during the production of a frame.
+ /// No data will be available in the data buffer corresponding to this
+ /// notification.
+ ERROR_FRAME = 1;
+
+ /// No space was available in the data buffer, resulting in a dropped frame.
+ ERROR_BUFFER_FULL = 2;
+};
+
+struct Metadata {
+ int64 timestamp;
+};
+
+/// Sent by the driver to the client when a frame is available for processing,
+/// or an error occurred.
+struct FrameAvailableEvent {
+ /// Non zero if an error occurred.
+ FrameStatus frame_status;
+
+ /// The index of the buffer in the buffer collection.
+ uint32 buffer_id;
+
+ Metadata metadata;
+};
+
+struct FrameRate {
+ /// The frame rate is frames_per_sec_numerator / frames_per_sec_denominator.
+ uint32 frames_per_sec_numerator;
+ uint32 frames_per_sec_denominator;
+};
+
+struct VideoFormat {
+ fuchsia.sysmem.ImageFormat format;
+ FrameRate rate;
+};
+
+/// These are the original interfaces, which are being used for compatibility.
+/// The names are preserved from the ones in camera.h for porting ease.
+[Discoverable]
+protocol Control {
+ /// Get the available format types for this device
+ /// NOTE: The formats are paginated to `MAX_FORMATS_PER_RESPONSE`, multiple
+ /// GetFormats need to be issued until total_format_count are received
+ GetFormats(uint32 index)
+ -> (vector<VideoFormat> formats, uint32 total_format_count,
+ zx.status status);
+
+ /// Sent by the client to indicate desired stream characteristics.
+ /// If setting the format is successful, the stream request will be honored.
+ /// The stream token is used to provide additional control over the interface from the
+ /// Camera Manager. The driver provides the guarantee that:
+ /// 1) If the stream token receives the `PEER_CLOSED` event, the driver will close
+ /// the stream.
+ /// 2) If the Stream interface is closed, the driver will close the eventpair.
+ CreateStream(fuchsia.sysmem.BufferCollectionInfo buffer_collection,
+ FrameRate rate, request<Stream> stream, handle<eventpair> stream_token);
+
+ GetDeviceInfo() -> (DeviceInfo device_info);
+};
+
+protocol Stream {
+ /// Starts the streaming of frames.
+ Start();
+
+ /// Stops the streaming of frames.
+ Stop();
+
+ /// Unlocks the specified frame, allowing the driver to reuse the memory.
+ ReleaseFrame(uint32 buffer_id);
+
+ /// Sent by the driver to the client when a frame is available for processing,
+ /// or an error occurred.
+ -> OnFrameAvailable(FrameAvailableEvent frame);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.camera/manager.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.camera/manager.fidl
new file mode 100644
index 0000000..9e72137
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.camera/manager.fidl
@@ -0,0 +1,73 @@
+// Copyright 2018 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.
+
+library fuchsia.camera;
+
+using fuchsia.sysmem;
+
+/// A stream that the camera manager can provide. Video streams reference a
+/// a camera, but may have additional hardware and bandwidth restrictions
+/// from and ISP or other processing units.
+/// This is being deprecated - please use VideoStreamV2 (below).
+struct VideoStream {
+ /// The camera_id corresponds to the camera_id that is given in the DeviceInfo
+ /// received from GetDevices.
+ uint64 camera_id;
+ /// The requested video format. Note that this is field is necessary to
+ /// set The frame rate, even when calling CreateStream.
+ /// When calling CreateStream, format.format should match buffer_info.format.
+ VideoFormat format;
+};
+
+/// Preferred version of stream.
+/// A version of stream that relies on definition of VideoFormat coming out of
+/// fuchsia.hardware.camera. Streams reference a camera, but may have additional
+/// hardware and bandwidth restrictions from an ISP or other processing units.
+/// New code should depend on this as the other version will be deprecated when
+/// dependencies are removed.
+struct VideoStreamV2 {
+ /// The camera_id corresponds to the camera_id that is given in DeviceInfo
+ /// received from GetDevices.
+ uint64 camera_id;
+ /// The requested video format. Note that this field is necessary to set the
+ /// frame rate, even when calling CreateStream. When calling CreateStream
+ /// format.format should match buffer_info.format.
+ VideoFormat format;
+};
+
+/// The Camera Manager grants access to individual or sets of cameras
+/// 1) You request the list of cameras, which gives you camera descriptions
+/// 2) You request the list of formats available for the camera to which you
+/// wish to connect.
+/// 3) You request a Stream interface using CreateStream.
+[Discoverable]
+protocol Manager {
+ /// Returns a list of all the video devices that are currently plugged in
+ /// and enumerated. The camera_id field of the DeviceInfo is used to specify
+ /// a device in GetFormats, GetStream and GetStreamAndBufferCollection.
+ GetDevices() -> (vector<DeviceInfo> descriptions);
+
+ /// Get all the available formats for a camera.
+ /// `camera_id` is obtained from a DeviceInfo returned by GetDevices.
+ GetFormats(uint64 camera_id, uint32 index)
+ -> (vector<VideoFormat> formats, uint32 total_format_count);
+
+ /// Create a Stream with the specified access rights. This may not succeed.
+ /// If it does succeed, the Stream will have the rights indicated.
+ /// `buffer_info` contains a set of buffers to be used with the Stream.
+ /// This is being deprecated - please use CreateStreamV2.
+ CreateStream(VideoStream request,
+ fuchsia.sysmem.BufferCollectionInfo buffer_info,
+ request<Stream> stream, handle<eventpair> client_token);
+
+ /// Create a Stream with the specified access rights. This may not succeed.
+ /// If it does succeed, the Stream will have the rights indicated.
+ /// `buffer_info` contains a set of buffers to be used with the Stream.
+ [Transitional="This is meant to replace CreateStream"]
+ CreateStreamV2(VideoStreamV2 request,
+ fuchsia.sysmem.BufferCollectionInfo buffer_info,
+ request<Stream> stream,
+ handle<eventpair> client_token);
+
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.camera/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.camera/meta.json
new file mode 100644
index 0000000..7e44edf
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.camera/meta.json
@@ -0,0 +1,12 @@
+{
+ "deps": [
+ "fuchsia.sysmem"
+ ],
+ "name": "fuchsia.camera",
+ "root": "fidl/fuchsia.camera",
+ "sources": [
+ "fidl/fuchsia.camera/camera.fidl",
+ "fidl/fuchsia.camera/manager.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.camera2.hal/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.camera2.hal/BUILD.gn
new file mode 100644
index 0000000..751ea7c
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.camera2.hal/BUILD.gn
@@ -0,0 +1,27 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.camera2.hal") {
+ library_name = "hal"
+ namespace = "fuchsia.camera2"
+ public_deps = [
+ "../fuchsia.camera2",
+ "../fuchsia.sysmem",
+ ]
+ sources = [
+ "hal.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.camera2.hal",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.camera2.hal/hal.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.camera2.hal/hal.fidl
new file mode 100644
index 0000000..5979760
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.camera2.hal/hal.fidl
@@ -0,0 +1,77 @@
+// 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.
+
+library fuchsia.camera2.hal;
+
+using fuchsia.camera2;
+using fuchsia.sysmem;
+using zx;
+
+/// Maximum number of configurations per device.
+const uint64 MAX_CONFIGURATIONS = 256;
+
+/// Maximum number of streams per config.
+const uint64 MAX_STREAMS = 64;
+
+/// Represents one stream within a particular configuration.
+struct StreamConfig {
+ fuchsia.camera2.FrameRate frame_rate;
+ /// `constraints` should allow for all the image formats listed in image_formats.
+ fuchsia.sysmem.BufferCollectionConstraints constraints;
+
+ /// Properties of the stream:
+ fuchsia.camera2.StreamProperties properties;
+
+ /// We need to specify both the constraints & the image formats because
+ /// there are fixed set of resolutions supported by the Camera Controller
+ /// so a range within the `constraints` won't be sufficient.
+ /// Some streams support multiple resolutions for same configuration
+ /// We would need to change the resolution runtime, without stopping the
+ /// streaming. This provides a list of resolutions a stream would be providing.
+ /// At least one format must be provided.
+ vector<fuchsia.sysmem.ImageFormat_2>:fuchsia.camera2.MAX_IMAGE_FORMATS image_formats;
+};
+
+/// Represents one configuration
+struct Config {
+ // One configuration could have multiple streams.
+ vector<StreamConfig>:MAX_STREAMS stream_configs;
+};
+
+/// This is the interface to the camera driver
+/// which allows setting up a given configuration
+/// and setting up a stream.
+[Discoverable]
+protocol Controller {
+ // TODO(48707): Change to GetConfig() which returns a single configuration instead
+ /// of a vector of Configs.
+ /// Get an available configurations which the camera driver supports.
+ /// Clients need to keep calling GetConfigs() to get all available configurations.
+ /// Returns |nullptr| if no new configurations are supported.
+ GetConfigs() -> (vector<Config>:MAX_CONFIGURATIONS? configs, zx.status status);
+
+ /// Set a particular configuration and create the requested stream.
+ /// `config_index` : Configuration index from the vector which needs to be applied.
+ /// `stream_index` : Stream index from the vector of streams provided within a config.
+ /// `buffer_collection` : Buffer collections for the stream.
+ /// `stream` : Stream channel for the stream requested
+ /// `image_format_index` : Image format index which needs to be set up upon creation.
+ /// If there is already an active configuration which is different than the one
+ /// which is requested to be set, then the HAL will be closing all existing streams
+ /// and honor this new setup call.
+ /// If the new stream requested is already part of the existing running configuration
+ /// the HAL will just be creating this new stream while the other stream still exists as is.
+ CreateStream(uint32 config_index,
+ uint32 stream_index,
+ uint32 image_format_index,
+ fuchsia.sysmem.BufferCollectionInfo_2 buffer_collection,
+ request<fuchsia.camera2.Stream> stream);
+
+ /// Enable/Disable Streaming
+ EnableStreaming();
+ DisableStreaming();
+
+ // Get identifying information about the device:
+ GetDeviceInfo() -> (fuchsia.camera2.DeviceInfo info);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.camera2.hal/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.camera2.hal/meta.json
new file mode 100644
index 0000000..9575c35
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.camera2.hal/meta.json
@@ -0,0 +1,12 @@
+{
+ "deps": [
+ "fuchsia.camera2",
+ "fuchsia.sysmem"
+ ],
+ "name": "fuchsia.camera2.hal",
+ "root": "fidl/fuchsia.camera2.hal",
+ "sources": [
+ "fidl/fuchsia.camera2.hal/hal.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.camera2/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.camera2/BUILD.gn
new file mode 100644
index 0000000..f558a7b
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.camera2/BUILD.gn
@@ -0,0 +1,27 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.camera2") {
+ library_name = "camera2"
+ namespace = "fuchsia"
+ public_deps = [
+ "../fuchsia.sysmem",
+ ]
+ sources = [
+ "manager.fidl",
+ "stream.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.camera2",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.camera2/manager.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.camera2/manager.fidl
new file mode 100644
index 0000000..43f3dfa
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.camera2/manager.fidl
@@ -0,0 +1,91 @@
+// 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.
+
+library fuchsia.camera2;
+
+using fuchsia.sysmem;
+using zx;
+
+[Discoverable]
+protocol Manager {
+ /// Notifies the client when a camera becomes available. A number of these events will
+ /// be sent when a client first connects to this protocol.
+ /// `device_id` is used to identify the camera. The device_id should not change throughout
+ /// the lifetime of the camera.
+ /// `last_known_camera` is set to true when the Camera Manager has notified the client
+ /// of all the devices it currently knows about.
+ /// `description` describes the properties of the camera.
+ -> OnDeviceAvailable(int32 device_id, DeviceInfo description, bool last_known_camera);
+
+ /// Notifies the client when a camera becomes unavailable.
+ -> OnDeviceUnavailable(int32 device_id);
+
+ /// Notifies the client when a camera becomes muted or unmuted.
+ /// `device_id` refers to the device_id from the description of a previous OnDeviceAvailable
+ /// call.
+ -> OnDeviceMuteChanged(int32 device_id, bool currently_muted);
+
+ /// AcknowledgeDeviceEvent must be called after any of the above events before more
+ /// events will be sent.
+ AcknowledgeDeviceEvent();
+
+ /// Connect to a camera stream:
+ /// `device_id` Refers to a specific device_id that has been advertised by OnDeviceAvailable.
+ /// `constraints` contains a set of constraints on the requested stream. The Camera
+ /// Manager will attempt to find a stream that meets the constraints. If multiple
+ /// streams match, one of the matching streams will be connected.
+ /// `token` refers to a Sysmem buffer allocation that will be used to pass images using
+ /// the Stream protocol. The Camera Manager will apply a BufferCollectionContraints
+ /// related to the image format(s), so the client does not need to apply any
+ /// ImageFormatConstraints.
+ /// Sync is assumed to have been called on `token` before it is passed to
+ /// ConnectToStream.
+ /// Since `constraints` may not dictate a specific format, the initial format of images
+ /// on the stream is indicated on the response.
+ /// The connection is considered to be successful once a response has been given, unless
+ /// `stream` is closed.
+ ConnectToStream(int32 device_id, StreamConstraints constraints,
+ fuchsia.sysmem.BufferCollectionToken token,
+ request<Stream> stream) -> (fuchsia.sysmem.ImageFormat_2 format);
+};
+
+[Discoverable]
+protocol MuteControl {
+ /// Mutes a camera. This is independent from stopping or closing a stream. A muted
+ /// camera will not produce any more images until
+ /// unmute is called. You can still connect to streams from a muted camera, but they
+ /// will not produce frames until the camera is unmuted.
+ /// `device_id` refers to the device_id from a previous OnDeviceAvailable call.
+ Mute(int32 device_id) -> (zx.status status);
+ Unmute(int32 device_id) -> (zx.status status);
+};
+
+/// These constraints are given to the Camera Manager when requesting a stream. The
+/// Camera Manager will use these constraints to match an appropriate stream.
+table StreamConstraints {
+ /// A table that describes the properties of the stream. Any properties specified will
+ /// be considered requirements for matching streams.
+ 1: StreamProperties properties;
+
+ /// If specified, the stream will be created using this index for the initial format index.
+ /// If unspecified, the first stream format will be used.
+ 2: uint32 format_index;
+};
+
+enum DeviceType {
+ BUILTIN = 1;
+ VIRTUAL = 2;
+};
+
+/// Identifying information about the device.
+table DeviceInfo {
+ /// Information from physical device enumeration:
+ 1: uint16 vendor_id;
+ 2: string:255 vendor_name;
+ 3: uint16 product_id;
+ 4: string:255 product_name;
+
+ /// Information about the type of device:
+ 5: DeviceType type;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.camera2/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.camera2/meta.json
new file mode 100644
index 0000000..e343ca9
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.camera2/meta.json
@@ -0,0 +1,12 @@
+{
+ "deps": [
+ "fuchsia.sysmem"
+ ],
+ "name": "fuchsia.camera2",
+ "root": "fidl/fuchsia.camera2",
+ "sources": [
+ "fidl/fuchsia.camera2/manager.fidl",
+ "fidl/fuchsia.camera2/stream.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.camera2/stream.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.camera2/stream.fidl
new file mode 100644
index 0000000..1271fe0
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.camera2/stream.fidl
@@ -0,0 +1,114 @@
+// 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.
+
+library fuchsia.camera2;
+
+using fuchsia.sysmem;
+using zx;
+
+/// Maximum number of image formats per stream.
+const uint64 MAX_IMAGE_FORMATS = 256;
+
+/// Status to be set when a frame is signalled available.
+enum FrameStatus {
+ OK = 0;
+ /// An error occurred during the production of a frame.
+ /// No data will be available in the data buffer corresponding to this
+ /// notification.
+ ERROR_FRAME = 1;
+
+ /// No space was available in the data buffer, resulting in a dropped frame.
+ ERROR_BUFFER_FULL = 2;
+};
+
+table FrameMetadata {
+ 1: int64 timestamp;
+ /// |image_format_index| references the index into the vector of available
+ /// formats supported by the stream.
+ 2: uint32 image_format_index;
+};
+
+/// Sent by the driver to the client when a frame is available for processing,
+/// or an error occurred.
+struct FrameAvailableInfo {
+ /// Non zero if an error occurred.
+ FrameStatus frame_status;
+
+ /// The index of the buffer in the buffer collection.
+ uint32 buffer_id;
+
+ FrameMetadata metadata;
+};
+
+struct FrameRate {
+ /// The frame rate is frames_per_sec_numerator / frames_per_sec_denominator.
+ uint32 frames_per_sec_numerator;
+ uint32 frames_per_sec_denominator;
+};
+
+/// Different Stream types provided by the camera stack.
+bits CameraStreamType : uint32 {
+ /// ML request FR(Full Resolution) stream as well as
+ /// a DS(Down Scaled Resolution) stream for Security Use Case
+ /// which are of fixed resolutions
+ MACHINE_LEARNING = 0x01;
+ /// This is Security Video Stream which could support multiple
+ /// resolutions at runtime.
+ MONITORING = 0x02;
+ FULL_RESOLUTION = 0x04;
+ /// ML request a DS stream for Video Conferencing which is fixed resolution
+ DOWNSCALED_RESOLUTION = 0x08;
+ /// This is Video Conferencing Stream which could support
+ /// multiple resolutions at runtime.
+ VIDEO_CONFERENCE = 0x10;
+ /// Stream with extended field of view.
+ EXTENDED_FOV = 0x20;
+};
+
+table StreamProperties {
+ /// These could be one or more of the above mentioned Stream Types
+ 1: CameraStreamType stream_type;
+};
+
+protocol Stream {
+ /// Control Operations
+ /// Starts the streaming of frames.
+ Start();
+
+ /// Stops the streaming of frames.
+ Stop();
+
+ /// Unlocks the specified frame, allowing the driver to reuse the memory.
+ ReleaseFrame(uint32 buffer_id);
+
+ /// Sent by the driver to the client when a frame is available for processing,
+ /// or an error occurred. The frame is considered read-locked by the client
+ /// after this message. The client must call ReleaseFrame to release the
+ /// read-lock for a non-error frame, or the consumer will eventually run out of buffers.
+ /// If a frame has an error, the client must call AcknowledgeFrameError before
+ /// another OnFrameAvailable will be called with an error frame.
+ -> OnFrameAvailable(FrameAvailableInfo frame);
+
+ /// Provides flow control for receiving frame errors. See OnFrameAvailable comment.
+ AcknowledgeFrameError();
+
+ /// Data operations
+ /// This is used by clients to provide inputs for region of interest
+ /// selection.
+ /// Inputs are the x & y coordinates for the new bounding box.
+ /// For streams which do not support smart framing, this would
+ /// return an error.
+ SetRegionOfInterest(float32 x_min,
+ float32 y_min,
+ float32 x_max,
+ float32 y_max) -> (zx.status s);
+
+ /// Change the image format of the stream. This is called when clients want
+ /// to dynamically change the resolution of the stream while the streaming is
+ /// is going on.
+ SetImageFormat(uint32 image_format_index) -> (zx.status s);
+
+ /// Get the image formats that this stream supports.
+ GetImageFormats() -> (vector<fuchsia.sysmem.ImageFormat_2>:MAX_IMAGE_FORMATS image_formats);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.camera3/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.camera3/BUILD.gn
new file mode 100644
index 0000000..5853ae2
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.camera3/BUILD.gn
@@ -0,0 +1,29 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.camera3") {
+ library_name = "camera3"
+ namespace = "fuchsia"
+ public_deps = [
+ "../fuchsia.math",
+ "../fuchsia.sysmem",
+ ]
+ sources = [
+ "device.fidl",
+ "device_watcher.fidl",
+ "stream.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.camera3",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.camera3/device.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.camera3/device.fidl
new file mode 100644
index 0000000..78ba4ba
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.camera3/device.fidl
@@ -0,0 +1,60 @@
+// Copyright 2020 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.
+
+library fuchsia.camera3;
+
+const uint32 MAX_IDENTIFIER_LENGTH = 256;
+const uint32 MAX_CONFIGURATIONS_PER_CAMERA = 256;
+const uint32 MAX_STREAMS_PER_CONFIGURATION = 256;
+const uint32 MAX_RESOLUTIONS_PER_STREAM = 1024;
+
+/// A Device represents a unique physical camera present in the system. Only one client may connect
+/// to an unbound physical camera, however the "Rebind" method can be used to create multiple
+/// connections to it to be used by a coordinated set of clients.
+protocol Device {
+ /// Returns an identifier for the camera. If present, identical devices on different systems
+ /// will have the same identifier. Clients may use this to determine if additional semantics
+ /// known a priori for a given device apply to the current camera.
+ // TODO(fxb/43247): unify device identification
+ // go/unified-device-discovery will eliminate the need for this protocol
+ GetIdentifier() -> (string:MAX_IDENTIFIER_LENGTH? identifier);
+
+ /// Returns a list of configurations supported by the camera. All cameras will have at least
+ /// one configuration. The values returned are immutable - they will not change for the
+ /// lifetime of the client's connection to the Camera.
+ GetConfigurations() -> (vector<Configuration>:MAX_CONFIGURATIONS_PER_CAMERA configurations);
+
+ /// Returns the index of the current configuration when it has changed from a previously
+ /// returned configuration, or is called by a client for the first time.
+ WatchCurrentConfiguration() -> (uint32 index);
+
+ /// Sets the configuration using the provided index. Calling this method disconnects any
+ /// existing Stream clients associated with this camera.
+ SetCurrentConfiguration(uint32 index);
+
+ /// Returns the camera's current mute state when it has changed from a previously returned
+ /// state, or is called by a client for the first time. A camera may be muted using
+ /// SetSoftwareMuteState or by a physical switch. If either muted mode is active, stream
+ /// clients associated with this physical camera will stop receiving new frames.
+ WatchMuteState() -> (bool software_muted, bool hardware_muted);
+
+ /// Sets the current camera's software mute state. When transitioning to the muted state, this
+ /// method returns when the camera has successfully ceased sending new frames to stream
+ /// clients. When transitioning to the unmuted state, this method returns immediately.
+ SetSoftwareMuteState(bool muted) -> ();
+
+ /// Connects to the Stream at the provided index. If any clients already exist for this stream,
+ /// the request is closed with the ZX_ERR_ALREADY_BOUND epitaph.
+ ConnectToStream(uint32 index, request<Stream> request);
+
+ /// Request another connection to this Device. This allows a client to delegate different
+ /// operations to different coordinated clients.
+ Rebind(request<Device> request);
+};
+
+/// Describes a distinct configuration for the camera.
+struct Configuration {
+ /// Descriptions of streams that are concurrently available in the configuration.
+ vector<StreamProperties>:MAX_STREAMS_PER_CONFIGURATION streams;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.camera3/device_watcher.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.camera3/device_watcher.fidl
new file mode 100644
index 0000000..18bf277
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.camera3/device_watcher.fidl
@@ -0,0 +1,41 @@
+// Copyright 2020 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.
+
+library fuchsia.camera3;
+
+const uint32 MAX_WATCH_DEVICES_EVENTS = 256;
+
+using DeviceId = uint64;
+
+/// The DeviceWatcher provides clients a mechanism to discover camera devices present on the
+/// system. This is a temporary mechanism intended to be replaced by go/drivers-as-components,
+/// which will allow multiple instances of the same protocol to exist side-by-side. Clients are
+/// not required to maintain a connection to the Watcher in order to use established Camera
+/// connections.
+[Discoverable]
+protocol DeviceWatcher {
+ /// Returns a list of available camera IDs when it has changed from the previously returned
+ /// list of IDs, or when it is called by a client for the first time. The returned list may be
+ /// empty, indicating no cameras are available. The IDs returned to the client will remain
+ /// consistent with respect to the physical devices they represent for the duration of the
+ /// client's connection. Events will be sorted first by event type - `existing`, `added`,
+ /// `removed`. Within each event type range, IDs will be provided in ascending order. Events
+ /// are coalesced by the server, so a given ID will only appear once in each list of events.
+ WatchDevices() -> (vector<WatchDevicesEvent>:MAX_WATCH_DEVICES_EVENTS events);
+
+ /// Acquires a camera interface for the given ID. If any clients already exist for this camera,
+ /// the request is closed with the ZX_ERR_ALREADY_BOUND epitaph.
+ ConnectToDevice(DeviceId id, request<Device> request);
+};
+
+union WatchDevicesEvent {
+ /// Indicates an existing camera with the provided ID is still available.
+ 1: DeviceId existing;
+
+ /// Indicates a new camera with the provided ID is now available.
+ 2: DeviceId added;
+
+ /// Indicates an existing camera with the provided ID is no longer available.
+ 3: DeviceId removed;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.camera3/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.camera3/meta.json
new file mode 100644
index 0000000..e2f3951
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.camera3/meta.json
@@ -0,0 +1,14 @@
+{
+ "deps": [
+ "fuchsia.math",
+ "fuchsia.sysmem"
+ ],
+ "name": "fuchsia.camera3",
+ "root": "fidl/fuchsia.camera3",
+ "sources": [
+ "fidl/fuchsia.camera3/device.fidl",
+ "fidl/fuchsia.camera3/device_watcher.fidl",
+ "fidl/fuchsia.camera3/stream.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.camera3/stream.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.camera3/stream.fidl
new file mode 100644
index 0000000..8f169ab
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.camera3/stream.fidl
@@ -0,0 +1,103 @@
+// Copyright 2020 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.
+
+library fuchsia.camera3;
+
+using fuchsia.math;
+using fuchsia.sysmem;
+using zx;
+
+/// A Stream represents timing, sequencing, and other camera-specific properties applied to a buffer
+/// collection.
+protocol Stream {
+ /// Sets the Stream's crop region to the provided region, with the top-left of the image
+ /// represented by (0,0) and the bottom-right of the image represented by (1,1). The resulting
+ /// content is subsequently scaled to fill the output buffer. If the implementation does not
+ /// precisely support the provided value, it will be expanded to the minimum region that covers
+ /// the provided region. If region is set to null, the crop region is unset, which is equivalent
+ /// to specifying a region covering the entire image. Upon initial connection, the region is
+ /// unset. If the stream does not support crop region, the connection is closed with the
+ /// ZX_ERR_NOT_SUPPORTED epitaph.
+ SetCropRegion(fuchsia.math.RectF? region);
+
+ /// Returns the crop region if it has changed from a previously returned value, or is called by
+ /// a client for the first time. Frame callbacks received after receiving this callback reflect
+ /// the use of the new region. See SetCropRegion for a description of the region parameter.
+ WatchCropRegion() -> (fuchsia.math.RectF? region);
+
+ /// Sets the resolution of the stream to the provided value. If the implementation does not
+ /// precisely support the provided value, it will be expanded to the minimum resolution that
+ /// exceeds the provided resolution.
+ SetResolution(fuchsia.math.Size coded_size);
+
+ /// Returns the resolution if it has changed from a previously returned value, or is called by
+ /// a client for the first time. Frame callbacks received after receiving this callback reflect
+ /// the new resolution.
+ WatchResolution() -> (fuchsia.math.Size coded_size);
+
+ /// If non-null, requests renegotiation of the buffer collection backing this stream, and
+ /// identifies this client as a participant in buffer negotiation. If null, identifies this
+ /// client as a non-participant in buffer negotiation. Upon initial connection, the client is a
+ /// non-participant. After registering as a participant, clients must always have an outstanding
+ /// call to WatchBufferCollection to receive tokens from the server so that they are able to
+ /// respond to current and future renegotiation requests.
+ SetBufferCollection(fuchsia.sysmem.BufferCollectionToken? token);
+
+ /// Returns when the server or any buffer negotiation participant (including the current client)
+ /// requires buffer renegotiation, and the current client is registered as a participant. Frame
+ /// callbacks received after receiving this callback apply to the newly negotiated collection.
+ WatchBufferCollection() -> (fuchsia.sysmem.BufferCollectionToken token);
+
+ /// Request the next available frame for this stream. Returns when the stream has completed
+ /// populating the buffer and may be read by the client, provided the number of unreleased
+ /// buffers held by the client is less than the count provided via the most recently negotiated
+ /// buffer collection token. If a buffer renegotiation is in progress, this call will return
+ /// only after the negotiation is complete and a new collection is available.
+ GetNextFrame() -> (FrameInfo info);
+
+ /// Request another connection to this Stream. This allows a client to delegate different
+ /// operations to different coordinated clients.
+ Rebind(request<Stream> request);
+};
+
+/// Metadata concerning a given frame.
+struct FrameInfo {
+ /// Identifies the buffer used for this frame as an index into the most recently negotiated
+ /// buffer collection.
+ uint32 buffer_index;
+
+ /// A monotonically increasing counter indicating the number of frames written to this stream's
+ /// most recently negotiated buffer collection. Clients can use this to detect dropped frames
+ /// or generate nominal timestamps using the associated stream's framerate.
+ uint64 frame_counter;
+
+ /// The value of the system monotonic clock, measured at the time the hardware completed
+ /// populating the buffer.
+ zx.time timestamp;
+
+ /// The client must close this when it has completed reading from the buffer.
+ handle<eventpair> release_fence;
+};
+
+/// The frequency at which a Stream produces frames. The value is `numerator` / `denominator`, with
+/// units of frames-per-second (Hz). The representation is not necessarily an irreducible fraction.
+struct FrameRate {
+ /// Fraction numerator.
+ uint32 numerator;
+
+ /// Fraction denominator. This value will not be zero.
+ uint32 denominator;
+};
+
+/// Describes the properties of a given stream.
+struct StreamProperties {
+ /// Describes the native image format used by a stream.
+ fuchsia.sysmem.ImageFormat_2 image_format;
+
+ /// Describes the framerate used by a stream.
+ FrameRate frame_rate;
+
+ /// Indicates whether a stream supports the SetCropRegion method.
+ bool supports_crop_region;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.castauth/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.castauth/BUILD.gn
new file mode 100644
index 0000000..e5bd7c9
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.castauth/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.castauth") {
+ library_name = "castauth"
+ namespace = "fuchsia"
+ public_deps = [
+ ]
+ sources = [
+ "cast_auth.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.castauth",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.castauth/cast_auth.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.castauth/cast_auth.fidl
new file mode 100644
index 0000000..81c659f
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.castauth/cast_auth.fidl
@@ -0,0 +1,40 @@
+// 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.
+
+library fuchsia.castauth;
+
+/// Input hash to be signed by Cast key.
+/// It must be ASN1-encoded SHA1 or SHA256 hash, with sizes 35 or 51 bytes.
+union Asn1EncodedHash {
+ 1: array<byte>:35 sha1;
+ 2: array<byte>:51 sha256;
+};
+
+/// Error codes for CastKeySigner operations.
+enum ErrorCode {
+ /// Key/cert not found in storage.
+ FILE_NOT_FOUND = 1;
+ /// Error occurred during signing operation.
+ CRYPTO_ERROR = 2;
+};
+
+/// This FIDL interface is used to sign with hardware Cast key.
+/// It is intended for short-term use only and will not be supported on all
+/// devices. It will eventually be replaced by an attestation service.
+[Discoverable]
+protocol CastKeySigner {
+ /// Use Cast key to sign a hash value.
+ ///
+ /// The input is hash value.
+ /// The return value is the error code or the signature if the operation
+ /// succeeds. The signature algorithm is RSA-2048-PKCS1.
+ SignHash(Asn1EncodedHash hash) -> (array<byte>:256 signature) error ErrorCode;
+
+ /// Get the Cast certificate chain.
+ ///
+ /// The return value is the error code or the certificate chain if
+ /// the operation succeeds. The chain contains Cast key cert,
+ /// one or more intermediate CA certs and root CA cert.
+ GetCertificateChain() -> (vector<bytes:2048>:16 cert_chain) error ErrorCode;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.castauth/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.castauth/meta.json
new file mode 100644
index 0000000..63890cb
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.castauth/meta.json
@@ -0,0 +1,9 @@
+{
+ "deps": [],
+ "name": "fuchsia.castauth",
+ "root": "fidl/fuchsia.castauth",
+ "sources": [
+ "fidl/fuchsia.castauth/cast_auth.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.castconfig/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.castconfig/BUILD.gn
new file mode 100644
index 0000000..c0455bf
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.castconfig/BUILD.gn
@@ -0,0 +1,26 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.castconfig") {
+ library_name = "castconfig"
+ namespace = "fuchsia"
+ public_deps = [
+ "../fuchsia.mem",
+ ]
+ sources = [
+ "cast_config.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.castconfig",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.castconfig/cast_config.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.castconfig/cast_config.fidl
new file mode 100644
index 0000000..fbdecee
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.castconfig/cast_config.fidl
@@ -0,0 +1,33 @@
+// 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.
+
+library fuchsia.castconfig;
+
+using fuchsia.mem;
+
+/// Error codes for the Watch operation.
+enum ErrorCode {
+ /// Error when there is no cast config available.
+ NO_CAST_CONFIG = 1;
+ /// Generic error.
+ INTERNAL = 2;
+};
+
+/// Interface that provides cast config data.
+[Discoverable]
+protocol Provider {
+ /// Requests a buffer containing cast config data.
+ /// This call implements the Hanging Get protocol as detailed in
+ /// https://fuchsia.dev/fuchsia-src/development/api/fidl.md#delay-responses-using-hanging-gets
+ ///
+ /// All error cases are terminal, clients should not retry on error.
+ Watch() -> (fuchsia.mem.Buffer config) error ErrorCode;
+
+ /// Notifies the config provider of the config status.
+ ///
+ /// `processed`: `true` if successfully recieved and processed
+ /// `retry`: If `processed` is `false` config provider determines if a retry
+ /// is appropriate.
+ Notify(bool processed) -> (bool retry);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.castconfig/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.castconfig/meta.json
new file mode 100644
index 0000000..b5dcb6b
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.castconfig/meta.json
@@ -0,0 +1,11 @@
+{
+ "deps": [
+ "fuchsia.mem"
+ ],
+ "name": "fuchsia.castconfig",
+ "root": "fidl/fuchsia.castconfig",
+ "sources": [
+ "fidl/fuchsia.castconfig/cast_config.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.castremotecontrol/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.castremotecontrol/BUILD.gn
new file mode 100644
index 0000000..1a48c7b
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.castremotecontrol/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.castremotecontrol") {
+ library_name = "castremotecontrol"
+ namespace = "fuchsia"
+ public_deps = [
+ ]
+ sources = [
+ "remote_control.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.castremotecontrol",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.castremotecontrol/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.castremotecontrol/meta.json
new file mode 100644
index 0000000..914f91f
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.castremotecontrol/meta.json
@@ -0,0 +1,9 @@
+{
+ "deps": [],
+ "name": "fuchsia.castremotecontrol",
+ "root": "fidl/fuchsia.castremotecontrol",
+ "sources": [
+ "fidl/fuchsia.castremotecontrol/remote_control.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.castremotecontrol/remote_control.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.castremotecontrol/remote_control.fidl
new file mode 100644
index 0000000..ce98c5f
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.castremotecontrol/remote_control.fidl
@@ -0,0 +1,22 @@
+// Copyright 2020 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.
+
+library fuchsia.castremotecontrol;
+
+// LaunchError enumerates the various ways in which launching a
+// remote control app may fail.
+enum LaunchError {
+ // The media session to control for the provided device could not be found.
+ NOT_FOUND = 1;
+
+ // A non-recoverable internal error occurred.
+ INTERNAL = 2;
+};
+
+[Discoverable]
+protocol Launcher {
+ /// Launches the Cast remote control application for the device
+ /// identified by |device_id|.
+ Launch(string:MAX device_id) -> () error LaunchError;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.castsetup/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.castsetup/BUILD.gn
new file mode 100644
index 0000000..6d4c136
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.castsetup/BUILD.gn
@@ -0,0 +1,26 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.castsetup") {
+ library_name = "castsetup"
+ namespace = "fuchsia"
+ public_deps = [
+ ]
+ sources = [
+ "cast_setup.fidl",
+ "server.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.castsetup",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.castsetup/cast_setup.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.castsetup/cast_setup.fidl
new file mode 100644
index 0000000..6750d37
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.castsetup/cast_setup.fidl
@@ -0,0 +1,28 @@
+// 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.
+
+library fuchsia.castsetup;
+
+/// Interface that allows watching of changes to the cast setup state.
+[Discoverable]
+protocol StateWatcher {
+ /// Will immediately return on first call; subsequent calls will return on
+ /// change.
+ Watch() -> (State state);
+};
+
+/// Enum of different possible setup states
+enum State {
+ /// State is not determined.
+ UNKNOWN = 0;
+
+ /// Setup is not complete and is in progress.
+ IN_PROGRESS = 1;
+
+ /// Configured once but disconnected for now.
+ OFFLINE = 2;
+
+ /// Setup is complete and device is connected.
+ COMPLETE = 3;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.castsetup/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.castsetup/meta.json
new file mode 100644
index 0000000..ce040a2
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.castsetup/meta.json
@@ -0,0 +1,10 @@
+{
+ "deps": [],
+ "name": "fuchsia.castsetup",
+ "root": "fidl/fuchsia.castsetup",
+ "sources": [
+ "fidl/fuchsia.castsetup/cast_setup.fidl",
+ "fidl/fuchsia.castsetup/server.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.castsetup/server.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.castsetup/server.fidl
new file mode 100644
index 0000000..25d059a
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.castsetup/server.fidl
@@ -0,0 +1,46 @@
+// Copyright 2020 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.
+
+/// For internal Google use only.
+/// This API is not to be used within the Fuchsia tree.
+library fuchsia.castsetup;
+
+/// Specifies the required security for a client of the API.
+enum SecurityState : uint32 {
+ SECURITY_STATE_NONE = 0;
+ SECURITY_STATE_ENCRYPTED = 1;
+ SECURITY_STATE_TRUSTED = 2;
+};
+
+/// Registered API that handles an incoming request.
+protocol ApiRequestHandler {
+ /// Called to handle a request to this setup API. The request `data` is JSON.
+ /// The response `data` must be JSON.
+ HandleRequest(string:MAX? data) -> (uint32 response_code, string:MAX? data);
+};
+
+/// API operation mode to specify during registration.
+enum ApiMode : uint32 {
+ ACCEPTS_NO_DATA = 1;
+ ACCEPTS_DATA = 2;
+};
+
+/// Registry that hosts APIs on behalf of clients.
+[Discoverable]
+protocol ApiRegistry {
+ /// Registers an API that may accept incoming data.
+ ///
+ /// `path` identifies how to access the API. If multiple registrations occur with
+ /// the same path, then the last registration is bound, and the rest are unbound.
+ ///
+ /// `accepts_data` indicates whether this API should allow callers to provide
+ /// data in the form of a JSON string.
+ ///
+ /// `security_state` indicates what level of security the caller must
+ /// adhere to.
+ RegisterApi(string:1024 path,
+ ApiMode api_mode,
+ SecurityState security_state,
+ ApiRequestHandler api_handler);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.castsysteminfo/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.castsysteminfo/BUILD.gn
new file mode 100644
index 0000000..facf37d
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.castsysteminfo/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.castsysteminfo") {
+ library_name = "castsysteminfo"
+ namespace = "fuchsia"
+ public_deps = [
+ ]
+ sources = [
+ "cast_system_info.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.castsysteminfo",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.castsysteminfo/cast_system_info.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.castsysteminfo/cast_system_info.fidl
new file mode 100644
index 0000000..0e57673
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.castsysteminfo/cast_system_info.fidl
@@ -0,0 +1,36 @@
+// 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.
+
+library fuchsia.castsysteminfo;
+
+/// Error codes for the GetSystemInfo operation.
+enum ErrorCode {
+ /// Error when there is no system info available.
+ ERR_NO_SYSTEM_INFO = 1;
+ /// Generic error.
+ ERR_INTERNAL = 2;
+};
+
+/// Cast-related device settings
+///
+/// This table may be extended to include additional cast-specific information.
+/// The values requested here are generated on first boot of the device and
+/// don't change unless there is a factory reset.
+table SystemInfo {
+ /// Local (CastV2) device ID. Identifies the device on a local network.
+ /// Used by the Home app as the device identifier and for MDNS record matching.
+ 1: string local_device_id;
+ /// The device will use this identifier to send/receive CloudCast commands.
+ /// Sending a CloudCast command to the receiver with this ID will ensure that
+ /// the command is accepted and consumed by the device.
+ 2: string cloud_device_id;
+};
+
+/// Exposes Cast system info, as modeled in the SystemInfo table.
+[Discoverable]
+protocol Provider {
+ /// Retrieves the SystemInfo fields that are generated at first boot and are
+ /// available at startup.
+ GetSystemInfo() -> (SystemInfo systemInfo) error ErrorCode;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.castsysteminfo/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.castsysteminfo/meta.json
new file mode 100644
index 0000000..4f6c07a
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.castsysteminfo/meta.json
@@ -0,0 +1,9 @@
+{
+ "deps": [],
+ "name": "fuchsia.castsysteminfo",
+ "root": "fidl/fuchsia.castsysteminfo",
+ "sources": [
+ "fidl/fuchsia.castsysteminfo/cast_system_info.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.castwindow/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.castwindow/BUILD.gn
new file mode 100644
index 0000000..f7c9045
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.castwindow/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.castwindow") {
+ library_name = "castwindow"
+ namespace = "fuchsia"
+ public_deps = [
+ ]
+ sources = [
+ "window.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.castwindow",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.castwindow/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.castwindow/meta.json
new file mode 100644
index 0000000..2f50edc
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.castwindow/meta.json
@@ -0,0 +1,9 @@
+{
+ "deps": [],
+ "name": "fuchsia.castwindow",
+ "root": "fidl/fuchsia.castwindow",
+ "sources": [
+ "fidl/fuchsia.castwindow/window.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.castwindow/window.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.castwindow/window.fidl
new file mode 100644
index 0000000..1fa5539
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.castwindow/window.fidl
@@ -0,0 +1,16 @@
+// Copyright 2020 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.
+
+library fuchsia.castwindow;
+
+enum Interaction : uint32 {
+ GO_BACK = 1;
+};
+
+/// Routes interaction requests to the application instance identified
+/// by |session_id|.
+[Discoverable]
+protocol InteractionHandler {
+ SendInteraction(string:MAX session_id, Interaction interaction);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.cobalt/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.cobalt/BUILD.gn
new file mode 100644
index 0000000..e00ac55
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.cobalt/BUILD.gn
@@ -0,0 +1,26 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.cobalt") {
+ library_name = "cobalt"
+ namespace = "fuchsia"
+ public_deps = [
+ ]
+ sources = [
+ "cobalt.fidl",
+ "cobalt_controller.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.cobalt",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.cobalt/cobalt.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.cobalt/cobalt.fidl
new file mode 100644
index 0000000..eb3d306
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.cobalt/cobalt.fidl
@@ -0,0 +1,744 @@
+// Copyright 2018 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.
+
+/// Cobalt is the Fuchsia service used to log, collect and analyze metrics.
+/// The two main pillars of Cobalt are protecting user privacy and providing
+/// high-quality, aggregate metrics to serve system and component software
+/// developers' needs.
+///
+/// This file contains interfaces that allow clients to log Events to
+/// Cobalt.
+///
+/// To use Cobalt, you must have a Project and one or more Metrics registered
+/// with the Cobalt registration system. You must also register one or more
+/// Reports in order to see the results of your logging aggregated over
+/// all Fuchsia devices. Registration of Projects, Metrics and Reports consists
+/// of entries in the YAML files in this repo:
+/// https:///cobalt-analytics.googlesource.com/config/.
+/// In a Garnet checkout that is mapped to ///third_party/cobalt_config.
+/// Each registered object has an integer ID and those IDs are used as
+/// parameters in the methods in this file.
+///
+/// While Cobalt's code and registration files are open source, the running
+/// system being managed by the Cobalt team is currently intended to be used by
+/// software engineers at Google in order to collect metrics in a way that
+/// preserves our users' privacy. If you are a Google software engineer
+/// please see our internal [user guide](go/fuchsia-cobalt-userguide) or
+/// ask for assistance from the Cobalt [team](go/fuchsia-cobalt#comms).
+///
+/// Usage: First use LoggerFactory to get a Logger for your
+/// project. Then you log Events using the Log*() methods.
+/// Events are accumulated by the cobalt FIDL service and periodically
+/// Observations, derived from the logged Events, are sent to the Cobalt server,
+/// where they are used to generate Reports.
+library fuchsia.cobalt;
+
+/// The maximum size of a single Event is 100 KB.
+const int64 MAX_BYTES_PER_EVENT = 102400;
+
+/// This is intended as a reasonable maximum number of histogram buckets per event.
+const uint32 MAX_HISTOGRAM_BUCKETS = 500;
+
+/// Maximum number of Cobalt events that may be logged in a single
+/// FIDL call.
+const uint32 MAX_BATCHED_EVENTS = 500;
+
+/// Component strings should not be longer than this.
+const uint32 MAX_COMPONENT_LENGTH = 64;
+
+/// Timer ids should not be longer than this.
+const uint32 MAX_TIMER_ID_LENGTH = 64;
+
+/// String events should not be longer than this.
+const uint32 MAX_STRING_EVENT_SIZE = 256;
+
+/// We only support up to 5 event_codes
+const uint32 MAX_EVENT_CODE_COUNT = 5;
+
+/// In Cobalt 1.1 we support up to 10 event codes.
+const uint32 MAX_METRIC_DIMENSIONS = 10;
+
+/// Channels should not be longer than this.
+const uint32 MAX_CHANNEL_NAME_LENGTH = 256;
+
+/// Response codes for Logger operations.
+enum Status : int32 {
+ OK = 0;
+
+ /// For example the supplied metric id is invalid.
+ INVALID_ARGUMENTS = 1;
+
+ /// An attempt was made to log an Event whose serialized size exceeds
+ /// MAX_BYTES_PER_EVENT.
+ EVENT_TOO_BIG = 2;
+
+ /// Cobalt's local buffer is temporarily full and cannot handle any more
+ /// Events at this time. Try again later. This condition should be rare
+ BUFFER_FULL = 3;
+
+ /// Catch-all for unexpected errors.
+ INTERNAL_ERROR = -1;
+};
+
+/// A specification of a Cobalt project.
+///
+/// Note: This type is part of the Cobalt 1.1 interface which is still
+/// in development. Do not use this yet.
+table ProjectSpec {
+ /// The customer ID, as specified in Cobalt's metrics registry.
+ /// If omitted (i.e. set to 0) then it defaults to
+ /// the customer ID for the "fuchsia" customer.
+ 1: uint32 customer_id;
+
+ /// The ID of the project, as specified in Cobalt's metrics registry.
+ 2: uint32 project_id;
+};
+
+/// Note: This protocol is part of the Cobalt 1.1 interface which is still
+/// in development. Do not use this yet.
+///
+[Discoverable]
+protocol MetricEventLoggerFactory {
+ /// Create a MetricEventLogger for the project specified by `project_spec`.
+ CreateMetricEventLogger(ProjectSpec project_spec,
+ request<MetricEventLogger> logger)
+ -> (Status status);
+};
+
+/// LoggerFactory creates Loggers.
+[Discoverable, Layout = "Simple"]
+protocol LoggerFactory {
+ /// Creates a Logger for the project with the given ID, using the state of
+ /// the metrics registry that is bundled with Cobalt. The project must be in
+ /// the "fuchsia" customer.
+ ///
+ /// `project_id` The ID of the client's Cobalt project.
+ ///
+ /// `status` Returns OK on success or INVALID_ARGUMENTS if there is no
+ /// project with the given ID in the version of the metrics registry that
+ /// is bundled with Cobalt.
+ CreateLoggerFromProjectId(uint32 project_id,
+ request<Logger> logger)
+ -> (Status status);
+
+ /// Creates a LoggerSimple for the project with the given ID, using the
+ /// state of the metrics registry that is bundled with Cobalt. The project
+ /// must be in the "fuchsia" customer.
+ ///
+ /// `project_id` The ID of the client's Cobalt project.
+ ///
+ /// `status` Returns OK on success or INVALID_ARGUMENTS if there is no
+ /// project with the given ID in the version of the metrics registry that
+ /// is bundled with Cobalt.
+ CreateLoggerSimpleFromProjectId(uint32 project_id,
+ request<LoggerSimple> logger)
+ -> (Status status);
+
+ /// Creates a Logger for the project specified, using the state of the
+ /// metrics registry that is bundled with Cobalt.
+ ///
+ /// `customer_id` The ID of the client's Cobalt customer.
+ ///
+ /// `project_id` The ID of the client's Cobalt project.
+ ///
+ /// `status` Returns OK on success or INVALID_ARGUMENTS if there is no
+ /// project with the given IDs in the version of the metrics registry that
+ /// is bundled with Cobalt.
+ CreateLoggerFromProjectSpec(uint32 customer_id, uint32 project_id,
+ request<Logger> logger)
+ -> (Status status);
+};
+
+/// A vector of event codes. When used in one of the Log*() calls below,
+/// there must be one event code for each dimension of the metric whose
+/// metric_id is supplied, or else the call will return INVALID_ARGUMENTS.
+/// Each event code is a key from the `event_codes` map of the corresponding
+/// MetricDimension.
+///
+/// This type is part of the Cobalt 1.1 interface which is still in development.
+/// Do not use this yet.
+using event_vector = vector<uint32>:MAX_METRIC_DIMENSIONS;
+
+/// A histogram that assigns a count to each of several integer ranges.
+/// The order of the vector is immaterial.
+using integer_histogram = vector<HistogramBucket>:MAX_HISTOGRAM_BUCKETS;
+
+/// Note: This protocol is part of the Cobalt 1.1 interface which is still
+/// in development. Do not use this yet.
+protocol MetricEventLogger {
+ /// Logs the fact that an event has occurred a number of times.
+ ///
+ /// `metric_id` ID of the metric being logged. It must be one of the metrics
+ /// declared in Cobalt's registry for the project associated with this
+ /// logger, and it must be of type OCCURRENCE.
+ ///
+ /// `count` The number of times the event has occurred. The value should
+ /// be positive as a value of 0 is ignored.
+ ///
+ /// `event_codes`. Enum parameters, one for each of the metric's
+ /// metric_dimensions. Cobalt aggregates occurrence counts based on this
+ /// parameter.
+ LogOccurrence(uint32 metric_id, uint64 count, event_vector event_codes)
+ -> (Status status);
+
+ /// Logs an integer measurement.
+ ///
+ /// `metric_id` ID of the metric being logged. It must be one of the metrics
+ /// declared in Cobalt's registry for the project associated with this
+ /// logger, and it must be of type INTEGER.
+ ///
+ /// `value` The integer measurement.
+ ///
+ /// `event_codes`. Enum parameters, one for each of the metric's
+ /// metric_dimensions. Cobalt aggregates integer values that have
+ /// the same event_codes.
+ LogInteger(uint32 metric_id, int64 value, event_vector event_codes)
+ -> (Status status);
+
+ /// Logs a histogram giving many approximate integer measurements.
+ ///
+ /// `metric_id` ID of the metric being logged. It must be one of the metrics
+ /// declared in Cobalt's registry for the project associated with this
+ /// logger, and it must be of type INTEGER_HISTOGRAM.
+ ///
+ /// `histogram` The collection of approximate integer measurements.
+ ///
+ /// `event_codes`. Enum parameters, one for each of the metric's
+ /// metric_dimensions. Cobalt aggregates histograms that have the same
+ /// event_codes.
+ LogIntegerHistogram(uint32 metric_id, integer_histogram histogram,
+ event_vector event_codes)
+ -> (Status status);
+
+ /// Logs a string value that was observed.
+ ///
+ /// `metric_id` ID of the metric being logged. It must be one of the metrics
+ /// declared in Cobalt's registry for the project associated with this
+ /// logger, and it must be of type STRING.
+ ///
+ /// `string_value` The string to log.
+ ///
+ /// `event_codes`. Enum parameters, one for each of the metric's
+ /// metric_dimensions. Cobalt aggregates counts of logged strings separately
+ /// for each event_codes.
+ LogString(uint32 metric_id, string:MAX_STRING_EVENT_SIZE string_value,
+ event_vector event_codes)
+ -> (Status status);
+
+ /// Bulk logging method, equivalent to making many of the above Log*() calls
+ /// at once.
+ LogMetricEvents(vector<MetricEvent>:MAX_BATCHED_EVENTS events)
+ -> (Status status);
+
+ /// Logs a custom Event.
+ ///
+ /// `metric_id` ID of the metric being logged. It must be one of the metrics
+ /// declared in Cobalt's registry for the project associated with this
+ /// logger, and it must be of type CUSTOM.
+ ///
+ /// `event_values` The values for the custom Event. There must be one value
+ /// for each dimension of the Metric and the types of the values must
+ /// be consistent with the dimensions declared in the Metric definition.
+ LogCustomEvent(uint32 metric_id, vector<CustomEventValue>:MAX event_values)
+ -> (Status status);
+};
+
+/// A specification of an event that occurred to be passed to LogMetricEvents().
+///
+/// Note: This type is part of the Cobalt 1.1 interface which is still
+/// in development. Do not use this yet.
+struct MetricEvent {
+ /// ID of the metric being logged. It must be one of the metrics
+ /// declared in Cobalt's registry for the project associated with the
+ /// MetricEventLogger being used and its type must match the type of
+ /// `payload`.
+ uint32 metric_id;
+
+ /// `event_codes`. Enum parameters corresponding to the metric's additional
+ /// dimensions.
+ event_vector event_codes;
+
+ /// The metric-type-specific data for the event being logged.
+ MetricEventPayload payload;
+};
+
+/// The variadic part of a MetricEvent.
+///
+/// Note: This type is part of the Cobalt 1.1 interface which is still
+/// in development. Do not use this yet.
+flexible union MetricEventPayload {
+ /// This should be used for metrics of type OCCURRENCE. See
+ /// MetricEventLogger::LogOcurrenceCount().
+ 1: uint64 count;
+
+ /// This should be used for metrics of type INTEGER. See
+ /// MetricEventLogger::LogInteger().
+ 2: int64 integer_value;
+
+ /// This payload type should be used for metrics of type
+ /// INTEGER_HISTOGRAM. See
+ /// MetricEventLogger::LogIntegerHistogram().
+ 3: integer_histogram histogram;
+
+ /// This payload type should be used for metrics of type STRING.
+ 4: string:MAX_STRING_EVENT_SIZE string_value;
+};
+
+/////////////////////////////////////////////////////////////////////
+
+// LoggerBase Interface
+/////////////////////////////////////////////////////////////////////
+
+/// LoggerBase and its extensions are used to log Events to the Cobalt system.
+/// The Cobalt FIDL service stores the Events locally for some period of time,
+/// processes the Events to form Observations, and periodically uploads batches
+/// of Observations to the Cobalt server. The Cobalt server processes the
+/// Observations and generates Reports. See [TODO(rudominer)] for more
+/// description of the Cobalt server and Reports.
+///
+/// LoggerBase or one of its extensions is associated with a single Cobalt
+/// project.
+///
+/// This interface conforms to the Simple layout so that Simple bindings
+/// may be generated for it. For the full interfaces, see Logger and LoggerSimple
+/// below.
+[Layout = "Simple"]
+protocol LoggerBase {
+ /// Logs the fact that an event has occurred.
+ ///
+ /// `metric_id` ID of the metric to use. It must be one of the Metrics
+ /// from the ProjectProfile used to obtain this Logger, and it must be of
+ /// type EVENT_OCCURRED.
+ ///
+ /// `event_code` The index of the event that occurred. The indexed set of all
+ /// event codes and their labels is specified in the metric definition.
+ LogEvent(uint32 metric_id, uint32 event_code)
+ -> (Status status);
+
+ /// Logs that an event has occurred a given number of times.
+ ///
+ /// `metric_id` ID of the metric to use. It must be one of the Metrics
+ /// from the ProjectProfile used to obtain this Logger, and it must be of
+ /// type EVENT_COUNT.
+ ///
+ /// `event_code` The index of the event that occurred. The indexed set of all
+ /// event codes and their labels is specified in the metric definition.
+ ///
+ /// `component` Optionally, a component associated with the event may also be
+ /// logged. Any notion of component that makes sense may be used or use the
+ /// empty string if there is no natural notion of component.
+ ///
+ /// `period_duration_micros` Optionally, the period of time over which the
+ /// `count` events occurred may be logged. If this is not relevant the value
+ /// may be set to 0. Otherwise specify the period duration as a number of
+ /// microseconds.
+ ///
+ /// `count` The number of times the event occurred. One may choose to always
+ /// set this value to 1 and always set
+ ///
+ /// `period_duration_micros` to 0 in order to achieve a semantics similar to
+ /// the LogEventOccurred() method, but with a `component`.
+ LogEventCount(uint32 metric_id, uint32 event_code, string:MAX_COMPONENT_LENGTH component,
+ int64 period_duration_micros, int64 count)
+ -> (Status status);
+
+ /// Logs that an event lasted a given amount of time.
+ ///
+ /// `metric_id` ID of the metric to use. It must be one of the Metrics
+ /// from the ProjectProfile used to obtain this Logger, and it must be of
+ /// type ELAPSED_TIME.
+ ///
+ /// `event_code` The index of the event that occurred. The indexed set of all
+ /// event codes and their labels is specified in the metric definition.
+ ///
+ /// `component` Optionally, a component associated with the event may also be
+ /// logged. Any notion of component that makes sense may be used or use the
+ /// empty string if there is no natural notion of component.
+ ///
+ /// `elapsed_micros` The elapsed time of the event, specified as a number of
+ /// microseconds.
+ LogElapsedTime(uint32 metric_id, uint32 event_code, string:MAX_COMPONENT_LENGTH component,
+ int64 elapsed_micros)
+ -> (Status status);
+
+ /// Logs a measured average frame rate.
+ ///
+ /// `metric_id` ID of the metric to use. It must be one of the Metrics
+ /// from the ProjectProfile used to obtain this Logger, and it must be of
+ /// type FRAME_RATE.
+ ///
+ /// `event_code` The index of the event that associated with the frame-rate
+ /// measurement. The indexed set of all event codes and their labels is
+ /// specified in the metric definition.
+ ///
+ /// `component` Optionally, a component associated with the frame-rate
+ /// measurement may also be logged. Any notion of component that makes sense
+ /// may be used or use the empty string if there is no natural notion of
+ /// component.
+ ///
+ /// `fps` The average-frame rate in frames-per-second.
+ LogFrameRate(uint32 metric_id, uint32 event_code, string:MAX_COMPONENT_LENGTH component,
+ float32 fps)
+ -> (Status status);
+
+ /// Logs a measured memory usage.
+ ///
+ /// `metric_id` ID of the metric to use. It must be one of the Metrics
+ /// from the ProjectProfile used to obtain this Logger, and it must be of
+ /// type MEMORY_USAGE.
+ ///
+ /// `event_code` The index of the event type associated with the memory
+ /// usage. The indexed set of all event codes and their labels is specified
+ /// in the metric definition.
+ ///
+ /// `component` Optionally, a component associated with the memory usage may
+ /// also be logged. Any notion of component that makes sense may be used or
+ /// use the empty string if there is no natural notion of component.
+ ///
+ /// `bytes` The memory used, in bytes.
+ LogMemoryUsage(uint32 metric_id, uint32 event_code, string:MAX_COMPONENT_LENGTH component,
+ int64 bytes)
+ -> (Status status);
+
+ /// This method is part of Cobalt's helper service for measuring the time
+ /// delta between two events that occur in different processes. This starts
+ /// the timer. A corresponding invocation of EndTimer() with the same
+ /// `timer_id` ends the timer. After both StartTimer() and EnvdTimer() have
+ /// been invoked, LogElapsedTime() will be invoked with the difference
+ /// between the end timestamp and the start timestamp as the value of
+ /// `duration_microseconds`. It is OK if Cobalt receives the EndTimer()
+ /// call before the StartTimer() call.
+ ///
+ /// `metric_id` ID of the metric to use. It must be one of the Metrics
+ /// from the ProjectProfile used to obtain this Logger, and it must be of
+ /// type ELAPSED_TIME.
+ ///
+ /// `event_code` The index of the event type to associate with the elapsed
+ /// time. This is passed to LogElapsedTime()
+ ///
+ /// `component` Optionally, a component associated with the event may also be
+ /// logged. See the description at LogElapsedTime().
+ ///
+ /// `timer_id` The ID of the timer being started. This is an arbitrary
+ /// non-empty string provided by the caller and it is the caller's
+ /// responsibility to ensure that Cobalt receives a pair of StartTimer(),
+ /// EndTimer() calls with this id before the timeout and without any
+ /// intervening additional calls to StartTimer() or EndTimer() using the same
+ /// id. Once such a pair is received Cobalt will delete the timer with this
+ /// ID and after that the ID may be re-used.
+ ///
+ /// `timestamp` The timestamp to set as the start of the timer. The units
+ /// must be microseconds. The absolute value does not matter, only the
+ /// difference between the end and start timestamps will be used.
+ ///
+ /// `timeout_s` The number of seconds Cobalt should wait to receive the
+ /// corresponding EndTimer() call with the same `timer_id`. If Cobalt has
+ /// already received the corresponding EndTimer() call before receiving this
+ /// StartTimer() call then this value is ignored as the timeout has already
+ /// been set by the EndTimer() call. If Cobalt does not receive the
+ /// corresponding EndTimer() call before the timeout then the timer will be
+ /// deleted and this invocation of StartTimer() will be forgotten. Must be a
+ /// positive value less than 300.
+ ///
+ /// `status` Returns OK on success. There are two success cases:
+ /// (i) Cobalt does not currently have any timers with the given
+ /// timer_id. In that case this call creates a new timer with
+ /// the given ID and start timestamp.
+ /// (ii) Cobalt currently has a timer with the given timer_id for
+ /// which it has received exactly one EndTimer() call and no
+ /// StartTimer() calls. In this case Cobalt will delete the
+ /// timer and invoke LogElapsedTime() using the difference
+ /// between the end timestamp and the start timestamp as the
+ /// value of `duration_micros`. It is ok if this value is
+ /// negative.
+ /// Returns INVALID_ARGUMENTS if `timer_id` is empty, the timeout
+ /// is not positive and less than 5 minutes or Cobalt currently
+ /// has a timer with the given timer_ID and it already has a start
+ /// timestamp. In the last case Cobalt will delete the timer with
+ /// the given `timer_id` and this invocation of StartTimer()
+ /// will be forgotten.
+ /// Any error returned by LogElapsedTime() may also be returned by this
+ /// method.
+ StartTimer(uint32 metric_id, uint32 event_code, string:MAX_COMPONENT_LENGTH component,
+ string:MAX_TIMER_ID_LENGTH timer_id, uint64 timestamp, uint32 timeout_s)
+ -> (Status status);
+
+ /// This method is part of Cobalt's helper service for measuring the time
+ /// delta between two events that occur in different processes. This ends
+ /// the timer. A corresponding invocation of StartTimer() with the same
+ /// `timer_id` starts the timer. After both StartTimer() and EndTimer() have
+ /// been invoked, LogElapsedTime() will be invoked with the difference
+ /// between the end timestamp and the start timestamp as the value of
+ /// `duration_microseconds`. It is OK if Cobalt receives the EndTimer()
+ /// call before the StartTimer() call.
+ ///
+ /// `timer_id` The ID of the timer being ended. This is an arbitrary
+ /// non-empty string provided by the caller and it is the caller's
+ /// responsibility to ensure that Cobalt receives a pair of StartTimer(),
+ /// EndTimer() calls with this id before the timeout and without any
+ /// intervening additional calls to StartTimer() or EndTimer() using the same
+ /// id. Once such a pair is received Cobalt will delete the timer with this
+ /// ID and after that the ID may be re-used.
+ ///
+ /// `timestamp` The timestamp to set as the end of the timer. The units must
+ /// be microseconds. The absolute value does not matter, only the difference
+ /// between the end and start timestamps will be used.
+ ///
+ /// `timeout_s` The number of seconds Cobalt should wait to receive the
+ /// corresponding EndTimer() call with the same `timer_id`. If Cobalt has
+ /// already received the corresponding EndTimer() call before receiving this
+ /// StartTimer() call then this value is ignored as the timeout has already
+ /// been set by the EndTimer() call. If Cobalt does not receive the
+ /// corresponding EndTimer() call before the timeout then the timer will be
+ /// deleted and this invocation of StartTimer() will be forgotten. Must be a
+ /// positive value less than 300.
+ ///
+ /// `status` Returns OK on success. There are two success cases:
+ /// (i) Cobalt does not currently have any timers with the given
+ /// timer_id. In that case this call creates a new timer with
+ /// the given ID and end timestamp.
+ /// (ii) Cobalt currently has a timer with the given timer_id for
+ /// which it has received exactly one StartTimer() call and no
+ /// EndTimer() calls. In this case Cobalt will delete the
+ /// timer and invoke LogElapsedTime() using the difference
+ /// between the end timestamp and the start timestamp as the
+ /// value of `duration_micros`. It is ok if this value is
+ /// negative.
+ /// Returns INVALID_ARGUMENTS if `timer_id` is empty, the timeout
+ /// is not positive and less than 5 minutes or Cobalt currently
+ /// has a timer with the given timer_ID and it already has an end
+ /// timestamp. In the last case Cobalt will delete the timer with
+ /// the given `timer_id` and this invocation of EndTimer()
+ /// will be forgotten.
+ /// Any error returned by LogElapsedTime() may also be returned by this
+ /// method.
+ EndTimer(string:MAX_TIMER_ID_LENGTH timer_id, uint64 timestamp, uint32 timeout_s)
+ -> (Status status);
+
+ // Method ordinals >= 100 are reserved for sub-interfaces.
+};
+
+/////////////////////////////////////////////////////////////////////
+
+// Logger Interface
+/////////////////////////////////////////////////////////////////////
+
+/// A value for a custom Event. This is used by the method LogCustomEvent().
+struct CustomEventValue {
+ /// The name of the Metric dimension this value is for.
+ string:MAX dimension_name;
+
+ /// The value for that dimension.
+ Value value;
+};
+
+/// A value that may be a string, int, double, or index.
+union Value {
+ 1: string:MAX string_value;
+ 2: int64 int_value;
+ 3: float64 double_value;
+ 4: uint32 index_value;
+};
+
+/// One bucket of histogram. This is used by the methods LogIntHistogram() from
+/// Cobalt 1.0 and LogIntegerHistogram from Cobalt 1.1.
+struct HistogramBucket {
+ /// The index of the bucket. The MetricDefinition includes a specification
+ /// of a sequence of N+1 integer-range buckets that are indexed from
+ /// 0, the underflow bucket, to N, the overflow bucket.
+ uint32 index;
+
+ /// The number of values in that bucket.
+ uint64 count;
+};
+
+/// Used to log that an event has occurred a given number of times. Using this
+/// struct with LogCobaltEvent() is equivalent to invoking LogEventCount().
+struct CountEvent {
+ /// The number of microseconds over which this count was observed.
+ int64 period_duration_micros;
+
+ /// The number of times the event occurred
+ int64 count;
+};
+
+/// Used to log an event that has no extra fields. Using this struct with
+/// LogCobaltEvent() is equivalent to invoking LogEvent().
+struct Event {
+};
+
+/// The variadic part of a CobaltEvent.
+union EventPayload {
+ /// This maps to a call to LogEvent().
+ 1: Event event;
+
+ /// This maps to a call to LogEventCount().
+ 2: CountEvent event_count;
+
+ /// This maps to a call to LogElapsedTime().
+ 3: int64 elapsed_micros;
+
+ /// This maps to a call to LogFrameRate().
+ 4: float32 fps;
+
+ /// This maps to a call to LogMemoryUsage().
+ 5: int64 memory_bytes_used;
+
+ // Previously mapped to a call to LogString() (deprecated).
+ 6: reserved;
+
+ /// This maps to a call to LogIntHistogram().
+ 7: vector<HistogramBucket>:MAX_HISTOGRAM_BUCKETS int_histogram;
+};
+
+/// A specification of an event that occurred to be passed to LogCobaltEvent().
+/// This is part of an alternative API to cobalt that uses a single method with a
+/// variadic parameter instead of the multiple methods above. This technique
+/// allows multiple event codes to be passed whereas the methods above support
+/// only a single event code.
+struct CobaltEvent {
+ /// ID of the metric to use. It must be one of the Metrics from the
+ /// ProjectProfile used to obtain this Logger, and its type must match the
+ /// `payload` type.
+ uint32 metric_id;
+
+ /// The event codes for the event that occurred. There must be one event code
+ /// given for each dimension specified in the metric definition.
+ vector<uint32>:MAX_EVENT_CODE_COUNT event_codes;
+
+ /// Optionally, a component associated with the event that occurred may also
+ /// be logged also be logged. Any notion of component that makes sense may be
+ /// used or use the empty string if there is no natural notion of component.
+ string:MAX_COMPONENT_LENGTH? component;
+
+ /// The event-specific information for the event to be logged.
+ EventPayload payload;
+};
+
+/// Logger is an extension of the LoggerBase interface that adds some additional
+/// methods that do not naturally conform to the Simple layout. We opt for
+/// a natural easy-to-understand interface at the cost of not being "Simple".
+/// See the interface LoggerSimple below for versions of some of these methods
+/// that do conform to the Simple layout.
+protocol Logger {
+ compose LoggerBase;
+
+ /// Logs a histogram over a set of integer buckets. The meaning of the
+ /// Metric and the buckets is specified in the Metric definition.
+ ///
+ /// This method is intended to be used in situations where the client
+ /// wishes to aggregate a large number of integer-valued measurements
+ /// *in-process*, prior to submitting the data to Cobalt.
+ /// One reason a client may wish to do this is that the measurements occur
+ /// with very high frequency and it is not practical to make a FIDL call
+ /// for each individual measurement.
+ ///
+ /// `metric_id` ID of the metric to use. It must be one of the Metrics
+ /// from the ProjectProfile used to obtain this Logger, and it must be of
+ /// type INT_HISTOGRAM.
+ ///
+ /// `event_code` The index of the event type associated with the
+ /// integer-valued measurement. The indexed set of all event codes and their
+ /// labels is specified in the metric definition.
+ ///
+ /// `component` Optionally, a component associated with integer-valued
+ /// measurements may also be logged. Any notion of component that makes sense
+ /// may be used or use the empty string if there is no natural notion of
+ /// component.
+ ///
+ /// `histogram` The histogram to log. Each HistogramBucket gives the count
+ /// for one bucket of the histogram. The definitions of the buckets is given
+ /// in the Metric definition.
+ LogIntHistogram(uint32 metric_id, uint32 event_code,
+ string:MAX_COMPONENT_LENGTH component, vector<HistogramBucket>:MAX_HISTOGRAM_BUCKETS histogram)
+ -> (Status status);
+
+ /// Logs a custom Event. The semantics of the Metric are specified in the
+ /// Metric definition.
+ ///
+ /// `metric_id` ID of the metric to use. It must be one of the Metrics
+ /// from the ProjectProfile used to obtain this Logger, and it must be of
+ /// type CUSTOM.
+ ///
+ /// `event_values` The values for the custom Event. There is one value for
+ /// each dimension of the Metric. The number and types of the values must
+ /// be consistent with the dimensions declared in the Metric definition.
+ LogCustomEvent(uint32 metric_id, vector<CustomEventValue>:MAX event_values)
+ -> (Status status);
+
+ /// Logs a CobaltEvent. This method offers an alternative API to Cobalt that
+ /// uses a single method with a variadic parameter instead of the multiple
+ /// methods defined above. The reason to use this method is that a
+ /// CobaltEvent allows multiple event codes to be specified whereas the
+ /// methods above allow only a single event code.
+ LogCobaltEvent(CobaltEvent event) -> (Status status);
+
+ /// Logs a list of CobaltEvents. This method is equivalent to invoking
+ /// LogCobaltEvent() multiple times but is more efficient as it requires only
+ /// a single FIDL call.
+ LogCobaltEvents(vector<CobaltEvent>:MAX_BATCHED_EVENTS events) -> (Status status);
+};
+
+/////////////////////////////////////////////////////////////////////
+
+// LoggerSimple Interface
+/////////////////////////////////////////////////////////////////////
+
+/// LoggerSimple is an extension of the LoggerBase interface that adds some
+/// additional methods intended to be used by lower-levels of the Fuchsia system.
+///
+/// This interface conforms to the Simple layout so that Simple bindings
+/// may be generated for it.
+[Layout = "Simple"]
+protocol LoggerSimple {
+ compose LoggerBase;
+
+ /// Logs a histogram over a set of integer buckets. The meaning of the
+ /// Metric and the buckets is specified in the Metric definition.
+ ///
+ /// See the method LogIntHistogram() in the Logger interface for more
+ /// information. This method is similar except that it adheres to the
+ /// requirements of Simple layout. Instead of a vector of HistogramBucekts
+ /// this version takes two parallel vectors of bucket indices and the
+ /// corresponding bucket counts.
+ LogIntHistogram(uint32 metric_id, uint32 event_code,
+ string:MAX_COMPONENT_LENGTH component,
+ vector<uint32>:MAX_HISTOGRAM_BUCKETS bucket_indices,
+ vector<uint64>:MAX_HISTOGRAM_BUCKETS bucket_counts)
+ -> (Status status);
+};
+
+/////////////////////////////////////////////////////////////////////
+
+// SystemProfileUpdater Interface
+/////////////////////////////////////////////////////////////////////
+
+/// The state of a single experiment on a device or binary.
+struct Experiment {
+ /// The id of the experiment as defined by the A/B Experiment framework.
+ uint64 experiment_id;
+ /// The id of the experiment arm as defined by the A/B Experiment framework.
+ uint32 arm_id;
+};
+
+/// The SystemDataUpdater interface allows callers to update the state of
+/// the System Data in Cobalt. This includes the SystemProfile and experiment
+/// state. The changes are global and affect all loggers running on the device.
+[Discoverable]
+protocol SystemDataUpdater {
+ /// Resets Cobalt's view of the system-wide experiment state and replaces it
+ /// with the given values.
+ ///
+ /// `experiments` All experiments the device has a notion of and the arms
+ /// the device belongs to for each of them. These are the only experiments
+ /// the device can collect data for.
+ SetExperimentState(vector<Experiment>:MAX experiments)
+ -> (Status status);
+
+ /// Sets Cobalt's view of the system-wide channel replacing the existing values.
+ ///
+ /// `current_channel` The channel that the device last used as an update source. This value may
+ /// be empty to indicate that the device is not currently associated with any channel.
+ SetChannel(string:MAX_CHANNEL_NAME_LENGTH current_channel) -> (Status status);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.cobalt/cobalt_controller.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.cobalt/cobalt_controller.fidl
new file mode 100644
index 0000000..f6bc40f
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.cobalt/cobalt_controller.fidl
@@ -0,0 +1,54 @@
+// Copyright 2017 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.
+
+library fuchsia.cobalt;
+
+/// The Controller is primarily useful for testing the Cobalt service.
+/// Cobalt clients should use the Logger.
+[Discoverable]
+protocol Controller {
+ /// Requests that the collection of Observations that are currently cached
+ /// locally be sent to the Cobalt server soon. Cobalt will send the
+ /// Observations in one or more batches and will retry several times upon
+ /// failure. The response occurs only after that procedure is completed. A
+ /// return value of true indicates that all Observations were successfully
+ /// sent. A return value of false indicates otherwise.
+ RequestSendSoon() -> (bool success);
+
+ /// The Cobalt FIDL service will block, not processing any further FIDL
+ /// requests or responses, on either this interface or the Logger interface,
+ /// until either `max_wait_seconds` have elapsed or the Cobalt service's
+ /// worker thread has successfully sent all previously added Observations to
+ /// the Shuffler. The response will be returned after the blocking period has
+ /// ended. Note that this method does not request an expedited send and so it
+ /// is possible that the worker thread is currently waiting for the next
+ /// scheduled send time and so the empty state will not be achieved prior
+ /// that time.
+ BlockUntilEmpty(uint32 max_wait_seconds) -> ();
+
+ /// These diagnostic stats are mostly useful in a testing environment but
+ /// may possibly prove useful in production also.
+ GetNumSendAttempts() -> (uint32 num);
+ GetFailedSendAttempts() -> (uint32 num);
+ GetNumObservationsAdded() -> (uint64 num_obs);
+ GetNumEventAggregatorRuns() -> (uint64 num_runs);
+
+ /// Triggers Cobalt to generate Observations based on locally aggregated
+ /// event data and write them to the local ObservationStore. In a non-test
+ /// environment this would normally be done periodically by a background
+ /// thread. In a test environment this method should be invoked against an
+ /// instance of the Cobalt FIDL service that was passed the flag
+ /// --start_event_aggregator_worker=false.
+ ///
+ /// `day_index` The index of the day for which locally aggregated
+ /// Observations should be generated.
+ ///
+ /// `report_ids` A vector of report IDs.
+ ///
+ /// Returns a vector whose k-th element is the number of observations
+ /// generated for the k-th element of `report_ids`. If `report_ids`
+ /// is the empty vector, then an empty vector is returned.
+ GenerateAggregatedObservations(uint32 day_index, vector<uint32>:MAX report_ids)
+ -> (vector<uint64>:MAX num_obs);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.cobalt/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.cobalt/meta.json
new file mode 100644
index 0000000..8c57f6e
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.cobalt/meta.json
@@ -0,0 +1,10 @@
+{
+ "deps": [],
+ "name": "fuchsia.cobalt",
+ "root": "fidl/fuchsia.cobalt",
+ "sources": [
+ "fidl/fuchsia.cobalt/cobalt.fidl",
+ "fidl/fuchsia.cobalt/cobalt_controller.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.component.runner/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.component.runner/BUILD.gn
new file mode 100644
index 0000000..bfef985
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.component.runner/BUILD.gn
@@ -0,0 +1,29 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.component.runner") {
+ library_name = "runner"
+ namespace = "fuchsia.component"
+ public_deps = [
+ "../fuchsia.component",
+ "../fuchsia.data",
+ "../fuchsia.io",
+ "../fuchsia.url",
+ ]
+ sources = [
+ "component_runner.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.component.runner",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.component.runner/component_runner.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.component.runner/component_runner.fidl
new file mode 100644
index 0000000..4e37805
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.component.runner/component_runner.fidl
@@ -0,0 +1,164 @@
+// Copyright 2016 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.
+
+library fuchsia.component.runner;
+
+using fuchsia.data;
+using fuchsia.io;
+using fuchsia.component;
+using fuchsia.url;
+
+const uint32 MAX_NAMESPACE_COUNT = 32;
+
+/// A protocol used for running components.
+///
+/// This protocol is implemented by components which provide a runtime
+/// environment for other components.
+///
+/// Note: The component manager is the only intended direct client of this
+/// interface.
+[Discoverable]
+protocol ComponentRunner {
+ /// Start running a component instance described by `start_info`.
+ ///
+ /// Component manager binds and uses `controller` to control the
+ /// lifetime of the newly started component instance.
+ ///
+ /// Errors are delivered as epitaphs over the `ComponentController`
+ /// protocol. In the event of an error, the runner must ensure that
+ /// resources are cleaned up.
+ ///
+ /// Errors:
+ ///
+ Start(ComponentStartInfo start_info,
+ request<ComponentController> controller);
+};
+
+/// A single component namespace entry, which describes a namespace mount point
+/// (`path`) and the directory backing it (`directory`). This type is usually
+/// composed inside a vector. See `ComponentStartInfo.ns` for more details.
+table ComponentNamespaceEntry {
+ /// The mount point for the directory, including a
+ /// leading slash. For example: "/pkg", "/svc", or "/config/data".
+ 1: string:fuchsia.component.MAX_PATH_LENGTH path;
+
+ /// The directory mounted at the above `path`.
+ 2: fuchsia.io.Directory directory;
+};
+
+/// Parameters for starting a new component instance.
+table ComponentStartInfo {
+ /// The resolved URL of the component.
+ ///
+ /// This is the canonical URL obtained by the component resolver after
+ /// following redirects and resolving relative paths.
+ 1: fuchsia.url.Url resolved_url;
+
+ /// The component's program declaration.
+ /// This information originates from `ComponentDecl.program`.
+ 2: fuchsia.data.Dictionary program;
+
+ /// The namespace to provide to the component instance.
+ ///
+ /// A namespace specifies the set of directories that a component instance
+ /// receives at start-up. Through the namespace directories, a component
+ /// may access capabilities available to it. The contents of the namespace
+ /// are mainly determined by the component's `use` declarations but may
+ /// also contain additional capabilities automatically provided by the
+ /// framework.
+ ///
+ /// By convention, a component's namespace typically contains some or all
+ /// of the following directories:
+ ///
+ /// - "/svc": A directory containing services that the component requested
+ /// to use via its "import" declarations.
+ /// - "/pkg": A directory containing the component's package, including its
+ /// binaries, libraries, and other assets.
+ ///
+ /// The mount points specified in each entry must be unique and
+ /// non-overlapping. For example, [{"/foo", ..}, {"/foo/bar", ..}] is
+ /// invalid.
+ 3: vector<ComponentNamespaceEntry>:MAX_NAMESPACE_COUNT ns;
+
+ /// The directory this component serves.
+ 4: request<fuchsia.io.Directory> outgoing_dir;
+
+ /// The directory served by the runner to present runtime information about
+ /// the component.
+ 5: request<fuchsia.io.Directory> runtime_dir;
+};
+
+/// A protocol for binding and controlling the lifetime of a component instance
+/// started using `ComponentRunner.Start()`. The component manager is the
+/// intended direct client of this protocol.
+///
+/// When the controlled component instance terminates or becomes inaccessible
+/// for any reason, the server closes the connection with an epitaph.
+///
+/// LIFECYCLE
+///
+/// A component may exist in one of two states: `Started`, or `Stopped`. The
+/// component is `Started` from the time `ComponentRunner.Start()` is called
+/// until the ComponentRunner closes the ComponentController handle. The
+/// component then transitions to `Stopped`.
+///
+/// Component manager uses ComponentController to terminate a component in two
+/// steps:
+/// 1) Component manager calls `Stop()` to indicate that the ComponentRunner
+/// should stop a component's execution and close this connection with an
+/// epitaph.
+/// 2) If after some time the ComponentController is not closed, component
+/// manager calls `Kill()` to indicate that the ComponentRunner must halt a
+/// component's execution immediately, and then close this connection with
+/// an epitaph.
+///
+/// Component manager first waits for the ComponentController to close, and
+/// then tears down the namespace it hosts for the stopped component. Component
+/// manager may call `Kill()` without first having called `Stop()`.
+///
+/// EPITAPH
+///
+/// This protocol sends a FIDL epitaph to indicate that the component instance
+/// has been terminated. The component runner is expected to clean up all
+/// resources attributed to the component before closing the connection.
+///
+/// The following epitaphs may be sent by the server on error:
+/// - `INVALID_ARGUMENTS`:
+/// * `start_info.resolved_url` is not supported by this
+/// runner;
+/// * `start_info` contains missing or invalid arguments.
+/// - `INSTANCE_CANNOT_START`: The runner could not start the component.
+/// For example, a critical part of the program could not be found or
+/// loaded, or the referenced binary was invalid for this runner.
+/// - `RESOURCE_UNAVAILABLE`: The component could not be launched due to
+/// lack of resources.
+/// - `INTERNAL`: An unexpected internal runner error was encountered.
+/// - `INSTANCE_DIED`: The component instance was started but
+/// subsequently terminated unexpectedly.
+/// - `ZX_OK`: The component instance was successfully terminated without
+/// error.
+/// - Other status codes (e.g. `ZX_ERR_PEER_CLOSED`) may indicate a failure
+/// of the component runner itself. The component manager may respond to such
+/// failures by terminating the component runner's job to ensure system
+/// stability.
+protocol ComponentController {
+ /// Request to stop the component instance.
+ ///
+ /// After stopping the component instance, the server should close this
+ /// connection with an epitaph. After the connection
+ /// closes, component manager considers this component instance to be
+ /// Stopped and the component's namespace will be torn down.
+ Stop();
+
+ /// Stop this component instance immediately.
+ ///
+ /// The ComponentRunner must immediately kill the component instance, and
+ /// then close this connection with an epitaph. After the connection
+ /// closes, component manager considers this component instance to be
+ /// Stopped and the component's namespace will be torn down.
+ ///
+ /// In some cases Kill() may be issued before Stop(), but that is not
+ /// guaranteed.
+ Kill();
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.component.runner/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.component.runner/meta.json
new file mode 100644
index 0000000..378ca8a
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.component.runner/meta.json
@@ -0,0 +1,14 @@
+{
+ "deps": [
+ "fuchsia.component",
+ "fuchsia.data",
+ "fuchsia.url",
+ "fuchsia.io"
+ ],
+ "name": "fuchsia.component.runner",
+ "root": "fidl/fuchsia.component.runner",
+ "sources": [
+ "fidl/fuchsia.component.runner/component_runner.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.component/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.component/BUILD.gn
new file mode 100644
index 0000000..0a7f68b
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.component/BUILD.gn
@@ -0,0 +1,27 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.component") {
+ library_name = "component"
+ namespace = "fuchsia"
+ public_deps = [
+ ]
+ sources = [
+ "constants.fidl",
+ "error.fidl",
+ "types.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.component",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.component/constants.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.component/constants.fidl
new file mode 100644
index 0000000..a84575d
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.component/constants.fidl
@@ -0,0 +1,17 @@
+// Copyright 2020 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.
+
+library fuchsia.component;
+
+const uint32 MAX_FACET_NAME_LENGTH = 100;
+const uint32 MAX_CHILD_NAME_LENGTH = 100;
+const uint32 MAX_COLLECTION_NAME_LENGTH = 100;
+const uint32 MAX_RESOLVER_NAME_LENGTH = 100;
+const uint32 MAX_RUNNER_NAME_LENGTH = 100;
+const uint32 MAX_STORAGE_NAME_LENGTH = 100;
+const uint32 MAX_EVENT_NAME_LENGTH = 100;
+const uint32 MAX_ENVIRONMENT_NAME_LENGTH = 100;
+const uint32 MAX_PATH_LENGTH = 1024;
+const uint32 MAX_MONIKER_LENGTH = 4096;
+const uint32 MAX_URL_SCHEME_LENGTH = 100;
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.component/error.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.component/error.fidl
new file mode 100644
index 0000000..3a458f0
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.component/error.fidl
@@ -0,0 +1,30 @@
+// Copyright 2020 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.
+
+library fuchsia.component;
+
+/// Standard error codes for component framework protocols.
+enum Error {
+ /// Component manager encountered an otherwise unspecified error while
+ /// performing the operation.
+ INTERNAL = 1;
+ /// At least one argument had an invalid format.
+ INVALID_ARGUMENTS = 2;
+ /// The feature is not yet supported.
+ UNSUPPORTED = 3;
+ /// The component instance was not found.
+ INSTANCE_NOT_FOUND = 4;
+ /// The component instance already exists.
+ INSTANCE_ALREADY_EXISTS = 5;
+ /// The component instance could not be started.
+ INSTANCE_CANNOT_START = 6;
+ /// Failed to resolve the component's declaration.
+ INSTANCE_CANNOT_RESOLVE = 7;
+ /// The component collection was not found.
+ COLLECTION_NOT_FOUND = 8;
+ /// There was insufficient resources to perform the operation.
+ RESOURCE_UNAVAILABLE = 9;
+ /// The component instance died unexpectedly.
+ INSTANCE_DIED = 10;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.component/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.component/meta.json
new file mode 100644
index 0000000..d3034b1
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.component/meta.json
@@ -0,0 +1,11 @@
+{
+ "deps": [],
+ "name": "fuchsia.component",
+ "root": "fidl/fuchsia.component",
+ "sources": [
+ "fidl/fuchsia.component/constants.fidl",
+ "fidl/fuchsia.component/error.fidl",
+ "fidl/fuchsia.component/types.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.component/types.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.component/types.fidl
new file mode 100644
index 0000000..2547c58
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.component/types.fidl
@@ -0,0 +1,13 @@
+// Copyright 2020 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.
+
+library fuchsia.component;
+
+using child_name = string:MAX_CHILD_NAME_LENGTH;
+using collection_name = string:MAX_COLLECTION_NAME_LENGTH;
+using environment_name = string:MAX_ENVIRONMENT_NAME_LENGTH;
+using event_name = string:MAX_EVENT_NAME_LENGTH;
+using resolver_name = string:MAX_RESOLVER_NAME_LENGTH;
+using runner_name = string:MAX_RUNNER_NAME_LENGTH;
+using url_scheme = string:MAX_URL_SCHEME_LENGTH;
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.data/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.data/BUILD.gn
new file mode 100644
index 0000000..bddbf14
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.data/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.data") {
+ library_name = "data"
+ namespace = "fuchsia"
+ public_deps = [
+ ]
+ sources = [
+ "data.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.data",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.data/data.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.data/data.fidl
new file mode 100644
index 0000000..78c91d4
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.data/data.fidl
@@ -0,0 +1,35 @@
+// Copyright 2018 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.
+
+library fuchsia.data;
+
+// Maximum number of items in a dictionary's value.
+const uint32 MAX_NUM_VALUE_ITEMS = 1024;
+const uint32 MAX_NUM_ENTRIES = 1024;
+const uint32 MAX_KEY_LENGTH = 1024;
+const uint32 MAX_VALUE_LENGTH = 1024;
+
+/// A dictionary is a sequence of key/value pairs.
+/// Keys must be unique and sorted in lexicographically increasing order.
+table Dictionary {
+ // A list of dictionary entries, where each entry is a (key, value) pair.
+ //
+ // Required.
+ 1: vector<DictionaryEntry>:MAX_NUM_ENTRIES entries;
+};
+
+/// A key/value pair in a `Dictionary`.
+struct DictionaryEntry {
+ // The key for a dictionary entry.
+ string:MAX_KEY_LENGTH key;
+
+ // The value associated with the `key`.
+ DictionaryValue? value;
+};
+
+/// A dictionary's value is a string, or a list of strings.
+union DictionaryValue {
+ 1: string:MAX_VALUE_LENGTH str;
+ 2: vector<string:MAX_VALUE_LENGTH>:MAX_NUM_VALUE_ITEMS str_vec;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.data/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.data/meta.json
new file mode 100644
index 0000000..a025320
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.data/meta.json
@@ -0,0 +1,9 @@
+{
+ "deps": [],
+ "name": "fuchsia.data",
+ "root": "fidl/fuchsia.data",
+ "sources": [
+ "fidl/fuchsia.data/data.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.deprecatedtimezone/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.deprecatedtimezone/BUILD.gn
new file mode 100644
index 0000000..19f6b60
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.deprecatedtimezone/BUILD.gn
@@ -0,0 +1,26 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.deprecatedtimezone") {
+ library_name = "deprecatedtimezone"
+ namespace = "fuchsia"
+ public_deps = [
+ ]
+ sources = [
+ "deprecated_time_service.fidl",
+ "deprecated_time_zone.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.deprecatedtimezone",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.deprecatedtimezone/deprecated_time_service.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.deprecatedtimezone/deprecated_time_service.fidl
new file mode 100644
index 0000000..f1da6ea
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.deprecatedtimezone/deprecated_time_service.fidl
@@ -0,0 +1,14 @@
+// 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.
+
+library fuchsia.deprecatedtimezone;
+
+/// Interface to allow manual updates of the system time.
+[Discoverable]
+protocol TimeService {
+
+ /// Requests an immediate update of the time from network.
+ Update(uint8 num_retries)
+ -> (bool successful);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.deprecatedtimezone/deprecated_time_zone.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.deprecatedtimezone/deprecated_time_zone.fidl
new file mode 100644
index 0000000..29d86bb
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.deprecatedtimezone/deprecated_time_zone.fidl
@@ -0,0 +1,38 @@
+// 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.
+
+library fuchsia.deprecatedtimezone;
+
+// NOTE: this FIDL protocol is deprecated and slated for removal. Please do
+// not add new uses that depend on it. Use instead the following functionality:
+//
+// - For `GetTimezoneOffsetMinutes` and `GetTimezoneId`, get the timezone name
+// from `fuchsia.intl.ProfileProvider`, and use the ICU library to compute
+// the offset.
+// - For `SetTimezone` and `Watch`, please use `fuchsia.settings.Intl`.
+//
+// For more information on the ICU timezone ID format, see:
+// http://userguide.icu-project.org/datetime
+[Discoverable]
+protocol Timezone {
+ /// Returns local timezone offset (in minutes from UTC. Can be negative) for
+ /// the supplied number of milliseconds since the Unix epoch. Returns a
+ /// non-zero DST offset when appropriate.
+ GetTimezoneOffsetMinutes(int64 milliseconds_since_epoch)
+ -> (int32 local_offset_minutes, int32 dst_offset_minutes);
+
+ /// Sets the timezone for the machine based on an ICU ID.
+ SetTimezone(string timezone_id) -> (bool status);
+
+ /// Gets the timezone ID string.
+ GetTimezoneId() -> (string timezone_id);
+
+ /// Watches for updates to the timezone ID.
+ Watch(TimezoneWatcher watcher);
+};
+
+protocol TimezoneWatcher {
+ /// When the timezone changes, returns the new timezone ID.
+ OnTimezoneOffsetChange(string timezone_id);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.deprecatedtimezone/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.deprecatedtimezone/meta.json
new file mode 100644
index 0000000..01d147b
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.deprecatedtimezone/meta.json
@@ -0,0 +1,10 @@
+{
+ "deps": [],
+ "name": "fuchsia.deprecatedtimezone",
+ "root": "fidl/fuchsia.deprecatedtimezone",
+ "sources": [
+ "fidl/fuchsia.deprecatedtimezone/deprecated_time_service.fidl",
+ "fidl/fuchsia.deprecatedtimezone/deprecated_time_zone.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.developer.tiles/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.developer.tiles/BUILD.gn
new file mode 100644
index 0000000..416183e
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.developer.tiles/BUILD.gn
@@ -0,0 +1,27 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.developer.tiles") {
+ library_name = "tiles"
+ namespace = "fuchsia.developer"
+ public_deps = [
+ "../fuchsia.ui.app",
+ "../fuchsia.ui.gfx",
+ ]
+ sources = [
+ "tiles.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.developer.tiles",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.developer.tiles/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.developer.tiles/meta.json
new file mode 100644
index 0000000..27daf1d
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.developer.tiles/meta.json
@@ -0,0 +1,12 @@
+{
+ "deps": [
+ "fuchsia.ui.app",
+ "fuchsia.ui.gfx"
+ ],
+ "name": "fuchsia.developer.tiles",
+ "root": "fidl/fuchsia.developer.tiles",
+ "sources": [
+ "fidl/fuchsia.developer.tiles/tiles.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.developer.tiles/tiles.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.developer.tiles/tiles.fidl
new file mode 100644
index 0000000..95b32f8
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.developer.tiles/tiles.fidl
@@ -0,0 +1,28 @@
+// Copyright 2018 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.
+
+library fuchsia.developer.tiles;
+
+using fuchsia.ui.app;
+using fuchsia.ui.gfx;
+
+[Discoverable]
+protocol Controller {
+ /// Instantiates a component by its URL and adds a tile backed by that component's ViewProvider.
+ /// Returns a key for the tile that can be used for resizing or removing the tile, or 0 on failure.
+ AddTileFromURL(string url, bool allow_focus, vector<string>? args) -> (uint32 key);
+
+ /// Adds a tile backed by a view from the view provider.
+ /// Returns a key for the tile that can be used for resizing or removing the tile, or 0 on failure.
+ AddTileFromViewProvider(string url, fuchsia.ui.app.ViewProvider provider) -> (uint32 key);
+
+ /// Removes the tile with the given key.
+ RemoveTile(uint32 key);
+
+ /// Returns a list of tiles.
+ ListTiles() -> (vector<uint32> keys, vector<string> urls, vector<fuchsia.ui.gfx.vec3> sizes, vector<bool> focusabilities);
+
+ /// Asks the tiles component to quit.
+ Quit();
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.diagnostics/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.diagnostics/BUILD.gn
new file mode 100644
index 0000000..08ab7d8
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.diagnostics/BUILD.gn
@@ -0,0 +1,28 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.diagnostics") {
+ library_name = "diagnostics"
+ namespace = "fuchsia"
+ public_deps = [
+ "../fuchsia.mem",
+ ]
+ sources = [
+ "format.fidl",
+ "reader.fidl",
+ "selector.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.diagnostics",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.diagnostics/format.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.diagnostics/format.fidl
new file mode 100644
index 0000000..73ff1ca
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.diagnostics/format.fidl
@@ -0,0 +1,15 @@
+// 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.
+
+library fuchsia.diagnostics;
+
+/// Enum used to specify the output format for
+/// Reader results.
+enum Format {
+ /// Dump read results per the Diagnostics Json
+ /// Schema specifications.
+ JSON = 1;
+ /// Dump read results per the Iquery text specifications.
+ TEXT = 2;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.diagnostics/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.diagnostics/meta.json
new file mode 100644
index 0000000..5be730f
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.diagnostics/meta.json
@@ -0,0 +1,13 @@
+{
+ "deps": [
+ "fuchsia.mem"
+ ],
+ "name": "fuchsia.diagnostics",
+ "root": "fidl/fuchsia.diagnostics",
+ "sources": [
+ "fidl/fuchsia.diagnostics/format.fidl",
+ "fidl/fuchsia.diagnostics/reader.fidl",
+ "fidl/fuchsia.diagnostics/selector.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.diagnostics/reader.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.diagnostics/reader.fidl
new file mode 100644
index 0000000..01c349b
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.diagnostics/reader.fidl
@@ -0,0 +1,159 @@
+// 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.
+
+library fuchsia.diagnostics;
+
+using fuchsia.mem;
+
+/// The size bound of 1024 is a reasonably low size restriction that meets most
+/// canonical selectors we've ecountered.
+const uint16 MAXIMUM_RAW_SELECTOR_LENGTH = 1024;
+
+/// The size 64 was chosen because entries in batches are handles to
+/// VMOs and there is a limit of 64 handles per fidl message.
+const uint16 MAXIMUM_ENTRIES_PER_BATCH = 64;
+
+/// Enum describing the potential failure states of the streaming protocol when serving results
+/// to the client over the result iterator.
+enum ReaderError {
+ // An IO error suggests that parsing of data hierarchy VMOs or writing of formatted data to
+ // sockets has failed.
+ IO = 1;
+};
+
+/// Argument used for Archive selectors, can be either the pre-parsed
+/// fidl struct or string representation.
+flexible union SelectorArgument {
+ /// A Selector defining a pattern-matcher which selects for components within a hierarchy
+ /// and properties in a data hierarchy namespaced by component.
+ 1: Selector structured_selector;
+
+ /// A raw string representing a [fuchsia.diagnostics/Selector].
+ /// The Selector defines a pattern-matcher which selects for components within a hierarchy
+ /// and properties in a data hierarchy namespaced by component.
+ /// NOTE: All StringSelectors parsed from the raw_selector will be interperetted in
+ /// string_pattern mode, giving significance to special characters.
+ /// TODO(4601): Link to in-tree documentation for raw selector strings.
+ 2: string:MAXIMUM_RAW_SELECTOR_LENGTH raw_selector;
+};
+
+/// A fidl union containing a complete hierarchy of structured diagnostics
+/// data, such that the content can be parsed into a file by itself.
+flexible union FormattedContent {
+ /// A diagnostics schema encoded as json.
+ /// The VMO will contain up to 1mb of diagnostics data.
+ 1: fuchsia.mem.Buffer json;
+
+ /// A diagnostics schema encoded as text.
+ /// The VMO will contain up to 1mb of diagnostics data.
+ 2: fuchsia.mem.Buffer text;
+};
+
+/// Enum specifying the modes by which a user can connect to and stream diagnostics metrics.
+enum StreamMode : uint8 {
+ /// The stream will serve a snapshot of the diagnostics data at the time of
+ /// connection, then end.
+ SNAPSHOT = 1;
+ /// The stream will serve a snapshot of the diagnostics data at the time of
+ /// connection, then subsequent calls to the stream will hang until
+ /// new diagnostics data is available.
+ SNAPSHOT_THEN_SUBSCRIBE = 2;
+ /// Calls to the stream will hang until new diagnostics data is available. Between calls to
+ /// the stream, newly arrived data is buffered.
+ SUBSCRIBE = 3;
+};
+
+// Enum specifying the data types available through the diagnostics platform.
+enum DataType : uint8 {
+ /// Complete inspect hierarchies on the system.
+ INSPECT = 1;
+};
+
+flexible union ClientSelectorConfiguration {
+ /// A vector of [fuchsia.diagnostics/SelectorArgument] which
+ /// provide additional filters to scope data streams with. An empty vector is considered
+ /// a misconfiguration and will result in an epitaph signaling incorrect parameters.
+ 1: vector<SelectorArgument>:MAX selectors;
+
+ /// select_all must be true if set, and specifies that the client wants to retrieve
+ /// all data that their connection is able to expose.
+ 2: bool select_all;
+};
+
+/// Parameters needed to configure a stream of diagnostics information.
+table StreamParameters {
+ /// A [fuchsia.diagnostics/DataType] that specifies the diagnostics data type
+ /// to stream to the client.
+ /// NOTE: REQUIRED
+ 1: DataType data_type;
+
+ /// A [fuchsia.diagnostics/StreamMode] that specifies how the
+ /// streaming server provides streamed results.
+ /// NOTE: REQUIRED
+ 2: StreamMode stream_mode;
+
+ /// A [fuchsia.diagnostics/Format] that specifies how to format the returned
+ /// diagnostics data.
+ /// NOTE: REQUIRED
+ 3: Format format;
+
+ /// Configuration specifying what results the client wants returned from their
+ /// connection. The client can request a specific subset of data using a vector
+ /// of provided selectors, or can specify that they want all available data.
+ /// NOTE: REQUIRED
+ 4: ClientSelectorConfiguration client_selector_configuration;
+};
+
+/// Outer protocol for interacting with the different diagnostics data sources.
+[Discoverable]
+protocol ArchiveAccessor {
+ /// Creates an iterator over diagnostics data on the system.
+ /// * The iterator may be finite by streaming in SNAPSHOT mode, serving only the
+ /// current state of diagnostics data on the system.
+ /// * The iterator may be infinite by streaming in either SNAPSHOT_THEN_SUBSCRIBE
+ /// or SUBSCRIBE mode; the prior first provides iteration over the current state of
+ /// the sytem, and then both provide ongoing iteration over newly arriving diagnostics
+ /// data.
+ ///
+ /// + request `result stream` a [fuchsia.diagnostics/BatchIterator] that diagnostic
+ /// records are exposed to the client over.
+ /// * epitaphs:
+ /// - INVALID_ARGS: A required argument in the StreamParameters struct was missing.
+ /// - WRONG_TYPE: A selector provided by the StreamParameters struct was incorrectly
+ /// formatted.
+ ///
+ /// + request `stream_parameters` is a [fuchsia.diagnostics/StreamParameter] which
+ /// specifies how to configure the stream.
+ StreamDiagnostics(StreamParameters stream_parameters, request<BatchIterator> result_stream);
+};
+
+/// Conceptually, a directory iterator, where each element in the iterator is a single
+/// complete file that can be concatenated with other results.
+protocol BatchIterator {
+ /// Returns a vector of [fuchsia.diagnostics/FormattedContent] structs
+ /// with a format dictated by the format_settings argument provided to the Reader protocol
+ /// which spawned this BatchIterator.
+ ///
+ /// An empty vector implies that the data hierarchy has been fully iterated, and subsequent
+ /// GetNext calls will always return the empty vector.
+ ///
+ /// When the BatchIterator is serving results via subscription model, calls to GetNext will
+ /// hang until there is new data available, it will not return an empty vector.
+ ///
+ /// - returns a vector of FormattedContent structs. Clients connected to a
+ /// Batch are expected to call GetNext() until an empty vector
+ /// is returned, denoting that the entire data hierarchy has been read.
+ ///
+ /// * error a [fuchsia.diagnostics/ReaderError]
+ /// value indicating that there was an issue reading the underlying data hierarchies
+ /// or formatting those hierarchies to populate the `batch`. Note, these
+ /// issues do not include a single component's data hierarchy failing to be read.
+ /// The iterator is tolerant of individual component data sources failing to be read,
+ /// whether that failure is a timeout or a malformed binary file.
+ /// In the event that a GetNext call fails, that subset of the data hierarchy results is
+ /// dropped, but future calls to GetNext will provide new subsets of
+ /// FormattedDataHierarchies.
+ ///
+ GetNext() -> (vector<FormattedContent>:MAXIMUM_ENTRIES_PER_BATCH batch) error ReaderError;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.diagnostics/selector.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.diagnostics/selector.fidl
new file mode 100644
index 0000000..882377d
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.diagnostics/selector.fidl
@@ -0,0 +1,139 @@
+// 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.
+library fuchsia.diagnostics;
+
+// The size bound of 100 is a reasonably low limit chosen based on observed
+// strings used as identifiers.
+const uint16 MAX_STRING_SELECTOR_LENGTH = 100;
+
+// The size bound of 25 is a reasonably low limit chosen based on observed
+// component hierarchy depths, and awareness of maximum zircon message sizes.
+const uint16 MAX_MONIKER_SEGMENTS = 25;
+
+// The size bound of 100 is a reasonably low limit chosen based on observed Inspect
+// hierarchy use cases.
+const uint16 MAX_DATA_HIERARCHY_DEPTH = 100;
+
+/// StringSelector is an union defining different ways to describe a pattern to match
+/// strings against.
+flexible union StringSelector {
+ /// This is a provided string that defines a pattern to
+ /// match against. The parser treats asterisks (*), colons (:) and backslashes
+ /// (\) as special characters.
+ ///
+ /// If you wish to match against literal asterisks (*), they must be escaped.
+ /// If you wish to match against literal backslashes (\), they must be escaped.
+ /// If you wish to match against literal colons (:), they must be escaped.
+ ///
+ /// eg: abc will match any string with the exact name "abc".
+ /// eg: a\* will match any string with the exact name "a*".
+ /// eg: a\\* will match any that starts with exactly "a\".
+ /// eg: a* will match any string that starts with "a".
+ /// eg: a*b will match any string that starts with a and ends with b.
+ /// eg: a*b*c will match any string that starts with a and ends with c, with `b`
+ /// in the middle.
+ 1: string:MAX_STRING_SELECTOR_LENGTH string_pattern;
+
+ /// This is a provided string that defines an exact string to match against. No
+ /// characters are treated as special, or carry special syntax.
+ 2: string:MAX_STRING_SELECTOR_LENGTH exact_match;
+};
+
+/// Specifies a pattern of component relative monikers which
+/// identify components being selected for.
+///
+/// Component selectors support wildcarding, which will glob a single "level" of a
+/// component moniker. eg:
+/// hub/*/echo.cmx
+/// will match all echo.cmx instances running only in realms directly under hub, but none
+/// nested further.
+table ComponentSelector {
+ /// Vector encoding the a pattern for monikers of components being selected for.
+ /// These monikers are child-monikers relative to a "root" hierarchy that the archivist
+ /// is aware of.
+ ///
+ /// There must be at least one StringSelector provided, which
+ /// specifies the component names that are matched by
+ /// the current selector.
+ 1: vector<StringSelector>:MAX_MONIKER_SEGMENTS moniker_segments;
+};
+
+/// A selector defining a set of nodes to match, for which the entire subtree including
+/// those nodes are selected.
+struct SubtreeSelector {
+ /// A vector of StringSelectors which serve as a pattern matcher
+ /// for paths through a hierarchy of named nodes. Each entry in the vector
+ /// is a selector for a single named node in a data hierarchy. The vector
+ /// of selectors for named nodes, then, defines a selector on paths through the
+ /// data hierarchy.
+ ///
+ /// Node paths support wildcarding, which will glob a single level of a
+ /// node hierarchy. eg:
+ /// root/a/b/*/d
+ /// will match all nodes named d which are below some child of node b.
+ /// root/a/b/c*
+ /// will match all nodes below b which start with the character "c".
+ vector<StringSelector>:MAX_DATA_HIERARCHY_DEPTH node_path;
+};
+
+/// A selector defining a set of nodes to match, and on those matched nodes a set of named
+/// propperties to match.
+struct PropertySelector {
+ /// A vector of StringSelectors which serve as a pattern matcher
+ /// for paths through a hierarchy of named nodes. Each entry in the vector
+ /// is a selector for a single named node in a data hierarchy. The vector
+ /// of selectors for named nodes, then, defines a selector on paths through the
+ /// data hierarchy.
+ ///
+ /// Node paths support wildcarding, which will glob a single level of a
+ /// node hierarchy. eg:
+ /// root/a/b/*/d
+ /// will match all nodes named d which are below some child of node b.
+ /// root/a/b/c*
+ /// will match all nodes below b which start with the character "c".
+ vector<StringSelector>:MAX_DATA_HIERARCHY_DEPTH node_path;
+
+ /// A StringSelector which serves as a pattern matcher for
+ /// string-named properties on a node in a data hierarchy.
+ ///
+ /// target_properties supports wildcarding, which will match against all properties
+ /// on any node matched by node_path.
+ StringSelector target_properties;
+};
+
+/// TreeSelector represents a selection request on a hierarchy of named nodes, with
+/// named properties on those nodes.
+flexible union TreeSelector {
+ /// A selector defining a set of nodes to match, for which the entire subtree including
+ /// those nodes are selected.
+ 1: SubtreeSelector subtree_selector;
+
+ /// A selector defining a set of nodes to match, and on those matched nodes a set of named
+ /// propperties to match.
+ 2: PropertySelector property_selector;
+};
+
+/// Structured selector containing all required information for pattern-matching onto
+/// string-named properties owned by nodes in a data hierarchy, where data hierarchies belong
+/// to specific components.
+///
+/// These selectors are represented in text form as three segments, colon delimited,
+/// specifying:
+/// <component_moniker>:<node_selector>:<property_selector>
+/// Examples:
+/// Property selection:
+/// realm1/realm2/echo.cmx:root/active_users:user_count
+///
+/// Subtree selection:
+/// realm1/realm2/echo.cmx:root/active_users
+table Selector {
+ /// The selector defining a pattern of component monikers to match
+ /// against.
+ 1: ComponentSelector component_selector;
+
+ /// The selector defining data hierarchy properties to match against
+ /// within the data hierarchies owned by components matched by
+ /// `component_selector`.
+ 2: TreeSelector tree_selector;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.factory/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.factory/BUILD.gn
new file mode 100644
index 0000000..b6d494d
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.factory/BUILD.gn
@@ -0,0 +1,26 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.factory") {
+ library_name = "factory"
+ namespace = "fuchsia"
+ public_deps = [
+ "../fuchsia.io",
+ ]
+ sources = [
+ "factory.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.factory",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.factory/factory.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.factory/factory.fidl
new file mode 100644
index 0000000..c6fd44a
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.factory/factory.fidl
@@ -0,0 +1,62 @@
+// 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.
+
+library fuchsia.factory;
+using fuchsia.io;
+
+// NOTE: This API will be completely removed when components v2 is implemented.
+// TODO(mbrunson): Add link to factory scaffolding library when available to
+// allow easier transition to components v2 for clients.
+
+/// This protocol is a base protocol for all providers of factory store
+/// directories. It exposes a single method to allow clients to establish a
+/// connection to a directory containing the relevant factory data. All files
+/// surfaced by a component that implements FactoryStoreProvider (or any
+/// protocol that depends on it) are expected to be validated for consistency
+/// before being exposed to clients.
+protocol FactoryStoreProvider {
+ GetFactoryStore(request<fuchsia.io.Directory> dir);
+};
+
+/// This protocol exposes a method to connect to a directory containing
+/// Cast-specific factory data: public certificates and keys for
+/// authentication with Cast servers.
+[Discoverable]
+protocol CastCredentialsFactoryStoreProvider {
+ compose FactoryStoreProvider;
+};
+
+/// This protocol exposes a method to connect to a directory containing
+/// Widevine-specific factory data: public certificates and keys for
+/// authentication with Widevine systems.
+[Discoverable]
+protocol WidevineFactoryStoreProvider {
+ compose FactoryStoreProvider;
+};
+
+/// This protocol exposes a method to connect to a directory containing
+/// PlayReady-specific factory data: public certificates and keys for
+/// authentication with PlayReady systems.
+[Discoverable]
+protocol PlayReadyFactoryStoreProvider {
+ compose FactoryStoreProvider;
+};
+
+/// This protocol exposes a method to connect to a directory containing
+/// Weave-specific factory data: public certificates, signing keys, and
+/// identity files for interoperation with a Weave-based home-area-network.
+[Discoverable]
+protocol WeaveFactoryStoreProvider {
+ compose FactoryStoreProvider;
+};
+
+/// This protocol exposes a method to connect to a directory containing
+/// miscellaneous factory data such as tuning/calibration files, region-specific
+/// audio files, factory process metadata files, and more. Any raw files not
+/// covered by other FactoryStoreProviders or methods in fuchsia.hwinfo will
+/// appear here.
+[Discoverable]
+protocol MiscFactoryStoreProvider {
+ compose FactoryStoreProvider;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.factory/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.factory/meta.json
new file mode 100644
index 0000000..0cd0e7b
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.factory/meta.json
@@ -0,0 +1,11 @@
+{
+ "deps": [
+ "fuchsia.io"
+ ],
+ "name": "fuchsia.factory",
+ "root": "fidl/fuchsia.factory",
+ "sources": [
+ "fidl/fuchsia.factory/factory.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.feedback/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.feedback/BUILD.gn
new file mode 100644
index 0000000..838dbbc
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.feedback/BUILD.gn
@@ -0,0 +1,32 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.feedback") {
+ library_name = "feedback"
+ namespace = "fuchsia"
+ public_deps = [
+ "../fuchsia.math",
+ "../fuchsia.mem",
+ ]
+ sources = [
+ "annotation.fidl",
+ "attachment.fidl",
+ "crash_reporter.fidl",
+ "data_provider.fidl",
+ "data_register.fidl",
+ "device_id_provider.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.feedback",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.feedback/annotation.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.feedback/annotation.fidl
new file mode 100644
index 0000000..00cd39c
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.feedback/annotation.fidl
@@ -0,0 +1,12 @@
+// 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.
+
+library fuchsia.feedback;
+
+/// An annotation and its plain ASCII string key.
+/// Annotations are short strings, e.g., the board name or the build version.
+struct Annotation {
+ string:128 key;
+ string:1024 value;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.feedback/attachment.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.feedback/attachment.fidl
new file mode 100644
index 0000000..d5d25fe
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.feedback/attachment.fidl
@@ -0,0 +1,14 @@
+// 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.
+
+library fuchsia.feedback;
+
+using fuchsia.mem;
+
+/// An attachment and its plain ASCII string key.
+/// Attachments are larger objects, e.g., log files. They may be binary or text data.
+struct Attachment {
+ string:128 key;
+ fuchsia.mem.Buffer value;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.feedback/crash_reporter.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.feedback/crash_reporter.fidl
new file mode 100644
index 0000000..9e517be
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.feedback/crash_reporter.fidl
@@ -0,0 +1,106 @@
+// 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.
+
+library fuchsia.feedback;
+
+using fuchsia.mem;
+using zx;
+
+/// Provides the ability to file crash reports.
+[Discoverable]
+protocol CrashReporter {
+ /// Files a crash `report`.
+ ///
+ /// This could mean generating a crash report in a local crash report database or uploading the
+ /// crash report to a remote crash server depending on the FIDL server's configuration.
+ File(CrashReport report) -> () error zx.status;
+};
+
+const uint32 MAX_PROGRAM_NAME_LENGTH = 1024;
+const uint32 MAX_NUM_ANNOTATIONS_PER_CRASH_REPORT = 32;
+const uint32 MAX_NUM_ATTACHMENTS_PER_CRASH_REPORT = 16;
+const uint32 MAX_EVENT_ID_LENGTH = 128;
+
+/// Represents a crash report.
+table CrashReport {
+ /// The name of the program that crashed, e.g., the process or component's name.
+ 1: string:MAX_PROGRAM_NAME_LENGTH program_name;
+
+ /// How long the program was running before it crashed.
+ 6: zx.duration program_uptime;
+
+ /// The specific report that depends on the type of crashes.
+ 2: SpecificCrashReport specific_report;
+
+ /// A vector of key-value string pairs representing arbitrary data that should be attached to a
+ /// crash report.
+ ///
+ /// Keys should be unique as only the latest value for a given key in the vector will be
+ /// considered.
+ 3: vector<Annotation>:MAX_NUM_ANNOTATIONS_PER_CRASH_REPORT annotations;
+
+ /// A vector of key-value string-to-VMO pairs representing arbitrary data that should be
+ /// attached to a crash report.
+ ///
+ /// Keys should be unique as only the latest value for a given key in the vector will be
+ /// considered.
+ 4: vector<Attachment>:MAX_NUM_ATTACHMENTS_PER_CRASH_REPORT attachments;
+
+ /// A text ID that the crash server can use to group multiple crash reports related to the
+ /// same event.
+ ///
+ /// Unlike the crash signature, crash reports sharing the same ID correspond to different
+ /// crashes, but can be considered as belonging to the same event, e.g., a crash in a low-level
+ /// server causing a crash in a high-level UI widget.
+ 5: string:MAX_EVENT_ID_LENGTH event_id;
+};
+
+/// Represents a specific crash report.
+///
+/// Add a new member when the server needs to special case how it handles certain annotations and
+/// attachments for a given type of crashes, e.g., a `RuntimeCrashReport` for Javascript.
+flexible union SpecificCrashReport {
+ /// Intended for arbitrary crashes, e.g., OOM, out-of-disk.
+ 1: GenericCrashReport generic;
+
+ /// Intended for a native exception.
+ 2: NativeCrashReport native;
+
+ /// Intended for a Dart exception.
+ 3: RuntimeCrashReport dart;
+};
+
+const uint32 MAX_CRASH_SIGNATURE_LENGTH = 128;
+
+/// Represents a generic crash report.
+table GenericCrashReport {
+ /// A text signature that the crash server can use to track the same crash over time, e.g.,
+ /// "kernel-panic" or "oom".
+ ///
+ /// Unlike the event ID, crash reports sharing the same signature correspond to the same crash,
+ /// but happening over multiple events, e.g., a null pointer exception in a server whenever
+ /// asked the same request.
+ 1: string:MAX_CRASH_SIGNATURE_LENGTH crash_signature;
+};
+
+/// Represents a crash report for a native exception out of which the client has built a minidump.
+table NativeCrashReport {
+ /// The core dump in the Minidump format.
+ 1: fuchsia.mem.Buffer minidump;
+};
+
+const uint32 MAX_EXCEPTION_TYPE_LENGTH = 128;
+const uint32 MAX_EXCEPTION_MESSAGE_LENGTH = 2048;
+
+/// Represents a crash report for a runtime exception, applicable to most languages.
+table RuntimeCrashReport {
+ /// The exception type, e.g., "FileSystemException".
+ 1: string:MAX_EXCEPTION_TYPE_LENGTH exception_type;
+
+ /// The exception message, e.g., "cannot open file".
+ 2: string:MAX_EXCEPTION_MESSAGE_LENGTH exception_message;
+
+ /// The text representation of the exception stack trace.
+ 3: fuchsia.mem.Buffer exception_stack_trace;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.feedback/data_provider.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.feedback/data_provider.fidl
new file mode 100644
index 0000000..d91a56f
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.feedback/data_provider.fidl
@@ -0,0 +1,64 @@
+// 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.
+
+library fuchsia.feedback;
+
+using fuchsia.math;
+using fuchsia.mem;
+using zx;
+
+/// Provides data useful to attach in feedback reports (crash, user feedback or bug reports).
+[Discoverable]
+protocol DataProvider {
+ /// Returns all the feedback data except the screenshot, which is provided
+ /// separately.
+ GetData() -> (Data data) error zx.status;
+
+ /// Returns an image of the current view encoded in the provided `encoding`.
+ ///
+ /// `screenshot` may be null if the encoding is not supported, the device
+ /// does not have a display, or there is not enough memory to allocate the
+ /// screenshot image.
+ ///
+ /// The screenshot is provided separately from the rest of the data as
+ /// callers might want to block on it before changing the view.
+ GetScreenshot(ImageEncoding encoding) -> (Screenshot? screenshot);
+};
+
+const uint32 MAX_NUM_ANNOTATIONS_PROVIDED = 64;
+
+/// Data to attach to feedback reports.
+///
+/// Clients typically upload the data straight to servers without expecting some
+/// particular fields. So the data comes in the form of arbitrary key-value pairs
+/// that clients can directly forward to the servers.
+table Data {
+ /// A vector of key-value string pairs. Keys are guaranteed to be unique.
+ 1: vector<Annotation>:MAX_NUM_ANNOTATIONS_PROVIDED annotations;
+
+ /// A bundle of Attachments objects stored as an Attachment itself, e.g., it
+ /// could be a ZIP archive bundling a vector of Attachment objects.
+ 3: Attachment attachment_bundle;
+
+ // Deprecated.
+ 2: reserved;
+};
+
+/// The encoding used for the image.
+///
+/// Today, only PNG is supported, but in the future the screenshot could be
+/// returned in other encodings if need arises.
+enum ImageEncoding {
+ PNG = 0;
+};
+
+/// An encoded image of the screen.
+struct Screenshot {
+ fuchsia.mem.Buffer image;
+
+ // While all encoded images contain their dimensions in their headers, some
+ // clients still expect to receive the width and height separately, so we
+ // also provide it separately so clients don't need to decode `image`.
+ fuchsia.math.Size dimensions_in_px;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.feedback/data_register.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.feedback/data_register.fidl
new file mode 100644
index 0000000..1944ebf
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.feedback/data_register.fidl
@@ -0,0 +1,89 @@
+// Copyright 2020 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.
+
+library fuchsia.feedback;
+
+/// Registers data useful to attach in feedback reports (crash, user feedback or bug reports).
+///
+/// This can be used by components to augment the data attached to all feedback reports. By default
+/// the Feedback service attaches data exposed to the platform. This protocol is useful for data
+/// known by certain components in certain products, but that is not exposed to the platform.
+///
+/// The epitaph ZX_ERR_INVALID_ARGS indicates that the client is sending invalid requests. See
+/// below for each request why they might be invalid.
+///
+/// The epitaph ZX_ERR_NO_RESOURCES indicates that the server can no longer store additional
+/// component data and will not service new connections.
+[Discoverable]
+protocol ComponentDataRegister {
+ /// Updates or inserts extra component data to be included in feedback reports.
+ ///
+ /// The namespace and each annotation key are used to decide whether to update or insert an
+ /// annotation. If an annotation is already present for a given key within the same namespace,
+ /// update the value, otherwise insert the annotation with that key under that namespace.
+ ///
+ /// For instance, assuming these are the data already held by the server (from previous calls
+ /// to Upsert()):
+ /// {
+ /// "bar": { # namespace
+ /// "channel": "stable",
+ /// },
+ /// "foo": { # namespace
+ /// "version": "0.2",
+ /// },
+ /// }
+ ///
+ /// then Upsert({
+ /// "namespace": "bar",
+ /// "annotations": [
+ /// "version": "1.2.3.45",
+ /// "channel": "beta",
+ /// ]
+ /// }) would result in the server now holding:
+ /// {
+ /// "bar": { # namespace
+ /// "channel": "beta", # updated
+ /// "version": "1.2.3.45" # inserted
+ /// },
+ /// "foo": { # namespace
+ /// "version": "0.2", # untouched
+ /// },
+ /// }
+ ///
+ /// Note that the server will only hold at most MAX_NUM_ANNOTATIONS_PER_NAMESPACE distinct
+ /// annotation keys per namespace, picking up the latest values.
+ Upsert(ComponentData data) -> ();
+};
+
+const uint32 MAX_NAMESPACE_LENGTH = 32;
+const uint32 MAX_NUM_ANNOTATIONS_PER_NAMESPACE = 16;
+
+/// Data known to a component, but not exposed to the platform, to attach to feedback reports.
+table ComponentData {
+ /// The top-level namespace associated with the data:
+ /// * Is intended to group related data together and reduce data key collisions across
+ /// namespaces.
+ /// * May be shared by multiple clients, e.g., there could be multiple clients within the same
+ /// component or across components that want to expose related data and they would all use
+ /// the same namespace.
+ /// * Will be prefixed to every data key passed within that namespace in all feedback reports,
+ /// e.g., the annotation "version" would appear as "foo.version" in all feedback reports if
+ /// the namespace is "foo".
+ /// * Must match [a-z\-]+, i.e. only lowercase letters and hyphens or this will result in a
+ /// ZX_ERR_INVALID_ARGS epitaph.
+ /// * Must not match a reserved namespace used internally for platform data, e.g., "build", or
+ /// this will result in a ZX_ERR_INVALID_ARGS epitaph. The list of reserved namespaces is
+ /// internal and subject to change for now.
+ 1: string:MAX_NAMESPACE_LENGTH namespace;
+
+ /// A vector of key-value string pairs, e.g., `<"version", "1.2.3.45">`.
+ ///
+ /// Keys:
+ /// * Should be unique as only the latest value for a given key in the vector will be
+ /// considered.
+ /// * Must match [a-z\-\.]+, i.e. only lowercase letters, hyphens and periods. Use periods for
+ /// sub-namespacing, e.g., "build.label" and "build.type", so that related annotations are
+ /// grouped together (here related to "build") when sorted lexicographically.
+ 2: vector<Annotation>:MAX_NUM_ANNOTATIONS_PER_NAMESPACE annotations;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.feedback/device_id_provider.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.feedback/device_id_provider.fidl
new file mode 100644
index 0000000..77c108e
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.feedback/device_id_provider.fidl
@@ -0,0 +1,22 @@
+// 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.
+
+library fuchsia.feedback;
+
+/// Provides the device's feedback ID.
+///
+/// The feedback ID is a persisted UUID used to group feedback reports. The ID
+/// is not intended to be used for any reporting purposes other than feedback,
+/// e.g., not intended to be used for telemetry.
+[Discoverable]
+protocol DeviceIdProvider {
+ /// Returns the device's feedback ID.
+ GetId() -> (string:64 feedback_id) error DeviceIdError;
+};
+
+/// The DeviceIdError values are returned in the following circumstances:
+/// * NOT_FOUND - a valid feedback id was not found by the server.
+enum DeviceIdError {
+ NOT_FOUND = 1;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.feedback/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.feedback/meta.json
new file mode 100644
index 0000000..e9e8b63
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.feedback/meta.json
@@ -0,0 +1,17 @@
+{
+ "deps": [
+ "fuchsia.math",
+ "fuchsia.mem"
+ ],
+ "name": "fuchsia.feedback",
+ "root": "fidl/fuchsia.feedback",
+ "sources": [
+ "fidl/fuchsia.feedback/annotation.fidl",
+ "fidl/fuchsia.feedback/attachment.fidl",
+ "fidl/fuchsia.feedback/crash_reporter.fidl",
+ "fidl/fuchsia.feedback/data_provider.fidl",
+ "fidl/fuchsia.feedback/data_register.fidl",
+ "fidl/fuchsia.feedback/device_id_provider.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.fonts/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.fonts/BUILD.gn
new file mode 100644
index 0000000..6f19387
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.fonts/BUILD.gn
@@ -0,0 +1,30 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.fonts") {
+ library_name = "fonts"
+ namespace = "fuchsia"
+ public_deps = [
+ "../fuchsia.intl",
+ "../fuchsia.mem",
+ ]
+ sources = [
+ "events.fidl",
+ "font_provider.fidl",
+ "provider.fidl",
+ "styles.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.fonts",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.fonts/events.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.fonts/events.fidl
new file mode 100644
index 0000000..867540b
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.fonts/events.fidl
@@ -0,0 +1,25 @@
+// 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.
+
+library fuchsia.fonts;
+
+/// Protocol for listening to possible events that may occur in the `Provider`'s set of fonts.
+///
+/// Register a listener using [`fuchsia.fonts/Provider.RegisterFontSetEventListener`].
+protocol FontSetEventListener {
+ /// The set of fonts available in the `Provider` has changed. See
+ /// [`fuchsia.fonts/FontSetUpdatedEvent`].
+ OnFontSetUpdated(FontSetUpdatedEvent event) -> ();
+
+ // A future addition might include an event that is triggered when the user changes the mapping
+ // for generic font families (e.g. configuring "monospace" to default to "Inconsolata" instead of
+ // "Roboto Mono").
+};
+
+/// An event indicating that the set of fonts available in the `Provider` has changed. This is most
+/// frequently caused by an ephemeral font being downloaded and cached. Clients should consider
+/// re-requesting fonts and re-rendering any displayed text.
+table FontSetUpdatedEvent {
+ // No fields at the moment.
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.fonts/font_provider.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.fonts/font_provider.fidl
new file mode 100644
index 0000000..c16a832
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.fonts/font_provider.fidl
@@ -0,0 +1,142 @@
+// Copyright 2016 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.
+
+// NOTE: This file is deprecated and will soon be removed in favor of provider.fidl.
+
+library fuchsia.fonts;
+
+using fuchsia.mem;
+
+/// Deprecated. See `GenericFontFamily`.
+[Transitional]
+enum FallbackGroup {
+ NONE = 0;
+ SERIF = 1;
+ SANS_SERIF = 2;
+ MONOSPACE = 3;
+ CURSIVE = 4;
+ FANTASY = 5;
+};
+
+/// Deprecated. See `FaceRequestFlags`.
+/// Disables font fallback. The service won't try to search fallback font set if
+/// there is no requested font family or if it doesn't contain requested
+/// character.
+const uint32 REQUEST_FLAG_NO_FALLBACK = 1;
+
+/// Deprecated. See `FaceRequestFlags`.
+/// Disables approximate style matching. The service will only return font that
+/// matches the requested style exactly.
+const uint32 REQUEST_FLAG_EXACT_MATCH = 2;
+
+/// Deprecated. See `FaceRequest`.
+struct Request {
+ /// Desired font family name, e.g. "Roboto". Font family search is
+ /// case-insensitive. In case when there is no specified family or the
+ /// specified family doesn't have glyph for the requested `character` then
+ /// a font from another family may be returned. This behavior can be disabled
+ /// using `REQUEST_FLAG_NO_FALLBACK`.
+ string:MAX_FAMILY_NAME_LENGTH? family;
+
+ /// For example, 400 is normal, 700 is bold.
+ uint32 weight = 400;
+
+ /// Numeric values matching OS/2 & Windows Metrics usWidthClass table.
+ /// https://www.microsoft.com/typography/otspec/os2.htm
+ /// For example, 5 is normal.
+ uint32 width = 5;
+
+ Slant slant = Slant.UPRIGHT;
+
+ /// BCP47 language tags in order of preference. See
+ /// https://tools.ietf.org/html/bcp47 .
+ vector<string:35>:8? language;
+
+ /// Codepoint for the character that must be present in the returned font or 0.
+ /// Caller that specify this field are expected to extract character set from
+ /// the result and cache it in order to avoid calling the API more than
+ /// necessary.
+ uint32 character = 0;
+
+ /// Fallback group preference. Caller can leave this field set to NONE. In
+ /// that case the font provider will use fallback group of the specified font
+ /// family.
+ FallbackGroup fallback_group = FallbackGroup.NONE;
+
+ uint32 flags = 0;
+};
+
+struct Response {
+ fuchsia.mem.Buffer buffer;
+
+ /// Buffer identifier for the buffer. Responses with the same buffer_id are
+ /// guaranteed to contain the same data in the buffer. Clients may use this
+ /// value to detect if they already have the font cached in parsed form.
+ uint32 buffer_id;
+
+ /// Font index within `buffer`. Used for font formats that may contain more
+ /// than one font per file, e.g. TTC (TrueType Collection).
+ uint32 font_index;
+};
+
+/// Deprecated.
+/// See `Style2`.
+struct Style {
+ uint32 weight;
+ uint32 width;
+ Slant slant;
+};
+
+/// Deprecated. See `FontFamilyInfo`.
+///
+/// Information about font family that can be requested using GetFamilyInfo().
+struct FamilyInfo {
+ /// Canonical font family name. Note that this may be different from the
+ /// value passed to GetFamilyInfo() because GetFamilyInfo() also resolves
+ /// font aliases and ignores case. For example GetFamilyInfo("robotoslab")
+ /// will FamilyInfo.name = "Robot Slab".
+ string:MAX_FAMILY_NAME_LENGTH name;
+
+ /// Unordered list of all available styles in the family.
+ vector<Style>:MAX_FAMILY_STYLES styles;
+};
+
+/// Provider of digital font files and metadata.
+///
+/// TODO(I18N-12): Remove deprecated methods and move to provider.fidl.
+[Discoverable]
+protocol Provider {
+
+ /// Deprecated. See `GetTypeface`.
+ ///
+ /// Returns font that matches specified `request`.
+ GetFont(Request request) -> (Response? response);
+
+ /// Deprecated. See `GetFontFamilyInfo`.
+ ///
+ /// Returns information for the specified font family or null if there is
+ /// no family with the specified name. This function respects family name
+ /// aliases and ignores case, so request for "robotoSLAB" will return
+ /// FamilyInfo for "Roboto Slab".
+ GetFamilyInfo(string:MAX_FAMILY_NAME_LENGTH family) -> (FamilyInfo? family_info);
+
+ /// Returns a typeface that matches the specified `request`, or an empty table if no matching
+ /// face is found. (The latter is more likely to happen if `TypefaceRequestFlags.EXACT_FAMILY`
+ /// is used to disable fallbacks.)
+ GetTypeface(TypefaceRequest request) -> (TypefaceResponse response);
+
+ /// Returns information for the specified font family, or an empty table if there is no family
+ /// with the specified name.
+ ///
+ /// This function respects family name aliases and ignores case. For example, "RobotoSlab" is an
+ /// alias for the canonical name "Roboto Slab". A request for "robotoSLAB" would return the
+ /// `FontFamilyInfo` for "Roboto Slab" due to the case-insensitivity and alias resolution.
+ GetFontFamilyInfo(FamilyName family) -> (FontFamilyInfo family_info);
+
+ /// Register a listener to be notified when the set of available fonts or mappings has changed.
+ /// A client can register as many listeners as it wishes.
+ ///
+ /// To unregister, close the channel.
+ RegisterFontSetEventListener(FontSetEventListener listener) -> ();
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.fonts/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.fonts/meta.json
new file mode 100644
index 0000000..96fb6a1
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.fonts/meta.json
@@ -0,0 +1,15 @@
+{
+ "deps": [
+ "fuchsia.intl",
+ "fuchsia.mem"
+ ],
+ "name": "fuchsia.fonts",
+ "root": "fidl/fuchsia.fonts",
+ "sources": [
+ "fidl/fuchsia.fonts/events.fidl",
+ "fidl/fuchsia.fonts/font_provider.fidl",
+ "fidl/fuchsia.fonts/provider.fidl",
+ "fidl/fuchsia.fonts/styles.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.fonts/provider.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.fonts/provider.fidl
new file mode 100644
index 0000000..339f280
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.fonts/provider.fidl
@@ -0,0 +1,154 @@
+// 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.
+
+library fuchsia.fonts;
+
+using fuchsia.intl;
+using fuchsia.mem;
+
+/// The maximum length of a font family name.
+const uint32 MAX_FAMILY_NAME_LENGTH = 128;
+
+/// The maximum number of code points allowed in a typeface query.
+const uint32 MAX_FACE_QUERY_CODE_POINTS = 128;
+
+/// The maximum number of preferred languages allowed in a typeface query.
+const uint32 MAX_FACE_QUERY_LANGUAGES = 8;
+
+/// The maximum number of styles that will be returned for a font family.
+const uint32 MAX_FAMILY_STYLES = 300;
+
+/// The name of a family of fonts.
+///
+/// Examples: "Roboto", "Noto Serif".
+struct FamilyName {
+ /// The characters that make up the name.
+ string:MAX_FAMILY_NAME_LENGTH name;
+};
+
+/// Boolean flags for `TypefaceRequest`.
+bits TypefaceRequestFlags : uint32 {
+ /// Disables font family fallback. The service won't try to search the fallback font set if the
+ /// requested font family doesn't exist or if it doesn't contain the requested code point.
+ EXACT_FAMILY = 0x00000001;
+
+ /// Disables approximate style matching. The service will only return a face that matches the
+ /// requested style exactly. For example, there will be no substitutions of "medium" for a
+ /// requested "semi-bold" weight, or "oblique" for a requested "italic" slant.
+ EXACT_STYLE = 0x00000002;
+};
+
+/// Options for what the font server should do if the client requests a typeface that is not yet
+/// cached.
+enum CacheMissPolicy {
+ /// The server will attempt to load the uncached typeface before providing a response. This is
+ /// the *default* behavior.
+ ///
+ /// This option is not recommended for synchronous clients that block rendering while waiting
+ /// for a font.
+ BLOCK_UNTIL_DOWNLOADED = 1;
+
+ /// The server will tell the client that the uncached typeface is unavailable, by returning an
+ /// empty [`fuchsia.fonts/TypefaceResponse`]. The uncached typeface may be downloaded
+ /// asynchronously to be available for future requests.
+ ///
+ /// This is similar to `font-display: block` in CSS.
+ RETURN_EMPTY_RESPONSE = 2;
+
+ /// The server will attempt to provide a cached fallback typeface (if allowed by the fallback
+ /// restrictions in [`fuchsia.fonts/TypefaceRequestFlags`]). The uncached typeface may be
+ /// downloaded asynchronously to be available for future requests.
+ ///
+ /// This is similar to `font-display: swap` in CSS.
+ RETURN_FALLBACK = 3;
+};
+
+/// Parameters for requesting a typeface.
+table TypefaceRequest {
+ /// Parameters for looking up a typeface.
+ 1: TypefaceQuery query;
+
+ /// Flags for how to process the request, such as which kinds of substitutions are permitted.
+ 2: TypefaceRequestFlags flags;
+
+ /// Setting for what to do if the requested typeface exists but is not cached, and therefore
+ /// cannot be served immediately.
+ ///
+ /// If this field is empty, the default policy is
+ /// [`fuchsia.fonts/CacheMissPolicy.BLOCK_UNTIL_DOWNLOADED`].
+ ///
+ /// If the client needs an immediate response, it can choose one of the non-blocking policies.
+ /// In this case, clients can also register to be notified when new fonts have been added to the
+ /// cache by calling [`fuchsia.fonts/Provider.RegisterFontSetEventListener`].
+ 3: CacheMissPolicy cache_miss_policy;
+};
+
+/// Parameters for looking up a typeface.
+table TypefaceQuery {
+ /// Desired font family name, e.g. "Roboto". Font family search is case-insensitive.
+ ///
+ /// Note: In cases where the specified family doesn't exist, or the specified family doesn't
+ /// have a glyph for the requested `code_point`, a face from another family may be returned.
+ /// This behavior can be disabled using `TypefaceRequestFlags.EXACT_FAMILY`.
+ 1: FamilyName family;
+
+ /// Style properties of the desired typeface.
+ 2: Style2 style;
+
+ /// Language tags in order of preference. This allows disambiguating code points that map
+ /// to different glyphs in different languages (e.g. CJK code points).
+ ///
+ /// See `fuchsia.intl.LocaleId`.
+ 3: vector<fuchsia.intl.LocaleId>:MAX_FACE_QUERY_LANGUAGES languages;
+
+ /// Optional code points for which glyphs must be present in the returned face.
+ ///
+ /// Callers that specify this field are expected to extract the character set from the result
+ /// and cache it in order to avoid calling the API more than necessary.
+ 4: vector<uint32>:MAX_FACE_QUERY_CODE_POINTS code_points;
+
+ /// A generic font family to fall back to if an exact match is unavailable or does not contain
+ /// the requested code point.
+ ///
+ /// Every font family belongs to a generic family (configured in the font manifest). If a
+ /// particular font family doesn't contain a requested code point, the provider can search for
+ /// the code point in other font families _in the same generic family_ as a fallback.
+ ///
+ /// Specifying `fallback_family` in a query allows the client to override the generic family
+ /// that would be used as a fallback.
+ 5: GenericFontFamily fallback_family;
+};
+
+/// Response to a TypefaceRequest. Contains the digital font file and metadata corresponding to a
+/// returned typeface. Clients are expected to cache the results if they plan to reuse them.
+///
+/// If a matching typeface cannot be found, the table will be empty.
+table TypefaceResponse {
+ /// A memory buffer containing the bytes of a digital font file.
+ /// It is the client's responsibility to identify the type of file and to parse it (usually by
+ /// delegating to FreeType or a similar library).
+ 1: fuchsia.mem.Buffer buffer;
+
+ /// Identifier for the buffer. Responses with the same `buffer_id` are guaranteed to contain the
+ /// same data in the buffer. Clients may use this value to detect if they already have the font
+ /// cached in parsed form.
+ 2: uint32 buffer_id;
+
+ /// Index of the returned typeface within `buffer`. Used for digital font formats that may
+ /// contain more than one typeface per file, e.g. TTC (TrueType Collection).
+ 3: uint32 font_index;
+};
+
+/// Information about a font family that can be requested using `Provider.GetFontFamilyInfo()`.
+///
+/// If a matching font family is not found, the table will be empty.
+table FontFamilyInfo {
+ /// Canonical font family name. Note that this may be different from the value passed to
+ /// `GetFontFamilyInfo()` due to the resolution of font aliases, and/or differences in
+ /// whitespace and capitalization.
+ 1: FamilyName name;
+
+ /// Unordered list of all available styles in the family.
+ 2: vector<Style2>:MAX_FAMILY_STYLES styles;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.fonts/styles.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.fonts/styles.fidl
new file mode 100644
index 0000000..ab2b916
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.fonts/styles.fidl
@@ -0,0 +1,126 @@
+// 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.
+
+library fuchsia.fonts;
+
+using Weight = uint16;
+
+// Commonly used constants for font weight.
+const Weight WEIGHT_THIN = 100;
+const Weight WEIGHT_EXTRA_LIGHT = 200;
+const Weight WEIGHT_LIGHT = 300;
+const Weight WEIGHT_NORMAL = 400;
+const Weight WEIGHT_MEDIUM = 500;
+const Weight WEIGHT_SEMI_BOLD = 600;
+const Weight WEIGHT_BOLD = 700;
+const Weight WEIGHT_EXTRA_BOLD = 800;
+const Weight WEIGHT_BLACK = 900;
+
+/// The type of slant of a type face.
+enum Slant {
+ /// The default; upright glyphs.
+ UPRIGHT = 1;
+ /// Specially designed, slanted and slightly calligraphic glyphs.
+ ITALIC = 2;
+ /// Skewed glyphs. Oblique usually means an geometric transformation of the upright variant,
+ /// rather than a custom-designed variant.
+ OBLIQUE = 3;
+};
+
+/// Horizontal width class of the glyphs.
+///
+/// See https://docs.microsoft.com/en-us/typography/opentype/spec/os2#uswidthclass.
+enum Width {
+ /// 50% of normal width
+ ULTRA_CONDENSED = 1;
+ /// 62.5% of normal width
+ EXTRA_CONDENSED = 2;
+ /// 75% of normal width
+ CONDENSED = 3;
+ /// 87.5% of normal width
+ SEMI_CONDENSED = 4;
+ /// Normal width
+ NORMAL = 5;
+ /// 112.5% of normal width
+ SEMI_EXPANDED = 6;
+ /// 125% of normal width
+ EXPANDED = 7;
+ /// 150% of normal width
+ EXTRA_EXPANDED = 8;
+ /// 200% of normal width
+ ULTRA_EXPANDED = 9;
+};
+
+/// Default weight of a typeface when none is specified.
+const Weight DEFAULT_WEIGHT = WEIGHT_NORMAL;
+
+/// Default slant of a typeface when none is specified.
+const Slant DEFAULT_SLANT = Slant.UPRIGHT;
+
+/// Default width of a typeface when none is specified.
+const Width DEFAULT_WIDTH = Width.NORMAL;
+
+/// Style properties that can be used when requesting or describing a type face.
+table Style2 {
+ /// See `Slant`.
+ 1: Slant slant;
+ /// Weight or thickness of the glyphs. Allowed values are integers in the range [1, 1000], but
+ /// most real-world font families only support some integer multiples of 100:
+ /// {100, 200, ..., 900}. Normal text (`WEIGHT_NORMAL`) is 400; `WEIGHT_BOLD` is 700.
+ ///
+ /// See:
+ /// https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight#Common_weight_name_mapping
+ /// https://docs.microsoft.com/en-us/typography/opentype/spec/os2#usweightclass
+ 2: Weight weight;
+ /// See `Width`.
+ 3: Width width;
+};
+
+/// Generic groups of font families that can serve as fallbacks for a specific family.
+///
+/// Every font family belongs to some _generic_ font family (see examples below).
+///
+/// If an exact requested family is unavailable but a fallback group is specified in the request,
+/// the provider may return some other family that belongs to the fallback group. For example, if
+/// the client requests the "Arial" family with a `SANS_SERIF` fallback, and "Arial" is unavailable,
+/// the provider may return another available sans serif family, such as "Roboto Regular", instead.
+///
+/// See also:
+/// https://www.w3.org/TR/css-fonts-4/#generic-font-families
+enum GenericFontFamily {
+ /// Glyphs have little "serifs", hooks, or notches at the ends of most strokes.
+ /// Examples: Georgia, Noto Serif, Times New Roman.
+ SERIF = 1;
+ /// Glyphs that have no serifs at the ends of most strokes.
+ /// Examples: Arial, Noto Sans, Roboto, Tahoma.
+ SANS_SERIF = 2;
+ /// Fixed-width fonts.
+ /// Examples: Consolas, Courier New, Inconsolata.
+ MONOSPACE = 3;
+ /// Handwritten or cursive fonts.
+ /// Examples: Brush Script, Comic Sans, Lucida Calligraphy.
+ CURSIVE = 4;
+ /// Decorative fonts.
+ /// Examples: Impact, Papyrus.
+ FANTASY = 5;
+ /// The default user interface font on the target platform.
+ /// This is included for completeness with the CSS specification; font manifests should not
+ /// declare that a font belongs to the `SYSTEM_UI` generic family, but instead should declare a
+ /// more specific option (e.g. `SERIF` for Roboto).
+ ///
+ /// Not commonly used.
+ SYSTEM_UI = 6;
+ /// Fonts that are used specifically for rendering emoji code points.
+ /// Examples: Noto Color Emoji.
+ EMOJI = 7;
+ /// Fonts that are used primarily for rendering mathematical expressions.
+ ///
+ /// Not commonly used.
+ MATH = 8;
+ /// A group of Chinese fonts between serif and cursive, often used for official Chinese
+ /// Government documents.
+ ///
+ /// Not commonly used.
+ FANGSONG = 9;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.hardware.ethernet/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.hardware.ethernet/BUILD.gn
new file mode 100644
index 0000000..411b982
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.hardware.ethernet/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.hardware.ethernet") {
+ library_name = "ethernet"
+ namespace = "fuchsia.hardware"
+ public_deps = [
+ ]
+ sources = [
+ "ethernet.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.hardware.ethernet",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.hardware.ethernet/ethernet.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.hardware.ethernet/ethernet.fidl
new file mode 100644
index 0000000..8b038b7
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.hardware.ethernet/ethernet.fidl
@@ -0,0 +1,113 @@
+// Copyright 2018 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.
+
+library fuchsia.hardware.ethernet;
+
+using zx;
+
+struct MacAddress {
+ array<uint8>:6 octets;
+};
+
+// Info.features bits
+const uint32 INFO_FEATURE_WLAN = 0x00000001;
+const uint32 INFO_FEATURE_SYNTH = 0x00000002;
+const uint32 INFO_FEATURE_LOOPBACK = 0x00000004;
+
+struct Info {
+ uint32 features;
+ uint32 mtu;
+ MacAddress mac;
+};
+
+struct Fifos {
+ // handles for the rx and tx fifo
+ handle<fifo> rx;
+ handle<fifo> tx;
+
+ // maximum number of items in rx and tx fifo
+ uint32 rx_depth;
+ uint32 tx_depth;
+};
+
+/// Signal that is asserted on the RX fifo whenever the Device has a status
+/// change. This is ZX_USER_SIGNAL_0.
+// TODO(teisenbe/kulakowski): find a better way to represent this
+const uint32 SIGNAL_STATUS = 0x01000000;
+
+// device_status bits
+const uint32 DEVICE_STATUS_ONLINE = 0x00000001;
+
+/// Max client name length
+const uint32 MAX_CLIENT_NAME_LEN = 15;
+
+/// For compatibility with a past revision, allow one extra byte for an optional
+/// null-terminator.
+const uint32 SET_CLIENT_NAME_MAX_LEN = 16;
+
+/// Operation
+///
+/// Packets are transmitted by writing data into the IO buffer and writing
+/// a FifoEntry referencing that data (offset + length) into the tx fifo.
+/// When the driver is done accessing the data, a FifoEntry with the same
+/// cookie value (opaque to the driver) will be readable from the tx fifo.
+///
+/// Packets are received by writing a FifoEntry referencing an available
+/// buffer (offset + length) in the IO buffer. When a packet is received,
+/// a FifoEntry with the same cookie value (opaque to the driver) will be
+/// readable from the rx fifo. The offset field will be the same as was
+/// sent. The length field will reflect the actual size of the received
+/// packet. The flags field will indicate success or a specific failure
+/// condition.
+///
+/// IMPORTANT: The driver *will not* buffer response messages. It is the
+/// client's responsibility to ensure that there is space in the reply side
+/// of each fifo for each outstanding tx or rx request. The fifo sizes
+/// are returned along with the fifo handles from GetFifos().
+///
+/// See //zircon/system/public/zircon/device/ethernet.h for fifo entry layout
+/// and request / response message bits.
+[Layout = "Simple"]
+protocol Device {
+ /// Obtain information about device
+ GetInfo() -> (Info info);
+
+ /// Obtain a pair of fifos for queueing tx and rx operations
+ GetFifos() -> (zx.status status, Fifos? info);
+
+ /// Set the IO Buffer that will provide the data buffers for tx and rx operations
+ SetIOBuffer(handle<vmo> h) -> (zx.status status);
+
+ /// Start transferring packets
+ /// Start will not succeed (ZX_ERR_BAD_STATE) until the fifos have been
+ /// obtained and an io buffer vmo has been registered.
+ Start() -> (zx.status status);
+
+ /// Stop transferring packets
+ Stop() -> ();
+
+ /// Start listening to the packets that we're transmitting
+ /// as well as the packets we're receiving.
+ ListenStart() -> (zx.status status);
+
+ /// Stop listening to the packets that we're transmitting.
+ ListenStop() -> ();
+
+ SetClientName(string:SET_CLIENT_NAME_MAX_LEN name) -> (zx.status status);
+
+ /// Obtain the device status bits
+ /// When these change, the signal SIGNAL_STATUS is asserted on the rx fifo.
+ /// When these are read, the signal is deasserted.
+ GetStatus() -> (uint32 device_status);
+
+ SetPromiscuousMode(bool enabled) -> (zx.status status);
+
+ ConfigMulticastAddMac(MacAddress addr) -> (zx.status status);
+ ConfigMulticastDeleteMac(MacAddress addr) -> (zx.status status);
+ ConfigMulticastSetPromiscuousMode(bool enabled) -> (zx.status status);
+
+ // TODO(teisenbe): We should probably remove these? They are only used for testing.
+ ConfigMulticastTestFilter() -> (zx.status status);
+ DumpRegisters() -> (zx.status status);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.hardware.ethernet/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.hardware.ethernet/meta.json
new file mode 100644
index 0000000..7736638
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.hardware.ethernet/meta.json
@@ -0,0 +1,9 @@
+{
+ "deps": [],
+ "name": "fuchsia.hardware.ethernet",
+ "root": "fidl/fuchsia.hardware.ethernet",
+ "sources": [
+ "fidl/fuchsia.hardware.ethernet/ethernet.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.hardware.goldfish/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.hardware.goldfish/BUILD.gn
new file mode 100644
index 0000000..840c9d2
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.hardware.goldfish/BUILD.gn
@@ -0,0 +1,27 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.hardware.goldfish") {
+ library_name = "goldfish"
+ namespace = "fuchsia.hardware"
+ public_deps = [
+ ]
+ sources = [
+ "goldfish_address_space.fidl",
+ "goldfish_control.fidl",
+ "goldfish_pipe.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.hardware.goldfish",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.hardware.goldfish/goldfish_address_space.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.hardware.goldfish/goldfish_address_space.fidl
new file mode 100644
index 0000000..3be17e7
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.hardware.goldfish/goldfish_address_space.fidl
@@ -0,0 +1,95 @@
+// 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.
+
+library fuchsia.hardware.goldfish;
+
+using zx;
+
+// Interface for the Goldfish address space driver.
+
+enum AddressSpaceChildDriverType : uint32 {
+ /// The DEFAULT child driver type is for graphics.
+ DEFAULT = 0;
+};
+
+// State
+// The driver consists of three main pieces of state:
+
+// 1. A PCI BAR that clients can suballocate into. This is used for mapping
+// coherent memory from the hardware, such as for Vulkan HOST_COHERENT
+// memory, or for any other buffer owned by the hardware such as video
+// codec buffers. This also includes a mapping where each connection of the
+// driver is associated with one or more mappings.
+
+// The next two pieces of state are for child driver connections.
+
+// 2. A set of context handles, one per driver connection that the client
+// establishes. This is used to support higher-level/VMM-defined (child)
+// drivers. Each such driver is considered a "child" driver of goldfish address
+// space.
+
+// 3. A set of command pages, one per connection. This is used as a shared
+// device/host memory to support the "Ping" command. The "Ping" command is used
+// to run the child driver logic, driven by the app. There is a protocol to
+// permanently associate a particular goldfish address space driver connection
+// with a particular type of child driver, discussed next.
+
+[Layout = "Simple"]
+protocol AddressSpaceDevice {
+ OpenChildDriver(AddressSpaceChildDriverType type, request<AddressSpaceChildDriver> req);
+};
+
+// Child driver protocol
+
+// By default, creating connection to the driver does not associate any child
+// driver with the connection.
+
+// The client opens a child driver via OpenChildDriver, giving the type of the
+// driver as an argument along with a request for the connection. The type of
+// the driver is a number and the number/drivertype mapping is
+// determined/maintained in:
+// https://android.googlesource.com/platform/external/qemu/+/refs/heads/emu-master-dev/android/android-emu/android/emulation/AddressSpaceService.h
+// In Fuchsia, we currently only support the DEFAULT type, which is used for
+// graphics.
+
+/// After opening the child driver, the client and hardware communicate via a
+/// child driver-specific protocol, with notifications driven by
+/// Ping(), each of which writes and reads messages to the hardware
+/// that follow this AddressSpaceChildDriverPingMessage struct.
+/// Each child driver type will have its own semantics for each field.
+/// It's common for child drivers to refer to offset/size plus a metadata
+/// field. We also provide extra data fields for other use cases in
+/// particular child drivers.
+struct AddressSpaceChildDriverPingMessage {
+ uint64 offset;
+ uint64 size;
+ uint64 metadata;
+ uint64 data0;
+ uint64 data1;
+ uint32 data2;
+ uint32 data3;
+};
+
+[Layout = "Simple"]
+protocol AddressSpaceChildDriver {
+ // Allocates goldfish address space of given size.
+ AllocateBlock(uint64 size) -> (zx.status res, uint64 paddr, handle<vmo>? vmo);
+ // Free goldfish address space associated with given ID.
+ DeallocateBlock(uint64 paddr) -> (zx.status res);
+
+ // Claim a region at [offset, offset + size) that is a subregion of a
+ // larger region managed by hardware. It is possible to share the same
+ // regions across different connections, but within a connection, we
+ // require the claimed regions to be disjoint. Otherwise, ZX_ERROR_INVALID_ARGS
+ // is returned.
+ ClaimSharedBlock(uint64 offset, uint64 size) -> (zx.status res, handle<vmo>? vmo);
+
+ // Unclaim a hardware-shared region. This must correspond to an existing claimed
+ // region in the current connection. Otherwise, ZX_ERROR_INVALID_ARGS is returned.
+ UnclaimSharedBlock(uint64 offset) -> (zx.status res);
+
+ // Ping (General notification for child drivers)
+ Ping(AddressSpaceChildDriverPingMessage ping)
+ -> (zx.status res, AddressSpaceChildDriverPingMessage ping);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.hardware.goldfish/goldfish_control.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.hardware.goldfish/goldfish_control.fidl
new file mode 100644
index 0000000..2e7c39b
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.hardware.goldfish/goldfish_control.fidl
@@ -0,0 +1,31 @@
+// 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.
+
+library fuchsia.hardware.goldfish;
+
+using zx;
+
+/// Color buffer formats.
+enum ColorBufferFormatType : uint32 {
+ RGBA = 0x1908;
+ BGRA = 0x80E1;
+};
+
+/// Interface for the Goldfish control driver providing color buffers.
+[Layout = "Simple"]
+protocol ControlDevice {
+ /// Create shared color buffer. Color buffer is automatically freed when
+ /// all references to `vmo` have been closed. Fails if VMO is not
+ /// associated with goldfish heap memory.
+ /// Returns ZX_ERR_ALREADY_EXISTS if color buffer has already been created.
+ CreateColorBuffer(handle<vmo> vmo,
+ uint32 width,
+ uint32 height,
+ ColorBufferFormatType format)
+ -> (zx.status res);
+
+ /// Get color buffer for VMO. Fails if VMO is not associated with a color
+ /// buffer.
+ GetColorBuffer(handle<vmo> vmo) -> (zx.status res, uint32 id);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.hardware.goldfish/goldfish_pipe.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.hardware.goldfish/goldfish_pipe.fidl
new file mode 100644
index 0000000..62da439
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.hardware.goldfish/goldfish_pipe.fidl
@@ -0,0 +1,60 @@
+// 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.
+
+library fuchsia.hardware.goldfish;
+
+using zx;
+
+/// Signal that will be active on event handle if the Read() method
+/// will return data.
+const uint32 SIGNAL_READABLE = 0x01000000; // ZX_USER_SIGNAL_0
+
+/// Signal that will be active on event handle if the Write() method
+/// will accept data.
+const uint32 SIGNAL_WRITABLE = 0x02000000; // ZX_USER_SIGNAL_1
+
+/// Signal that will be active on event handle if the device has been
+/// disconnected.
+const uint32 SIGNAL_HANGUP = 0x04000000; // ZX_USER_SIGNAL_2
+
+/// Interface for the Goldfish pipe driver.
+[Layout = "Simple"]
+protocol PipeDevice {
+ /// Open pipe. A protocol request `pipe_request` provides an interface
+ /// to the pipe. Multiple pipes can be opened for a single device.
+ /// Closing the device connection will also close all pipe connections.
+ /// TODO(DX-1766): Unify `device` and `pipe`.
+ OpenPipe(request<Pipe> pipe_request);
+};
+
+[Layout = "Simple"]
+protocol Pipe {
+ /// Request new IO buffer size. Can fail if out of memory. Discards
+ /// contents of existing buffer on success. Leaves existing buffer
+ /// intact on failure.
+ SetBufferSize(uint64 size) -> (zx.status res);
+
+ /// Set event used to signal device state. Discards existing event
+ /// after having transferred device state to the new event.
+ SetEvent(handle<event> event);
+
+ /// Acquire VMO for IO buffer. Can be called multiple times. Each call
+ /// returns a new handle to the VMO.
+ GetBuffer() -> (zx.status res, handle<vmo>? vmo);
+
+ /// Attempt to read up to count bytes into IO buffer at specified offset.
+ /// Returns `ZX_ERR_SHOULD_WAIT` if pipe device is not readable.
+ Read(uint64 count, uint64 offset) -> (zx.status res, uint64 actual);
+
+ /// Writes up to count bytes from the IO buffer at specified offset.
+ /// Returns `ZX_ERR_SHOULD_WAIT` if pipe device is not writable.
+ Write(uint64 count, uint64 offset) -> (zx.status res, uint64 actual);
+
+ /// Writes count bytes from the IO buffer at specified write
+ /// offset. Blocks if pipe device is not writable. Subsequently reads
+ /// read_count bytes into the IO buffer at specified read offset.
+ /// Returns `ZX_ERR_SHOULD_WAIT` if pipe device is not readable.
+ Call(uint64 count, uint64 offset, uint64 read_count, uint64 read_offset)
+ -> (zx.status res, uint64 actual);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.hardware.goldfish/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.hardware.goldfish/meta.json
new file mode 100644
index 0000000..c09a361
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.hardware.goldfish/meta.json
@@ -0,0 +1,11 @@
+{
+ "deps": [],
+ "name": "fuchsia.hardware.goldfish",
+ "root": "fidl/fuchsia.hardware.goldfish",
+ "sources": [
+ "fidl/fuchsia.hardware.goldfish/goldfish_address_space.fidl",
+ "fidl/fuchsia.hardware.goldfish/goldfish_control.fidl",
+ "fidl/fuchsia.hardware.goldfish/goldfish_pipe.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.hardware.light/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.hardware.light/BUILD.gn
new file mode 100644
index 0000000..2130991
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.hardware.light/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.hardware.light") {
+ library_name = "light"
+ namespace = "fuchsia.hardware"
+ public_deps = [
+ ]
+ sources = [
+ "light.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.hardware.light",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.hardware.light/light.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.hardware.light/light.fidl
new file mode 100644
index 0000000..e1dc7f9
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.hardware.light/light.fidl
@@ -0,0 +1,147 @@
+// 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.
+
+library fuchsia.hardware.light;
+
+const uint8 LIGHT_NAME_LEN = 32;
+
+enum Capability {
+ /// This capability indicates that the light supports setting brightness to a uint8_t value.
+ /// If this capability is not supported, the light only supports off and on state.
+ BRIGHTNESS = 1;
+ /// This capability indicates that the light supports setting an RGB value.
+ RGB = 2;
+ /// No capabilities
+ SIMPLE = 3;
+};
+
+struct Rgb {
+ uint8 red;
+ uint8 green;
+ uint8 blue;
+};
+
+struct Info {
+ string:LIGHT_NAME_LEN name;
+ Capability capability;
+};
+
+struct GroupInfo {
+ string:LIGHT_NAME_LEN name;
+ uint32 count;
+ Capability capability;
+};
+
+enum LightError {
+ OK = 0;
+ NOT_SUPPORTED = 1;
+ INVALID_INDEX = 2;
+ FAILED = 3;
+};
+
+[Discoverable]
+protocol Light {
+ /// Returns the total number of physical lights.
+ /// This will typically be 1 for a simple LED light, but may be greater than one for an array of
+ /// lights or a more complicated lighting device.
+ /// The multiple lights are addressed using "index" parameter in the calls below.
+ GetNumLights() -> (uint32 count);
+
+ /// Returns the total number of light groups (does not count single lights).
+ /// The light groups are addressed using "group_id" parameter in the calls below.
+ GetNumLightGroups() -> (uint32 count);
+
+ /// Returns info for the single light.
+ /// index: Index of the light defined by board. Must be less than value returned by GetNumLights.
+ GetInfo(uint32 index) -> (Info info) error LightError;
+
+ /// Returns the current value. If the light is ON, the value is True. If the light is OFF,
+ /// the value is False.
+ /// If the capability 'SIMPLE' is not supported by this light, returns NOT_SUPPORTED.
+ /// Use GetInfo to check if light supports this operation.
+ /// index: a number between 0 inclusive and the count received from GetNumLights.
+ GetCurrentSimpleValue(uint32 index) -> (bool value) error LightError;
+
+ /// Sets the current value. Value should be set to 'TRUE' to turn on the light. Value should be
+ /// set to 'FALSE' to turn off the light.
+ /// If the capability 'SIMPLE' is not supported by this light, returns NOT_SUPPORTED.
+ /// Use GetInfo to check if light supports this operation.
+ /// index: a number between 0 inclusive and the count received from GetNumLights.
+ SetSimpleValue(uint32 index, bool value) -> () error LightError;
+
+ /// Returns the current brightness value (0 - 255) of the light indicated by index.
+ /// If the capability 'BRIGHTNESS' is not supported by this light, returns NOT_SUPPORTED.
+ /// Use GetInfo to check if light supports this operation.
+ /// index: a number between 0 inclusive and the count received from GetNumLights.
+ GetCurrentBrightnessValue(uint32 index) -> (uint8 value) error LightError;
+
+ /// Sets the current brightness value (0 - 255).
+ /// If the capability 'BRIGHTNESS' is not supported by this light, returns NOT_SUPPORTED.
+ /// Use GetInfo to check if light supports this operation.
+ /// index: a number between 0 inclusive and the count received from GetNumLights.
+ SetBrightnessValue(uint32 index, uint8 value) -> () error LightError;
+
+ /// Returns the current RGB value for the single light.
+ /// If the capability 'RGB' is not supported by this light, returns NOT_SUPPORTED.
+ /// Use GetInfo to check if light supports this operation.
+ /// index: a number between 0 inclusive and the count received from GetNumLights.
+ GetCurrentRgbValue(uint32 index) -> (Rgb value) error LightError;
+
+ /// Sets the current RGB value.
+ /// If the capability 'RGB' is not supported by this light, returns NOT_SUPPORTED.
+ /// Use GetInfo to check if light supports this operation.
+ /// index: a number between 0 inclusive and the count received from GetNumLights.
+ SetRgbValue(uint32 index, Rgb value) -> () error LightError;
+
+ /// Returns group info for the light group.
+ /// group_id: a number between 0 inclusive and the count received from GetNumLightGroups.
+ GetGroupInfo(uint32 group_id) -> (GroupInfo info) error LightError;
+
+ /// Returns an array of the current values.If the light is ON, the value is True. If the light
+ /// is OFF, the value is False.
+ /// If group_id is invalid, INVALID_INDEX will be returned.
+ /// If the capability 'SIMPLE' is not supported by this group, returns NOT_SUPPORTED.
+ /// Use GetGroupInfo to check if group supports this operation.
+ /// group_id: a number between 0 inclusive and the count received from GetNumLightGroups.
+ GetGroupCurrentSimpleValue(uint32 group_id) -> (vector<bool>:MAX? values) error LightError;
+
+ /// Sets the current values through the values array. Value should be set to 'TRUE' to turn on
+ /// the light. Value should be set to 'FALSE' to turn off the light.
+ /// If group_id is invalid, INVALID_INDEX will be returned.
+ /// If the capability 'SIMPLE' is not supported by this group, returns NOT_SUPPORTED.
+ /// Use GetGroupInfo to check if group supports this operation.
+ /// group_id: a number between 0 inclusive and the count received from GetNumLightGroups.
+ SetGroupSimpleValue(uint32 group_id, vector<bool>:MAX values) -> () error LightError;
+
+ /// Returns an array of the current brightness values (0 - 255) for the light group.
+ /// If group_id is invalid, INVALID_INDEX will be returned.
+ /// If the capability 'BRIGHTNESS' is not supported by this group, returns NOT_SUPPORTED.
+ /// Use GetGroupInfo to check if group supports this operation.
+ /// group_id: a number between 0 inclusive and the count received from GetNumLightGroups.
+ GetGroupCurrentBrightnessValue(uint32 group_id) -> (vector<uint8>:MAX? values) error LightError;
+
+ /// Sets the current brightness values (0 - 255) for the light group through the values array.
+ /// If group_id is invalid, INVALID_INDEX will be returned.
+ /// If the capability 'BRIGHTNESS' is not supported by this group, returns NOT_SUPPORTED.
+ /// Use GetGroupInfo to check if group supports this operation.
+ /// group_id: a number between 0 inclusive and the count received from GetNumLightGroups.
+ SetGroupBrightnessValue(uint32 group_id, vector<uint8>:MAX values) -> () error LightError;
+
+ /// Returns an array of the current RGB values for the light group.
+ /// If group_id is invalid, INVALID_INDEX will be returned.
+ /// If the capability 'RGB' is not supported by this group, returns NOT_SUPPORTED.
+ /// Use GetGroupInfo to check if group supports this operation.
+ /// group_id: a number between 0 inclusive and the count received from GetNumLightGroups.
+ GetGroupCurrentRgbValue(uint32 group_id) -> (vector<Rgb>:MAX? values) error LightError;
+
+ /// Sets the current RGB value for the light group.
+ /// If group_id is invalid, INVALID_INDEX will be returned.
+ /// If the capability 'RGB' is not supported by this group, returns NOT_SUPPORTED.
+ /// Use GetGroupInfo to check if group supports this operation.
+ /// group_id: a number between 0 inclusive and the count received from GetNumLightGroups.
+ SetGroupRgbValue(uint32 group_id, vector<Rgb>:MAX values) -> () error LightError;
+
+ // TODO: Ideas for future expansion
+ // - Hardware blinking configuration, for lights that have hardware or MCU support for blinking.
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.hardware.light/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.hardware.light/meta.json
new file mode 100644
index 0000000..8a2fceb
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.hardware.light/meta.json
@@ -0,0 +1,9 @@
+{
+ "deps": [],
+ "name": "fuchsia.hardware.light",
+ "root": "fidl/fuchsia.hardware.light",
+ "sources": [
+ "fidl/fuchsia.hardware.light/light.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.hardware.power.statecontrol/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.hardware.power.statecontrol/BUILD.gn
new file mode 100644
index 0000000..26d96cf
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.hardware.power.statecontrol/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.hardware.power.statecontrol") {
+ library_name = "statecontrol"
+ namespace = "fuchsia.hardware.power"
+ public_deps = [
+ ]
+ sources = [
+ "admin.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.hardware.power.statecontrol",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.hardware.power.statecontrol/admin.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.hardware.power.statecontrol/admin.fidl
new file mode 100644
index 0000000..05f3ac8
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.hardware.power.statecontrol/admin.fidl
@@ -0,0 +1,40 @@
+// 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.
+
+library fuchsia.hardware.power.statecontrol;
+
+using zx;
+
+/// All available suspend flags.
+// TODO(fxb/42257): When all clients start using the system power state
+// these flags can be removed.
+const uint32 SUSPEND_FLAG_REBOOT = 0xdcdc0100;
+const uint32 SUSPEND_FLAG_REBOOT_BOOTLOADER = 0xdcdc0101;
+const uint32 SUSPEND_FLAG_REBOOT_RECOVERY = 0xdcdc0102;
+const uint32 SUSPEND_FLAG_POWEROFF = 0xdcdc0200;
+const uint32 SUSPEND_FLAG_MEXEC = 0xdcdc0300;
+const uint32 SUSPEND_FLAG_SUSPEND_RAM = 0xdcdc0400;
+
+// TODO(ravoorir): When the system power states are properly defined,
+// remove the suspend flags. For now, treat each suspend flag as a system
+// power state.
+enum SystemPowerState : uint8 {
+ FULLY_ON = 1;
+ REBOOT = 2;
+ REBOOT_BOOTLOADER = 3;
+ REBOOT_RECOVERY = 4;
+ POWEROFF = 5;
+ MEXEC = 6;
+ SUSPEND_RAM = 7;
+};
+const uint32 MAX_SYSTEM_POWER_STATES = 7;
+
+/// Provides administration services for the device manager service and the device tree it controls.
+[Discoverable]
+protocol Admin {
+ /// Ask all devices to enter into the system power state indicated by 'state'.
+ /// The devices will get into a low power state, that corresponds to the system
+ /// power state 'state'.
+ Suspend(SystemPowerState state) -> () error zx.status;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.hardware.power.statecontrol/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.hardware.power.statecontrol/meta.json
new file mode 100644
index 0000000..7b32917
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.hardware.power.statecontrol/meta.json
@@ -0,0 +1,9 @@
+{
+ "deps": [],
+ "name": "fuchsia.hardware.power.statecontrol",
+ "root": "fidl/fuchsia.hardware.power.statecontrol",
+ "sources": [
+ "fidl/fuchsia.hardware.power.statecontrol/admin.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.hwinfo/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.hwinfo/BUILD.gn
new file mode 100644
index 0000000..d7609a7
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.hwinfo/BUILD.gn
@@ -0,0 +1,26 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.hwinfo") {
+ library_name = "hwinfo"
+ namespace = "fuchsia"
+ public_deps = [
+ "../fuchsia.intl",
+ ]
+ sources = [
+ "hwinfo.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.hwinfo",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.hwinfo/hwinfo.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.hwinfo/hwinfo.fidl
new file mode 100644
index 0000000..ab23350
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.hwinfo/hwinfo.fidl
@@ -0,0 +1,59 @@
+// 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.
+
+library fuchsia.hwinfo;
+using fuchsia.intl;
+
+const uint8 MAX_VALUE_LENGTH = 255;
+
+/// Collection of properties that is unique per device.
+table DeviceInfo {
+ 1: string serial_number;
+};
+
+/// Collection of properties that is shared with other devices within the same
+/// product line.
+table ProductInfo {
+ 1: string sku;
+ 2: string language;
+ 3: fuchsia.intl.RegulatoryDomain regulatory_domain;
+ 4: vector<fuchsia.intl.LocaleId> locale_list;
+ 5: string name;
+ 6: string model;
+ 7: string manufacturer;
+ 8: string build_date;
+ 9: string:MAX_VALUE_LENGTH build_name;
+ 10: string:MAX_VALUE_LENGTH colorway;
+ 11: string:MAX_VALUE_LENGTH display;
+ 12: string:MAX_VALUE_LENGTH memory;
+ 13: string:MAX_VALUE_LENGTH nand_storage;
+ 14: string:MAX_VALUE_LENGTH emmc_storage;
+ 15: string:MAX_VALUE_LENGTH microphone;
+ 16: string:MAX_VALUE_LENGTH audio_amplifier;
+};
+
+/// Collection of properties that are common among a set of devices based on
+/// hardware type
+table BoardInfo {
+ 1: string name;
+ 2: string revision;
+};
+
+/// Device provides an interface to retrieve device-specific properties.
+[Discoverable]
+protocol Device {
+ GetInfo() -> (DeviceInfo info);
+};
+
+/// Product provides an interface to retrieve product-specific properties.
+[Discoverable]
+protocol Product {
+ GetInfo() -> (ProductInfo info);
+};
+
+/// Board provides an interface to retrieve hardware-specific information.
+[Discoverable]
+protocol Board {
+ GetInfo() -> (BoardInfo info);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.hwinfo/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.hwinfo/meta.json
new file mode 100644
index 0000000..ee88763
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.hwinfo/meta.json
@@ -0,0 +1,11 @@
+{
+ "deps": [
+ "fuchsia.intl"
+ ],
+ "name": "fuchsia.hwinfo",
+ "root": "fidl/fuchsia.hwinfo",
+ "sources": [
+ "fidl/fuchsia.hwinfo/hwinfo.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.images/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.images/BUILD.gn
new file mode 100644
index 0000000..345b605
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.images/BUILD.gn
@@ -0,0 +1,31 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.images") {
+ library_name = "images"
+ namespace = "fuchsia"
+ public_deps = [
+ "../fuchsia.sysmem",
+ ]
+ sources = [
+ "encoded_image.fidl",
+ "image_info.fidl",
+ "image_pipe.fidl",
+ "image_pipe2.fidl",
+ "memory_type.fidl",
+ "presentation_info.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.images",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.images/encoded_image.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.images/encoded_image.fidl
new file mode 100644
index 0000000..d8cad1d
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.images/encoded_image.fidl
@@ -0,0 +1,12 @@
+// Copyright 2018 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.
+
+library fuchsia.images;
+
+struct EncodedImage {
+ /// The vmo.
+ handle<vmo> vmo;
+ /// The size of the image in the vmo in bytes.
+ uint64 size;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.images/image_info.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.images/image_info.fidl
new file mode 100644
index 0000000..1a77e28
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.images/image_info.fidl
@@ -0,0 +1,139 @@
+// Copyright 2018 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.
+
+library fuchsia.images;
+
+/// Specifies how pixels are represented in the image buffer.
+enum PixelFormat {
+ /// BGRA_8
+ ///
+ /// A 32-bit four-component unsigned integer format.
+ /// Byte order: B, G, R, A (little-endian ARGB packed 32-bit word).
+ /// Equivalent to Skia `kBGRA_8888_SkColorType` color type.
+ /// Equivalent to Zircon `ARGB_8888` pixel format on little-endian arch.
+ BGRA_8 = 0;
+
+ /// YUY2
+ ///
+ /// 4:2:2 (2x down-sampled UV horizontally; full res UV vertically)
+ ///
+ /// A 32-bit component that contains information for 2 pixels:
+ /// Byte order: Y1, U, Y2, V
+ /// Unpacks to 2 RGB pixels, where RGB1 = func(Y1, U, V)
+ /// and RGB2 = func(Y2, U, V)
+ /// Equivalent to YUV422
+ YUY2 = 1;
+
+ /// NV12
+ ///
+ /// 4:2:0 (2x down-sampled UV in both directions)
+ ///
+ /// Offset 0:
+ /// 8 bit per pixel Y plane with bytes YYY.
+ /// Offset height * stride:
+ /// 8 bit UV data interleaved bytes as UVUVUV.
+ ///
+ /// Y plane has line stride >= width.
+ ///
+ /// In this context, both width and height are required to be even.
+ ///
+ /// The UV data is separated into "lines", with each "line" having same byte
+ /// width as a line of Y data, and same "line" stride as Y data's line stride.
+ /// The UV data has height / 2 "lines".
+ ///
+ /// In converting to RGB, the UV data gets up-scaled by 2x in both directions
+ /// overall. This comment is intentionally silent on exactly how UV up-scaling
+ /// phase/filtering/signal processing works, as it's a complicated topic that
+ /// can vary by implementation, typically trading off speed and quality of the
+ /// up-scaling. See comments in relevant conversion code for approach taken
+ /// by any given convert path. The precise relative phase of the UV data is
+ /// not presently conveyed.
+ NV12 = 2;
+
+ /// YV12
+ ///
+ /// Like I420, except with V and U swapped.
+ ///
+ /// 4:2:0 (2x down-sampled UV in both directions)
+ ///
+ /// Offset 0:
+ /// 8 bit per pixel Y plane with bytes YYY.
+ /// Offset height * stride:
+ /// 8 bit V data with uv_stride = stride / 2
+ /// Offset height * stride + uv_stride * height / 2:
+ /// 8 bit U data with uv_stride = stride / 2
+ ///
+ /// Y plane has line stride >= width.
+ ///
+ /// Both width and height are required to be even.
+ YV12 = 3;
+};
+
+/// Specifies how pixel color information should be interpreted.
+enum ColorSpace {
+ SRGB = 0;
+};
+
+/// Specifies how pixels are arranged in memory.
+enum Tiling {
+ /// Pixels are packed linearly.
+ /// Equivalent to `VK_IMAGE_TILING_LINEAR`.
+ LINEAR = 0;
+
+ /// Pixels are packed in a GPU-dependent optimal format.
+ /// Equivalent to `VK_IMAGE_TILING_OPTIMAL`.
+ GPU_OPTIMAL = 1;
+};
+
+/// Specifies how alpha information should be interpreted.
+enum AlphaFormat {
+ /// Image is considered to be opaque. Alpha channel is ignored.
+ /// Blend function is: src.RGB
+ OPAQUE = 0;
+ /// Color channels have been premultiplied by alpha.
+ /// Blend function is: src.RGB + (dest.RGB * (1 - src.A))
+ PREMULTIPLIED = 1;
+ /// Color channels have not been premultiplied by alpha.
+ /// Blend function is: (src.RGB * src.A) + (dest.RGB * (1 - src.A))
+ NON_PREMULTIPLIED = 2;
+};
+
+enum Transform {
+ /// Pixels are displayed normally.
+ NORMAL = 0;
+
+ /// Pixels are mirrored left-right.
+ FLIP_HORIZONTAL = 1;
+
+ /// Pixels are flipped vertically.
+ FLIP_VERTICAL = 2;
+
+ /// Pixels are flipped vertically and mirrored left-right.
+ FLIP_VERTICAL_AND_HORIZONTAL = 3;
+};
+
+/// Information about a graphical image (texture) including its format and size.
+struct ImageInfo {
+ /// Specifies if the image should be mirrored before displaying.
+ Transform transform = Transform.NORMAL;
+
+ /// The width and height of the image in pixels.
+ uint32 width;
+ uint32 height;
+
+ /// The number of bytes per row in the image buffer.
+ uint32 stride;
+
+ /// The pixel format of the image.
+ PixelFormat pixel_format = PixelFormat.BGRA_8;
+
+ /// The pixel color space.
+ ColorSpace color_space = ColorSpace.SRGB;
+
+ /// The pixel arrangement in memory.
+ Tiling tiling = Tiling.LINEAR;
+
+ /// Specifies the interpretion of the alpha channel, if one exists.
+ AlphaFormat alpha_format = AlphaFormat.OPAQUE;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.images/image_pipe.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.images/image_pipe.fidl
new file mode 100644
index 0000000..6c8695b
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.images/image_pipe.fidl
@@ -0,0 +1,121 @@
+// Copyright 2018 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.
+
+library fuchsia.images;
+
+/// ImagePipe is a mechanism for streaming shared images between a producer
+/// and a consumer which may be running in different processes.
+///
+/// Conceptually, the image pipe maintains a table of image resources supplied
+/// by the producer into which graphical content may be stored as well as a
+/// presentation queue containing a sequence of images which the producer has
+/// asked the consumer to present.
+///
+/// The presentation queue is initially empty.
+///
+/// Each entry in the presentation queue consists of an image together with a
+/// pair of optional synchronization fences:
+/// - Acquire fence: signaled by the producer when the image is ready to be consumed
+/// - Release fence: signaled by the consumer when the image is free to be freed or
+/// modified by the producer
+///
+/// The producer performs the following sequence of steps to present content:
+/// - Allocate and add some number of images (often 2 or 3) to the image pipe
+/// to establish a pool using `AddImage()`.
+/// - Obtain the next available image from the pool.
+/// - Ask the consumer to enqueue an image for presentation and provide fences
+/// using `PresentImage()`.
+/// - Start rendering the image.
+/// - Signal the image's acquire fence when rendering is complete.
+/// - Loop to present more image, listen for signals on release fences to recycle
+/// images back into the pool.
+///
+/// The consumer performs the following sequence of steps for each image which
+/// is enqueued in the presentation queue:
+/// - Await signals on the image's acquire fence.
+/// - If the fence wait cannot be satisfied or if some other error is detected,
+/// close the image pipe.
+/// Otherwise, begin presenting the image's content.
+/// - Retire the previously presented image (if any) from the presentation queue
+/// and signal its release fence when no longer needed.
+/// - Continue presenting the same image until the next one is ready. Loop.
+///
+/// If the producer wants to close the image pipe, it should:
+/// - Close its side of the connection.
+/// - Wait on all release fences for buffers that it has submitted with
+/// `PresentImage()`.
+/// - Proceed with resource cleanup.
+///
+/// When the consumer detects the image pipe has closed, it should:
+/// - Stop using/presenting any images from the pipe.
+/// - Unmap all VMOs associated with the images in the pipe.
+/// - Close all handles to the VMOs.
+/// - Signal all release fences for presented and queued buffers.
+/// - Close all handles to fences.
+/// - Close its side of the connection.
+///
+/// When either party detects that a fence has been abandoned (remotely closed
+/// without being signaled) it should assume that the associated image is in
+/// an indeterminate state. This will typically happen when the other party
+/// (or one of its delegates) has crashed. The safest course of action is to
+/// close the image pipe, release all resources which were shared with the
+/// other party, and re-establish the connection to recover.
+protocol ImagePipe {
+ /// Adds an image resource to image pipe.
+ ///
+ /// The `memory` is the handle of a memory object which contains the image
+ /// data. It is valid to create multiple images backed by the same memory
+ /// object; they may even overlap. Consumers must detect this and handle
+ /// it accordingly. The `offset_bytes` indicates the offset within the
+ /// memory object at which the image data begins. The `size_bytes`
+ /// indicates the amount of memory from `memory` that should be utilized.
+ /// The type of memory stored in the VMO is `memory_type` (e.g. GPU memory,
+ /// host memory).
+ ///
+ /// The following errors will cause the connection to be closed:
+ /// - `image_id` is already registered
+ /// - `image_info` represents a format not supported by the consumer
+ /// - `memory` is not a handle for a readable VMO
+ /// - the image data expected at `offset_bytes` according to the `image_info`
+ /// exceeds the memory object's bounds
+ AddImage(uint32 image_id, ImageInfo image_info,
+ handle<vmo> memory, uint64 offset_bytes, uint64 size_bytes, MemoryType memory_type);
+
+ /// Removes an image resource from the pipe.
+ ///
+ /// The `image_id` is detached from the image resource and is free to be
+ /// reused to add a new image resource.
+ ///
+ /// Removing an image from the image pipe does not affect the presentation
+ /// queue or the currently presented image.
+ ///
+ /// The producer must wait for all release fences associated with the image to
+ /// be signaled before freeing or modifying the underlying memory object since
+ /// the image may still be in use in the presentation queue.
+ ///
+ /// The following errors will cause the connection to be closed:
+ /// - `image_id` does not reference a currently registered image resource
+ RemoveImage(uint32 image_id);
+
+ /// Enqueues the specified image for presentation by the consumer.
+ ///
+ /// The `acquire_fences` are a set of fences which must all be signaled by the
+ /// producer before the consumer presents the image.
+ /// The `release_fences` are set of fences which must all be signaled by the
+ /// consumer before it is safe for the producer to free or modify the image.
+ /// `presentation_time` specifies the time on or after which the
+ /// client would like the enqueued operations should take visible effect
+ /// (light up pixels on the screen), expressed in nanoseconds in the
+ /// `CLOCK_MONOTONIC` timebase. Desired presentation times must be
+ /// monotonically non-decreasing.
+ ///
+ /// `presentation_info` returns timing information about the submitted frame
+ /// and future frames (see presentation_info.fidl).
+ ///
+ /// The following errors will cause the connection to be closed:
+ /// - `image_id` does not reference a currently registered image resource
+ PresentImage(uint32 image_id, uint64 presentation_time,
+ vector<handle<event>> acquire_fences, vector<handle<event>> release_fences)
+ -> (PresentationInfo presentation_info);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.images/image_pipe2.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.images/image_pipe2.fidl
new file mode 100644
index 0000000..f684f38
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.images/image_pipe2.fidl
@@ -0,0 +1,166 @@
+// 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.
+
+library fuchsia.images;
+
+using fuchsia.sysmem;
+
+// A maximum of 16 fences is enough for the current usage of these APIs.
+const int32 MAX_ACQUIRE_RELEASE_FENCE_COUNT = 16;
+
+/// ImagePipe is a mechanism for streaming shared images between a producer
+/// and a consumer which may be running in different processes.
+///
+/// Conceptually, the image pipe maintains a table of image resources supplied
+/// by the producer into which graphical content may be stored as well as a
+/// presentation queue containing a sequence of images which the producer has
+/// asked the consumer to present.
+///
+/// The presentation queue is initially empty.
+///
+/// Each entry in the presentation queue consists of an image together with a
+/// pair of optional synchronization fences:
+/// - Acquire fence: signaled by the producer when the image is ready to be consumed
+/// - Release fence: signaled by the consumer when the image is free to be freed or
+/// modified by the producer
+///
+/// The producer performs the following sequence of steps to present content:
+/// - Allocate and add some number of BufferCollections to the image pipe to allow
+/// consumer to set constraints.
+/// - Allocate and add some number of images (often 2 or 3) to the image pipe
+/// to establish a pool using `AddImage()`.
+/// - Obtain the next available image from the pool.
+/// - Ask the consumer to enqueue an image for presentation and provide fences
+/// using `PresentImage()`.
+/// - Start rendering the image.
+/// - Signal the image's acquire fence when rendering is complete.
+/// - Loop to present more image, listen for signals on release fences to recycle
+/// images back into the pool.
+///
+/// The consumer performs the following sequence of steps for each image which
+/// is enqueued in the presentation queue:
+/// - Await signals on the image's acquire fence.
+/// - If the fence wait cannot be satisfied or if some other error is detected,
+/// close the image pipe.
+/// Otherwise, begin presenting the image's content.
+/// - Retire the previously presented image (if any) from the presentation queue
+/// and signal its release fence when no longer needed.
+/// - Continue presenting the same image until the next one is ready. Loop.
+///
+/// If the producer wants to close the image pipe, it should:
+/// - Close its side of the connection.
+/// - Wait on all release fences for buffers that it has submitted with
+/// `PresentImage()`.
+/// - Proceed with resource cleanup.
+///
+/// When the consumer detects the image pipe has closed, it should:
+/// - Stop using/presenting any images from the pipe.
+/// - Unmap all memory objects associated with the images in the pipe.
+/// - Close all BufferCollection resources.
+/// - Signal all release fences for presented and queued buffers.
+/// - Close all handles to fences.
+/// - Close its side of the connection.
+///
+/// When either party detects that a fence has been abandoned (remotely closed
+/// without being signaled) it should assume that the associated image is in
+/// an indeterminate state. This will typically happen when the other party
+/// (or one of its delegates) has crashed. The safest course of action is to
+/// close the image pipe, release all resources which were shared with the
+/// other party, and re-establish the connection to recover.
+protocol ImagePipe2 {
+ /// Adds a BufferCollection resource to the image pipe.
+ ///
+ /// The producer is expected to set constraints on this resource for images added
+ /// via `AddImage()`. The consumer can set its constraints on
+ /// `buffer_collection_token` before or after. Note that the buffers won’t be
+ /// allocated until all BufferCollectionToken instances are used to set
+ /// constraints, on both the producer and consumer side. See collection.fidl for
+ /// details.
+ ///
+ /// The following errors will cause the connection to be closed:
+ /// - `buffer_collection_id` is already registered
+ AddBufferCollection(uint32 buffer_collection_id,
+ fuchsia.sysmem.BufferCollectionToken buffer_collection_token);
+
+ /// Adds an image resource to image pipe.
+ ///
+ /// `buffer_collection_id` refers to the BufferCollectionToken instance that is
+ /// registered via `AddBufferCollection()`. The underlying memory objects allocated
+ /// are used to address to the image data. `buffer_collection_id` refers to the
+ /// index of the memory object allocated in BufferCollection.
+ ///
+ /// `image_format` specifiies image properties. `coded_width` and `coded_height` are
+ /// used to set image dimensions.
+ ///
+ /// It is valid to create multiple images backed by the same memory object; they
+ /// may even overlap. Consumers must detect this and handle it accordingly.
+ ///
+ /// The following errors will cause the connection to be closed:
+ /// - `image_id` is already registered
+ /// - `buffer_collection_id` refers to an unregistered BufferCollection.
+ /// - `buffer_collection_index` points to a resource index out of the initialized
+ /// BufferCollection bounds
+ /// - No resource is allocated in the registered BufferCollection.
+ AddImage(uint32 image_id, uint32 buffer_collection_id, uint32 buffer_collection_index,
+ fuchsia.sysmem.ImageFormat_2 image_format);
+
+ /// Removes a BufferCollection resource from the pipe.
+ ///
+ /// The `buffer_collection_id` resource is detached as well as all Images that are
+ /// associated with that BufferCollection. Leads to the same results as calling
+ /// `RemoveImage()` on all Images for `buffer_collection_id`.
+ ///
+ /// The producer must wait for all release fences associated with the Images to
+ /// be signaled before freeing or modifying the underlying memory object since
+ /// the image may still be in use in the presentation queue.
+ ///
+ /// The following errors will cause the connection to be closed:
+ /// - `buffer_collection_id` does not reference a currently registered BufferCollection
+ RemoveBufferCollection(uint32 buffer_collection_id);
+
+ /// Removes an image resource from the pipe.
+ ///
+ /// The `image_id` is detached from the image resource and is free to be
+ /// reused to add a new image resource.
+ ///
+ /// Removing an image from the image pipe does not affect the presentation
+ /// queue or the currently presented image.
+ ///
+ /// The producer must wait for all release fences associated with the image to
+ /// be signaled before freeing or modifying the underlying memory object since
+ /// the image may still be in use in the presentation queue.
+ ///
+ /// The following errors will cause the connection to be closed:
+ /// - `image_id` does not reference a currently registered image resource
+ RemoveImage(uint32 image_id);
+
+ /// Enqueues the specified image for presentation by the consumer.
+ ///
+ /// The `acquire_fences` are a set of fences which must all be signaled by the
+ /// producer before the consumer presents the image.
+ /// The `release_fences` are set of fences which must all be signaled by the
+ /// consumer before it is safe for the producer to free or modify the image.
+ /// `presentation_time` specifies the time on or after which the
+ /// client would like the enqueued operations should take visible effect
+ /// (light up pixels on the screen), expressed in nanoseconds in the
+ /// `CLOCK_MONOTONIC` timebase. Desired presentation times must be
+ /// monotonically non-decreasing.
+ ///
+ /// `presentation_info` returns timing information about the submitted frame
+ /// and future frames (see presentation_info.fidl).
+ ///
+ /// The producer may decide not to signal `acquire_fences` for an image.
+ /// In that case, if a later image is enqueued and later image’s
+ /// `presentation_time` is reached, the consumer presents the later image when
+ /// later image’s `acquire_fences` are signaled. The consumer also signals
+ /// earlier image’s `release_fences` and removes it from the presentation queue.
+ /// This sequence works as a cancellation mechanism.
+ ///
+ /// The following errors will cause the connection to be closed:
+ /// - `image_id` does not reference a currently registered image resource
+ PresentImage(uint32 image_id, uint64 presentation_time,
+ vector<handle<event>>:MAX_ACQUIRE_RELEASE_FENCE_COUNT acquire_fences,
+ vector<handle<event>>:MAX_ACQUIRE_RELEASE_FENCE_COUNT release_fences)
+ -> (PresentationInfo presentation_info);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.images/memory_type.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.images/memory_type.fidl
new file mode 100644
index 0000000..e8ba269
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.images/memory_type.fidl
@@ -0,0 +1,15 @@
+// Copyright 2018 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.
+
+library fuchsia.images;
+
+/// Specifies the type of VMO's memory.
+enum MemoryType {
+ /// VMO is regular host CPU memory.
+ HOST_MEMORY = 0;
+
+ /// VMO can be imported as a VkDeviceMemory by calling VkAllocateMemory with a
+ /// VkImportMemoryFuchsiaHandleInfoKHR wrapped in a VkMemoryAllocateInfo.
+ VK_DEVICE_MEMORY = 1;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.images/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.images/meta.json
new file mode 100644
index 0000000..aa85887
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.images/meta.json
@@ -0,0 +1,16 @@
+{
+ "deps": [
+ "fuchsia.sysmem"
+ ],
+ "name": "fuchsia.images",
+ "root": "fidl/fuchsia.images",
+ "sources": [
+ "fidl/fuchsia.images/encoded_image.fidl",
+ "fidl/fuchsia.images/image_info.fidl",
+ "fidl/fuchsia.images/image_pipe.fidl",
+ "fidl/fuchsia.images/image_pipe2.fidl",
+ "fidl/fuchsia.images/memory_type.fidl",
+ "fidl/fuchsia.images/presentation_info.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.images/presentation_info.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.images/presentation_info.fidl
new file mode 100644
index 0000000..23f8ebd
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.images/presentation_info.fidl
@@ -0,0 +1,27 @@
+// Copyright 2017 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.
+
+library fuchsia.images;
+
+/// Information returned by methods such as `ImagePipe.PresentImage()` and
+/// `Session.Present()`, when the consumer begins preparing the first frame
+/// which includes the presented content.
+struct PresentationInfo {
+ /// The actual time at which the enqueued operations are anticipated to take
+ /// visible effect, expressed in nanoseconds in the `CLOCK_MONOTONIC`
+ /// timebase.
+ ///
+ /// This value increases monotonically with each new frame, typically in
+ /// increments of the `presentation_interval`.
+ uint64 presentation_time;
+
+ /// The nominal amount of time which is anticipated to elapse between
+ /// successively presented frames, expressed in nanoseconds. When rendering
+ /// to a display, the interval will typically be derived from the display
+ /// refresh rate.
+ ///
+ /// This value is non-zero. It may vary from time to time, such as when
+ /// changing display modes.
+ uint64 presentation_interval;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.input/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.input/BUILD.gn
new file mode 100644
index 0000000..73f013a
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.input/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.input") {
+ library_name = "input"
+ namespace = "fuchsia"
+ public_deps = [
+ ]
+ sources = [
+ "keys.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.input",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.input/keys.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.input/keys.fidl
new file mode 100644
index 0000000..f6aed45
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.input/keys.fidl
@@ -0,0 +1,347 @@
+// Copyright 2020 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.
+
+library fuchsia.input;
+
+/// A Fuchsia key represents a control that can be pressed or released such as a key or
+/// a button on a keyboard or another input device.
+///
+/// The ordinal index for enum elements is derived from the USB HID Usage Tables at the
+/// time of definition. It is a 32 bit unsigned integer representing the USB HID Usage
+/// where the low 16 bits are the USB HID Usage ID and the high 16 bits are the
+/// USB HID Usage Page.
+///
+/// The descriptions for each value in the enum assume a US English keyboard layout.
+/// Actual behavior varies by layout.
+enum Key : uint32 {
+ /// Keyboard a and A
+ A = 0x00070004;
+
+ /// Keyboard b and B
+ B = 0x00070005;
+
+ /// Keyboard c and C
+ C = 0x00070006;
+
+ /// Keyboard d and D
+ D = 0x00070007;
+
+ /// Keyboard e and E
+ E = 0x00070008;
+
+ /// Keyboard f and F
+ F = 0x00070009;
+
+ /// Keyboard g and G
+ G = 0x0007000a;
+
+ /// Keyboard h and H
+ H = 0x0007000b;
+
+ /// Keyboard i and I
+ I = 0x0007000c;
+
+ /// Keyboard j and J
+ J = 0x0007000d;
+
+ /// Keyboard k and K
+ K = 0x0007000e;
+
+ /// Keyboard l and L
+ L = 0x0007000f;
+
+ /// Keyboard m and M
+ M = 0x00070010;
+
+ /// Keyboard n and N
+ N = 0x00070011;
+
+ /// Keyboard o and O
+ O = 0x00070012;
+
+ /// Keyboard p and P
+ P = 0x00070013;
+
+ /// Keyboard q and Q
+ Q = 0x00070014;
+
+ /// Keyboard r and R
+ R = 0x00070015;
+
+ /// Keyboard s and S
+ S = 0x00070016;
+
+ /// Keyboard t and T
+ T = 0x00070017;
+
+ /// Keyboard u and U
+ U = 0x00070018;
+
+ /// Keyboard v and V
+ V = 0x00070019;
+
+ /// Keyboard w and W
+ W = 0x0007001a;
+
+ /// Keyboard x and X
+ X = 0x0007001b;
+
+ /// Keyboard y and Y
+ Y = 0x0007001c;
+
+ /// Keyboard z and Z
+ Z = 0x0007001d;
+
+ /// Keyboard 1 and !
+ KEY_1 = 0x0007001e;
+
+ /// Keyboard 2 and @
+ KEY_2 = 0x0007001f;
+
+ /// Keyboard 3 and #
+ KEY_3 = 0x00070020;
+
+ /// Keyboard 4 and $
+ KEY_4 = 0x00070021;
+
+ /// Keyboard 5 and %
+ KEY_5 = 0x00070022;
+
+ /// Keyboard 6 and ^
+ KEY_6 = 0x00070023;
+
+ /// Keyboard 7 and &
+ KEY_7 = 0x00070024;
+
+ /// Keyboard 8 and *
+ KEY_8 = 0x00070025;
+
+ /// Keyboard 9 and (
+ KEY_9 = 0x00070026;
+
+ /// Keyboard 0 and )
+ KEY_0 = 0x00070027;
+
+ /// Keyboard Enter (Return)
+ ENTER = 0x00070028;
+
+ /// Keyboard Escape
+ ESCAPE = 0x00070029;
+
+ /// Keyboard Backspace (Backward Delete)
+ BACKSPACE = 0x0007002a;
+
+ /// Keyboard Tab
+ TAB = 0x0007002b;
+
+ /// Keyboard Spacebar
+ SPACE = 0x0007002c;
+
+ /// Keyboard - and (underscore)
+ MINUS = 0x0007002d;
+
+ /// Keyboard = and +
+ EQUALS = 0x0007002e;
+
+ /// Keyboard [ and {
+ LEFT_BRACE = 0x0007002f;
+
+ /// Keyboard ] and }
+ RIGHT_BRACE = 0x00070030;
+
+ /// Keyboard \ and |
+ BACKSLASH = 0x00070031;
+
+ /// Keyboard Non-US # and ~
+ NON_US_HASH = 0x00070032;
+
+ /// Keyboard ; and :
+ SEMICOLON = 0x00070033;
+
+ /// Keyboard ' and "
+ APOSTROPHE = 0x00070034;
+
+ /// Keyboard Grave Accent and Tilde
+ GRAVE_ACCENT = 0x00070035;
+
+ /// Keyboard , and <
+ COMMA = 0x00070036;
+
+ /// Keyboard . and >
+ DOT = 0x00070037;
+
+ /// Keyboard / and ?
+ SLASH = 0x00070038;
+
+ /// Keyboard Caps Lock
+ CAPS_LOCK = 0x00070039;
+
+ /// Keyboard F1
+ F1 = 0x0007003a;
+
+ /// Keyboard F2
+ F2 = 0x0007003b;
+
+ /// Keyboard F3
+ F3 = 0x0007003c;
+
+ /// Keyboard F4
+ F4 = 0x0007003d;
+
+ /// Keyboard F5
+ F5 = 0x0007003e;
+
+ /// Keyboard F6
+ F6 = 0x0007003f;
+
+ /// Keyboard F7
+ F7 = 0x00070040;
+
+ /// Keyboard F8
+ F8 = 0x00070041;
+
+ /// Keyboard F9
+ F9 = 0x00070042;
+
+ /// Keyboard F10
+ F10 = 0x00070043;
+
+ /// Keyboard F11
+ F11 = 0x00070044;
+
+ /// Keyboard F12
+ F12 = 0x00070045;
+
+ /// Keyboard Print Screen
+ PRINT_SCREEN = 0x00070046;
+
+ /// Keyboard Scroll Lock
+ SCROLL_LOCK = 0x00070047;
+
+ /// Keyboard Pause
+ PAUSE = 0x00070048;
+
+ /// Keyboard Insert
+ INSERT = 0x00070049;
+
+ /// Keyboard Home
+ HOME = 0x0007004a;
+
+ /// Keyboard Page Up
+ PAGE_UP = 0x0007004b;
+
+ /// Keyboard Forward Delete
+ DELETE = 0x0007004c;
+
+ /// Keyboard End
+ END = 0x0007004d;
+
+ /// Keyboard Page Down
+ PAGE_DOWN = 0x0007004e;
+
+ /// Keyboard Right Arrow
+ RIGHT = 0x0007004f;
+
+ /// Keyboard Left Arrow
+ LEFT = 0x00070050;
+
+ /// Keyboard Down Arrow
+ DOWN = 0x00070051;
+
+ /// Keyboard Up Arrow
+ UP = 0x00070052;
+
+ /// Keyboard Non-US \ and |
+ NON_US_BACKSLASH = 0x00070064;
+
+ /// Keyboard Left Control
+ LEFT_CTRL = 0x000700e0;
+
+ /// Keyboard Left Shift
+ LEFT_SHIFT = 0x000700e1;
+
+ /// Keyboard Left Alt
+ LEFT_ALT = 0x000700e2;
+
+ /// Keyboard Left GUI (Meta, Windows)
+ LEFT_META = 0x000700e3;
+
+ /// Keyboard Right Control
+ RIGHT_CTRL = 0x000700e4;
+
+ /// Keyboard Right Shift
+ RIGHT_SHIFT = 0x000700e5;
+
+ /// Keyboard Right Alt
+ RIGHT_ALT = 0x000700e6;
+
+ /// Keyboard Right GUI (Meta, Windows)
+ RIGHT_META = 0x000700e7;
+
+ /// Keyboard Menu
+ MENU = 0x00070076;
+
+ /// Keypad Num Lock and Clear
+ NUM_LOCK = 0x00070053;
+
+ /// Keypad /
+ KEYPAD_SLASH = 0x00070054;
+
+ /// Keypad *
+ KEYPAD_ASTERISK = 0x00070055;
+
+ /// Keypad -
+ KEYPAD_MINUS = 0x00070056;
+
+ /// Keypad +
+ KEYPAD_PLUS = 0x00070057;
+
+ /// Keypad ENTER
+ KEYPAD_ENTER = 0x00070058;
+
+ /// Keypad 1 and End
+ KEYPAD_1 = 0x00070059;
+
+ /// Keypad 2 and Down Arrow
+ KEYPAD_2 = 0x0007005a;
+
+ /// Keypad 3 and Page Down
+ KEYPAD_3 = 0x0007005b;
+
+ /// Keypad 4 and Left Arrow
+ KEYPAD_4 = 0x0007005c;
+
+ /// Keypad 5
+ KEYPAD_5 = 0x0007005d;
+
+ /// Keypad 6 and Right Arrow
+ KEYPAD_6 = 0x0007005e;
+
+ /// Keypad 7 and Home
+ KEYPAD_7 = 0x0007005f;
+
+ /// Keypad 8 and Up Arrow
+ KEYPAD_8 = 0x00070060;
+
+ /// Keypad 9 and Page Up
+ KEYPAD_9 = 0x00070061;
+
+ /// Keypad 0 and Insert
+ KEYPAD_0 = 0x00070062;
+
+ /// Keypad . and Delete
+ KEYPAD_DOT = 0x00070063;
+
+ /// Keypad =
+ KEYPAD_EQUALS = 0x00070067;
+
+ /// Mute
+ MEDIA_MUTE = 0x000c00e2;
+
+ /// Volume Increment
+ MEDIA_VOLUME_INCREMENT = 0x000c00e9;
+
+ /// Volume Decrement
+ MEDIA_VOLUME_DECREMENT = 0x000c00ea;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.input/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.input/meta.json
new file mode 100644
index 0000000..798ac6e
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.input/meta.json
@@ -0,0 +1,9 @@
+{
+ "deps": [],
+ "name": "fuchsia.input",
+ "root": "fidl/fuchsia.input",
+ "sources": [
+ "fidl/fuchsia.input/keys.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.inspect/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.inspect/BUILD.gn
new file mode 100644
index 0000000..7054a66
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.inspect/BUILD.gn
@@ -0,0 +1,26 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.inspect") {
+ library_name = "inspect"
+ namespace = "fuchsia"
+ public_deps = [
+ "../fuchsia.mem",
+ ]
+ sources = [
+ "tree.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.inspect",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.inspect/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.inspect/meta.json
new file mode 100644
index 0000000..092874c
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.inspect/meta.json
@@ -0,0 +1,11 @@
+{
+ "deps": [
+ "fuchsia.mem"
+ ],
+ "name": "fuchsia.inspect",
+ "root": "fidl/fuchsia.inspect",
+ "sources": [
+ "fidl/fuchsia.inspect/tree.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.inspect/tree.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.inspect/tree.fidl
new file mode 100644
index 0000000..73dd766
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.inspect/tree.fidl
@@ -0,0 +1,65 @@
+// 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.
+
+library fuchsia.inspect;
+using fuchsia.mem;
+
+/// Maximum length of an Inspect Tree, specified by the format.
+const uint64 MAX_TREE_NAME_LENGTH = 2040;
+
+/// Maximum number of children returned by a single read of the tree name iterator.
+const uint64 MAX_TREE_NAME_LIST_SIZE = 64;
+
+using TreeName = string:MAX_TREE_NAME_LENGTH;
+
+/// The content of a specific Inspect Tree.
+table TreeContent {
+ /// Buffer containing the bytes of a tree in Inspect format.
+ 1: fuchsia.mem.Buffer buffer;
+};
+
+/// Iterator protocol for listing the names of children of a particular Tree.
+protocol TreeNameIterator {
+ /// Get the next batch of names.
+ ///
+ /// Returns an empty vector and closes the channel when no more names are present.
+ /// Implementors may eagerly close the channel after sending the last batch.
+ GetNext() -> (vector<TreeName>:MAX_TREE_NAME_LIST_SIZE name);
+};
+
+/// The Tree protocol represents a hierarchy of Inspect VMOs.
+///
+/// Link values stored in an Inspect file contain references to new
+/// named files that contain a continuation of the data for the overall
+/// hierarchy. Protocol Tree allows clients to request these named files so
+/// long as the hosting component is still alive.
+///
+/// Connecting to a particular tree keeps the content for that Tree resident
+/// in memory. Clients are recommended to traverse the trees in depth-first
+/// order to reduce memory usage. Serving components are free to deny
+/// connections to avoid unbounded memory usage.
+[Discoverable]
+protocol Tree {
+ /// Get the content for the Inspect VMO backing this tree.
+ ///
+ /// So long as the Tree connection is still maintained, the contents
+ /// of the tree are guaranteed to still be live. Once the connection is
+ /// lost, the serving component is free to clear the contents of returned
+ /// shared buffers.
+ ///
+ /// Serving components may return different buffers to GetContent
+ /// requests for the same Tree.
+ GetContent() -> (TreeContent content);
+
+ /// Iterate over the names of Trees that are children of this Tree.
+ ///
+ /// The underlying list of children may change in between calls to
+ /// ListChildNames and OpenChild.
+ ListChildNames(request<TreeNameIterator> tree_iterator);
+
+ /// Open a child Tree by name.
+ ///
+ /// If the child cannot be opened, the given request is closed.
+ OpenChild(TreeName child_name, request<Tree> tree);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.intl/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.intl/BUILD.gn
new file mode 100644
index 0000000..370f977
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.intl/BUILD.gn
@@ -0,0 +1,26 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.intl") {
+ library_name = "intl"
+ namespace = "fuchsia"
+ public_deps = [
+ ]
+ sources = [
+ "intl.fidl",
+ "property_provider.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.intl",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.intl/intl.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.intl/intl.fidl
new file mode 100644
index 0000000..d453015
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.intl/intl.fidl
@@ -0,0 +1,107 @@
+// Copyright 2018 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.
+
+library fuchsia.intl;
+
+/// Typed identifier for a regulatory domain as specified in the IEEE 802.11 standard.
+table RegulatoryDomain {
+ /// ISO 3166-1 alpha-2, a two-letter code representing a domain of operation.
+ /// (https://www.iso.org/publication/PUB500001.html)
+ 1: string country_code;
+};
+
+/// Typed identifier for a single Locale, which is a set of internationalization-related properties.
+///
+/// Most APIs that consume locales will probably want to accept a vector of locales to account for
+/// priority.
+struct LocaleId {
+ /// Unicode BCP-47 Locale Identifier
+ /// (http://www.unicode.org/reports/tr35/#BCP_47_Conformance).
+ ///
+ /// Must be canonicalized and well-formed. This field should not be populated from arbitrary
+ /// user- or third-party input, but instead generated programmatically.
+ ///
+ /// Includes language, region, script, and variant, plus Unicode extensions (under the "u"
+ /// singleton). Other extensions are allowed but ignored.
+ ///
+ /// Examples:
+ /// "en-US"
+ /// American English
+ /// "fr-u-hc-h12"
+ /// French, with 12-hour clock
+ /// "ar-EG-u-fw-mon-nu-latn"
+ /// Egyptian Arabic with "Latin" numerals and first day of week on Monday
+ string id;
+};
+
+/// Typed identifier for a single calendar system. Currently consists only of a calendar ID.
+struct CalendarId {
+ /// Unicode BCP-47 Locale Identifier with an undefined language tag and a single extension
+ /// specifying the calendar ID (from
+ /// https://unicode.org/repos/cldr/trunk/common/bcp47/calendar.xml).
+ ///
+ /// Examples:
+ /// "und-u-ca-gregory"
+ /// "und-u-ca-islamic"
+ string id;
+};
+
+/// This is the time zone reported when no time zones have been set.
+const string DEFAULT_TIME_ZONE_ID = "UTC";
+
+/// Typed identifier for a time zone.
+struct TimeZoneId {
+ /// Time zone ID from tzdata, e.g. "America/New_York". See https://www.iana.org/time-zones.
+ string id;
+};
+
+/// Selection of [temperature units](https://en.wikipedia.org/wiki/Degree_(temperature)).
+enum TemperatureUnit {
+ /// The temperature should be formatted to show temperature in degrees Celsius.
+ CELSIUS = 0;
+ /// The temperature should be formatted to show temperature in degrees Fahrenheit.
+ FAHRENHEIT = 1;
+};
+
+/// A collection of ranked internationalization properties.
+///
+/// There is no implied origin for this information; it might come from a user account, device
+/// settings, a synthesis of user settings and app-specific overrides, or anywhere else.
+///
+/// Language-independent properties that are supported by Unicode BCP-47 Locale IDs (e.g.
+/// first-day-of-week, time zone) are denormalized into the locale IDs in `locales`.
+table Profile {
+ /// Ranked list of locales (in descending order of preference). The vector will always
+ /// contain at least one element. For example, locales = [ LocaleId("en-US") ] is valid, but
+ /// locales = [], or locales = <unset> is not.
+ 1: vector<LocaleId> locales;
+
+ /// Ranked list of calendars (in descending order of preference).
+ /// The first entry is the primary calendar, and will be equal to the calendar indicated
+ /// in `locales`.
+ /// The vector will always contain at least one element.
+ /// The list allows multiple ranked preferences, and is intended for use
+ /// by applications that can display multiple calendar systems.
+ 2: vector<CalendarId> calendars;
+
+ /// Ranked list of time zones (in descending order). The first entry is the primary time zone,
+ /// which should be used by default for formatting dates and times; it will be equal to the
+ /// calendar indicated in `locales`.
+ /// The list is intended for use by applications that can display multiple time zones, e.g.
+ /// a world clock.
+ /// The vector will always contain at least one element.
+ /// On Fuchsia, the default time zone is always `DEFAULT_TIME_ZONE_ID` when
+ /// no more specific time zones have been defined or selected.
+ 3: vector<TimeZoneId> time_zones;
+
+ /// Selected temperature unit. The unit is always reported: if there is no
+ /// setting in the current environment, the default value of CELSIUS is
+ /// used.
+ 4: TemperatureUnit temperature_unit;
+
+ // TODO(CF-168): Other properties that don't fit into locale IDs. Examples:
+ // - User date format overrides, like d/mmm/y
+ // - User currency overrides
+ // - User number overrides (grouping, decimal point)
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.intl/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.intl/meta.json
new file mode 100644
index 0000000..1ef4f05
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.intl/meta.json
@@ -0,0 +1,10 @@
+{
+ "deps": [],
+ "name": "fuchsia.intl",
+ "root": "fidl/fuchsia.intl",
+ "sources": [
+ "fidl/fuchsia.intl/intl.fidl",
+ "fidl/fuchsia.intl/property_provider.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.intl/property_provider.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.intl/property_provider.fidl
new file mode 100644
index 0000000..296a2cb
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.intl/property_provider.fidl
@@ -0,0 +1,22 @@
+// 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.
+
+library fuchsia.intl;
+
+/// Provides internationalization properties.
+///
+/// Components that need to change their behavior in response to the user's internationalization
+/// profile may request an instance of this service from their namespace, if available. A component
+/// may choose to pass along the service that it received from its parent to its own children, or to
+/// override it and apply additional customizations.
+///
+/// See also `fuchsia.ui.views.View`.
+[Discoverable]
+protocol PropertyProvider {
+ /// Gets the user's internationalization profile.
+ GetProfile() -> (Profile profile);
+
+ /// Indicates that the properties may have changed and the client should query them again.
+ -> OnChange();
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.io/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.io/BUILD.gn
new file mode 100644
index 0000000..c94be42
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.io/BUILD.gn
@@ -0,0 +1,26 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.io") {
+ library_name = "io"
+ namespace = "fuchsia"
+ public_deps = [
+ "../fuchsia.mem",
+ ]
+ sources = [
+ "io.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.io",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.io/io.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.io/io.fidl
new file mode 100644
index 0000000..6259620
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.io/io.fidl
@@ -0,0 +1,659 @@
+// Copyright 2018 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.
+
+library fuchsia.io;
+
+using fuchsia.mem;
+using zx;
+
+/// Describes how the connection to an should be handled, as well as
+/// how to interpret the optional handle.
+///
+/// Refer to `Node.Describe()` and `Node.OnOpen()` for usage.
+union NodeInfo {
+ 1: Service service;
+ 2: FileObject file;
+ 3: DirectoryObject directory;
+ 4: Pipe pipe;
+ 5: Vmofile vmofile;
+ 6: Device device;
+ 7: Tty tty;
+ 8: reserved;
+ 9: DatagramSocket datagram_socket;
+ 10: StreamSocket stream_socket;
+};
+
+/// The default protocol, interface information must be acquired some
+/// other way.
+struct Service {
+};
+
+/// Indicates the file is ready for reading.
+const uint32 FILE_SIGNAL_READABLE = 0x01000000; // ZX_USER_SIGNAL_0
+/// Indicates the file is ready for writing.
+const uint32 FILE_SIGNAL_WRITABLE = 0x02000000; // ZX_USER_SIGNAL_1
+
+/// The object may be cast to interface 'File'.
+struct FileObject {
+ /// An optional event which transmits information about an object's readability
+ /// or writability. This event relays information about the underlying object, not
+ /// the capability granted to client: this event may be signalled "readable" on a
+ /// connection that does not have the capability to read.
+ ///
+ /// The "`FILE_SIGNAL_`" values may be observed on this event.
+ handle<event>? event;
+
+ /// A placeholder for future stream support.
+ ///
+ /// Currently, servers are required not to send a handle in this field.
+ handle<stream>? stream;
+};
+
+/// The object may be cast to interface 'Directory'.
+struct DirectoryObject {
+};
+
+/// The object is accompanied by a pipe.
+struct Pipe {
+ handle<socket> socket;
+};
+
+/// The object is a file which is represented as an immutable VMO.
+/// Although a VMO is returned as a part of this structure, this underlying object
+/// may represent multiple Vmofiles. To identify the logical portion of the VMO
+/// that represents the single file, an offset and length parameter are also supplied.
+struct Vmofile {
+ /// The VMO which backs this file.
+ handle<vmo> vmo;
+ /// The index into `vmo` which represents the first byte of the file.
+ uint64 offset;
+ /// The number of bytes, starting at `offset`, which may be used to represent this file.
+ uint64 length;
+};
+
+/// Indicates the device is ready for reading.
+const uint32 DEVICE_SIGNAL_READABLE = 0x01000000; // ZX_USER_SIGNAL_0
+/// Indicates an out-of-band state transition has occurred.
+const uint32 DEVICE_SIGNAL_OOB = 0x02000000; // ZX_USER_SIGNAL_1
+/// Indicates the device is ready for writing.
+const uint32 DEVICE_SIGNAL_WRITABLE = 0x04000000; // ZX_USER_SIGNAL_2
+/// Indicates the device has encountered an error state.
+const uint32 DEVICE_SIGNAL_ERROR = 0x08000000; // ZX_USER_SIGNAL_3
+/// Indicates the device has hung up on the current connection.
+const uint32 DEVICE_SIGNAL_HANGUP = 0x10000000; // ZX_USER_SIGNAL_4
+
+/// The object may be cast to interface 'Device'.
+struct Device {
+ /// An optional event which transmits information about a device's state.
+ ///
+ /// The "`DEVICE_SIGNAL_`" values may be observed on this event.
+ handle<eventpair>? event;
+};
+
+/// The object may be cast to interface 'Tty'
+struct Tty {
+ handle<eventpair>? event;
+};
+
+/// The object may be cast to interface [`fuchsia.posix.socket.DatagramSocket`].
+struct DatagramSocket {
+ /// See [`fuchsia.posix.socket.DatagramSocket`] for details.
+ handle<eventpair> event;
+};
+
+/// The object may be cast to interface [`fuchsia.posix.socket.StreamSocket`].
+struct StreamSocket {
+ handle<socket> socket;
+};
+
+/// Can read from target object.
+const uint32 OPEN_RIGHT_READABLE = 0x00000001;
+/// Can write to target object.
+const uint32 OPEN_RIGHT_WRITABLE = 0x00000002;
+/// Connection can mount/umount filesystem.
+const uint32 OPEN_RIGHT_ADMIN = 0x00000004;
+/// Connection can map target object executable.
+const uint32 OPEN_RIGHT_EXECUTABLE = 0x00000008;
+
+/// Create the object if it doesn't exist.
+const uint32 OPEN_FLAG_CREATE = 0x00010000;
+/// (with Create) Fail if the object already exists.
+const uint32 OPEN_FLAG_CREATE_IF_ABSENT = 0x00020000;
+/// Truncate the object before usage.
+const uint32 OPEN_FLAG_TRUNCATE = 0x00040000;
+/// Assert that the object to be opened is a directory.
+/// Return an error if the target object is not a directory.
+const uint32 OPEN_FLAG_DIRECTORY = 0x00080000;
+/// Seek to the end of the object before all writes.
+const uint32 OPEN_FLAG_APPEND = 0x00100000;
+/// If the object is a mount point, open the local directory.
+const uint32 OPEN_FLAG_NO_REMOTE = 0x00200000;
+/// Open a reference to the object, not the object itself.
+/// It is ONLY valid to pass the following flags together with `OPEN_FLAG_NODE_REFERENCE`:
+/// - `OPEN_FLAG_DIRECTORY`
+/// - `OPEN_FLAG_NOT_DIRECTORY`
+/// - `OPEN_FLAG_DESCRIBE`
+/// otherwise an error is returned.
+/// If an object is opened or cloned using this method, the resulting connection does not carry
+/// any permission flags.
+/// The resulting node allows a limited set of operations: `GetAttr`, `Clone`, `Close`, `Describe`,
+/// and, if the node is a file, these extra operations: `GetFlags`, `SetFlags`.
+const uint32 OPEN_FLAG_NODE_REFERENCE = 0x00400000;
+/// Binary OR of `OPEN_FLAG_DIRECTORY`, OPEN_FLAG_NOT_DIRECTORY, OPEN_FLAG_DESCRIBE, and
+/// `OPEN_FLAG_NODE_REFERENCE`. Flags used when opening a node reference must fall within this mask.
+const uint32 OPEN_FLAGS_ALLOWED_WITH_NODE_REFERENCE = 0x02c80000;
+/// Requests that an "OnOpen" event is sent to the interface request.
+/// The event will contain a non-null NodeInfo if the open/clone is successful.
+const uint32 OPEN_FLAG_DESCRIBE = 0x00800000;
+/// Specify this flag to request POSIX-compatibility. Currently, it affects permission handling.
+/// During Open:
+/// - If the target path is a directory, the rights on the new connection expand to include
+/// `OPEN_RIGHT_WRITABLE` if and only if the current connection and all intermediate mount points
+/// are writable, and to include `OPEN_RIGHT_EXECUTABLE` if and only if the current connection and
+/// all intermediate mount points are executable.
+/// - Otherwise, this flag is ignored. It is an access denied error to request more rights
+/// than those on the current connection, or any intermediate mount points.
+///
+/// If the posix compatibility flag is not specified, opening always uses the requested rights,
+/// failing the operation with access denied error if requested rights exceeds the rights attached
+/// to the current connection.
+///
+/// If the requesting connection is read-only and the requested rights are read-only, the flag
+/// may be ignored by the server, and is not forwarded downstream. This is an implementation detail,
+/// necessary to enforce hierarchical permissions across mount points, and should have no effect
+/// on the expected behavior for clients.
+const uint32 OPEN_FLAG_POSIX = 0x01000000;
+/// Assert that the object to be opened is not a directory.
+/// Return an error if the target object is a directory.
+const uint32 OPEN_FLAG_NOT_DIRECTORY = 0x02000000;
+/// When used during clone, the new connection inherits the rights on the source connection,
+/// regardless if it is a file or directory. Otherwise, clone attempts to use the requested rights.
+/// It is invalid to pass any of the `OPEN_RIGHT_*` flags together with `CLONE_FLAG_SAME_RIGHTS`.
+const uint32 CLONE_FLAG_SAME_RIGHTS = 0x04000000;
+
+/// Node defines the minimal interface for entities which can be accessed in a filesystem.
+[Layout = "Simple"]
+protocol Node {
+ /// Create another connection to the same remote object.
+ ///
+ /// `flags` may be any of:
+ ///
+ /// - `OPEN_RIGHT_*`
+ /// - `OPEN_FLAG_APPEND`
+ /// - `OPEN_FLAG_NO_REMOTE`
+ /// - `OPEN_FLAG_DESCRIBE`
+ /// - `CLONE_FLAG_SAME_RIGHTS`
+ ///
+ /// All other flags are ignored.
+ ///
+ /// The `OPEN_RIGHT_*` bits in `flags` request corresponding rights over the resulting
+ /// cloned object.
+ /// The cloned object must have rights less than or equal to the original object.
+ /// Alternatively, pass `CLONE_FLAG_SAME_RIGHTS` to inherit the rights on the source connection.
+ /// It is invalid to pass any of the `OPEN_RIGHT_*` flags together with
+ /// `CLONE_FLAG_SAME_RIGHTS`.
+ Clone(uint32 flags, request<Node> object);
+
+ /// Terminates connection with object.
+ ///
+ /// This method does not require any rights.
+ Close() -> (zx.status s);
+
+ /// Returns extra information about the type of the object.
+ /// If the `Describe` operation fails, the connection is closed.
+ ///
+ /// This method does not require any rights.
+ Describe() -> (NodeInfo info);
+
+ /// An event produced eagerly by a FIDL server if requested by `OPEN_FLAG_DESCRIBE`.
+ ///
+ /// Indicates the success or failure of the open operation, and optionally describes the
+ /// object. If the status is `ZX_OK`, `info` contains descriptive information about the object
+ /// (the same as would be returned by `Describe`).
+ -> OnOpen(zx.status s, NodeInfo? info);
+
+ /// Synchronizes updates to the node to the underlying media, if it exists.
+ ///
+ /// This method does not require any rights.
+ Sync() -> (zx.status s);
+
+ /// Acquires information about the node.
+ ///
+ /// This method does not require any rights.
+ GetAttr() -> (zx.status s, NodeAttributes attributes);
+
+ /// Updates information about the node.
+ /// `flags` may be any of `NODE_ATTRIBUTE_FLAG_*`.
+ ///
+ /// This method requires following rights: `OPEN_RIGHT_WRITABLE`.
+ SetAttr(uint32 flags, NodeAttributes attributes) -> (zx.status s);
+
+ /// Acquires the `Directory.Open` rights and flags used to access this file.
+ ///
+ /// This method does not require any rights.
+ /// This method has the same functionality as GetFlags for File and is
+ /// meant as an in-progress replacement.
+ [Transitional]
+ NodeGetFlags() -> (zx.status s, uint32 flags);
+
+ /// Changes the `Directory.Open` flags used to access the file.
+ /// Supported flags which can be turned on / off:
+ /// - `OPEN_FLAG_APPEND`
+ ///
+ /// This method does not require any rights.
+ /// This method has the same functionality as SetFlags for File and is
+ /// meant as an in-progress replacement.
+ [Transitional]
+ NodeSetFlags(uint32 flags) -> (zx.status s);
+};
+
+/// Bits reserved for posix protections. Native fuchsia filesystems
+/// are not required to set bits contained within `MODE_PROTECTION_MASK`,
+/// but filesystems that wish to do so may refer to sys/stat.h for their
+/// definitions.
+const uint32 MODE_PROTECTION_MASK = 0x00FFF;
+/// Bits indicating node type. The canonical mechanism to check
+/// for a node type is to take 'mode', bitwise AND it with the
+/// `MODE_TYPE_MASK`, and check exact equality against a mode type.
+const uint32 MODE_TYPE_MASK = 0xFF000;
+const uint32 MODE_TYPE_DIRECTORY = 0x04000;
+const uint32 MODE_TYPE_BLOCK_DEVICE = 0x06000;
+const uint32 MODE_TYPE_FILE = 0x08000;
+const uint32 MODE_TYPE_SOCKET = 0x0C000;
+const uint32 MODE_TYPE_SERVICE = 0x10000;
+
+/// NodeAttributes defines generic information about a filesystem node.
+struct NodeAttributes {
+ /// Protection bits and node type information describe in 'mode'.
+ uint32 mode;
+ /// A filesystem-unique ID.
+ uint64 id;
+ /// Node size, in bytes.
+ uint64 content_size;
+ /// Space needed to store node (possibly larger than size), in bytes.
+ uint64 storage_size;
+ /// Hard link count.
+ uint64 link_count;
+ /// Time of creation (may be updated manually after creation) in ns since Unix epoch, UTC.
+ uint64 creation_time;
+ /// Time of last modification in ns since Unix epoch, UTC.
+ uint64 modification_time;
+};
+
+/// The maximal buffer size which can be transmitted for buffered operations.
+/// This capacity is currently set somewhat arbitrarily.
+const uint64 MAX_BUF = 8192;
+/// The maximum length, in bytes, of a filesystem string.
+// TODO(smklein): Update to 4095. +1 is for null-terminator, which shouldn't be
+// part of the FIDL length.
+const uint64 MAX_PATH = 4096;
+/// The maximum length, in bytes, of a single filesystem component.
+const uint64 MAX_FILENAME = 255;
+
+/// The fields of 'attributes' which are used to update the Node are indicated
+/// by the 'flags' argument.
+const uint32 NODE_ATTRIBUTE_FLAG_CREATION_TIME = 0x00000001;
+const uint32 NODE_ATTRIBUTE_FLAG_MODIFICATION_TIME = 0x00000002;
+
+/// Update the Seek offset.
+enum SeekOrigin : uint32 {
+ /// Seek from the start of the file.
+ START = 0;
+ /// Seek from the current position in the file.
+ CURRENT = 1;
+ /// Seek from the end of the file.
+ END = 2;
+};
+
+/// Requests that the VMO be readable.
+const uint32 VMO_FLAG_READ = 0x00000001;
+
+/// Requests that the VMO be writable.
+const uint32 VMO_FLAG_WRITE = 0x00000002;
+
+/// Requests that the VMO be executable.
+const uint32 VMO_FLAG_EXEC = 0x00000004;
+
+/// Require a copy-on-write clone of the underlying VMO.
+/// The request should fail if the VMO is not cloned.
+/// May not be supplied with fuchsia_io_`VMO_FLAG_EXACT`.
+const uint32 VMO_FLAG_PRIVATE = 0x00010000;
+
+/// Require an exact (non-cloned) handle to the underlying VMO.
+/// The request should fail if a handle to the exact VMO is not returned.
+/// May not be supplied with `VMO_FLAG_PRIVATE`.
+const uint32 VMO_FLAG_EXACT = 0x00020000;
+
+/// File defines the interface of a node which contains a flat layout of data.
+[Layout = "Simple"]
+protocol File {
+ compose Node;
+
+ /// Reads `count` bytes at the seek offset.
+ /// The seek offset is moved forward by the number of bytes read.
+ ///
+ /// This method requires following rights: `OPEN_RIGHT_READABLE`.
+ Read(uint64 count) -> (zx.status s, vector<uint8>:MAX_BUF data);
+
+ /// Reads `count` bytes at the provided offset.
+ /// Does not affect the seek offset.
+ ///
+ /// This method requires following rights: `OPEN_RIGHT_READABLE`.
+ ReadAt(uint64 count, uint64 offset) -> (zx.status s, vector<uint8>:MAX_BUF data);
+
+ /// Writes data at the seek offset.
+ /// The seek offset is moved forward by the number of bytes written.
+ ///
+ /// This method requires following rights: `OPEN_RIGHT_WRITABLE`.
+ Write(vector<uint8>:MAX_BUF data) -> (zx.status s, uint64 actual);
+
+ /// Writes data to the provided offset.
+ /// Does not affect the seek offset.
+ ///
+ /// This method requires following rights: `OPEN_RIGHT_WRITABLE`.
+ WriteAt(vector<uint8>:MAX_BUF data, uint64 offset) -> (zx.status s, uint64 actual);
+
+ /// Moves the offset at which the next invocation of `Read()` or `Write()` will
+ /// occur.
+ ///
+ /// This method does not require any rights.
+ Seek(int64 offset, SeekOrigin start) -> (zx.status s, uint64 offset);
+
+ /// Shrinks the file size to 'length' bytes.
+ ///
+ /// This method requires following rights: `OPEN_RIGHT_WRITABLE`.
+ Truncate(uint64 length) -> (zx.status s);
+
+ /// Acquires the `Directory.Open` rights and flags used to access this file.
+ ///
+ /// This method does not require any rights.
+ GetFlags() -> (zx.status s, uint32 flags);
+
+ /// Changes the `Directory.Open` flags used to access the file.
+ /// Supported flags which can be turned on / off:
+ /// - `OPEN_FLAG_APPEND`
+ ///
+ /// This method does not require any rights.
+ SetFlags(uint32 flags) -> (zx.status s);
+
+ /// Acquires a buffer representing this file, if there is one, with the
+ /// requested access rights.
+ ///
+ /// `flags` may be any of `VMO_FLAG_*`.
+ ///
+ /// This method requires following rights:
+ ///
+ /// - `OPEN_RIGHT_WRITABLE` if `flags` includes `VMO_FLAG_WRITE`.
+ /// - `OPEN_RIGHT_READABLE` if `flags` includes `VMO_FLAG_READ` or `VMO_FLAG_EXEC`.
+ GetBuffer(uint32 flags) -> (zx.status s, fuchsia.mem.Buffer? buffer);
+};
+
+// Dirent type information associated with the results of ReadDirents.
+// The following values are aligned with the values from libc's "dirent.h" "DT_...".
+
+/// A dirent with an unknown type.
+const uint8 DIRENT_TYPE_UNKNOWN = 0;
+/// A dirent representing a directory object.
+const uint8 DIRENT_TYPE_DIRECTORY = 4;
+/// A dirent representing a block device object.
+const uint8 DIRENT_TYPE_BLOCK_DEVICE = 6;
+/// A dirent representing a file object.
+const uint8 DIRENT_TYPE_FILE = 8;
+/// A dirent representing a socket object.
+const uint8 DIRENT_TYPE_SOCKET = 12;
+/// A dirent representing a service object.
+const uint8 DIRENT_TYPE_SERVICE = 16;
+
+/// Nodes which do not have ino values should return this value
+/// from Readdir and GetAttr.
+const uint64 INO_UNKNOWN = 0xFFFFFFFFFFFFFFFF;
+
+/// Indicates the directory being watched has been deleted.
+const uint8 WATCH_EVENT_DELETED = 0;
+/// Indicates a node has been created (either new or moved) into a directory.
+const uint8 WATCH_EVENT_ADDED = 1;
+/// Identifies a node has been removed (either deleted or moved) from the directory.
+const uint8 WATCH_EVENT_REMOVED = 2;
+/// Identifies a node already existed in the directory when watching started.
+const uint8 WATCH_EVENT_EXISTING = 3;
+/// Identifies that no more `WATCH_EVENT_EXISTING` events will be sent.
+const uint8 WATCH_EVENT_IDLE = 4;
+
+/// Used by `Directory.Watch`. Requests transmission of `WATCH_EVENT_DELETED`.
+const uint32 WATCH_MASK_DELETED = 0x00000001;
+/// Used by `Directory.Watch`. Requests transmission of `WATCH_EVENT_ADDED`.
+const uint32 WATCH_MASK_ADDED = 0x00000002;
+/// Used by `Directory.Watch`. Requests transmission of `WATCH_EVENT_REMOVED`.
+const uint32 WATCH_MASK_REMOVED = 0x00000004;
+/// Used by `Directory.Watch`. Requests transmission of `WATCH_EVENT_EXISTING`.
+const uint32 WATCH_MASK_EXISTING = 0x00000008;
+/// Used by `Directory.Watch`. Requests transmission of `WATCH_EVENT_IDLE`.
+const uint32 WATCH_MASK_IDLE = 0x00000010;
+/// Used by `Directory.Watch`. Requests transmission of all watcher events.
+const uint32 WATCH_MASK_ALL = 0x0000001F;
+
+// TODO(ZX-2645): Unused.
+/// WatchedEvent describes events returned from a DirectoryWatcher.
+struct WatchedEvent {
+ uint8 event;
+ uint8 len;
+ vector<uint8>:MAX_FILENAME name;
+};
+
+// TODO(ZX-2645): Unused.
+/// DirectoryWatcher transmits messages from a filesystem server
+/// about events happening in the filesystem. Clients can register
+/// new watchers using the `Directory.Watch` method, where they can
+/// filter which events they want to receive notifications for.
+[Layout = "Simple"]
+protocol DirectoryWatcher {
+ // TODO(smklein): Convert this to a vector of WatchedEvents, when possible.
+ OnEvent(vector<uint8>:MAX_BUF events);
+};
+
+/// Directory defines a node which is capable of containing other Objects.
+[Layout = "Simple"]
+protocol Directory {
+ compose Node;
+
+ /// Opens a new object relative to this directory object.
+ ///
+ /// `path` may contain multiple segments, separated by "/" characters,
+ /// and should never be empty; i.e., "" is an invalid path.
+ ///
+ /// `flags` may be any of the `OPEN_FLAG_*` and `OPEN_RIGHT_*` values, bitwise ORed together.
+ /// The `OPEN_FLAG_DESCRIBE` flag may cause an `OnOpen` event to be transmitted
+ /// on the `object` handle, indicating the type of object opened.
+ ///
+ /// If an unknown value is sent for either flags or mode, the connection should
+ /// be closed.
+ ///
+ /// `OPEN_RIGHT_*` flags provided in `flags` will restrict access rights on
+ /// the `object` channel which will be connected to the opened entity.
+ ///
+ /// Rights are never increased. When you open a nested entity within a directory, you may only
+ /// request the same rights as what the directory connection already has, or a subset of those.
+ /// Exceeding those rights causes an access denied error to be transmitted in the
+ /// `OnOpen` event if applicable, and the `object` connection closed.
+ ///
+ /// The caller must specify either one or more of the `OPEN_RIGHT_*` flags, or
+ /// the `OPEN_FLAG_NODE_REFERENCE` flag.
+ // TODO(smklein): Who uses mode? Can it be removed?
+ Open(uint32 flags, uint32 mode, string:MAX_PATH path, request<Node> object);
+
+ /// Detaches an object from this directory object.
+ ///
+ /// The underlying object may or may not be deleted after this method
+ /// completes: although the link will be removed from the containing directory,
+ /// objects with multiple references (such as files which are still open)
+ /// will not actually be destroyed until all references are removed.
+ ///
+ /// If a directory is unlinked while it still has an open reference,
+ /// it must become read-only, preventing new entries from being created
+ /// until all references close and the directory is destroyed.
+ ///
+ /// `path` identifies the file which should be detached.
+ /// If `path` contains multiple segments, separated by "/" characters,
+ /// then the directory is traversed, one segment at a time, relative to the
+ /// originally accessed Directory.
+ ///
+ /// Returns:
+ /// `ZX_ERR_ACCESS_DENIED` if the connection (or the underlying filesystem) does not
+ /// allow writable access.
+ /// `ZX_ERR_INVALID_ARGS` if `path` contains ".." segments.
+ /// `ZX_ERR_NOT_EMPTY` if `path` refers to a non-empty directory.
+ /// `ZX_ERR_UNAVAILABLE` if `path` refers to a mount point, containing a remote channel.
+ /// `ZX_ERR_UNAVAILABLE` if `path` is ".".
+ ///
+ /// Other errors may be returned for filesystem-specific reasons.
+ ///
+ /// This method requires following rights: `OPEN_RIGHT_WRITABLE`.
+ Unlink(string:MAX_PATH path) -> (zx.status s);
+
+ /// Reads a collection of variably sized dirents into a buffer.
+ /// The number of dirents in a directory may be very large: akin to
+ /// calling read multiple times on a file, directories have a seek
+ /// offset which is updated on subsequent calls to ReadDirents.
+ ///
+ /// These dirents are of the form:
+ /// ```
+ /// struct dirent {
+ /// // Describes the inode of the entry.
+ /// uint64 ino;
+ /// // Describes the length of the dirent name in bytes.
+ /// uint8 size;
+ /// // Describes the type of the entry. Aligned with the
+ /// // POSIX d_type values. Use `DIRENT_TYPE_*` constants.
+ /// uint8 type;
+ /// // Unterminated name of entry.
+ /// char name[0];
+ /// }
+ /// ```
+ ///
+ /// This method does not require any rights, since one could always probe for
+ /// directory contents by triggering name conflicts during file creation.
+ // TODO(smklein): Convert to a vector of variable-length objects, when
+ // llcpp arrives.
+ // TODO(smklein): Get rid of "max_bytes".
+ // TODO(smklein): Document the behavior when the seek pointer reaches the end of the directory.
+ ReadDirents(uint64 max_bytes) -> (zx.status s, vector<uint8>:MAX_BUF dirents);
+
+ /// Resets the directory seek offset.
+ ///
+ /// This method does not require any rights, similar to ReadDirents.
+ Rewind() -> (zx.status s);
+
+ /// Acquires a token to a Directory which can be used to identify
+ /// access to it at a later point in time.
+ ///
+ /// This method requires following rights: `OPEN_RIGHT_WRITABLE`.
+ GetToken() -> (zx.status s, handle? token);
+
+ /// Renames an object named src to the name dst, in a directory represented by token.
+ ///
+ /// `src/dst` must be resolved object names. Including "/" in any position
+ /// other than the end of the string will return `ZX_ERR_INVALID_ARGS`.
+ /// Returning "/" at the end of either string implies that it must be a
+ /// directory, or else `ZX_ERR_NOT_DIR` should be returned.
+ ///
+ /// This method requires following rights: `OPEN_RIGHT_WRITABLE`.
+ Rename(string:MAX_PATH src, handle dst_parent_token, string:MAX_PATH dst) -> (zx.status s);
+
+ /// Creates a link to an object named src by the name dst, within a directory represented by
+ /// token.
+ ///
+ /// `src` must be a resolved object name. Including "/" in the string will
+ /// return `ZX_ERR_INVALID_ARGS`.
+ ///
+ /// `dst` must be a resolved object name. Including "/" in the string will
+ /// return `ZX_ERR_INVALID_ARGS`.
+ ///
+ /// This method requires following rights: `OPEN_RIGHT_WRITABLE`.
+ Link(string:MAX_PATH src, handle dst_parent_token, string:MAX_PATH dst) -> (zx.status s);
+
+ // TODO(smklein): When stablized, remove the "This API is unstable" comment
+ /// Watches a directory, receiving events of added messages on the
+ /// watcher request channel.
+ ///
+ /// The `watcher` handle will send messages of the form:
+ /// ```
+ /// struct {
+ /// uint8 event;
+ /// uint8 len;
+ /// char name[];
+ /// };
+ /// ```
+ /// Where names are NOT null-terminated.
+ ///
+ /// This API is unstable; in the future, watcher will be a `DirectoryWatcher` client.
+ ///
+ /// Mask specifies a bitmask of events to observe.
+ /// Options must be zero; it is reserved.
+ ///
+ /// This method does not require any rights, similar to ReadDirents.
+ Watch(uint32 mask, uint32 options, handle<channel> watcher) -> (zx.status s);
+};
+
+const uint32 MOUNT_CREATE_FLAG_REPLACE = 0x00000001;
+
+const uint64 MAX_FS_NAME_BUFFER = 32;
+
+struct FilesystemInfo {
+ /// The number of data bytes which may be stored in a filesystem.
+ uint64 total_bytes;
+ /// The number of data bytes which are in use by the filesystem.
+ uint64 used_bytes;
+ /// The number of nodes which may be stored in the filesystem.
+ uint64 total_nodes;
+ /// The number of nodes used by the filesystem.
+ uint64 used_nodes;
+ /// The amount of space which may be allocated from the underlying
+ /// volume manager. If unsupported, this will be zero.
+ uint64 free_shared_pool_bytes;
+ /// A unique identifier for this filesystem instance. Will not be preserved
+ /// across reboots.
+ uint64 fs_id;
+ /// The size of a single filesystem block.
+ uint32 block_size;
+ /// The maximum length of a filesystem name.
+ uint32 max_filename_size;
+ /// A unique identifier for the type of the underlying filesystem.
+ uint32 fs_type;
+ uint32 padding;
+ // TODO(smklein): Replace this field with a string when supported
+ // by the "Simple" interface. At the moment, name is a fixed-size,
+ // null-terminated buffer.
+ array<int8>:MAX_FS_NAME_BUFFER name;
+};
+
+/// DirectoryAdmin defines a directory which is capable of handling
+/// administrator tasks within the filesystem.
+[Layout = "Simple"]
+protocol DirectoryAdmin {
+ compose Directory;
+
+ /// Mount a channel representing a remote filesystem onto this directory.
+ /// All future requests to this node will be forwarded to the remote filesystem.
+ /// To re-open a node without forwarding to the remote target, the node
+ /// should be opened with `OPEN_FLAG_NO_REMOTE`.
+ Mount(Directory remote) -> (zx.status s);
+
+ /// Atomically create a directory with a provided path, and mount the
+ /// remote handle to the newly created directory.
+ MountAndCreate(Directory remote, string:MAX_FILENAME name, uint32 flags) -> (zx.status s);
+
+ /// Unmount this filesystem. After this function returns successfully,
+ /// all connections to the filesystem will be terminated.
+ Unmount() -> (zx.status s);
+
+ /// Detach a node which was previously attached to this directory
+ /// with Mount.
+ UnmountNode() -> (zx.status s, Directory? remote);
+
+ /// Query the filesystem for filesystem-specific information.
+ QueryFilesystem() -> (zx.status s, FilesystemInfo? info);
+
+ /// Acquire the path to the device backing this filesystem, if there is one.
+ GetDevicePath() -> (zx.status s, string:MAX_PATH? path);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.io/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.io/meta.json
new file mode 100644
index 0000000..1a7c2a5
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.io/meta.json
@@ -0,0 +1,11 @@
+{
+ "deps": [
+ "fuchsia.mem"
+ ],
+ "name": "fuchsia.io",
+ "root": "fidl/fuchsia.io",
+ "sources": [
+ "fidl/fuchsia.io/io.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ldsvc/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.ldsvc/BUILD.gn
new file mode 100644
index 0000000..960ff46
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ldsvc/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.ldsvc") {
+ library_name = "ldsvc"
+ namespace = "fuchsia"
+ public_deps = [
+ ]
+ sources = [
+ "ldsvc.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.ldsvc",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ldsvc/ldsvc.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ldsvc/ldsvc.fidl
new file mode 100644
index 0000000..e823db7
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ldsvc/ldsvc.fidl
@@ -0,0 +1,34 @@
+// Copyright 2018 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.
+
+library fuchsia.ldsvc;
+
+using zx;
+
+/// See ///docs/zircon/program_loading.md for a more complete
+/// description of this and related process bootstrapping protocols, and
+/// for specifics about the default global loader service's
+/// interpretation of names, paths, and configurations.
+
+// WARNING: This interface is manually implemented in libldmsg.a. Please
+// update that implementation if you change this protocol.
+
+[Layout = "Simple"]
+protocol Loader {
+ /// Cleanly shutdown the connection to the Loader service.
+ Done();
+
+ /// The dynamic linker sends `object_name` and gets back a VMO
+ /// handle containing the file.
+ LoadObject(string:1024 object_name) -> (zx.status rv, handle<vmo>? object);
+
+ /// The dynamic linker sends a `config` identifying its load
+ /// configuration. This is intended to affect how later
+ /// `LoadObject` requests decide what particular implementation
+ /// file to supply for a given name.
+ Config(string:1024 config) -> (zx.status rv);
+
+ /// Obtain a new loader service connection.
+ Clone(request<Loader> loader) -> (zx.status rv);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ldsvc/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.ldsvc/meta.json
new file mode 100644
index 0000000..8c5869b
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ldsvc/meta.json
@@ -0,0 +1,9 @@
+{
+ "deps": [],
+ "name": "fuchsia.ldsvc",
+ "root": "fidl/fuchsia.ldsvc",
+ "sources": [
+ "fidl/fuchsia.ldsvc/ldsvc.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.legacymetrics/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.legacymetrics/BUILD.gn
new file mode 100644
index 0000000..bc26c8c
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.legacymetrics/BUILD.gn
@@ -0,0 +1,26 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.legacymetrics") {
+ library_name = "legacymetrics"
+ namespace = "fuchsia"
+ public_deps = [
+ ]
+ sources = [
+ "event.fidl",
+ "metrics_recorder.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.legacymetrics",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.legacymetrics/event.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.legacymetrics/event.fidl
new file mode 100644
index 0000000..faec2e6
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.legacymetrics/event.fidl
@@ -0,0 +1,61 @@
+// Copyright 2020 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.
+
+library fuchsia.legacymetrics;
+
+using zx;
+
+/// A single metric event to be recorded and sent to the UMA backend.
+union Event {
+ 1: UserActionEvent user_action_event;
+ 2: Histogram histogram;
+ 3: ImplementationDefinedEvent impl_defined_event;
+};
+
+/// Event that occurs in response to a user action. See
+/// https://chromium.googlesource.com/chromium/src.git/+/HEAD/tools/metrics/actions/README.md
+table UserActionEvent {
+ 1: string:MAX name;
+
+ /// Required timestamp of the event occurrence. See TimeTicks in
+ /// https://cs.chromium.org/chromium/src/base/time/time.h
+ 2: zx.time time;
+};
+
+table Histogram {
+ /// Required histogram identifier. See these guidelines for more info:
+ /// https://chromium.googlesource.com/chromium/src.git/+/HEAD/tools/metrics/histograms/README.md#naming-your-histogram
+ 1: string:MAX name;
+
+ 2: vector<HistogramBucket>:MAX buckets;
+
+ // The sum of all the sample values.
+ // Together with the total count of the sample values, this allows us to
+ // compute the average value. The count of all sample values is just the sum
+ // of the counts of all the buckets.
+ 3: int64 sum;
+};
+
+struct HistogramBucket {
+ // Each bucket's range is bounded by min <= x < max.
+ int64 min;
+ int64 max;
+
+ // The number of entries in this bucket.
+ int64 count;
+};
+
+/// A custom event defined by the MetricsRecorder service. Refer to your
+/// MetricsRecorder implementation for more details on the payload structure.
+table ImplementationDefinedEvent {
+ /// Custom binary payload whose structure is defined by the MetricsRecorder
+ /// implementation. For example, it can represent a custom event protocol
+ /// buffer serialized to its wire format.
+ 1: bytes data;
+
+ /// Event identifier required if it's not already included in binary `data`.
+ /// This field takes precedence over any equivalent name included in binary
+ /// `data`, if both are provided.
+ 2: string:MAX name;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.legacymetrics/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.legacymetrics/meta.json
new file mode 100644
index 0000000..a069465
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.legacymetrics/meta.json
@@ -0,0 +1,10 @@
+{
+ "deps": [],
+ "name": "fuchsia.legacymetrics",
+ "root": "fidl/fuchsia.legacymetrics",
+ "sources": [
+ "fidl/fuchsia.legacymetrics/event.fidl",
+ "fidl/fuchsia.legacymetrics/metrics_recorder.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.legacymetrics/metrics_recorder.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.legacymetrics/metrics_recorder.fidl
new file mode 100644
index 0000000..f96ee5b
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.legacymetrics/metrics_recorder.fidl
@@ -0,0 +1,15 @@
+// Copyright 2020 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.
+
+library fuchsia.legacymetrics;
+
+/// Accepts metrics events and uploads them to UMA servers for analysis. Metrics
+/// events are batched and uploaded at a regular interval. For similar behavior,
+/// see Chromium's MetricsService:
+/// https://chromium.googlesource.com/chromium/src.git/+/refs/heads/master/components/metrics/metrics_service.cc
+[Discoverable]
+protocol MetricsRecorder {
+ /// Processes and enqueues a batch of events for upload.
+ Record(vector<Event>:MAX events) -> ();
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.location.namedplace/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.location.namedplace/BUILD.gn
new file mode 100644
index 0000000..9ae8527
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.location.namedplace/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.location.namedplace") {
+ library_name = "namedplace"
+ namespace = "fuchsia.location"
+ public_deps = [
+ ]
+ sources = [
+ "namedplace.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.location.namedplace",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.location.namedplace/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.location.namedplace/meta.json
new file mode 100644
index 0000000..3a67357
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.location.namedplace/meta.json
@@ -0,0 +1,9 @@
+{
+ "deps": [],
+ "name": "fuchsia.location.namedplace",
+ "root": "fidl/fuchsia.location.namedplace",
+ "sources": [
+ "fidl/fuchsia.location.namedplace/namedplace.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.location.namedplace/namedplace.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.location.namedplace/namedplace.fidl
new file mode 100644
index 0000000..f75f64e
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.location.namedplace/namedplace.fidl
@@ -0,0 +1,74 @@
+// 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.
+
+/// Protocols and types related to named places. Named places include cities,
+/// countries, regions, etc. This specifically excludes protocols and types
+/// related to latitude and longitude.
+library fuchsia.location.namedplace;
+
+/// Represents a regulatory region. These values should generally be chosen
+/// from [ISO 3166-2](https://en.wikipedia.org/wiki/ISO_3166-2) codes. However,
+/// some radios may support extensions beyond the set of ISO 3166-2 codes.
+using RegionCode = string:2;
+
+/// The RegulatoryRegionConfigurator protocol provides mechanisms to
+/// inform Location Services of the inputs that should be used to
+/// determine the regulatory region whose rules should govern the
+/// operation of radios on the system.
+[Discoverable]
+protocol RegulatoryRegionConfigurator {
+ /// Sets the region.
+ ///
+ /// Clients should take care that their calls to this API arrive in a
+ /// well-defined order. For example, when using Zircon channels as the
+ /// underlying transport, the code below may not behave as intended.
+ ///
+ /// ```
+ /// // DANGER: The service may receive "BB" before "AA".
+ /// service1 = Open(RegulatoryRegionConfigurator);
+ /// service1.SetRegion("AA");
+ /// service1.Close();
+ /// service2 = Open(RegulatoryRegionConfigurator);
+ /// service2.SetRegion("BB");
+ /// service2.Close();
+ /// ```
+ ///
+ /// A client can avoid this problem by holding a single channel open to
+ /// the service, for the lifetime of the client.
+ ///
+ /// ```
+ /// // We use a single channel to ensure that calls arrive in a
+ /// // well-defined order.
+ /// service = Open(RegulatoryRegionConfigurator);
+ /// service1.SetRegion("AA");
+ /// service2.SetRegion("BB");
+ /// ```
+ ///
+ /// + request `region` the current regulatory region.
+ SetRegion(RegionCode region);
+};
+
+/// The RegulatoryRegionWatcher protocol provides the mechanism for
+/// radio subsystems to learn the currently applicable regulatory
+/// region, and to be notified when that value changes.
+[Discoverable]
+protocol RegulatoryRegionWatcher {
+ /// Returns the new RegionCode, when it changes.
+ ///
+ /// Notes:
+ /// * The first call returns immediately, if the region is already known.
+ /// * The client is _not_ guaranteed to observe the effects of every call
+ /// to `SetRegion()`.
+ /// * The client can, however, achieve _eventual_ consistency by always
+ /// issuing a new request when a request completes.
+ /// * Clients should _not_ issue concurrent requests to this method.
+ /// * At present, concurrent requests
+ /// * May yield the same value, or different values.
+ /// * May complete out-of-order.
+ /// * In the future, concurrent requests will cause the channel to be
+ /// closed with `ZX_ERR_BAD_STATE`.
+ ///
+ /// - response `new_region` the current regulatory region.
+ GetUpdate() -> (RegionCode new_region);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.logger/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.logger/BUILD.gn
new file mode 100644
index 0000000..19c1ad6
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.logger/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.logger") {
+ library_name = "logger"
+ namespace = "fuchsia"
+ public_deps = [
+ ]
+ sources = [
+ "logger.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.logger",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.logger/logger.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.logger/logger.fidl
new file mode 100644
index 0000000..8facfe2
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.logger/logger.fidl
@@ -0,0 +1,124 @@
+// Copyright 2018 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.
+
+library fuchsia.logger;
+
+using zx;
+
+enum LogLevelFilter : int8 {
+ NONE = -1;
+ INFO = 0;
+ WARN = 1;
+ ERROR = 2;
+ FATAL = 3;
+};
+
+/// Max number of tags that can be passed to filter by listener.
+const uint8 MAX_TAGS = 5;
+
+/// Max tag length that can be passed to filter by listener.
+const uint8 MAX_TAG_LEN_BYTES = 63;
+
+struct LogFilterOptions {
+ bool filter_by_pid;
+ uint64 pid;
+
+ bool filter_by_tid;
+ uint64 tid;
+
+ /// If more than zero, logs would be filtered based on verbosity and
+ /// `min_severity` would be ignored.
+ uint8 verbosity;
+
+ LogLevelFilter min_severity;
+
+ /// If non-empty, return all messages which contain at least one specified
+ /// tag. If empty, messages will not be filtered by tag.
+ /// Passed tags should not be more than `MAX_TAG_LEN_BYTES` bytes in length
+ /// and max tags can be `MAX_TAGS`.
+ /// Listener would be discarded if the limit is not followed.
+ vector<string:MAX_TAG_LEN_BYTES>:MAX_TAGS tags;
+};
+
+/// Max tags that will be attached to a LogMessage.
+const uint8 MAX_TAGS_PER_LOG_MESSAGE = 5;
+
+/// Max byte size for message payload.
+const uint32 MAX_DATAGRAM_LEN_BYTES = 2032;
+
+struct LogMessage {
+ uint64 pid;
+ uint64 tid;
+ /// https://fuchsia.dev/fuchsia-src/reference/syscalls/clock_get_monotonic.md
+ zx.time time;
+ int32 severity;
+
+ /// See //zircon/system/ulib/syslog/include/syslog/wire_format.h. As messages
+ /// can be served out of order, this should only be logged if more than last
+ /// count.
+ uint32 dropped_logs;
+ vector<string:MAX_TAG_LEN_BYTES>:MAX_TAGS_PER_LOG_MESSAGE tags;
+ string:MAX_DATAGRAM_LEN_BYTES msg;
+};
+
+/// Interface for LogListenerSafe to register to listen to logs.
+[Discoverable]
+protocol Log {
+ [Deprecated]
+ Listen(LogListener log_listener, LogFilterOptions? options);
+
+ [Deprecated]
+ DumpLogs(LogListener log_listener, LogFilterOptions? options);
+
+ /// Listens to new log entries by calling Log() on `log_listener`. A null `options` indicates no
+ /// filtering is requested.
+ [Transitional]
+ ListenSafe(LogListenerSafe log_listener, LogFilterOptions? options);
+
+ /// Dumps all cached logs by calling LogMany() followed by Done() on `log_listener`.
+ /// A null `options` indicates no filtering is requested.
+ [Transitional]
+ DumpLogsSafe(LogListenerSafe log_listener, LogFilterOptions? options);
+};
+
+/// Drains a program's logs.
+[Discoverable]
+protocol LogSink {
+ /// Send this socket to be drained.
+ ///
+ /// See //zircon/system/ulib/syslog/include/syslog/wire_format.h for what is expected to be
+ /// received over the socket.
+ Connect(handle<socket> socket);
+};
+
+/// Max log bytes per call to a listener.
+const uint64 MAX_LOG_MANY_SIZE_BYTES = 16384;
+
+/// Included temporarily for backwards compatiblity. Use `LogListenerSafe`.
+[Deprecated]
+protocol LogListener {
+ Log(LogMessage log);
+ LogMany(vector<LogMessage>:MAX log);
+ Done();
+};
+
+/// A listener who will notify the `Log` of the receipt of each message.
+protocol LogListenerSafe {
+ /// Called for single messages.
+ ///
+ /// The return value is used for flow control, and implementers should acknowledge receipt of
+ /// each message in order to continue receiving future messages.
+ Log(LogMessage log) -> ();
+
+ /// Called when serving cached logs.
+ ///
+ /// Max logs size per call is `MAX_LOG_MANY_SIZE_BYTES` bytes.
+ ///
+ /// The return value is used for flow control, and implementers should acknowledge receipt of
+ /// each batch in order to continue receiving future messages.
+ LogMany(vector<LogMessage>:MAX log) -> ();
+
+ /// Called when this listener was passed to `DumpLogsSafe()` and all cached logs have been sent.
+ Done();
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.logger/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.logger/meta.json
new file mode 100644
index 0000000..64b983c
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.logger/meta.json
@@ -0,0 +1,9 @@
+{
+ "deps": [],
+ "name": "fuchsia.logger",
+ "root": "fidl/fuchsia.logger",
+ "sources": [
+ "fidl/fuchsia.logger/logger.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.math/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.math/BUILD.gn
new file mode 100644
index 0000000..1029a96
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.math/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.math") {
+ library_name = "math"
+ namespace = "fuchsia"
+ public_deps = [
+ ]
+ sources = [
+ "math.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.math",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.math/math.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.math/math.fidl
new file mode 100644
index 0000000..c398fca
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.math/math.fidl
@@ -0,0 +1,289 @@
+// Copyright 2016 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.
+
+library fuchsia.math;
+
+/// An integer position in a 2D cartesian space.
+///
+/// This type does not specify units. Protocols that use this type should
+/// specify the characteristics of the vector space, including orientation and
+/// units.
+struct Point {
+ /// The number of units along the x-axis.
+ int32 x;
+
+ /// The number of units along the y-axis.
+ int32 y;
+};
+
+/// A floating point position in a 2D cartesian space.
+///
+/// This type does not specify units. Protocols that use this type should
+/// specify the characteristics of the vector space, including orientation and
+/// units.
+struct PointF {
+ /// The number of units along the x-axis.
+ float32 x;
+
+ /// The number of units along the y-axis.
+ float32 y;
+};
+
+/// A floating point position in a 3D cartesian space.
+///
+/// This type does not specify units. Protocols that use this type should
+/// specify the characteristics of the vector space, including orientation and
+/// units.
+struct Point3F {
+ /// The number of units along the x-axis.
+ float32 x;
+
+ /// The number of units along the y-axis.
+ float32 y;
+
+ /// The number of units along the z-axis.
+ float32 z;
+};
+
+/// The integer dimensions of a rectangular region in a 2D cartesian space.
+///
+/// This type does not specify units. Protocols that use this type should
+/// specify the characteristics of the vector space, including orientation and
+/// units.
+///
+/// This type allows for negative dimensions, to which protocols can give
+/// semantics. Protocols that use this type should specify whether negative
+/// dimensions are meaningful, and, if they are meaningful, what they mean.
+struct Size {
+ /// The distance along the x-axis.
+ int32 width;
+
+ /// The distance along the y-axis.
+ int32 height;
+};
+
+/// The floating point dimensions of a rectangular region in a 2D cartesian
+/// space.
+///
+/// This type does not specify units. Protocols that use this type should
+/// specify the characteristics of the vector space, including orientation and
+/// units.
+///
+/// This type allows for negative dimensions, to which protocols can give
+/// semantics. Protocols that use this type should specify whether negative
+/// dimensions are meaningful, and, if they are meaningful, what they mean.
+struct SizeF {
+ /// The distance along the x-axis.
+ float32 width;
+
+ /// The distance along the y-axis.
+ float32 height;
+};
+
+/// An integral, rectangular, axis-aligned region in a 2D cartesian
+/// space.
+///
+/// This type does not specify units. Protocols that use this type should
+/// specify the characteristics of the vector space, including orientation and
+/// units.
+struct Rect {
+ /// The location of the origin of the rectangle in the x-axis.
+ int32 x;
+
+ /// The location of the origin of the rectangle in the y-axis.
+ int32 y;
+
+ /// The distance along the x-axis.
+ ///
+ /// If `width` is positive, the region includes x values starting at `x` and
+ /// increasing along the x-axis. If `width` is negative, the region includes
+ /// x values starting at `x` and decreasing along the x-axis.
+ int32 width;
+
+ /// The distance along the y-axis.
+ ///
+ /// If `height` is positive, the region includes y values starting at `y`
+ /// and increasing along the y-axis. If `height` is negative, the region
+ /// includes y values starting at `y` and decreasing along the y-axis.
+ int32 height;
+};
+
+/// A floating point, rectangular, axis-aligned region in a 2D cartesian
+/// space.
+///
+/// This type does not specify units. Protocols that use this type should
+/// specify the characteristics of the vector space, including orientation and
+/// units.
+struct RectF {
+ /// The location of the origin of the rectangle in the x-axis.
+ float32 x;
+
+ /// The location of the origin of the rectangle in the y-axis.
+ float32 y;
+
+ /// The distance along the x-axis.
+ ///
+ /// If `width` is positive, the region includes x values starting at `x` and
+ /// increasing along the x-axis. If `width` is negative, the region includes
+ /// x values starting at `x` and decreasing along the x-axis.
+ float32 width;
+
+ /// The distance along the y-axis.
+ ///
+ /// If `height` is positive, the region includes y values starting at `y`
+ /// and increasing along the y-axis. If `height` is negative, the region
+ /// includes y values starting at `y` and decreasing along the y-axis.
+ float32 height;
+};
+
+/// A floating point rounded rectangle with the custom radii for all four
+/// corners.
+///
+/// A region in a 2D cartesian space consisting of linear, axis-aligned sides
+/// with corners rounded into a quarter ellipse.
+///
+/// If the quarter ellipses in two corners would overlap, their radii are
+/// clamped such that the ellipses meet with an axis-aligned tangent.
+///
+/// This type does not specify units. Protocols that use this type should
+/// specify the characteristics of the vector space, including orientation and
+/// units.
+struct RRectF {
+ /// The location of the origin of the region in the x-axis.
+ float32 x;
+
+ /// The location of the origin of the region in the y-axis.
+ float32 y;
+
+ /// The distance along the x-axis.
+ ///
+ /// If `width` is positive, the region includes x values starting at `x` and
+ /// increasing along the x-axis. If `width` is negative, the region includes
+ /// x values starting at `x` and decreasing along the x-axis.
+ float32 width;
+
+ /// The distance along the y-axis.
+ ///
+ /// If `height` is positive, the region includes y values starting at `y`
+ /// and increasing along the y-axis. If `height` is negative, the region
+ /// includes y values starting at `y` and decreasing along the y-axis.
+ float32 height;
+
+ /// The radius of the quarter ellipse in the top-left corner along the
+ /// x-axis.
+ ///
+ /// Must not be negative.
+ float32 top_left_radius_x;
+
+ /// The radius of the quarter ellipse in the top-left corner along the
+ /// y-axis.
+ ///
+ /// Must not be negative.
+ float32 top_left_radius_y;
+
+ /// The radius of the quarter ellipse in the top-right corner along the
+ /// x-axis.
+ ///
+ /// Must not be negative.
+ float32 top_right_radius_x;
+
+ /// The radius of the quarter ellipse in the top-right corner along the
+ /// y-axis.
+ ///
+ /// Must not be negative.
+ float32 top_right_radius_y;
+
+ /// The radius of the quarter ellipse in the bottom-left corner along the
+ /// x-axis.
+ ///
+ /// Must not be negative.
+ float32 bottom_left_radius_x;
+
+ /// The radius of the quarter ellipse in the bottom-left corner along the
+ /// y-axis.
+ ///
+ /// Must not be negative.
+ float32 bottom_left_radius_y;
+
+ /// The radius of the quarter ellipse in the bottom-right corner along the
+ /// x-axis.
+ ///
+ /// Must not be negative.
+ float32 bottom_right_radius_x;
+
+ /// The radius of the quarter ellipse in the bottom-right corner along the
+ /// y-axis.
+ ///
+ /// Must not be negative.
+ float32 bottom_right_radius_y;
+};
+
+/// A projective transformation of a 3D cartesian space.
+///
+/// A transform consists of a 4x4 matrix that operates in homogeneous
+/// coordinates. For example, a point located at (x, y, z) in the cartesian
+/// space is transformed by `M` to a point located at (x'/w', y'/w', z'/w'),
+/// where `(x', y', z', w') = M (x, y, z, 1)`.
+struct Transform {
+ /// The entries in the transformation matrix in row major order.
+ ///
+ /// Specifically, if the matrix is as follows:
+ ///
+ /// ```
+ /// a b c d
+ /// e f g h
+ /// i j k l
+ /// m n o p
+ /// ```
+ ///
+ /// then the entries in this array are
+ /// `(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p)`.
+ array<float32>:16 matrix;
+};
+
+/// An integer offset to apply to each edge of a rectangle.
+///
+/// This type does not specify units. Protocols that use this type should
+/// specify the characteristics of the vector space, including orientation and
+/// units.
+struct Inset {
+ /// The amount to move the top edge of the rectangle towards the center of
+ /// the rectangle.
+ int32 top;
+
+ /// The amount to move the right edge of the rectangle towards the center of
+ /// the rectangle.
+ int32 right;
+
+ /// The amount to move the bottom edge of the rectangle towards the center
+ /// of the rectangle.
+ int32 bottom;
+
+ /// The amount to move the left edge of the rectangle towards the center of
+ /// the rectangle.
+ int32 left;
+};
+
+/// A floating point offset to apply to each edge of a rectangle.
+///
+/// This type does not specify units. Protocols that use this type should
+/// specify the characteristics of the vector space, including orientation and
+/// units.
+struct InsetF {
+ /// The amount to move the top edge of the rectangle towards the center of
+ /// the rectangle.
+ float32 top;
+
+ /// The amount to move the right edge of the rectangle towards the center of
+ /// the rectangle.
+ float32 right;
+
+ /// The amount to move the bottom edge of the rectangle towards the center
+ /// of the rectangle.
+ float32 bottom;
+
+ /// The amount to move the left edge of the rectangle towards the center of
+ /// the rectangle.
+ float32 left;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.math/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.math/meta.json
new file mode 100644
index 0000000..cbfa9dc
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.math/meta.json
@@ -0,0 +1,9 @@
+{
+ "deps": [],
+ "name": "fuchsia.math",
+ "root": "fidl/fuchsia.math",
+ "sources": [
+ "fidl/fuchsia.math/math.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media.audio/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.media.audio/BUILD.gn
new file mode 100644
index 0000000..6f93e3c
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media.audio/BUILD.gn
@@ -0,0 +1,26 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.media.audio") {
+ library_name = "audio"
+ namespace = "fuchsia.media"
+ public_deps = [
+ ]
+ sources = [
+ "gain_control.fidl",
+ "volume_control.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.media.audio",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media.audio/gain_control.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media.audio/gain_control.fidl
new file mode 100644
index 0000000..ab2a11c
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media.audio/gain_control.fidl
@@ -0,0 +1,90 @@
+// Copyright 2018 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.
+
+library fuchsia.media.audio;
+
+// fuchsia.media.audio contains definitions relating to audio. Definitions in
+// this file concern control of audio gain.
+
+using zx;
+
+/// Enables control and monitoring of audio gain. This interface is typically
+/// a tear-off of other interfaces. For example, `fuchsia.media.audio.Renderer`
+/// has a `BindGainControl` method that binds to a gain control that controls
+/// gain for the renderer.
+// TODO(35393, 35311, 35309): Deprecate and remove.
+protocol GainControl {
+ /// Sets the gain in decibels.
+ SetGain(float32 gain_db);
+
+ /// Smoothly changes gain from its current value to specified value, over the
+ /// specified duration (in milliseconds). If 'duration_ns' is 0, gain changes
+ /// immediately. Otherwise, gain changes only while the stream is running.
+ ///
+ /// Any active or pending ramp is cancelled by subsequent call to SetGain.
+ ///
+ /// There can be at most 1 active ramp at any time. Any active or pending
+ /// ramp is replaced by a later call to SetGainWithRamp (even if duration is
+ /// 0). In this case gain would ramps directly from its most recent
+ /// (mid-ramp) value to the newly-specified one, over the new duration,
+ /// using the new easing.
+ ///
+ /// Usage example (using time in seconds):
+ /// Time 0
+ /// SetGainWithRamp(`MUTED_GAIN_DB`, 0, SCALE_LINEAR) // Ramp 1
+ /// SetGainWithRamp(0.0f, `ZX_SEC`(4), SCALE_LINEAR) // Ramp 2
+ /// Time 3
+ /// PlayNoReply(kNoTimestamp, any_media_time)
+ /// Time 4
+ /// PauseNoReply()
+ /// Time 7
+ /// PlayNoReply(kNoTimestamp, any_media_time)
+ /// Time 8
+ /// SetGainWithRamp(`MUTED_GAIN_DB`, ZX_SEC(1), SCALE_LINEAR) // Ramp 3
+ ///
+ ///
+ /// Time 0: Ramp 1 completes immediately, changing the gain to `MUTED_GAIN_DB`.
+ /// Ramp 2 is pending, since we are not in playback.
+ /// Time 3, Ramp 2 begins ramping from `MUTED_GAIN_DB` to 0 dB
+ /// (scale 0.0=>1.0).
+ /// Time 4: Ramp 2 pauses (3s remain). Per `SCALE_LINEAR`, scale is approx.
+ /// 0.25.
+ /// Time 7: Ramp 2 resumes from most recent value toward the target.
+ /// Time 8: Ramp 3 replaces Ramp 2 and starts from current scale
+ /// (approx 0.5).
+ /// Time 9: Ramp 3 completes; current scale value is now 0.0 (`MUTED_GAIN_DB`).
+ ///
+ SetGainWithRamp(float32 gain_db,
+ zx.duration duration,
+ RampType rampType);
+
+ /// Sets the mute value. Ramping and mute are fully independent, although
+ /// they both affect the scaling that is applied.
+ SetMute(bool muted);
+
+ /// Notifies the client of changes in the current gain/mute values.
+ //
+ // TODO(mpuryear): provide ramp-related values in this event, as well.
+ //
+ // TODO(mpuryear): notify upon ramp milestones (not just SetGain/Mute) --
+ // upon the start/pause/restart/completion of an active ramp?
+ -> OnGainMuteChanged(float32 gain_db, bool muted);
+};
+
+/// Gain value producing silence. Gain values less than this value are permitted,
+/// but produce the same effect as this value.
+const float32 MUTED_GAIN_DB = -160.0;
+
+/// Maximum permitted gain value.
+const float32 MAX_GAIN_DB = 24.0;
+
+/// Enumerates gain control ramp types.
+enum RampType : uint16 {
+ /// Amplitude scale changes at a fixed rate across the ramp duration.
+ SCALE_LINEAR = 1;
+
+ // TODO(mpuryear) Additional ramp shapes (easings) may be added in the
+ // future, perhaps including logarithmic (i.e. linear wrt dB), cubic
+ // (in/out/inout) or others.
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media.audio/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.media.audio/meta.json
new file mode 100644
index 0000000..2b94950
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media.audio/meta.json
@@ -0,0 +1,10 @@
+{
+ "deps": [],
+ "name": "fuchsia.media.audio",
+ "root": "fidl/fuchsia.media.audio",
+ "sources": [
+ "fidl/fuchsia.media.audio/gain_control.fidl",
+ "fidl/fuchsia.media.audio/volume_control.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media.audio/volume_control.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media.audio/volume_control.fidl
new file mode 100644
index 0000000..6c4936b
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media.audio/volume_control.fidl
@@ -0,0 +1,27 @@
+// 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.
+
+library fuchsia.media.audio;
+
+/// The volume value representing the maximum loudness.
+const float32 MAX_VOLUME = 1.0;
+
+/// The volume value representing silence.
+const float32 MIN_VOLUME = 0.0;
+
+/// A protocol for controlling volume.
+protocol VolumeControl {
+ /// Sets the volume of the audio element to the given value in
+ /// [0.0, 1.0]. If the value is provided is outside of [0.0, 1.0],
+ /// the value is clamped before application.
+ SetVolume(float32 volume);
+ /// Sets whether the controlled element is muted. Mute is not the same
+ /// as setting volume to 0.0; volume will persist for the duration of
+ /// a mute. If volume was 0.5 before mute, volume will resume at 0.5
+ /// following unmute.
+ SetMute(bool mute);
+
+ /// Emitted when the volume or mute state of the audio element changes.
+ -> OnVolumeMuteChanged(float32 new_volume, bool new_muted);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media.drm/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.media.drm/BUILD.gn
new file mode 100644
index 0000000..1292836
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media.drm/BUILD.gn
@@ -0,0 +1,34 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.media.drm") {
+ library_name = "drm"
+ namespace = "fuchsia.media"
+ public_deps = [
+ "../fuchsia.io",
+ "../fuchsia.media",
+ "../fuchsia.mem",
+ "../fuchsia.url",
+ ]
+ sources = [
+ "content_decryption.fidl",
+ "error.fidl",
+ "license_session.fidl",
+ "provisioning.fidl",
+ "services.fidl",
+ "types.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.media.drm",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media.drm/content_decryption.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media.drm/content_decryption.fidl
new file mode 100644
index 0000000..7c07a80
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media.drm/content_decryption.fidl
@@ -0,0 +1,118 @@
+// 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.
+
+library fuchsia.media.drm;
+
+using fuchsia.media;
+
+table DecryptorParams {
+ /// Requires the decryptor [`fuchsia.media/StreamProcessor`] to only output
+ /// to secure buffers.
+ 1: bool require_secure_mode;
+
+ /// Initial format details for the [`fuchsia.media/StreamProcessor`].
+ 2: fuchsia.media.FormatDetails input_details;
+};
+
+/// A protocol for managing content license sessions and providing decryption of
+/// media content. There may be zero to many active [`LicenseSession`]s
+/// associated with a `ContentDecryptionModule`, each with their own sets of
+/// keys.
+///
+/// From an EME client's perspective, this protocol has a 1:1 relationship with
+/// the MediaKeys object.
+protocol ContentDecryptionModule {
+ /// Indicates that the `ContentDecryptionModule` is provisioned.
+ ///
+ /// In order to create `LicenseSession`s, a `ContentDecryptionModule` must
+ /// be provisioned. A `ContentDecryptionModule` is not considered
+ /// provisioned until it meets the requirements for the underlying DRM
+ /// system. The DRM system may not require provisioning, may only require
+ /// factory provisioning or may require both factory provisioning and
+ /// service instance provisioning.
+ ///
+ /// If the `ContentDecryptionModule` has already has sufficient
+ /// provisioning, this event will be sent immediately upon creation. If the
+ /// `ContentDecryptionModule` has its provisioning removed, then the server
+ /// will close the channel and also close any active `LicenseSession`s or
+ /// Decryptors.
+ ///
+ /// If the DRM system does not require provisioning at all, this
+ /// event should still be sent to notify the client that it can create
+ /// `LicenseSession`s.
+ -> OnProvisioned();
+
+ /// Sets the certificate to be used for encrypting outgoing messages.
+ ///
+ /// + request `certificate` a buffer containing the certificate to be used.
+ /// * error an [`Error`] indicating the reason for failure.
+ SetServerCertificate(bytes certificate) -> () error Error;
+
+ /// Creates a new session for the given type.
+ ///
+ /// The `session_id` will be generated by the [`ContentDecryptionModule`]
+ /// and can be used to reload the session after closing. If the
+ /// `session_type` is not supported by the underlying DRM system, it will
+ /// immediately close the `license_session`.
+ ///
+ /// + request `session_type` a field containing either
+ /// [`LicenseSessionType.TEMPORARY`],
+ /// [`LicenseSessionType.PERSISTENT_LICENSE`] or
+ /// [`LicenseSessionType.PERSISTENT_USAGE_RECORD`]
+ /// + request `license_session` the server endpoint of the
+ /// [`LicenseSession`]
+ /// - response `session_id` an identifier that can be used to reload the
+ /// session later (if persistent).
+ CreateLicenseSession(LicenseSessionType session_type,
+ request<LicenseSession> license_session)
+ -> (SessionId session_id);
+
+ /// Loads an existing session from storage using the given `session_id`.
+ ///
+ /// If the session is not found, then the `license_session` will be closed.
+ ///
+ /// + request `session_id` contains an identifier of which session should be
+ /// loaded from storage.
+ /// + request `license_session` the server endpoint of the
+ /// [`LicenseSession`].
+ LoadLicenseSession(SessionId session_id,
+ request<LicenseSession> license_session);
+
+ /// Creates a Decryptor [`fuchsia.media/StreamProcessor`] to be used to
+ /// decrypt content.
+ ///
+ /// This `decryptor` would have access to the union of keys created by all
+ /// the active sessions for this [`ContentDecryptionModule`].
+ ///
+ /// + request `params` the parameters with which to create the `decryptor`.
+ /// + request `decryptor` the server endpoint of the
+ /// `fuchsia.media/StreamProcessor`.
+ CreateDecryptor(DecryptorParams params,
+ request<fuchsia.media.StreamProcessor> decryptor);
+
+ /// Queries the status of a hypothetical key associated with an HDCP policy.
+ ///
+ /// This aids clients in determining which content type to fetch prior to
+ /// establishing a [`LicenseSession`]. For example, if the device would
+ /// restrict output for HDCP 1.x, then the client can choose to fetch SD
+ /// content rather than HD.
+ ///
+ /// + request `hdcp_version` a field containing the HDCP version to check,
+ /// such as "1.2" or "2.0".
+ /// - response `key_status` a field indicating what the status of a
+ /// hypothetical key would be for this device if one could be licensed.
+ GetKeyStatusForHdcpVersion(HdcpVersion hdcp_version) -> (KeyStatus key_status);
+
+ /// Queries for the list of supported encryption schemes.
+ ///
+ /// This returns a list of the supported encryption schemes that the
+ /// `ContentDecryptionModule` supports, such as 'cenc' or 'cbcs'. If the
+ /// implementation supports passing unencrypted frames through decryption
+ /// prior to license arrival, it should also report
+ /// `fuchsia.media.UNENCRYPTED` as a supported scheme.
+ ///
+ /// - response `encryption_schemes` a list of the supported encryption
+ /// schemes.
+ GetSupportedEncryptionSchemes() -> (vector<EncryptionScheme>:MAX encryption_schemes);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media.drm/error.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media.drm/error.fidl
new file mode 100644
index 0000000..e40f66b
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media.drm/error.fidl
@@ -0,0 +1,37 @@
+// 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.
+
+library fuchsia.media.drm;
+
+/// Standard error codes for DRM related protocols. Many of the error code names
+/// originate from the [`W3C Encrypted Media Extensions`] specification to cover
+/// common CDM exception cases.
+///
+/// [`W3C Encrypted Media Extensions`]:
+/// https://www.w3.org/TR/encrypted-media
+enum Error {
+ // Encrypted Media Extension error codes
+ /// An error that occurs when the client provides invalid parameter data to
+ /// the server, such as an invalid license response message.
+ TYPE = 1;
+ /// An error that occurs when a requested operation is not supported by the
+ /// CDM, such as a license generation request with an unknown initialization
+ /// data type.
+ NOT_SUPPORTED = 2;
+ /// An error that occurs when the CDM is not in a proper state to perform
+ /// the requested operation, such as calling
+ /// [`LicenseSession.GenerateLicenseRequest`] when the [`LicenseSession`]
+ /// has already started the license release process.
+ INVALID_STATE = 3;
+ /// An error that occurs when a requested action would exceed allowable
+ /// limits, such as attempting to load an already opened session.
+ QUOTA_EXCEEDED = 4;
+
+ // Additional common error codes for DRM systems (100)
+ /// An internal, unexpected error that is not actionable by the client.
+ INTERNAL = 100;
+ /// An error that occurs when the CDM is not usable because it requires
+ /// additional provisioning.
+ NOT_PROVISIONED = 101;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media.drm/license_session.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media.drm/license_session.fidl
new file mode 100644
index 0000000..a43bce6
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media.drm/license_session.fidl
@@ -0,0 +1,153 @@
+// 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.
+
+library fuchsia.media.drm;
+
+using fuchsia.media;
+using fuchsia.mem;
+
+// Common initialization data formats. These are defined as strings rather than
+// enums so as to not limit the types a ContentDecryptionModule may support.
+const LicenseInitDataType LICENSE_INIT_DATA_TYPE_CENC = "cenc";
+const LicenseInitDataType LICENSE_INIT_DATA_TYPE_KEYIDS = "keyids";
+const LicenseInitDataType LICENSE_INIT_DATA_TYPE_WEBM = "webm";
+const LicenseInitDataType LICENSE_INIT_DATA_TYPE_HLS = "hls";
+
+enum LicenseSessionType {
+ /// A session for which the license, keys, and record of the session are not
+ /// persisted.
+ TEMPORARY = 1;
+ /// A session for which the license, keys, and record of the session will be
+ /// persisted for offline use and can subsequently be loaded using
+ /// LoadSession().
+ PERSISTENT_LICENSE = 2;
+ /// A session for which the the record of the session will be persisted, but
+ /// the keys and license will not be.
+ PERSISTENT_USAGE_RECORD = 3;
+};
+
+enum LicenseMessageType {
+ REQUEST = 1;
+ RENEWAL = 2;
+ RELEASE = 3;
+};
+
+struct LicenseInitData {
+ /// The type is a string that indicates the format of the accompanying init
+ /// data. Common types include "cenc", "keyids", "webm", and "hls". CDMs may
+ /// also define their own.
+ LicenseInitDataType type;
+ bytes data;
+};
+
+/// A message originating from the [`LicenseSession`] that the caller must route
+/// to the license server.
+struct LicenseMessage {
+ LicenseMessageType type;
+ fuchsia.mem.Buffer message;
+};
+
+/// A message originating from the license server that the caller must provide
+/// to the [`LicenseSession`] via `ProcessLicenseServerMessage`.
+struct LicenseServerMessage {
+ fuchsia.mem.Buffer message;
+};
+
+enum KeyStatus {
+ /// The key is currently usable for decryption.
+ USABLE = 0;
+ /// The Key is no longer usable for decryption because it has expired.
+ EXPIRED = 1;
+ /// The Key is no longer usable for decryption, but is still known to the
+ /// CDM.
+ RELEASED = 2;
+ /// The Key has output restrictions that cannot currently be met and may be
+ /// unusable for decryption.
+ OUTPUT_RESTRICTED = 3;
+ /// The Key has output restrictions that cannot currently be met. The Key
+ /// may be usable for decryption with lower quality content.
+ OUTPUT_DOWNSCALED = 4;
+ /// The Key is not yet known or usable for decryption.
+ STATUS_PENDING = 5;
+ /// The Key is not usable for decryption because of an internal error.
+ INTERNAL_ERROR = 6;
+};
+
+table KeyState {
+ 1: fuchsia.media.KeyId key_id;
+ 2: KeyStatus status;
+};
+
+/// A protocol for exchanging messages pertaining to the establishment of a
+/// media license and the encryption keys associated with it.
+///
+/// If the client closes the `LicenseSession`, any derived Decryptors will also
+/// be closed as the encryption keys will no longer be maintained.
+protocol LicenseSession {
+ /// Indicates that the [`LicenseSession`] has successfully initialized.
+ ///
+ /// This is always the first message sent by the `LicenseSession`.
+ -> OnReady();
+
+ /// Generates a license request for a session based on the `init_data`.
+ ///
+ /// When the [`LicenseMessage`] has been created, the
+ /// `OnLicenseMessageGenerated` event will be triggered with the message to
+ /// be sent to the license server.
+ ///
+ /// + request `init_data` container-specific data that is used to generate a
+ /// [`LicenseMessageType.REQUEST`] `LicenseMessage`.
+ /// * error an [`Error`] indicating the reason for failure.
+ GenerateLicenseRequest(LicenseInitData init_data) -> () error Error;
+
+ /// Inititiates the release process for the license session.
+ ///
+ /// This will cause the [`LicenseSession`] to generate a [`LicenseMessage`]
+ /// through the `OnLicenseMessageGenerated` event. The client must route
+ /// that message to the license server and the server's response to
+ /// `ProcessLicenseServerMessage`. Once the `LicenseSession` has received
+ /// the license server's reply, it will close the `LicenseSession` channel
+ /// as this session will no longer be usable.
+ GenerateLicenseRelease();
+
+ /// Updates the [`LicenseSession`] with a message from the license server.
+ ///
+ /// All responses from license requests, renewals, and releases should be
+ /// routed to the `LicenseSession` through this method.
+ ///
+ /// + request `response` a message from the license server to update the
+ /// state of the `LicenseSession`.
+ /// * error an [`Error`] indicating the reason for failure.
+ ProcessLicenseResponse(LicenseServerMessage response) -> () error Error;
+
+ /// Creates a Decryptor [`fuchsia.media/StreamProcessor`] to be used to
+ /// decrypt content.
+ ///
+ /// This `decryptor` would be restricted to only having access to the
+ /// keys maintained by this [`LicenseSession`].
+ ///
+ /// + request `params` the parameters with which to create the `decryptor`.
+ /// + request `decryptor` the server endpoint of the
+ /// `fuchsia.media/StreamProcessor`.
+ CreateDecryptor(DecryptorParams params,
+ request<fuchsia.media.StreamProcessor> decryptor);
+
+ /// Provides a [`LicenseMessage`] that should be sent to the license server.
+ ///
+ /// The client is responsible for transporting this message to the license
+ /// server.
+ ///
+ /// - response `request` a message from the `LicenseSession` that the client
+ /// should send to the license server.
+ -> OnLicenseMessageGenerated(LicenseMessage request);
+
+ /// Provides updated key state information.
+ ///
+ /// Some examples on when this might occur would be on license creation,
+ /// expiration, renewal, or load of a persistent license session.
+ ///
+ /// - response `key_states` a list of the key_ids and their related
+ /// [`KeyStatusCode`]s
+ -> OnKeyStatesChanged(vector<KeyState>:MAX key_states);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media.drm/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.media.drm/meta.json
new file mode 100644
index 0000000..2bae16a
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media.drm/meta.json
@@ -0,0 +1,19 @@
+{
+ "deps": [
+ "fuchsia.media",
+ "fuchsia.url",
+ "fuchsia.io",
+ "fuchsia.mem"
+ ],
+ "name": "fuchsia.media.drm",
+ "root": "fidl/fuchsia.media.drm",
+ "sources": [
+ "fidl/fuchsia.media.drm/content_decryption.fidl",
+ "fidl/fuchsia.media.drm/error.fidl",
+ "fidl/fuchsia.media.drm/license_session.fidl",
+ "fidl/fuchsia.media.drm/provisioning.fidl",
+ "fidl/fuchsia.media.drm/services.fidl",
+ "fidl/fuchsia.media.drm/types.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media.drm/provisioning.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media.drm/provisioning.fidl
new file mode 100644
index 0000000..aa405a5
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media.drm/provisioning.fidl
@@ -0,0 +1,110 @@
+// 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.
+
+library fuchsia.media.drm;
+
+using fuchsia.mem;
+using fuchsia.url;
+
+enum ProvisioningStatus {
+ NOT_PROVISIONED = 1;
+ PROVISIONED = 2;
+};
+
+/// Message passed to a [`ProvisioningFetcher`] by a DRM system, to pass on to
+/// the provisioning server.
+struct ProvisioningRequest {
+ /// A suggested server to send the `message` to.
+ fuchsia.url.Url? default_provisioning_server_url;
+
+ /// The DRM system specific provisioning request message body to be
+ /// delivered to the provisioning server. The VMO must at least have the
+ /// following rights:
+ /// ZX_RIGHT_READ
+ /// ZX_RIGHT_TRANSFER
+ fuchsia.mem.Buffer message;
+};
+
+/// Message originating from the provisioning server that the
+/// [`ProvisioningFetcher`] must pass back to the DRM system.
+struct ProvisioningResponse {
+ /// The DRM system specific provisioning response message body received from
+ /// the provisioning server. The VMO must at least have the following
+ /// rights:
+ /// ZX_RIGHT_READ
+ /// ZX_RIGHT_TRANSFER
+ fuchsia.mem.Buffer message;
+};
+
+/// Fetches provisioning from a server.
+///
+/// Some DRM systems require additional runtime provisioning (also known as
+/// individualization). This is a process by which a device receives DRM
+/// credentials (e.g. a certificate) to use for license acquisition for an
+/// individual content provider.
+///
+/// DRM systems use the [`ProvisioningFetcher`] to fetch the provisioning when
+/// the system determines that it is needed.
+protocol ProvisioningFetcher {
+ /// Fetches provisioning from a server.
+ ///
+ /// Called by the DRM system when it is in need of provisioning.
+ ///
+ /// + request `request` a [`ProvisioningRequest`] message to be provided to
+ /// a provisioning server.
+ /// - response `response` a [`ProvisioningResponse`] message from the
+ /// provisioning server.
+ Fetch(ProvisioningRequest request) -> (ProvisioningResponse response);
+};
+
+/// A protocol for exchanging messages pertaining to the establishment of a
+/// provisioning certificate.
+///
+/// DEPRECATED: See [`KeySystem.AddDataStore`] instead.
+[Deprecated]
+protocol Provisioner {
+ /// Gets the current status of provisioning for this service instance.
+ ///
+ /// - response `status` indicates whether the service instance is
+ /// sufficiently provisioned.
+ GetStatus() -> (ProvisioningStatus status);
+
+ /// Sets the certificate to be used for encrypting outgoing messages.
+ ///
+ /// + request `certificate` a buffer containing the certificate to be used.
+ /// * error an [`Error`] indicating the reason for failure.
+ SetServerCertificate(bytes certificate) -> () error Error;
+
+ /// Generates a provisioning request for this service instance.
+ ///
+ /// If the underlying DRM system requires provisioning for individual
+ /// providers (the owner of the service instance), then this method can be
+ /// used to generate [`ProvisioningRequest`]s. This message must be routed
+ /// to the provisioning server by the client and the server's response must
+ /// be routed back to `ProcessProvisioningResponse`.
+ ///
+ /// - response `request` a `ProvisioningRequest` message to be provided to a
+ /// provisioning server in order to receiving a provisioning certificate.
+ GenerateProvisioningRequest() -> (ProvisioningRequest request);
+
+ /// Updates the [`Provisioner`] with a message from the provisioning server.
+ ///
+ /// Not all underlying DRM systems will require provisioning for individual
+ /// providers. If they do, this method will carry the provisioning message
+ /// to the service instance so that it may persistently store the provider
+ /// certificate.
+ ///
+ /// + request `response` a [`ProvisioningResponse`] from the provisioning
+ /// server. It should contain the provisioning certificate.
+ /// * error an [`Error`] indicating the reason for failure.
+ ProcessProvisioningResponse(ProvisioningResponse response)
+ -> () error Error;
+
+ /// Removes all provider based provisioning for this service instance.
+ ///
+ /// Any active [`ContentDecryptionModule`]s on this service instance that
+ /// relied on this provisioning will be closed, as they will no longer be
+ /// usable without it. This does not impact any factory provisioning.
+ RemoveProvisioning();
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media.drm/services.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media.drm/services.fidl
new file mode 100644
index 0000000..acf6f67
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media.drm/services.fidl
@@ -0,0 +1,154 @@
+// 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.
+
+library fuchsia.media.drm;
+
+using fuchsia.io;
+
+/// A sentinel value for use with [`KeySystem.CreateContentDecryptionModule2`]
+/// to create a [`ContentDecryptionModule`] without a client data store.
+const uint32 NO_DATA_STORE = 0;
+
+protocol KeySystem {
+ /// Adds a client data store to the `KeySystem`.
+ ///
+ /// DRM systems generate data on behalf of clients as part of provisioning
+ /// and license management. This data is only usable by the DRM system, but
+ /// the client is the owner of the data. The client controls the lifetime of
+ /// the data and can select which data set is to be used for a
+ /// [`ContentDecryptionModule`].
+ ///
+ /// + request `data_store_id` a client-assigned identifier for the data
+ /// store. The identifier is scoped to the `KeySystem` channel. It is
+ /// invalid for the client to provide [`NO_DATA_STORE`] or an already
+ /// added `data_store_id` and the server should close the channel.
+ /// + request `data_store_params` the parameters to be used for this data
+ /// store.
+ [Transitional]
+ AddDataStore(uint32 data_store_id,
+ DataStoreParams data_store_params) -> () error Error;
+
+ /// Destroys the client data store.
+ ///
+ /// This method permanently removes this data store and all of its contents.
+ /// This means that all provisioning and license data will be removed and
+ /// any active [`ContentDecryptionModule`] using this data store will be
+ /// closed.
+ ///
+ /// + request `data_store_id` the client-assigned identifier for the data
+ /// store to be removed. It is invalid for the client to provide
+ /// [`NO_DATA_STORE`] or a `data_store_id` value that has not previously
+ /// been added.
+ [Transitional]
+ DestroyDataStore(uint32 data_store_id);
+
+ /// Creates a new [`ContentDecryptionModule`].
+ ///
+ /// Creates a `ContentDecryptionModule` that will use the associated data
+ /// store, if provided. If [`NO_DATA_STORE`] is provided for the
+ /// `data_store_id`, then the created `ContentDecryptionModule` will only
+ /// support [`LicenseSession`]s of [`LicenseSessionType.TEMPORARY`] type.
+ /// If a `data_store_id` is provided, then the created
+ /// `ContentDecryptionModule` will persist data to that data store. If the
+ /// `KeySystem` requires a data store and `NO_DATA_STORE` was provided or
+ /// the `KeySystem` does not support data stores and one was provided, then
+ /// the server should close the `cdm`.
+ ///
+ /// + request `data_store_id` the data store that should be used by the
+ /// `ContentDecryptionModule`.
+ /// + request `cdm` the server endpoint of the `ContentDecryptionModule`.
+ [Transitional]
+ CreateContentDecryptionModule2(uint32 data_store_id,
+ request<ContentDecryptionModule> cdm);
+};
+
+table DataStoreParams {
+ /// Directory into which this data store should write persistent
+ /// provisioning and licenses, or their proxy. This field is required.
+ 1: fuchsia.io.Directory data_directory;
+
+ /// Certificate to use for encrypting provisioning messages. This field is
+ /// optional.
+ 2: bytes provision_server_certificate;
+
+ /// The client endpoint of the [`ProvisioningFetcher`] to be used when this
+ /// data store requires provisioning. If the DRM system requires data store
+ /// provisioning, then this field is required to be set. Otherwise, it is
+ /// optional.
+ 3: ProvisioningFetcher provisioning_fetcher;
+};
+
+// TODO(MTWN-394): Convert these protocols to services once available.
+
+/// A service hub providing access to the ClearKey key system. This key system
+/// is defined by the [`W3C Encrypted Media Extensions`]. It uses plain-text
+/// keys to decrypt the source.
+///
+/// If the client closes the `ClearKey` channel, derived
+/// `ContentDecryptionModule`s will remain active.
+///
+/// [`W3C Encrypted Media Extensions`]:
+/// https://www.w3.org/TR/encrypted-media
+[Discoverable]
+protocol ClearKey {
+ compose KeySystem;
+
+ /// Creates a new [`ContentDecryptionModule`].
+ ///
+ /// DEPRECATED: See [`KeySystem.CreateContentDecryptionModule2`] instead.
+ ///
+ /// + request `cdm` the server endpoint of the `ContentDecryptionModule`.
+ [Transitional, Deprecated]
+ CreateContentDecryptionModule(request<ContentDecryptionModule> cdm);
+};
+
+/// A service hub providing access to the Widevine key system.
+///
+/// If the client closes the `Widevine` channel, derived
+/// `ContentDecryptionModule`s will remain active.
+[Discoverable]
+protocol Widevine {
+ compose KeySystem;
+
+ /// Creates a new [`ContentDecryptionModule`].
+ ///
+ /// The `ContentDecryptionModule`s created will share their persistent
+ /// state, but will not share active sessions.
+ ///
+ /// DEPRECATED: See [`KeySystem.CreateContentDecryptionModule2`] instead.
+ ///
+ /// + request `cdm` the server endpoint of the `ContentDecryptionModule`.
+ [Transitional, Deprecated]
+ CreateContentDecryptionModule(request<ContentDecryptionModule> cdm);
+
+ /// Creates a new [`Provisioner`].
+ ///
+ /// There can only be one active `Provisioner` for each service instance.
+ ///
+ /// DEPRECATED: See [`KeySystem.AddDataStore`] instead.
+ ///
+ /// + request `provisioner` the server endpoint of the `Provisioner`.
+ [Transitional, Deprecated]
+ CreateProvisioner(request<Provisioner> provisioner);
+};
+
+/// A service hub providing access to the PlayReady key system.
+///
+/// If the client closes the `PlayReady` channel, derived
+/// `ContentDecryptionModule`s will remain active.
+[Discoverable]
+protocol PlayReady {
+ compose KeySystem;
+
+ /// Creates a new [`ContentDecryptionModule`].
+ ///
+ /// The `ContentDecryptionModule`s created will share their persistent
+ /// state, but will not share active sessions.
+ ///
+ /// DEPRECATED: See [`KeySystem.CreateContentDecryptionModule2`] instead.
+ ///
+ /// + request `cdm` the server endpoint of the `ContentDecryptionModule`.
+ [Transitional, Deprecated]
+ CreateContentDecryptionModule(request<ContentDecryptionModule> cdm);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media.drm/types.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media.drm/types.fidl
new file mode 100644
index 0000000..cec5191
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media.drm/types.fidl
@@ -0,0 +1,16 @@
+// Copyright 2020 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.
+
+library fuchsia.media.drm;
+
+using fuchsia.media;
+
+const uint32 MAX_SESSION_ID_SIZE = 512;
+const uint32 MAX_LICENSE_INIT_DATA_TYPE_SIZE = 100;
+const uint32 MAX_HDCP_VERSION_SIZE = 16;
+
+using SessionId = string:MAX_SESSION_ID_SIZE;
+using LicenseInitDataType = string:MAX_LICENSE_INIT_DATA_TYPE_SIZE;
+using HdcpVersion = string:MAX_HDCP_VERSION_SIZE;
+using EncryptionScheme = fuchsia.media.EncryptionScheme;
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media.playback/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.media.playback/BUILD.gn
new file mode 100644
index 0000000..16144db
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media.playback/BUILD.gn
@@ -0,0 +1,32 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.media.playback") {
+ library_name = "playback"
+ namespace = "fuchsia.media"
+ public_deps = [
+ "../fuchsia.math",
+ "../fuchsia.media",
+ "../fuchsia.media.audio",
+ "../fuchsia.ui.views",
+ ]
+ sources = [
+ "player.fidl",
+ "problem.fidl",
+ "seeking_reader.fidl",
+ "source_manager.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.media.playback",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media.playback/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.media.playback/meta.json
new file mode 100644
index 0000000..f6cf6d5
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media.playback/meta.json
@@ -0,0 +1,17 @@
+{
+ "deps": [
+ "fuchsia.math",
+ "fuchsia.media",
+ "fuchsia.media.audio",
+ "fuchsia.ui.views"
+ ],
+ "name": "fuchsia.media.playback",
+ "root": "fidl/fuchsia.media.playback",
+ "sources": [
+ "fidl/fuchsia.media.playback/player.fidl",
+ "fidl/fuchsia.media.playback/problem.fidl",
+ "fidl/fuchsia.media.playback/seeking_reader.fidl",
+ "fidl/fuchsia.media.playback/source_manager.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media.playback/player.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media.playback/player.fidl
new file mode 100644
index 0000000..ff81897
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media.playback/player.fidl
@@ -0,0 +1,98 @@
+// Copyright 2018 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.
+
+library fuchsia.media.playback;
+
+using fuchsia.math;
+using fuchsia.media;
+using fuchsia.media.audio;
+using fuchsia.ui.views;
+using zx;
+
+/// Plays media.
+[Discoverable]
+protocol Player {
+ compose SourceManager;
+
+ /// Sets a file channel to read from.
+ SetFileSource(handle<channel> file_channel);
+
+ /// Starts playback.
+ Play();
+
+ /// Pauses playback.
+ Pause();
+
+ /// Provides current status immediately after binding and whenever status
+ /// changes thereafter.
+ -> OnStatusChanged(PlayerStatus player_status);
+
+ /// Seeks to the specified position, specified in nanoseconds.
+ Seek(int64 position);
+
+ /// Creates a video view.
+ CreateView(fuchsia.ui.views.ViewToken view_token);
+
+ /// Binds to the gain control for this player.
+ BindGainControl(
+ request<fuchsia.media.audio.GainControl> gain_control_request);
+
+ /// Adds a new binding to this player.
+ AddBinding(request<Player> player_request);
+};
+
+/// Player status information.
+struct PlayerStatus {
+ /// Duration of the content.
+ zx.duration duration;
+
+ /// Whether the player can pause.
+ bool can_pause;
+
+ /// Whether the player can seek.
+ bool can_seek;
+
+ /// Whether the source has an audio stream.
+ bool has_audio;
+
+ /// Whether the source has a video stream.
+ bool has_video;
+
+ /// Indicates whether the player is ready to play. After
+ /// `SetFileSource` or `SourceManager.SetSource` is called, this value is
+ /// false until the player is fully prepared to play the content from the
+ /// source.
+ bool ready;
+
+ // Describes the media.
+ fuchsia.media.Metadata? metadata;
+
+ /// Indicates a problem preventing intended operation.
+ Problem? problem;
+
+ /// Indicates whether an audio stream is currently connected for rendering.
+ /// This value will be false if `has_audio` is false or if the audio stream
+ /// type isn't supported.
+ bool audio_connected;
+
+ /// Indicates whether a video stream is currently connected for rendering.
+ /// This value will be false if `has_video` is false or if the video stream
+ /// type isn't supported.
+ bool video_connected;
+
+ /// Size of the video currently being produced. This value will be null if
+ /// the video size is currently unknown.
+ fuchsia.math.Size? video_size;
+
+ /// Relative dimensions of a video pixel. This value will be null if the
+ /// pixel aspect ratio is currently unknown.
+ fuchsia.math.Size? pixel_aspect_ratio;
+
+ /// Function translating local time to presentation time. This value will be
+ /// null if the timeline function is currently undefined.
+ fuchsia.media.TimelineFunction? timeline_function;
+
+ /// Indicates whether presentation for all streams has reached end-of-stream.
+ bool end_of_stream;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media.playback/problem.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media.playback/problem.fidl
new file mode 100644
index 0000000..8dc22b6
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media.playback/problem.fidl
@@ -0,0 +1,36 @@
+// Copyright 2016 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.
+
+library fuchsia.media.playback;
+
+/// Models a problem preventing intended operation.
+///
+/// A `Problem` is generally surfaced as part of a component's status, probably
+/// as an optional field. Absence of a `Problem` means that nothing is preventing
+/// intended operation. When a problem is exposed, the client can take action
+/// automatically or present relevant UI. If a problem can be resolved by some
+/// action, the client may take that action automatically or enlist the user
+/// somehow in the resolution. In either case, the problem goes away when the
+/// issue that caused it to be exposed is resolved. By design, there is no
+/// general means of dismissing a problem.
+struct Problem {
+ /// The type of problem. This is a string for extensibility.
+ string type;
+
+ /// Type-dependent details.
+ string? details;
+};
+
+const string PROBLEM_INTERNAL =
+ "fuchsia.media.playback.Internal";
+const string PROBLEM_ASSET_NOT_FOUND =
+ "fuchsia.media.playback.AssetNotFound";
+const string PROBLEM_CONTAINER_NOT_SUPPORTED =
+ "fuchsia.media.playback.ContainerNotSupported";
+const string PROBLEM_AUDIO_ENCODING_NOT_SUPPORTED =
+ "fuchsia.media.playback.AudioEncodingNotSupported";
+const string PROBLEM_VIDEO_ENCODING_NOT_SUPPORTED =
+ "fuchsia.media.playback.VideoEncodingNotSupported";
+const string PROBLEM_CONNECTION_FAILED =
+ "fuchsia.media.playback.ConnectionFailed";
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media.playback/seeking_reader.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media.playback/seeking_reader.fidl
new file mode 100644
index 0000000..b26b5ad
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media.playback/seeking_reader.fidl
@@ -0,0 +1,26 @@
+// Copyright 2016 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.
+
+library fuchsia.media.playback;
+
+using zx;
+
+// Reader with seek semantics.
+// TODO(dalesat): Report problems using Problem rather than SeekingReaderResult.
+protocol SeekingReader {
+ // Describes the content. If there’s a problem accessing the content, this
+ // is expressed by using result. The size_in_bytes may be reported as
+ // UNKNOWN_SIZE if the size of the content is unknown.
+ Describe() -> (zx.status status, uint64 size, bool can_seek);
+
+ // Reads the content. If there’s a problem performing the read, this is
+ // expressed using result. If the read succeeded, the reply must contain a
+ // valid socket from which the content can be read.
+ ReadAt(uint64 position) -> (zx.status status, handle<socket>? socket);
+};
+
+/// Distinguished value for the `size` value returned by `SeekingReader.Describe`
+/// Indicating that the size isn't known.
+const uint64 UNKNOWN_SIZE = 0xffffffffffffffff;
+
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media.playback/source_manager.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media.playback/source_manager.fidl
new file mode 100644
index 0000000..ec71820
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media.playback/source_manager.fidl
@@ -0,0 +1,115 @@
+// Copyright 2018 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.
+
+library fuchsia.media.playback;
+
+using fuchsia.media;
+using zx;
+
+/// Manages sources on behalf of a Player.
+protocol SourceManager {
+ /// Creates a source that reads from a file.
+ CreateFileSource(handle<channel> file_channel,
+ request<Source> source_request);
+
+ /// Creates a source that reads from a `SeekingReader`.
+ CreateReaderSource(SeekingReader seeking_reader,
+ request<Source> source_request);
+
+ /// Creates a source that allows the client to provide independent elementary
+ /// streams to the player. duration_ns, can_pause, can_seek and metadata are
+ /// all included in the SourceStatus and, when the `ElementarySource` is used by
+ /// the player, in the `PlayerStatus` as well. `can_pause` and `can_seek`, when
+ /// false, constrain the capabilities of the player.
+ CreateElementarySource(zx.duration duration_ns, bool can_pause, bool can_seek,
+ fuchsia.media.Metadata? metadata,
+ request<ElementarySource> source_request);
+
+ /// Sets the source for this player to use. If source is null, the player
+ /// becomes idle.
+ SetSource(Source? source);
+
+ /// Transitions to the specified source when playback of the current source
+ /// reaches transition_pts. The new source starts playback at start_pts. If
+ /// a transition is already pending, it will be discarded in favor of the new
+ /// transition.
+ TransitionToSource(Source source, int64 transition_pts,
+ int64 start_pts);
+
+ /// Cancels a pending transition, returning the source. If no transition is
+ /// pending, the request channel is closed.
+ CancelSourceTransition(request<Source> returned_source_request);
+};
+
+/// A source of content that may be used by a player.
+protocol Source {
+ // Provides current status immediately after binding and whenever status
+ // changes thereafter.
+ -> OnStatusChanged(SourceStatus source_status);
+};
+
+/// `Source` variant for providing elementary streams directly to the player.
+protocol ElementarySource {
+ compose Source;
+
+ /// Adds an elementary stream. The elementary stream can be removed by
+ /// closing the `SimpleStreamSink`. `ticks_per_second_numerator` and
+ /// `ticks_per_second_denominator` indicate the units that will be used for
+ /// `Streampacket` timestamp values. For nanoseconds units, for example,
+ /// `ticks_per_second_numerator` should be 1000000000 and
+ /// `ticks_per_second_denominator` should be 1. To use units of frames for
+ /// 48k audio, `ticks_per_second_numerator` should be 48000 and
+ /// `ticks_per_second_denominator` should be 1.
+ //
+ // SimpleStreamSink methods not currently implemented:
+ // DiscardAllPackets
+ // DiscardAllPacketsNoReply
+ AddStream(
+ fuchsia.media.StreamType type,
+ uint32 ticks_per_second_numerator,
+ uint32 ticks_per_second_denominator,
+ request<fuchsia.media.SimpleStreamSink> sink_request);
+
+ /// Adds a new binding to this `ElementarySource`. By using this method,
+ /// the client can obtain an additional channel through which to communicate
+ /// to this `ElementarySource` even after a channel is consumed by a call to
+ /// `SourceManager.SetSource`.
+ // IMPLEMENTATION NOTE:
+ // This method is implemented, however a limitation in the current
+ // implementation requires that the StreamSource handle passed to
+ // SourceManager.SetSource be created from the connection established by the
+ // original CreateStreamSource call. That is, a connection established
+ // using AddBinding cannot be passed to SourceManager.SetSource.
+ // TODO(dalesat): Remove this limitation.
+ AddBinding(request<ElementarySource> source_request);
+};
+
+/// Source status information.
+struct SourceStatus {
+ /// Duration of the content.
+ zx.duration duration;
+
+ /// Whether the source can pause.
+ bool can_pause;
+
+ /// Whether the source can seek.
+ bool can_seek;
+
+ /// Whether the source has an audio stream.
+ bool has_audio;
+
+ /// Whether the source has a video stream.
+ bool has_video;
+
+ /// Indicates whether the source is ready. A true value signals that the
+ /// content has been probed and there are no known problems with it.
+ bool ready;
+
+ /// Describes the media.
+ fuchsia.media.Metadata? metadata;
+
+ /// Indicates a problem preventing intended operation. A null value
+ /// indicates that the source is functioning as intended.
+ Problem? problem;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media.sessions2/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.media.sessions2/BUILD.gn
new file mode 100644
index 0000000..4e0a2d6
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media.sessions2/BUILD.gn
@@ -0,0 +1,30 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.media.sessions2") {
+ library_name = "sessions2"
+ namespace = "fuchsia.media"
+ public_deps = [
+ "../fuchsia.media",
+ "../fuchsia.media.audio",
+ ]
+ sources = [
+ "discovery.fidl",
+ "images.fidl",
+ "player.fidl",
+ "publisher.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.media.sessions2",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media.sessions2/discovery.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media.sessions2/discovery.fidl
new file mode 100644
index 0000000..dfa89c5
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media.sessions2/discovery.fidl
@@ -0,0 +1,165 @@
+// 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.
+
+library fuchsia.media.sessions2;
+
+using zx;
+using fuchsia.media.audio;
+using fuchsia.media;
+
+using SessionId = uint64;
+
+/// SessionInfoDelta holds a description of a media session.
+table SessionInfoDelta {
+ /// The domain on which the session takes place. A domain identifies a set of
+ /// mutually compatible media targets and sessions; sessions on a domain may
+ /// be played back on targets of the same domain.
+ ///
+ /// This field is always present.
+ 1: Domain domain;
+ /// Whether the source of the media playback is on this device.
+ ///
+ /// This field is present only if known.
+ 2: bool is_local;
+ /// If this is `true`, the playback is taking place local to the device.
+ /// Playing on the device speaker is local, playing on a remote speaker
+ /// is not. This is only set when the session is playing back; a paused
+ /// session is not active.
+ ///
+ /// This field is always present.
+ 3: bool is_locally_active;
+ /// The status of the player.
+ ///
+ /// This field is always present.
+ 4: PlayerStatus player_status;
+ /// Metadata describing the media session.
+ ///
+ /// This field is always present.
+ 5: fuchsia.media.Metadata metadata;
+ /// Images associated with the media or its source.
+ ///
+ /// This field is always present.
+ 6: vector<MediaImage> media_images;
+ /// The capabilities the player of the media implements.
+ ///
+ /// This field is always present.
+ 7: PlayerCapabilities player_capabilities;
+};
+
+/// Controls a media session and views its status.
+///
+/// The channel will close if the media session is stopped.
+protocol SessionControl {
+ /// Plays media.
+ Play();
+ /// Pauses playback and retains position in media
+ Pause();
+ /// Stops playback. The session should close.
+ Stop();
+ /// Seeks to a specific position in media. Implementations are free to
+ /// enter an error state if the position is out of bounds. `position`
+ /// is an offset from the beginning of the media.
+ Seek(zx.duration position);
+ /// Skips forward in media by the player's default skip amount.
+ SkipForward();
+ /// Skips in reverse in media by the player's default skip amount.
+ SkipReverse();
+ /// Changes media to the next item (e.g. next song in playlist).
+ NextItem();
+ /// Changes media to the previous item.
+ PrevItem();
+ /// Sets the playback rate of the media. This will not change the
+ /// playback mode.
+ SetPlaybackRate(float32 playback_rate);
+ /// Sets repeat mode to any of the supported repeat modes.
+ SetRepeatMode(RepeatMode repeat_mode);
+ /// Sets shuffle mode.
+ SetShuffleMode(bool shuffle_on);
+ /// Binds to the session's volume control for control and notifications.
+ BindVolumeControl(
+ request<fuchsia.media.audio.VolumeControl> volume_control_request);
+ /// Watches the session status. Leave a request hanging to receive a reply when
+ /// the session status changes. The first request will be answered immediately with
+ /// the current state.
+ WatchStatus() -> (SessionInfoDelta session_info_delta);
+};
+
+/// Views a media session's status.
+///
+/// The channel will close if the media session is stopped.
+protocol SessionObserver {
+ /// Watches the session status. Leave a request hanging to receive a reply when
+ /// the session status changes. The first request will be answered immediately with
+ /// the current state.
+ WatchStatus() -> (SessionInfoDelta session_info_delta);
+};
+
+/// Options that specify which sessions are watched when watching the collection.
+///
+/// The watched set is the set of sessions which satisfies all options.
+table WatchOptions {
+ /// Watch only the active session. Watches all if not set.
+ 1: bool only_active;
+ /// Watch only sessions with these allowlisted ids. Watches all if not set.
+ 2: vector<SessionId>:1000 allowed_sessions;
+};
+
+/// `SessionsWatcher` watches the collection of published sessions.
+protocol SessionsWatcher {
+ /// Called by the registry service when a session is updated. On first connection,
+ /// this will be called as many times as needed to communicate the state of the
+ /// world.
+ ///
+ /// `SessionsWatcher` must reply to acknowledge receipt of the session info delta.
+ /// Delinquent watchers who do not reply will eventually be disconnected.
+ SessionUpdated(SessionId session_id, SessionInfoDelta session_info_delta) -> ();
+
+ /// Called by the registry service when a session is removed from the registered
+ /// collection.
+ ///
+ /// `SessionsWatcher` must reply to acknlowledge receipt of the session removal.
+ /// Delinquent watchers who do not reply will eventually be disconnected.
+ SessionRemoved(SessionId session_id) -> ();
+};
+
+/// `Discovery` observes the collection of published media sessions
+/// and connects clients to them.
+[Discoverable]
+protocol Discovery {
+ /// Connects a session watcher configured with the given options.
+ WatchSessions(
+ WatchOptions watch_options,
+ SessionsWatcher session_watcher);
+
+ /// Connects to a `SessionControl` for `session_id` if present. Drops the
+ /// given channel otherwise.
+ ConnectToSession(SessionId session_id,
+ request<SessionControl> session_control_request);
+};
+
+/// `ObserverDiscovery` observes the collection of published media sessions
+/// and connects clients to them for observation without playback controls.
+[Discoverable]
+protocol ObserverDiscovery {
+ /// Connects a session watcher configured with the given options.
+ WatchSessions(WatchOptions watch_options,
+ SessionsWatcher sessions_watcher);
+
+ /// Connects to a `SessionObserver` for `session_id` if present. Drops the
+ /// given channel otherwise.
+ ConnectToSession(SessionId session_id,
+ request<SessionObserver> session_request);
+};
+
+/// A protocol for watching the current active media session on the device.
+///
+/// The currently active media session is the most recent existing media session
+/// to announce a "Playing" state on the local device, even if it is now paused.
+[Discoverable]
+protocol ActiveSession {
+ /// Watches the active session. The first request will be answered immediately
+ /// with the current active session. Always leave a request hanging to receive
+ /// a reply when the active session changes.
+ WatchActiveSession() -> (SessionControl? session);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media.sessions2/images.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media.sessions2/images.fidl
new file mode 100644
index 0000000..3cadbb7
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media.sessions2/images.fidl
@@ -0,0 +1,29 @@
+// 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.
+
+library fuchsia.media.sessions2;
+
+using Url = string:1000;
+
+enum MediaImageType {
+ /// Artwork for the playing media.
+ ARTWORK = 0;
+ /// An icon for the source of the playing media (e.g. the player or
+ /// streaming service).
+ SOURCE_ICON = 1;
+};
+
+/// A variant of an image at a specific size.
+struct ImageSizeVariant {
+ Url url;
+ uint32 width;
+ uint32 height;
+};
+
+/// An image for playing media.
+table MediaImage {
+ 1: MediaImageType image_type;
+ /// Available variants of the image.
+ 2: vector<ImageSizeVariant>:16 sizes;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media.sessions2/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.media.sessions2/meta.json
new file mode 100644
index 0000000..1a068d6
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media.sessions2/meta.json
@@ -0,0 +1,15 @@
+{
+ "deps": [
+ "fuchsia.media",
+ "fuchsia.media.audio"
+ ],
+ "name": "fuchsia.media.sessions2",
+ "root": "fidl/fuchsia.media.sessions2",
+ "sources": [
+ "fidl/fuchsia.media.sessions2/discovery.fidl",
+ "fidl/fuchsia.media.sessions2/images.fidl",
+ "fidl/fuchsia.media.sessions2/player.fidl",
+ "fidl/fuchsia.media.sessions2/publisher.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media.sessions2/player.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media.sessions2/player.fidl
new file mode 100644
index 0000000..e8544d0
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media.sessions2/player.fidl
@@ -0,0 +1,225 @@
+// 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.
+
+library fuchsia.media.sessions2;
+
+using zx;
+using fuchsia.media;
+using fuchsia.media.audio;
+
+/// A domain identifies the ecosystem in which the session takes place.
+///
+/// Domains should take the form of
+///
+/// `domain://<unique name for protocol>.version`
+///
+/// The `|` symbol is reserved and should not be used in a domain string.
+using Domain = string:1000;
+
+/// Controls for a media player.
+protocol PlayerControl {
+ /// Plays media.
+ Play();
+ /// Pauses playback and retains position in media
+ Pause();
+ /// Stops playback. The session should close.
+ Stop();
+ /// Seeks to a specific position in media. Implementations are free to
+ /// enter an error state if the position is out of bounds. `position`
+ /// is an offset from the beginning of the media.
+ Seek(zx.duration position);
+ /// Skips forward in media by the player's default skip amount.
+ SkipForward();
+ /// Skips in reverse in media by the player's default skip amount.
+ SkipReverse();
+ /// Changes media to the next item (e.g. next song in playlist).
+ NextItem();
+ /// Changes media to the previous item.
+ PrevItem();
+ /// Sets the playback rate of the media. This will not change the
+ /// playback mode.
+ SetPlaybackRate(float32 playback_rate);
+ /// Sets repeat mode to any of the supported repeat modes.
+ SetRepeatMode(RepeatMode repeat_mode);
+ /// Sets shuffle mode.
+ SetShuffleMode(bool shuffle_on);
+ /// Binds to the session's volume control for control and notifications.
+ BindVolumeControl(
+ request<fuchsia.media.audio.VolumeControl> volume_control_request);
+};
+
+/// The type of content playing back, which should be set to the largest
+/// applicable value.
+enum ContentType {
+ OTHER = 1;
+ AUDIO = 2;
+ VIDEO = 3;
+ MUSIC = 4;
+ TV_SHOW = 5;
+ MOVIE = 6;
+};
+
+/// Status of a media player.
+// Next Id: 9
+table PlayerStatus {
+ /// Total duration of playing media.
+ ///
+ /// Omit if not known or not applicable.
+ 1: zx.duration duration;
+ /// Whether the playing media is live (such as television or a
+ /// live stream).
+ ///
+ /// If omitted, the default is false.
+ 8: bool is_live;
+ /// State of the player.
+ ///
+ /// Will always be present.
+ 2: PlayerState player_state;
+ /// A playback function that describes the position and rate of
+ /// play through the media as a function of `CLOCK_MONOTONIC`.
+ ///
+ /// Include in order to render a position in media timeline
+ /// for users. Optional.
+ 3: fuchsia.media.TimelineFunction timeline_function;
+ /// Repeat mode of the player.
+ ///
+ /// Will always be present.
+ 4: RepeatMode repeat_mode;
+ /// Shuffle mode of the player.
+ ///
+ /// Will always be present.
+ 5: bool shuffle_on;
+ /// The type of content playing back.
+ ///
+ /// Will always be present.
+ 6: ContentType content_type;
+ /// An error the player may have encountered.
+ ///
+ /// Should only be present in case of error.
+ 7: Error error;
+};
+
+/// State of a media player.
+enum PlayerState {
+ /// The initial state of a session if there is no associated media.
+ IDLE = 0;
+ PLAYING = 1;
+ PAUSED = 2;
+ BUFFERING = 3;
+ /// The player cannot recover from this state and will close.
+ ERROR = 4;
+};
+
+// TODO(turnage): Add error codes for frontends as they are discovered to be
+// useful.
+enum Error {
+ OTHER = 1;
+};
+
+/// Modes of repeating playback of the current media.
+enum RepeatMode {
+ /// No repeat.
+ OFF = 0;
+ /// Repeat the relevant group of media (e.g. playlist).
+ GROUP = 1;
+ /// Repeat the currently playing media.
+ SINGLE = 2;
+};
+
+bits PlayerCapabilityFlags : uint32 {
+ /// If set, the player can `Play()`.
+ PLAY = 0x1;
+ /// If set, the player can `Pause()`.
+ PAUSE = 0x4;
+ /// If set, the player can `Seek()`.
+ SEEK = 0x8;
+ /// If set, the player can `SkipForward()`.
+ SKIP_FORWARD = 0x10;
+ /// If set, the player can `SkipReverse()`.
+ SKIP_REVERSE = 0x20;
+ /// If set, the player can shuffle media.
+ SHUFFLE = 0x40;
+ // If set, the player can `NextItem()` if there is a next item.
+ CHANGE_TO_NEXT_ITEM = 0x80;
+ // If set, the player can `PrevItem()` if there is a previous item.
+ CHANGE_TO_PREV_ITEM = 0x100;
+ /// If set, the player can `BindGainControl()`.
+ HAS_GAIN_CONTROL = 0x200;
+ /// If set, the player can repeat groups.
+ REPEAT_GROUPS = 0x400;
+ /// If set, the player can repeat single media items.
+ REPEAT_SINGLE = 0x800;
+};
+
+/// `PlaybackCapabilities` enumerates the capabilities of a media player, and
+/// corresponds to the control commands it can execute.
+table PlayerCapabilities {
+ 1: PlayerCapabilityFlags flags;
+};
+
+/// The behavior enforced on the player when it is
+/// interrupted, such as by an alarm.
+///
+/// Interruptions are detected using the player's usage.
+///
+/// By default the interruption behavior is `NONE`.
+enum InterruptionBehavior {
+ /// Interruptions have no effect on the player
+ /// and it may continue in spite of reduced audibility.
+ NONE = 0;
+ /// With this behavior, when playback is interrupted, the player
+ /// will be paused until the interruption is over, so the user
+ /// does not miss any content.
+ PAUSE = 1;
+};
+
+/// When emitted, fields that have changed should be set.
+/// The first emission to a new client should be a snapshot.
+table PlayerInfoDelta {
+ /// Whether the entry point for the media into our device network is the
+ /// local machine; this should be true if this is the device streaming
+ /// from a music service, but false or omitted if this machine is just
+ /// receiving an audio stream to act as a speaker.
+ ///
+ /// If omitted, the previous value is retained. If no value is ever
+ /// sent, the default is `true`.
+ 1: bool local;
+ /// The status of the player.
+ ///
+ /// If omitted, the previous status is retained. This must be included
+ /// at least once.
+ 2: PlayerStatus player_status;
+ /// The metadata of the playing media.
+ ///
+ /// If omitted, the previous metadata is retained. Including this at
+ /// least once for each new media is highly recommended.
+ 3: fuchsia.media.Metadata metadata;
+ /// The images associated with the playing media.
+ ///
+ /// If omitted, the previous media images are retained. Send an empty
+ /// vector to clear media images.
+ 4: vector<MediaImage>:16 media_images;
+ /// The capabilities of the player.
+ ///
+ /// If omitted, the previous capabilities are retained. This must be
+ /// sent at least once.
+ 5: PlayerCapabilities player_capabilities;
+ /// The behavior the player would like to engage in when interrupted
+ /// by something, such as an alarm.
+ ///
+ /// If omitted, the previous behavior is retained. If no value is ever
+ /// sent, the default is `NONE`.
+ 6: InterruptionBehavior interruption_behavior;
+};
+
+/// `Player` is a handle for a media player. Unsupported commands are
+/// no-ops. Consult `PlaybackCapabilities`, sent by to learn which
+/// commands are supported.
+protocol Player {
+ compose PlayerControl;
+
+ /// Leave hanging to receive a response when the player's
+ /// status changes.
+ WatchInfoChange() -> (PlayerInfoDelta player_info_delta);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media.sessions2/publisher.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media.sessions2/publisher.fidl
new file mode 100644
index 0000000..611d705
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media.sessions2/publisher.fidl
@@ -0,0 +1,30 @@
+// 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.
+
+library fuchsia.media.sessions2;
+
+using fuchsia.media;
+
+/// All information required by the media session registry service to
+/// register a player so that clients may observe its status and control
+/// it.
+table PlayerRegistration {
+ /// The domain on which the player exists. Unset if it is the native
+ /// Fuchsia domain.
+ 1: Domain domain;
+ /// The usage of the player's audio output. By default, this is assumed
+ /// to be MEDIA.
+ 2: fuchsia.media.AudioRenderUsage usage;
+};
+
+/// `Publisher` publishes media players so they may be discovered and
+/// controlled by clients who have permission to do so.
+[Discoverable]
+protocol Publisher {
+ [Deprecated, Transitional]
+ PublishPlayer(Player player, PlayerRegistration registration);
+
+ [Transitional]
+ Publish(Player player, PlayerRegistration registration) -> (SessionId session_id);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media.sounds/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.media.sounds/BUILD.gn
new file mode 100644
index 0000000..53c6fab
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media.sounds/BUILD.gn
@@ -0,0 +1,28 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.media.sounds") {
+ library_name = "sounds"
+ namespace = "fuchsia.media"
+ public_deps = [
+ "../fuchsia.io",
+ "../fuchsia.media",
+ "../fuchsia.mem",
+ ]
+ sources = [
+ "sound_player.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.media.sounds",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media.sounds/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.media.sounds/meta.json
new file mode 100644
index 0000000..24a65b8
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media.sounds/meta.json
@@ -0,0 +1,13 @@
+{
+ "deps": [
+ "fuchsia.media",
+ "fuchsia.io",
+ "fuchsia.mem"
+ ],
+ "name": "fuchsia.media.sounds",
+ "root": "fidl/fuchsia.media.sounds",
+ "sources": [
+ "fidl/fuchsia.media.sounds/sound_player.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media.sounds/sound_player.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media.sounds/sound_player.fidl
new file mode 100644
index 0000000..92fc8f7
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media.sounds/sound_player.fidl
@@ -0,0 +1,56 @@
+// 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.
+
+library fuchsia.media.sounds;
+
+using fuchsia.io;
+using fuchsia.media;
+using fuchsia.mem;
+using zx;
+
+/// Allows clients to play fire-and-forget sounds.
+[Discoverable]
+protocol Player {
+ /// Adds a sound to the collection maintained for the client, reading the sound from a file.
+ /// If `id` identifies an existing sound in the collection, the service will close the
+ /// connection. Returns the duration of the sound or an error status returned from an I/O
+ /// operation.
+ ///
+ /// Currently, only PCM WAV files are supported.
+ AddSoundFromFile(uint32 id, fuchsia.io.File file) -> (zx.duration duration) error zx.status;
+
+ /// Adds a sound, in the form of a buffer containing raw PCM samples, to the collection
+ /// maintained for the client. The service will retain a handle to the buffer's VMO until the
+ /// sound is removed and is no longer playing or until the connection is closed.
+ ///
+ /// If `id` identifies an existing sound in the collection, the service will close the
+ /// connection.
+ AddSoundBuffer(uint32 id, fuchsia.mem.Buffer buffer, fuchsia.media.AudioStreamType stream_type);
+
+ /// Removes a sound from the collection maintained for the client. A sound can be removed even
+ /// if a `PlaySound` method is pending for that sound.
+ ///
+ /// If `id` doesn't identify an existing sound in the collection, the service will do nothing.
+ /// This is tolerated so that clients don't have to wait for the response from
+ /// `AddSoundFromFile` before playing and removing the sound.
+ ///
+ /// Removing an unneeded sound frees the resources associated with that sound, principally
+ /// the VMO required to store the uncompressed sound.
+ RemoveSound(uint32 id);
+
+ /// Plays the existing sound identified by `id` using a renderer with usage `usage`. The
+ /// sound is played as soon as possible. The reply is sent when the sound is finished playing.
+ /// If `id` doesn't identify an existing sound in the collection, the method return
+ /// `PlaySoundError.NO_SUCH_SOUND`.
+ PlaySound(uint32 id, fuchsia.media.AudioRenderUsage usage) -> () error PlaySoundError;
+};
+
+/// Error type for `Player.PlaySound`.
+enum PlaySoundError {
+ /// The `id` passed to `PlaySound` is not recognized.
+ NO_SUCH_SOUND = 1;
+
+ /// Underlying audio renderer failed.
+ RENDERER_FAILED = 2;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media.target/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.media.target/BUILD.gn
new file mode 100644
index 0000000..ffbe22f
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media.target/BUILD.gn
@@ -0,0 +1,28 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.media.target") {
+ library_name = "target"
+ namespace = "fuchsia.media"
+ public_deps = [
+ "../fuchsia.media",
+ "../fuchsia.media.audio",
+ "../fuchsia.media.sessions2",
+ ]
+ sources = [
+ "target_discovery.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.media.target",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media.target/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.media.target/meta.json
new file mode 100644
index 0000000..55f287a
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media.target/meta.json
@@ -0,0 +1,13 @@
+{
+ "deps": [
+ "fuchsia.media",
+ "fuchsia.media.audio",
+ "fuchsia.media.sessions2"
+ ],
+ "name": "fuchsia.media.target",
+ "root": "fidl/fuchsia.media.target",
+ "sources": [
+ "fidl/fuchsia.media.target/target_discovery.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media.target/target_discovery.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media.target/target_discovery.fidl
new file mode 100644
index 0000000..e4cfa30
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media.target/target_discovery.fidl
@@ -0,0 +1,195 @@
+// Copyright 2020 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.
+
+/// A library of protocols for routing media between devices.
+///
+/// This library is based on "targets", which are devices or groups of devices
+/// which can render media sessions. See `fuchsia.media.sessions2` for media
+/// session details.
+///
+/// Through the `Discovery` protocol, clients can discover what media targets
+/// are available on the network, and select them to render media sessions.
+library fuchsia.media.target;
+
+using fuchsia.media;
+using fuchsia.media.audio;
+using fuchsia.media.sessions2;
+
+/// A unique id for a target.
+using Id = uint64;
+
+/// A user-visible name for a target to display in user interface or read
+/// in voice interfaces.
+using DisplayName = string:200;
+
+/// A protocol for discovering media targets.
+[Discoverable]
+protocol Discovery {
+ compose Group;
+ compose Selector;
+
+ /// Watches for bindings of media sessions to targets.
+ ///
+ /// A media session is rendered on the target to which it is bound.
+ ///
+ /// First, existing bindings will be returned. Then, bindings added
+ /// and removed since connection will be returned as deltas on the
+ /// initial set.
+ GetNextSessionBinding() -> (SessionBindingWatchEvent event);
+
+ /// Connects to a target by id. Drops the given channel if no such
+ /// target exists.
+ ConnectToTarget(Id target_id, request<Target> target_request);
+};
+
+/// A binding between a session and a target, indicating the media session
+/// is rendered on the target.
+struct SessionBinding {
+ fuchsia.media.sessions2.SessionId session_id;
+ Id target_id;
+};
+
+union SessionBindingWatchEvent {
+ /// An already existing binding at the time of connection.
+ 1: SessionBinding existing;
+ /// Indicates the full set of bindings from the time of connection have
+ /// been enumerated. No more `existing` events will be received.
+ 2: Void idle;
+ /// A new binding added since connection.
+ 3: SessionBinding added;
+ /// A binding removed.
+ 4: SessionBinding removed;
+};
+
+/// A target is a device or group of devices on which media can be rendered,
+/// such as a speaker which renders audio.
+protocol Target {
+ compose GroupEditor;
+ compose Group;
+ compose VolumeControl;
+};
+
+struct TargetChange {
+ Id new_target_id;
+};
+
+/// A protocol for adding and removing members of a group target.
+protocol GroupEditor {
+ /// Adds a target to this group target.
+ ///
+ /// If the added target is a group of devices, all the devices in that group
+ /// are added to this group. A group itself cannot be a member of a group.
+ ///
+ /// Returns the id of the new target if a new group was created to fulfill this
+ /// request.
+ AddTarget(Id target_id) -> (TargetChange? target_change) error Error;
+
+ /// Removes a target from this group. Returns the id of the new target
+ /// if a new group was created to fulfill this request.
+ RemoveTarget(Id target_id) -> (TargetChange? target_change) error Error;
+};
+
+/// A protocol for watching the members of a group.
+protocol Group {
+ /// Watches for changes to the set of registered targets. Leave a request
+ /// hanging to get replies when changes occur. New clients will be caught
+ /// up with the state of the world.
+ ///
+ /// First, existing targets will be returned. Then, targets added and removed
+ /// since connection will be returned as deltas on the initial set.
+ GetNextTarget() -> (TargetWatchEvent target_watch_event);
+};
+
+struct Void {
+};
+
+union TargetWatchEvent {
+ /// An already existing target at the time of connection.
+ 1: Description existing;
+ /// Indicates the full set of targets from the time of connection have
+ /// been enumerated. No more `existing` events will be received.
+ 2: Void idle;
+ /// A new target added since connection.
+ 3: Description added;
+ /// A target’s description was updated.
+ 4: Description updated;
+ /// A target removed.
+ 5: Id removed;
+};
+
+/// A protocol to control the volume of target.
+protocol VolumeControl {
+ /// Binds to the target's volume control. If this target is a group,
+ /// all member volumes are influenced. These settings persist
+ /// for the lifetime of the target.
+ BindVolumeControl(request<fuchsia.media.audio.VolumeControl> volume_control_request);
+
+ /// Binds to the target's volume control as a member of the given group.
+ /// The request channel is dropped if the target is not a member of the group.
+ ///
+ /// This volume control influences the volume of this target only when it is
+ /// participating as a member of the group. This is used to adjust the balance
+ /// of volume among members of a group. These settings persist for the lifetime
+ /// of the target
+ BindMemberVolumeControl(
+ Id group,
+ request<fuchsia.media.audio.VolumeControl> volume_control_request);
+};
+
+/// A description of a target.
+table Description {
+ /// Identifies the target.
+ 1: Id target_id;
+ /// Enumerates of the interoperability features the device supports.
+ 2: CapabilityFlags capability_flags;
+ 3: DisplayName display_name;
+ 4: fuchsia.media.Metadata metadata;
+};
+
+/// Capabilities of the target.
+bits CapabilityFlags : uint64 {
+ /// Indicates the target can receive a transfer of a
+ /// media session from another target.
+ TRANSFER_TO = 0x01;
+ /// Indicates the target can transfer a media session
+ /// to another target.
+ TRANSFER_FROM = 0x02;
+ /// Indicates the target can participate in rendering
+ /// media with other devices.
+ MULTI_TARGET_PLAYBACK = 0x04;
+ /// Indicates the target can render video.
+ VIDEO = 0x08;
+};
+
+/// A protocol for selecting a media target. Commands on this protocol can
+/// change the target on which a media session is rendered.
+protocol Selector {
+ /// Renders the media session specified by `session_id` on the target
+ /// specified by `target_id`.
+ BindTarget(
+ fuchsia.media.sessions2.SessionId session_id,
+ Id target_id) -> () error Error;
+
+ /// Renders the media session specified by `session_id` on the set of
+ /// targets specified by `target_ids`.
+ ///
+ /// This may create a new group target which contains all the specified
+ /// targets as members, if one does not exist. The group target may be
+ /// temporary, only existing for the lifetime of playback, and not
+ /// discoverable through `Discovery`.
+ BindGroupTarget(
+ fuchsia.media.sessions2.SessionId session_id,
+ vector<Id>:100 target_ids
+ ) -> (Id target_id) error Error;
+};
+
+enum Error {
+ NOT_A_GROUP = 0;
+ UNKNOWN_ON_DOMAIN = 1;
+ CANNOT_BE_GROUPED = 2;
+ NOT_MEMBER_OF_GROUP = 3;
+ TRANSFER_FROM_TARGET_UNSUPPORTED = 4;
+ TRANSFER_TO_TARGET_UNSUPPORTED = 5;
+ MULTI_TARGET_PLAYBACK_UNSUPPORTED = 6;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.media/BUILD.gn
new file mode 100644
index 0000000..d55d281
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media/BUILD.gn
@@ -0,0 +1,42 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.media") {
+ library_name = "media"
+ namespace = "fuchsia"
+ public_deps = [
+ "../fuchsia.images",
+ "../fuchsia.media.audio",
+ "../fuchsia.sysmem",
+ ]
+ sources = [
+ "activity_reporter.fidl",
+ "audio.fidl",
+ "audio_capturer.fidl",
+ "audio_consumer.fidl",
+ "audio_core.fidl",
+ "audio_device_enumerator.fidl",
+ "audio_renderer.fidl",
+ "metadata.fidl",
+ "profile_provider.fidl",
+ "stream.fidl",
+ "stream_common.fidl",
+ "stream_processor.fidl",
+ "stream_type.fidl",
+ "timeline_function.fidl",
+ "usage_reporter.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.media",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media/activity_reporter.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media/activity_reporter.fidl
new file mode 100644
index 0000000..683c4af
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media/activity_reporter.fidl
@@ -0,0 +1,15 @@
+// Copyright 2020 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.
+
+// TODO(36191): Move to fuchsia.media.audio
+
+library fuchsia.media;
+
+/// A protocol for monitoring the usage activity of the AudioRenderers.
+[Discoverable]
+protocol ActivityReporter {
+ /// Notifies the client whenever there is a change in the set of active AudioRenderUsages.
+ /// It returns immediately the first time that it is called.
+ WatchRenderActivity() -> (vector<AudioRenderUsage>:RENDER_USAGE_COUNT active_usages);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media/audio.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media/audio.fidl
new file mode 100644
index 0000000..4a6bcda
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media/audio.fidl
@@ -0,0 +1,37 @@
+// Copyright 2016 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.
+
+library fuchsia.media;
+
+[Discoverable]
+protocol Audio {
+ CreateAudioRenderer(request<AudioRenderer> audio_renderer_request);
+
+ /// Create an AudioCapturer which either captures from the current default
+ /// audio input device, or loops-back from the current default audio output
+ /// device based on value passed for the loopback flag.
+ ///
+ // TODO(mpuryear): Get rid of the loopback flag ASAP. Routing decisions (and
+ // security surrounding routing decisions) should be much more sophisticated
+ // than this. This is just a placeholder until we have a design in place.
+ // Eventually, I suspect that all of this will move up into the audio policy
+ // manager and application clients will obtain AudioCapturers from and control
+ // through the policy manager.
+ CreateAudioCapturer(request<AudioCapturer> audio_capturer_request,
+ bool loopback);
+
+ // TODO(38104): Remove these methods.
+ [Transitional, Deprecated]
+ SetSystemMute(bool muted);
+ [Transitional, Deprecated]
+ SetSystemGain(float32 gain_db);
+ [Transitional, Deprecated]
+ -> SystemGainMuteChanged(float32 gain_db, bool muted);
+};
+
+/// Permitted ranges for AudioRenderer and AudioCapturer
+const uint32 MIN_PCM_CHANNEL_COUNT = 1;
+const uint32 MAX_PCM_CHANNEL_COUNT = 8;
+const uint32 MIN_PCM_FRAMES_PER_SECOND = 1000;
+const uint32 MAX_PCM_FRAMES_PER_SECOND = 192000;
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media/audio_capturer.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media/audio_capturer.fidl
new file mode 100644
index 0000000..cd16913
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media/audio_capturer.fidl
@@ -0,0 +1,349 @@
+// Copyright 2017 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.
+
+library fuchsia.media;
+
+using fuchsia.media.audio;
+
+/// Configuration for a capturer which will receive a loopback stream
+/// a system output.
+table LoopbackAudioCapturerConfiguration {
+};
+
+/// Configuration for a capturer which will receive a stream from an
+/// input device.
+table InputAudioCapturerConfiguration {
+ 1: AudioCaptureUsage usage;
+};
+
+/// Configuration for an audio Capturer.
+union AudioCapturerConfiguration {
+ 1: LoopbackAudioCapturerConfiguration loopback;
+ 2: InputAudioCapturerConfiguration input;
+};
+
+// TODO(mpuryear): Routing policy needs to become more capable than this.
+// Clients will need to be able to request sets of inputs/outputs/renderers,
+// make changes to theses sets, have their requests vetted by policy (do they
+// have the permission to capture this private stream, do they have the
+// permission to capture at this frame rate, etc...). Eventually, this
+// functionality will need to be expressed at the AudioPolicy level, not here.
+// TODO(mpuryear): can we come up with better names than these? Both are
+// really async modes under the hood).
+// TODO(mpuryear): Add a new method to replace `DiscardAllPackets`, which will
+// be removed from `StreamSource`.
+// TODO(mpuryear): Fix obsolete docs.
+// TODO(mpuryear): Specify the way in which timestamps relative to a different
+// clock (such as an audio domain clock) may be delivered to a client.
+/// AudioCapturer
+///
+/// An AudioCapturer is an interface returned from an fuchsia.media.Audio's
+/// CreateAudioCapturer method, which may be used by clients to capture audio
+/// from either the current default audio input device, or the current default
+/// audio output device depending on the flags passed during creation.
+///
+/// ** Format support **
+///
+/// See (Get|Set)StreamType below. By default, the captured stream type will be
+/// initially determined by the currently configured stream type of the source
+/// that the AudioCapturer was bound to at creation time. Users may either fetch
+/// this type using GetStreamType, or they may choose to have the media
+/// resampled or converted to a type of their choosing by calling SetStreamType.
+/// Note: the stream type may only be set while the system is not running,
+/// meaning that there are no pending capture regions (specified using CaptureAt)
+/// and that the system is not currently running in 'async' capture mode.
+///
+/// ** Buffers and memory management **
+///
+/// Audio data is captured into a shared memory buffer (a VMO) supplied by the
+/// user to the AudioCapturer during the AddPayloadBuffer call. Please note the
+/// following requirements related to the management of the payload buffer.
+///
+/// ++ The payload buffer must be supplied before any capture operation may
+/// start. Any attempt to start capture (via either CaptureAt or
+/// StartAsyncCapture) before a payload buffer has been established is an
+/// error.
+/// ++ The payload buffer may not be changed while there are any capture
+/// operations pending.
+/// ++ The stream type may not be changed after the payload buffer has been set.
+/// ++ The payload buffer must be an integral number of audio frame sizes (in
+/// bytes)
+/// ++ When running in 'async' mode (see below), the payload buffer must be at
+/// least as large as twice the frames_per_packet size specified during
+/// StartAsyncCapture.
+/// ++ The handle to the payload buffer supplied by the user must be readable,
+/// writable, mappable and transferable.
+/// ++ Users should always treat the payload buffer as read-only.
+///
+/// ** Synchronous vs. Asynchronous capture mode **
+///
+/// The AudioCapturer interface can be used in one of two mutually exclusive
+/// modes: Synchronous and Asynchronous. A description of each mode and their
+/// tradeoffs is given below.
+///
+/// ** Synchronous mode **
+///
+/// By default, AudioCapturer instances are running in 'sync' mode. They will
+/// only capture data when a user supplies at least one region to capture into
+/// using the CaptureAt method. Regions supplied in this way will be filled in
+/// the order that they are received and returned to the client as StreamPackets
+/// via the return value of the CaptureAt method. If an AudioCapturer instance
+/// has data to capture, but no place to put it (because there are no more
+/// pending regions to fill), the next payload generated will indicate that their
+/// has been an overflow by setting the Discontinuity flag on the next produced
+/// StreamPacket. Synchronous mode may not be used in conjunction with
+/// Asynchronous mode. It is an error to attempt to call StartAsyncCapture while
+/// the system still regions supplied by CaptureAt waiting to be filled.
+///
+/// If a user has supplied regions to be filled by the AudioCapturer instance in
+/// the past, but wishes to reclaim those regions, they may do so using the
+/// DiscardAllPackets method. Calling the DiscardAllPackets method will cause
+/// all pending regions to be returned, but with `NO_TIMESTAMP` as their
+/// StreamPacket's PTS. See "Timing and Overflows", below, for a discussion of
+/// timestamps and discontinuity flags. After a DiscardAllPackets operation,
+/// an OnEndOfStream event will be produced. While an AudioCapturer will never
+/// overwrite any region of the payload buffer after a completed region is
+/// returned, it may overwrite the unfilled portions of a partially filled
+/// buffer which has been returned as a result of a DiscardAllPackets operation.
+///
+/// ** Asynchronous mode **
+///
+/// While running in 'async' mode, clients do not need to explicitly supply
+/// shared buffer regions to be filled by the AudioCapturer instance. Instead, a
+/// client enters into 'async' mode by calling StartAsyncCapture and supplying a
+/// callback interface and the number of frames to capture per-callback. Once
+/// running in async mode, the AudioCapturer instance will identify which
+/// payload buffer regions to capture into, capture the specified number of
+/// frames, then deliver those frames as StreamPackets using the OnPacketCapture
+/// FIDL event. Users may stop capturing and return the AudioCapturer instance to
+/// 'sync' mode using the StopAsyncCapture method.
+///
+/// It is considered an error to attempt any of the following operations.
+///
+/// ++ To attempt to enter 'async' capture mode when no payload buffer has been
+/// established.
+/// ++ To specify a number of frames to capture per payload which does not permit
+/// at least two contiguous capture payloads to exist in the established
+/// shared payload buffer simultaneously.
+/// ++ To send a region to capture into using the CaptureAt method while the
+/// AudioCapturer instance is running in 'async' mode.
+/// ++ To attempt to call DiscardAllPackets while the AudioCapturer instance is
+/// running in 'async' mode.
+/// ++ To attempt to re-start 'async' mode capturing without having first
+/// stopped.
+/// ++ To attempt any operation except for SetGain while in the process of
+/// stopping.
+///
+/// ** Synchronizing with a StopAsyncCapture operation **
+///
+/// Stopping asynchronous capture mode and returning to synchronous capture mode
+/// is an operation which takes time. Aside from SetGain, users may not call any
+/// other methods on the AudioCapturer interface after calling StopAsyncCapture
+/// (including calling StopAsyncCapture again) until after the stop operation has
+/// completed. Because of this, it is important for users to be able to
+/// synchronize with the stop operation. Two mechanisms are provided for doing
+/// so.
+///
+/// The first is to use StopAsyncCapture (not the NoReply variant). When the user's
+/// callback has been called, they can be certain that stop operation is complete
+/// and that the AudioCapturer instance has returned to synchronous operation
+/// mode.
+///
+/// The second way to determine that a stop operation has completed is to use the
+/// flags on the packets which get delivered via the user-supplied
+/// AudioCapturerCallback interface after calling StopAsyncCapture. When
+/// asked to stop, any partially filled packet will be returned to the user, and
+/// the final packet returned will always have the end-of-stream flag (kFlagsEos)
+/// set on it to indicate that this is the final frame in the sequence. If
+/// there is no partially filled packet to return, the AudioCapturer will
+/// synthesize an empty packet with no timestamp, and offset/length set to zero,
+/// in order to deliver a packet with the end-of-stream flag set on it. Once
+/// users have seen the end-of-stream flag after calling stop, the AudioCapturer
+/// has finished the stop operation and returned to synchronous operating mode.
+///
+/// ** Timing and Overflows **
+///
+/// All media packets produced by an AudioCapturer instance will have their PTS
+/// field filled out with the capture time of the audio expressed as a timestamp
+/// given by the reference clock timeline. Note: this timestamp is actually a
+/// capture timestamp, not a presentation timestamp (it is more of a CTS than a
+/// PTS) and is meant to represent the underlying system's best estimate of the
+/// capture time of the first frame of audio, including all outboard and hardware
+/// introduced buffering delay. As a result, all timestamps produced by an
+/// AudioCapturer should be expected to be in the past relative to 'now' on the
+/// stream's reference clock timeline.
+///
+/// The one exception to the "everything has an explicit timestamp" rule is when
+/// discarding submitted regions while operating in synchronous mode. Discarded
+/// packets have no data in them, but FIDL demands that all pending
+/// method-return-value callbacks be executed. Because of this, the regions will
+/// be returned to the user, but their timestamps will be set to
+/// `NO_TIMESTAMP`, and their payload sizes will be set to zero. Any
+/// partially filled payload will have a valid timestamp, but a payload size
+/// smaller than originally requested. The final discarded payload (if there
+/// were any to discard) will be followed by an OnEndOfStream event.
+///
+/// Two StreamPackets delivered by an AudioCapturer instance are 'continuous' if
+/// the first frame of audio contained in the second packet was capture exactly
+/// one nominal frame time after the final frame of audio in the first packet.
+/// If this relationship does not hold, the second StreamPacket will have the
+/// 'kFlagDiscontinuous' flag set in it's flags field.
+///
+/// Even though explicit timestamps are provided on every StreamPacket produced,
+/// users who have very precise timing requirements are encouraged to always
+/// reason about time by counting frames delivered since the last discontinuity,
+/// rather than simply using the raw capture timestamps. This is because the
+/// explicit timestamps written on continuous packets may have a small amount of
+/// rounding error based on whether or not the units of the capture timeline
+/// reference clock are divisible by the chosen audio frame rate.
+///
+/// Users should always expect the first StreamPacket produced by an
+/// AudioCapturer to have the discontinuous flag set on it (as there is no
+/// previous packet to be continuous with). Similarly, the first StreamPacket
+/// after a DiscardAllPackets or a Stop/Start cycle will always be
+/// discontinuous. After that, there are only two reasons that a StreamPacket
+/// will ever be discontinuous:
+///
+/// 1) The user is operating an synchronous mode and does not supply regions to
+/// be filled quickly enough. If the next continuous frame of data has not
+/// been captured by the time it needs to be purged from the source buffers,
+/// an overflow has occurred and the AudioCapturer will flag the next captured
+/// region as discontinuous.
+/// 2) The user is operating in asynchronous mode and some internal error
+/// prevents the AudioCapturer instance from capturing the next frame of audio
+/// in a continuous fashion. This might be high system load or a hardware
+/// error, but in general it is something which should never normally happen.
+/// In practice, however, if it does, the next produced packet will be flagged
+/// as being discontinuous.
+///
+/// ** Synchronous vs. Asynchronous Trade-offs **
+///
+/// The choice of operating in synchronous vs. asynchronous mode is up to the
+/// user, and depending on the user's requirements, there are some advantages and
+/// disadvantages to each choice.
+///
+/// Synchronous mode requires only a single Zircon channel under the hood and can
+/// achieve some small savings because of this. In addition, the user has
+/// complete control over the buffer management. Users specify exactly where
+/// audio will be captured to and in what order. Because of this, if users do
+/// not need to always be capturing, it is simple to stop and restart the capture
+/// later (just by ceasing to supply packets, then resuming later on). Payloads
+/// do not need to be uniform in size either, clients may specify payloads of
+/// whatever granularity is appropriate.
+///
+/// The primary downside of operating in synchronous mode is that two messages
+/// will need to be sent for every packet to be captured. One to inform the
+/// AudioCapturer of the instance to capture into, and one to inform the user
+/// that the packet has been captured. This may end up increasing overhead and
+/// potentially complicating client designs.
+///
+/// Asynchronous mode has the advantage requiring only 1/2 of the messages,
+/// however, when operating in 'async' mode, AudioCapturer instances have no way
+/// of knowing if a user is processing the StreamPackets being sent in a timely
+/// fashion, and no way of automatically detecting an overflow condition. Users
+/// of 'async' mode should be careful to use a buffer large enough to ensure that
+/// they will be able to process their data before an AudioCapturer will be
+/// forced to overwrite it.
+///
+// ** Future Directions (aka TODOs) **
+//
+// ++ Consider adding a 'zero message' capture mode where the AudioCapturer
+// simply supplies a linear transformation and some buffer parameters (max
+// audio hold time) each time that it is started in 'async' mode, or each
+// time an internal overflow occurs in 'async' mode. Based on this
+// information, client should know where the capture write pointer is at all
+// times as a function of the transformation removing the need to send any
+// buffer position messages. This would reduce the operational overhead just
+// about as low as it could go, and could allow for the lowest possible
+// latency for capture clients. OTOH - it might be better to achieve this
+// simply by allowing clients to be granted direct, exclusive access to the
+// driver level of capture if no resampling, reformatting, or sharing is
+// needed.
+// ++ Consider providing some mechanism by which users may specify the exact
+// time at which they want to capture data.
+// ++ Allow for more complex routing/mixing/AEC scenarios and place this under
+// the control of the policy manager.
+// ++ Define and enforce access permissions and downsampling requirements for
+// sensitive content. Enforce using the policy manager.
+// ++ Consider allowing the mixer to produce compressed audio.
+//
+
+protocol AudioCapturer {
+ compose StreamBufferSet;
+ compose StreamSource;
+
+ /// Sets the stream type of the stream to be delivered. Causes the source
+ /// material to be reformatted/resampled if needed in order to produce the
+ /// requested stream type. Note that the stream type may not be changed
+ /// after the payload buffer has been established.
+ SetPcmStreamType(AudioStreamType stream_type);
+
+ /// Explicitly specify a region of the shared payload buffer for the audio
+ /// input to capture into.
+ CaptureAt(uint32 payload_buffer_id, uint32 payload_offset,
+ uint32 frames) -> (StreamPacket captured_packet);
+
+ /// Place the AudioCapturer into 'async' capture mode and begin to produce
+ /// packets of exactly 'frames_per_packet' number of frames each. The
+ /// OnPacketProduced event (of StreamSink) will be used to inform the client
+ /// of produced packets.
+ StartAsyncCapture(uint32 frames_per_packet);
+
+ /// Stop capturing in 'async' capture mode and (optionally) deliver a
+ /// callback that may be used by the client if explicit synchronization
+ /// is needed.
+ StopAsyncCapture() -> ();
+ StopAsyncCaptureNoReply();
+
+ /// Binds to the gain control for this AudioCapturer.
+ BindGainControl(request<fuchsia.media.audio.GainControl> gain_control_request);
+
+ /// Retrieves the stream's reference clock. The returned handle will have READ, DUPLICATE
+ /// and TRANSFER rights, and will refer to a zx::clock that is MONOTONIC and CONTINUOUS.
+ ///
+ GetReferenceClock() -> (handle<clock> reference_clock);
+
+ /// Sets the reference clock that controls this capturer's playback rate. If the input
+ /// parameter is valid, it must have READ, DUPLICATE, TRANSFER rights and refer to a clock
+ /// that is MONOTONIC and CONTINUOUS. If instead ZX_HANDLE_INVALID is passed, then this
+ /// capturer will use the so-called 'optimal' clock generated by AudioCore for this stream.
+ ///
+ /// Calling |SetReferenceClock| during Async capture will generally cause a capture
+ /// discontinuity, with audio dropped or silence inserted (based on the discontinuity).
+ /// Cases that PRESERVE continuity would include setting as reference either the 'optimal'
+ /// clock provided by AudioCore, or the clone of a client-controlled reference clock.
+ ///
+ SetReferenceClock(handle<clock>? reference_clock);
+
+ /// Sets the usage of the capture stream. This may be changed on the fly, but
+ /// packets in flight may be affected by the new usage. By default the
+ /// Capturer is created with the FOREGROUND usage.
+ SetUsage(AudioCaptureUsage usage);
+
+ // ////////////////////////////////////////////////////////////////////////
+ // StreamBufferSet methods
+ // See stream.fidl.
+
+ // ////////////////////////////////////////////////////////////////////////
+ // StreamSource methods
+ // See stream.fidl.
+
+ // ////////////////////////////////////////////////////////////////////////
+ // Methods to be deprecated
+ // These methods will go away.
+
+ /// Gets the currently configured stream type. Note: for an AudioCapturer
+ /// which was just created and has not yet had its stream type explicitly
+ /// set, this will retrieve the stream type -- at the time the AudioCapturer
+ /// was created -- of the source (input or looped-back output) to which the
+ /// AudioCapturer is bound.
+ ///
+ // TODO(mpuryear): Get rid of this. Eventually, AudioCapturers will be
+ // bindable to a set of inputs/outputs/renderers, so the concept of a
+ // "native" stream type will go away. Mechanisms will need to be put in
+ // place to allow users to enumerate the configuration of these bind-able
+ // endpoints (and perhaps to exercise control over them), but it will be
+ // the user of the AudioCapturer's job to specify the format they want.
+ GetStreamType() -> (StreamType stream_type);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media/audio_consumer.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media/audio_consumer.fidl
new file mode 100644
index 0000000..433aeb0
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media/audio_consumer.fidl
@@ -0,0 +1,137 @@
+// 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.
+
+library fuchsia.media;
+
+using zx;
+using fuchsia.media.audio;
+
+/// Interface for creating audio consumers bound to a session
+[Discoverable]
+protocol SessionAudioConsumerFactory {
+ /// Creates an `AudioConsumer` which is an interface for playing audio bound
+ /// to a particular session. `session_id` is the identifier of the media session
+ /// for which audio is to be rendered.
+ // TODO(dalesat): Can't use fuchsia.media.sessions2.SessionId here, because dependencies.
+ CreateAudioConsumer(
+ uint64 session_id,
+ request<AudioConsumer> audio_consumer_request);
+};
+
+/// Interface for playing and controlling audio
+protocol AudioConsumer {
+ /// Creates a `StreamSink` for the consumer with the indicated properties.
+ ///
+ /// Multiple stream sinks may be acquired using this method, but they are intended to be used
+ /// sequentially rather than concurrently. The first stream sink that's created using this
+ /// method is used as the sole source of packets incoming to the logical consumer until that
+ /// stream sink is closed or the `EndOfStream` method is called on that sink. At that point,
+ /// the second stream sink is used, and so on.
+ ///
+ /// If an unsupported compression type is supplied, the
+ /// `stream_sink_request` request will be closed with an epitaph value of
+ /// `ZX_ERR_INVALID_ARGS`
+ CreateStreamSink(
+ vector<handle<vmo>>:16 buffers,
+ AudioStreamType stream_type,
+ Compression? compression,
+ request<StreamSink> stream_sink_request);
+
+ /// Indicates that the last packet prior to the end of the stream has been rendered.
+ -> OnEndOfStream();
+
+ /// Starts rendering as indicated by `flags`.
+ ///
+ /// `media_time` indicates the packet timestamp that corresponds to `reference_time`.
+ /// Typically, this is the timestamp of the first packet that will be
+ /// rendered. If packets will be supplied with no timestamps, this value
+ /// should be `NO_TIMESTAMP`. Passing a `media_time` value of
+ /// `NO_TIMESTAMP` chooses the default media time, established as follows:
+ /// 1. When starting for the first time, the default media time is the
+ /// timestamp on the first packet sent to the stream sink.
+ /// 2. When resuming after stop, the default media time is the media
+ /// time at which the stream stopped.
+ ///
+ /// `reference_time` is the monotonic system time at which rendering should
+ /// be started. For supply-driven sources, this must be the time at which
+ /// the first packet was (or will be) sent plus a lead time, which must be
+ /// in the range indicated in the `AudioConsumerStatus`. For demand-driven
+ /// sources, the client must ensure that the lead time requirement is met at
+ /// the start time. Passing the default value of 0 for `reference_time`
+ /// causes the consumer to choose a start time based on the availability of
+ /// packets, the lead time requirements, and whether `LOW_LATENCY` has been
+ /// specified.
+ ///
+ /// The actual start time will be reflected in the updated status.
+ Start(
+ AudioConsumerStartFlags flags,
+ zx.time reference_time,
+ int64 media_time);
+
+ /// Stops rendering as soon as possible after this method is called. The actual stop time will
+ /// be reflected in the updated status.
+ Stop();
+
+ /// Requests to change the playback rate of the renderer. 1.0 means normal
+ /// playback. Negative rates are not supported. The new rate will be
+ /// reflected in the updated status. The default rate of any newly created `StreamSink` is 1.0.
+ SetRate(float32 rate);
+
+ /// Binds to this `AudioConsumer` volume control for control and notifications.
+ BindVolumeControl(
+ request<fuchsia.media.audio.VolumeControl> volume_control_request);
+
+ /// Gets the current status of the consumer using the long get pattern. The consumer responds
+ /// to this method when the status changes - initially with respect to the initial status value
+ /// and thereafter with respect to the previously-reported status value.
+ WatchStatus() -> (AudioConsumerStatus status);
+};
+
+/// Flags passed to `AudioConsumer.Start`.
+bits AudioConsumerStartFlags {
+ /// Indicates that latency should be kept as low as possible.
+ LOW_LATENCY = 0x01;
+
+ /// Indicates that the timing of packet delivery is determined by an external process rather
+ /// than being demand-based. When this flag is set, the service should expect underflow or
+ /// overflow due to a mismatch between packet arrival rate and presentation rate. When this
+ /// flag is not set, packets arrive on demand.
+ SUPPLY_DRIVEN = 0x02;
+};
+
+/// Represents the status of the consumer. In the initial status, `error` and
+/// `presentation_timeline` are absent. The lead time fields are always present.
+table AudioConsumerStatus {
+ /// If present, indicates an error condition currently in effect. Absent if no error.
+ 1: AudioConsumerError error;
+
+ /// If present, indicates the current relationship between the presentation timeline
+ /// and local monotonic clock, both in nanosecond units. If not present,
+ /// indicates there is no relationship. Absent initially.
+ ///
+ /// 'Presentation timeline' refers to the `pts` (presentation timestamp) values on the packets.
+ /// This timeline function can be used to determine the local monotonic clock time that a
+ /// packet will be presented based on that packet's `pts` value.
+ 2: TimelineFunction presentation_timeline;
+
+ /// Indicates the minimum lead time in nanoseconds supported by this
+ /// `AudioConsumer`. Or in other words, how small of a gap between the
+ /// `media_time` provided to `AudioConsumer.Start` and the pts on the first
+ /// packet can be. Values outside this range will be clipped.
+ 3: uint64 min_lead_time;
+
+ /// Indicates the maximum lead time in nanoseconds supported by this
+ /// `AudioConsumer`. Or in other words, how large of a gap between the
+ /// `media_time` provided to `AudioConsumer.Start` and the pts on the first
+ /// packet can be. Values outside this range will be clipped.
+ 4: uint64 max_lead_time;
+};
+
+struct Void {
+};
+
+/// Represents a `AudioConsumer` error condition.
+union AudioConsumerError {
+ 1: Void place_holder;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media/audio_core.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media/audio_core.fidl
new file mode 100644
index 0000000..2519777
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media/audio_core.fidl
@@ -0,0 +1,201 @@
+// 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.
+
+library fuchsia.media;
+
+using fuchsia.media.audio;
+
+/// Usage annotating the purpose of the stream being used to render audio.
+/// An AudioRenderer's usage cannot be changed after creation. The
+/// AudioRenderUsage is used by audio policy to dictate how audio streams
+/// interact with each other.
+enum AudioRenderUsage {
+ /// Stream is intended to be used for ambient or background sound. Streams
+ /// that can be interrupted without consequence should use this.
+ BACKGROUND = 0;
+
+ /// Stream is intended to be used for normal functionality. Streams that
+ /// are part of normal functionality should use this.
+ MEDIA = 1;
+
+ /// Stream is intended to interrupt any ongoing function of the device.
+ /// Streams that are used for interruptions like notifications should use
+ /// this.
+ INTERRUPTION = 2;
+
+ /// Stream is for interaction with a system agent. This should be used
+ /// in response to a user initiated trigger.
+ SYSTEM_AGENT = 3;
+
+ /// Stream is intended to be used for some form of real time user to user
+ /// communication. Voice/Video chat should use this.
+ COMMUNICATION = 4;
+};
+const uint8 RENDER_USAGE_COUNT = 5;
+
+/// Usages annotating the purpose of the stream being used to capture audio. The
+/// AudioCaptureUsage is used by audio policy to dictate how audio streams
+/// interact with each other.
+enum AudioCaptureUsage {
+ /// Stream is used to capture audio while in the background. These streams
+ /// may be active at any the time and are considered privileged.
+ /// Example: Listening for Hotwords
+ BACKGROUND = 0;
+
+ /// Stream is intended to be used for normal capture functionality. Streams
+ /// that are used for audio capture while the stream creator is in the
+ /// foreground should use this.
+ /// Example: Voice Recorder
+ FOREGROUND = 1;
+
+ /// Stream is for interaction with a system agent. This should only be used
+ /// once a user has signalled their intent to have the interaction with an
+ /// interested party.
+ /// Examples: Assistant, Siri, Alexa
+ SYSTEM_AGENT = 2;
+
+ /// Stream is intended to be used for some form of real time user to user
+ /// communication. Voice/Video chat should use this.
+ COMMUNICATION = 3;
+};
+const uint8 CAPTURE_USAGE_COUNT = 4;
+
+/// The behaviors applied to streams when multiple are active.
+enum Behavior {
+ /// Mix the streams.
+ NONE = 0;
+
+ /// Apply a gain to duck the volume of one of the streams. (-14.0db)
+ DUCK = 1;
+
+ /// Apply a gain to mute one of the streams. (-160.0db)
+ MUTE = 2;
+};
+
+union Usage {
+ 1: AudioRenderUsage render_usage;
+ 2: AudioCaptureUsage capture_usage;
+};
+
+[Discoverable]
+protocol AudioCore {
+ /// Create an AudioRenderer which outputs audio to the default device.
+ CreateAudioRenderer(request<AudioRenderer> audio_out_request);
+
+ /// Create a new Audio Capturer according to the given requirements.
+ ///
+ /// `pcm_stream_type` sets the stream type of the stream to be delivered.
+ /// It causes the source material to be reformatted/resampled if needed
+ /// in order to produce the requested stream type.
+ ///
+ /// `usage` is used by Fuchsia to make decisions about user experience.
+ /// See `AudioCaptureUsage` for more details.
+ ///
+ /// `configuration` must be initialized to a variant, or no capturer
+ /// can be created.
+ ///
+ /// TODO(45240): Implement
+ [Transitional]
+ CreateAudioCapturerWithConfiguration(
+ AudioStreamType stream_type,
+ AudioCapturerConfiguration configuration,
+ request<AudioCapturer> audio_capturer_request);
+
+ /// Create an AudioCapturer which either captures from the current default
+ /// audio input device, or loops-back from the current default audio output
+ /// device based on value passed for the loopback flag.
+ //
+ // TODO(34915): Get rid of the loopback flag ASAP. Routing decisions (and
+ // security surrounding routing decisions) should be more sophisticated.
+ // This is a placeholder until we have a design in place. Eventually, this
+ // should move up to an audio policy layer, where application clients obtain
+ // and control AudioCapturers.
+ CreateAudioCapturer(bool loopback, request<AudioCapturer> audio_in_request);
+
+ // TODO(34948): remove these systemwide settings, once device-centric
+ // settings are plumbed into the system UI. Also, device-centric and
+ // systemwide settings should be moved out of this accessible-to-all public
+ // audio interface and relocated to a more restrictive interface that is
+ // only accessible by clients with the appropriate privileges (such as
+ // system configuration API, or the governor of audio policy).
+
+ /// System Gain and Mute
+ ///
+ /// Fuchsia clients control the volume of individual audio streams via the
+ /// fuchsia.media.audio.GainControl protocol. System Gain and Mute affect
+ /// all audio output, and are controlled with methods that use the same
+ /// concepts as GainControl, namely: independent gain and mute, with change
+ /// notifications. Setting System Mute to true leads to the same outcome as
+ /// setting System Gain to MUTED_GAIN_DB: all audio output across the system
+ /// is silenced.
+ ///
+ /// Sets the systemwide gain in decibels. `gain_db` values are clamped to
+ /// the range -160 db to 0 db, inclusive. This setting is applied to all
+ /// audio output devices. Audio input devices are unaffected.
+ /// Does not affect System Mute.
+ [Transitional, Deprecated]
+ SetSystemGain(float32 gain_db);
+
+ /// Sets/clears the systemwide 'Mute' state for audio output devices.
+ /// Audio input devices are unaffected. Changes to the System Mute state do
+ /// not affect the value of System Gain.
+ [Transitional, Deprecated]
+ SetSystemMute(bool muted);
+
+ /// Provides current values for systemwide Gain and Mute. When a client
+ /// connects to AudioCore, the system immediately sends that client a
+ /// SystemGainMuteChanged event with the current system Gain|Mute settings.
+ /// Subsequent events will be sent when these Gain|Mute values change.
+ [Transitional, Deprecated]
+ -> SystemGainMuteChanged(float32 gain_db, bool muted);
+
+ // By default, reading and writing device settings files is enabled. This
+ // method (which has impact across the entire audio subsystem) allows a test
+ // client to temporarily disable, then later enable, that reading/writing.
+ // TODO(13578): Move this to the hub, instead of FIDL API. Alternately,
+ // simply remove; going forward, HermeticTestEnvironment accepts a
+ // parameter that disables device settings writeback during testing.
+ EnableDeviceSettings(bool enabled);
+
+ /// Set the Usage gain applied to Renderers. By default, the gain for all
+ /// render usages is set to Unity (0 db).
+ SetRenderUsageGain(AudioRenderUsage usage, float32 gain_db);
+
+ /// Set the Usage gain applied to Capturers. By default, the gain for all
+ /// capture usages is set to Unity (0 db).
+ SetCaptureUsageGain(AudioCaptureUsage usage, float32 gain_db);
+
+ /// Binds to a volume control protocol for the given usage.
+ BindUsageVolumeControl(Usage usage, request<fuchsia.media.audio.VolumeControl> volume_control);
+
+ /// SetInteraction allows changing how audio_core handles interactions of multiple active
+ /// streams simultaneously. If streams of Usage `active` are processing audio, and streams of
+ /// Usage `affected` are as well, the Behavior specified will be applied to the streams of Usage
+ /// `affected`.
+ SetInteraction(Usage active, Usage affected, Behavior behavior);
+
+ /// Re-initializes the set of rules that are currently governing the interaction of streams in
+ /// audio_core. The default behavior is 'NONE'.
+ ResetInteractions();
+
+ /// Re-loads the platform policy configuration. Falls back to a default config if the platform
+ /// does not provide a config.
+ LoadDefaults();
+};
+
+// Placeholder for routing policies.
+// TODO(34922): Replace, when routing is handled by a central policy manager.
+enum AudioOutputRoutingPolicy {
+ // AudioRenderers are always connected to all audio outputs which currently
+ // in the plugged state (eg; have a connector attached to them)
+ ALL_PLUGGED_OUTPUTS = 0;
+
+ // AudioRenderers are only connected to the output stream which most
+ // recently entered the plugged state. AudioRenderers move around from
+ // output to output as streams are published/unpublished and become
+ // plugged/unplugged.
+ //
+ // This is the default initial setting for audio output routing.
+ LAST_PLUGGED_OUTPUT = 1;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media/audio_device_enumerator.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media/audio_device_enumerator.fidl
new file mode 100644
index 0000000..9e4349b
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media/audio_device_enumerator.fidl
@@ -0,0 +1,107 @@
+// Copyright 2018 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.
+
+library fuchsia.media;
+
+const uint32 AudioGainInfoFlag_Mute = 0x01;
+const uint32 AudioGainInfoFlag_AgcSupported = 0x02;
+const uint32 AudioGainInfoFlag_AgcEnabled = 0x04;
+
+struct AudioGainInfo {
+ float32 gain_db;
+ uint32 flags;
+};
+
+struct AudioDeviceInfo {
+ string name;
+ string unique_id;
+ uint64 token_id;
+ bool is_input;
+
+ // We include these during device enumeration to reduce server round-trip
+ // calls, and to simplify a user's state machine when determining current
+ // device state during initial enumeration.
+ AudioGainInfo gain_info;
+ bool is_default;
+};
+
+const uint32 SetAudioGainFlag_GainValid = 0x01;
+const uint32 SetAudioGainFlag_MuteValid = 0x02;
+const uint32 SetAudioGainFlag_AgcValid = 0x04;
+
+[Discoverable]
+protocol AudioDeviceEnumerator {
+ /// Obtain the list of currently active audio devices.
+ GetDevices() -> (vector<AudioDeviceInfo> devices);
+
+ /// Events sent when devices are added or removed, or when properties of a
+ /// device change.
+ //
+ // TODO(mpuryear): Should we have a set of filters which control which of
+ // these events a user receives?
+ //
+ // Pro: Having filters like this removes the need for the server to send
+ // messages to clients who don't care. In particular, it seems likely that a
+ // client who just called SetDeviceGain will not care about the
+ // OnDeviceGainChanged event being fired.
+ //
+ // Con: Having filters like this means that the server needs to maintain a
+ // bit more per-client state.
+ -> OnDeviceAdded(AudioDeviceInfo device);
+ -> OnDeviceRemoved(uint64 device_token);
+ -> OnDeviceGainChanged(uint64 device_token, AudioGainInfo gain_info);
+ [Deprecated]
+ -> OnDefaultDeviceChanged(uint64 old_default_token,
+ uint64 new_default_token);
+
+ /// Gain/Mute/AGC control
+ ///
+ /// Note that each of these operations requires a device_token in order to
+ /// target the proper input/output.
+ ///
+ /// The Get command returns the device_token of the device whose gain is
+ /// being reported, or `ZX_KOID_INVALID` in the case that the requested
+ /// device_token was invalid or the device had been removed from the system
+ /// before the Get command could be processed.
+ ///
+ /// Set commands which are given an invalid device token are ignored and
+ /// have no effect on the system. In addition, users do not need to control
+ /// all of the gain settings for an audio device with each call. Only the
+ /// settings with a corresponding flag set in the set_flags parameter will
+ /// be affected. For example, passing SetAudioGainFlag_MuteValid will cause
+ /// a SetDeviceGain call to care only about the mute setting in the
+ /// gain_info structure, while passing (SetAudioGainFlag_GainValid |
+ /// SetAudioGainFlag_MuteValid) will cause both the mute and the gain
+ /// status to be changed simultaneously.
+ GetDeviceGain(uint64 device_token)
+ -> (uint64 device_token, AudioGainInfo gain_info);
+ SetDeviceGain(uint64 device_token,
+ AudioGainInfo gain_info,
+ uint32 set_flags);
+
+ /// Default Device
+ ///
+ /// Fetch the device ID of the current default input or output device, or
+ /// `ZX_KOID_INVALID` if no such device exists.
+ //
+ // TODO(mpuryear): solidify the concept of "default" device. Right now, it
+ // basically means the device which would be chosen as the destination of an
+ // AudioRenderer stream (or the source for an AudioCapturer stream), in the
+ // absence of...
+ //
+ // 1) Any manual routing configuration imposed by the user.
+ // 2) Any property based routing decision made by the audio service.
+ //
+ // Currently, this translates to "the default inputs/output will be the last
+ // plugged input/output". As the human level logic which drives the audio
+ // routing policy evolves and becomes more complicated, this will probably
+ // change.
+ [Deprecated, Transitional]
+ GetDefaultInputDevice() -> (uint64 device_token);
+ [Deprecated, Transitional]
+ GetDefaultOutputDevice() -> (uint64 device_token);
+
+ AddDeviceByChannel(handle<channel> device_channel, string:256 device_name,
+ bool is_input);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media/audio_renderer.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media/audio_renderer.fidl
new file mode 100644
index 0000000..be29a19
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media/audio_renderer.fidl
@@ -0,0 +1,318 @@
+// Copyright 2018 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.
+
+library fuchsia.media;
+
+using fuchsia.media.audio;
+
+///
+/// AudioRenderers can be in one of two states at any time: _configurable_ or _operational_. A
+/// renderer is considered operational whenever it has packets queued to be rendered; otherwise it
+/// is _configurable_. Once an AudioRenderer enters the operational state, calls to "configuring"
+/// methods are disallowed and will cause the audio service to disconnect the client's connection.
+/// The following are considered configuring methods: `AddPayloadBuffer`, `SetPcmStreamType`,
+/// `SetStreamType`, `SetPtsUnits`, `SetPtsContinuityThreshold`.
+///
+/// If an AudioRenderer must be reconfigured, the client must ensure that no packets are still
+/// enqueued when these "configuring" methods are called. Thus it is best practice to call
+/// `DiscardAllPackets` on the AudioRenderer (and ideally `Stop` before `DiscardAllPackets`), prior
+/// to reconfiguring the renderer.
+///
+protocol AudioRenderer {
+ compose StreamBufferSet;
+ compose StreamSink;
+
+ /// Binds to the gain control for this AudioRenderer.
+ BindGainControl(request<fuchsia.media.audio.GainControl> gain_control_request);
+
+ /// Sets the units used by the presentation (media) timeline. By default, PTS units are
+ /// nanoseconds (as if this were called with numerator of 1e9 and denominator of 1).
+ SetPtsUnits(uint32 tick_per_second_numerator,
+ uint32 tick_per_second_denominator);
+
+ /// Sets the maximum threshold (in seconds) between explicit user-provided PTS
+ /// and expected PTS (determined using interpolation). Beyond this threshold,
+ /// a stream is no longer considered 'continuous' by the renderer.
+ ///
+ /// Defaults to an interval of half a PTS 'tick', using the currently-defined PTS units.
+ /// Most users should not need to change this value from its default.
+ ///
+ /// Example:
+ /// A user is playing back 48KHz audio from a container, which also contains
+ /// video and needs to be synchronized with the audio. The timestamps are
+ /// provided explicitly per packet by the container, and expressed in mSec
+ /// units. This means that a single tick of the media timeline (1 mSec)
+ /// represents exactly 48 frames of audio. The application in this scenario
+ /// delivers packets of audio to the AudioRenderer, each with exactly 470
+ /// frames of audio, and each with an explicit timestamp set to the best
+ /// possible representation of the presentation time (given this media
+ /// clock's resolution). So, starting from zero, the timestamps would be..
+ ///
+ /// [ 0, 10, 20, 29, 39, 49, 59, 69, 78, 88, ... ]
+ ///
+ /// In this example, attempting to use the presentation time to compute the
+ /// starting frame number of the audio in the packet would be wrong the
+ /// majority of the time. The first timestamp is correct (by definition), but
+ /// it will be 24 packets before the timestamps and frame numbers come back
+ /// into alignment (the 24th packet would start with the 11280th audio frame
+ /// and have a PTS of exactly 235).
+ ///
+ /// One way to fix this situation is to set the PTS continuity threshold
+ /// (henceforth, CT) for the stream to be equal to 1/2 of the time taken by
+ /// the number of frames contained within a single tick of the media clock,
+ /// rounded up. In this scenario, that would be 24.0 frames of audio, or 500
+ /// uSec. Any packets whose expected PTS was within +/-CT frames of the
+ /// explicitly provided PTS would be considered to be a continuation of the
+ /// previous frame of audio. For this example, calling 'SetPtsContinuityThreshold(0.0005)'
+ /// would work well.
+ ///
+ /// Other possible uses:
+ /// Users who are scheduling audio explicitly, relative to a clock which has
+ /// not been configured as the reference clock, can use this value to control
+ /// the maximum acceptable synchronization error before a discontinuity is
+ /// introduced. E.g., if a user is scheduling audio based on a recovered
+ /// common media clock, and has not published that clock as the reference
+ /// clock, and they set the CT to 20mSec, then up to 20mSec of drift error
+ /// can accumulate before the AudioRenderer deliberately inserts a
+ /// presentation discontinuity to account for the error.
+ ///
+ /// Users whose need to deal with a container where their timestamps may be
+ /// even less correct than +/- 1/2 of a PTS tick may set this value to
+ /// something larger. This should be the maximum level of inaccuracy present
+ /// in the container timestamps, if known. Failing that, it could be set to
+ /// the maximum tolerable level of drift error before absolute timestamps are
+ /// explicitly obeyed. Finally, a user could set this number to a very large
+ /// value (86400.0 seconds, for example) to effectively cause *all*
+ /// timestamps to be ignored after the first, thus treating all audio as
+ /// continuous with previously delivered packets. Conversely, users who wish
+ /// to *always* explicitly schedule their audio packets exactly may specify
+ /// a CT of 0.
+ ///
+ /// Note: explicitly specifying high-frequency PTS units reduces the default
+ /// continuity threshold accordingly. Internally, this threshold is stored as an
+ /// integer of 1/8192 subframes. The default threshold is computed as follows:
+ /// RoundUp((AudioFPS/PTSTicksPerSec) * 4096) / (AudioFPS * 8192)
+ /// For this reason, specifying PTS units with a frequency greater than 8192x
+ /// the frame rate (or NOT calling SetPtsUnits, which accepts the default PTS
+ /// unit of 1 nanosec) will result in a default continuity threshold of zero.
+ ///
+ SetPtsContinuityThreshold(float32 threshold_seconds);
+
+ /// Retrieves the stream's reference clock. The returned handle will have READ, DUPLICATE
+ /// and TRANSFER rights, and will refer to a zx::clock that is MONOTONIC and CONTINUOUS.
+ ///
+ GetReferenceClock() -> (handle<clock> reference_clock);
+
+ /// Sets the reference clock that controls this renderer's playback rate. If the input
+ /// parameter is valid, it must have READ, DUPLICATE, TRANSFER rights and refer to a clock
+ /// that is MONOTONIC and CONTINUOUS. If instead ZX_HANDLE_INVALID is passed, then this
+ /// renderer will use the so-called 'optimal' clock generated by AudioCore for this stream.
+ ///
+ /// Although |SetReferenceClock| is not considered a configuring method, calling it when
+ /// packets are queued (even if paused) will generally cause a reference timeline
+ /// discontinuity, with packets either discarded or delayed (based on the discontinuity).
+ /// Cases that PRESERVE continuity would include setting as reference either the 'optimal'
+ /// clock provided by AudioCore, or the clone of a client-controlled reference clock.
+ ///
+ SetReferenceClock(handle<clock>? reference_clock);
+
+ /// Sets the usage of the render stream. This method may not be called after
+ /// `SetPcmStreamType` is called. The default usage is `MEDIA`.
+ SetUsage(AudioRenderUsage usage);
+
+ /// Sets the type of the stream to be delivered by the client. Using this method implies
+ /// that the stream encoding is `AUDIO_ENCODING_LPCM`.
+ ///
+ /// This must be called before `Play` or `PlayNoReply`. After a call to `SetPcmStreamType`,
+ /// the client must then send an `AddPayloadBuffer` request, then the various `StreamSink`
+ /// methods such as `SendPacket`/`SendPacketNoReply`.
+ SetPcmStreamType(AudioStreamType type);
+
+ /// Enable or disable notifications about changes to the minimum clock lead
+ /// time (in nanoseconds) for this AudioRenderer. Calling this method with
+ /// 'enabled' set to true will trigger an immediate `OnMinLeadTimeChanged`
+ /// event with the current minimum lead time for the AudioRenderer. If the
+ /// value changes, an `OnMinLeadTimeChanged` event will be raised with the
+ /// new value. This behavior will continue until the user calls
+ /// `EnableMinLeadTimeEvents(false)`.
+ ///
+ /// The minimum clock lead time is the amount of time ahead of the reference
+ /// clock's understanding of "now" that packets needs to arrive (relative to
+ /// the playback clock transformation) in order for the mixer to be able to
+ /// mix packet. For example...
+ ///
+ /// ++ Let the PTS of packet X be P(X)
+ /// ++ Let the function which transforms PTS -> RefClock be R(p) (this
+ /// function is determined by the call to Play(...)
+ /// ++ Let the minimum lead time be MLT
+ ///
+ /// If R(P(X)) < RefClock.Now() + MLT
+ /// Then the packet is late, and some (or all) of the packet's payload will
+ /// need to be skipped in order to present the packet at the scheduled time.
+ ///
+ // TODO(mpuryear): What should the units be here? Options include...
+ //
+ // 1) Normalized to nanoseconds (this is the current API)
+ // 2) Reference clock units (what happens if the reference clock changes?)
+ // 3) PTS units (what happens when the user changes the PTS units?)
+ //
+ // TODO(mpuryear): Should `EnableMinLeadTimeEvents` have an optional -> ()
+ // return value for synchronization purposes? Probably not; users should be
+ // able to send a disable request and clear their event handler if they no
+ // longer want notifications. Their in-process dispatcher framework can
+ // handle draining and dropping any lead time changed events that were
+ // already in flight when the disable message was sent.
+ //
+ EnableMinLeadTimeEvents(bool enabled);
+ -> OnMinLeadTimeChanged(int64 min_lead_time_nsec);
+
+ // TODO(mpuryear): Eliminate this method when possible. Right now, it is
+ // used by code requiring synchronous FIDL interfaces to talk to
+ // AudioRenderers.
+ ///
+ /// While it is possible to call `GetMinLeadTime` before `SetPcmStreamType`,
+ /// there's little reason to do so. This is because lead time is a function
+ /// of format/rate, so lead time will be recalculated after `SetPcmStreamType`.
+ /// If min lead time events are enabled before `SetPcmStreamType` (with
+ /// `EnableMinLeadTimeEvents(true)`), then an event will be generated in
+ /// response to `SetPcmStreamType`.
+ GetMinLeadTime() -> (int64 min_lead_time_nsec);
+
+ /// Immediately put the AudioRenderer into a playing state. Start the advance
+ /// of the media timeline, using specific values provided by the caller (or
+ /// default values if not specified). In an optional callback, return the
+ /// timestamp values ultimately used -- these set the ongoing relationship
+ /// between the media and reference timelines (i.e., how to translate between
+ /// the domain of presentation timestamps, and the realm of local system
+ /// time).
+ ///
+ /// Local system time is specified in units of nanoseconds; media_time is
+ /// specified in the units defined by the user in the `SetPtsUnits` function,
+ /// or nanoseconds if `SetPtsUnits` is not called.
+ ///
+ /// The act of placing an AudioRenderer into the playback state establishes a
+ /// relationship between 1) the user-defined media (or presentation) timeline
+ /// for this particular AudioRenderer, and 2) the real-world system reference
+ /// timeline. To communicate how to translate between timelines, the Play()
+ /// callback provides an equivalent timestamp in each time domain. The first
+ /// value ('reference_time') is given in terms of the local system clock; the
+ /// second value ('media_time') is what media instant exactly corresponds to
+ /// that local time. Restated, the frame at 'media_time' in the audio stream
+ /// should be presented at system local time 'reference_time'.
+ ///
+ /// Note: on calling this API, media_time immediately starts advancing. It is
+ /// possible (if uncommon) for a caller to specify a system time that is
+ /// far in the past, or far into the future. This, along with the specified
+ /// media time, is simply used to determine what media time corresponds to
+ /// 'now', and THAT media time is then intersected with presentation
+ /// timestamps of packets already submitted, to determine which media frames
+ /// should be presented next.
+ ///
+ /// With the corresponding reference_time and media_time values, a user can
+ /// translate arbitrary time values from one timeline into the other. After
+ /// calling `SetPtsUnits(pts_per_sec_numerator, pts_per_sec_denominator)` and
+ /// given the 'ref_start' and 'media_start' values from `Play`, then for
+ /// any 'ref_time':
+ ///
+ /// media_time = ( (ref_time - ref_start) / 1e9
+ /// * (pts_per_sec_numerator / pts_per_sec_denominator) )
+ /// + media_start
+ ///
+ /// Conversely, for any presentation timestamp 'media_time':
+ ///
+ /// ref_time = ( (media_time - media_start)
+ /// * (pts_per_sec_denominator / pts_per_sec_numerator)
+ /// * 1e9 )
+ /// + ref_start
+ ///
+ /// Users, depending on their use case, may optionally choose not to specify
+ /// one or both of these timestamps. A timestamp may be omitted by supplying
+ /// the special value '`NO_TIMESTAMP`'. The AudioRenderer automatically deduces
+ /// any omitted timestamp value using the following rules:
+ ///
+ /// Reference Time
+ /// If 'reference_time' is omitted, the AudioRenderer will select a "safe"
+ /// reference time to begin presentation, based on the minimum lead times for
+ /// the output devices that are currently bound to this AudioRenderer. For
+ /// example, if an AudioRenderer is bound to an internal audio output
+ /// requiring at least 3 mSec of lead time, and an HDMI output requiring at
+ /// least 75 mSec of lead time, the AudioRenderer might (if 'reference_time'
+ /// is omitted) select a reference time 80 mSec from now.
+ ///
+ /// Media Time
+ /// If media_time is omitted, the AudioRenderer will select one of two
+ /// values.
+ /// - If the AudioRenderer is resuming from the paused state, and packets
+ /// have not been discarded since being paused, then the AudioRenderer will
+ /// use a media_time corresponding to the instant at which the presentation
+ /// became paused.
+ /// - If the AudioRenderer is being placed into a playing state for the first
+ /// time following startup or a 'discard packets' operation, the initial
+ /// media_time will be set to the PTS of the first payload in the pending
+ /// packet queue. If the pending queue is empty, initial media_time will be
+ /// set to zero.
+ ///
+ /// Return Value
+ /// When requested, the AudioRenderer will return the 'reference_time' and
+ /// 'media_time' which were selected and used (whether they were explicitly
+ /// specified or not) in the return value of the play call.
+ ///
+ /// Examples
+ /// 1. A user has queued some audio using `SendPacket` and simply wishes them
+ /// to start playing as soon as possible. The user may call Play without
+ /// providing explicit timestamps -- `Play(NO_TIMESTAMP, NO_TIMESTAMP)`.
+ ///
+ /// 2. A user has queued some audio using `SendPacket`, and wishes to start
+ /// playback at a specified 'reference_time', in sync with some other media
+ /// stream, either initially or after discarding packets. The user would call
+ /// `Play(reference_time, NO_TIMESTAMP)`.
+ ///
+ /// 3. A user has queued some audio using `SendPacket`. The first of these
+ /// packets has a PTS of zero, and the user wishes playback to begin as soon
+ /// as possible, but wishes to skip all of the audio content between PTS 0
+ /// and PTS 'media_time'. The user would call
+ /// `Play(NO_TIMESTAMP, media_time)`.
+ ///
+ /// 4. A user has queued some audio using `SendPacket` and want to present
+ /// this media in synch with another player in a different device. The
+ /// coordinator of the group of distributed players sends an explicit
+ /// message to each player telling them to begin presentation of audio at
+ /// PTS 'media_time', at the time (based on the group's shared reference
+ /// clock) 'reference_time'. Here the user would call
+ /// `Play(reference_time, media_time)`.
+ ///
+ // TODO(mpuryear): Define behavior in the case that a user calls `Play()`
+ // while the system is already playing. We should probably do nothing but
+ // return a valid correspondence pair in response -- unless both reference
+ // and media times are provided (and do not equate to the current timeline
+ // relationship), in which case we should introduce a discontinuity.
+ //
+ // TODO(mpuryear): Collapse these if we ever have optional retvals in FIDL
+ Play(int64 reference_time, int64 media_time)
+ -> (int64 reference_time, int64 media_time);
+ PlayNoReply(int64 reference_time, int64 media_time);
+
+ /// Immediately put the AudioRenderer into the paused state and then report
+ /// the relationship between the media and reference timelines which was
+ /// established (if requested).
+ ///
+ // TODO(mpuryear): Define behavior in the case that a user calls `Pause()`
+ // while the system is already in the paused state. We should probably do
+ // nothing but provide a valid correspondence pair in response.
+ //
+ // TODO(mpuryear): Collapse these if we ever have optional retvals in FIDL
+ Pause() -> (int64 reference_time, int64 media_time);
+ PauseNoReply();
+
+ // TODO(mpuryear): Spec methods/events which can be used for unintentional
+ // discontinuity/underflow detection.
+ //
+ // TODO(mpuryear): Spec methods/events which can be used to report routing
+ // changes. (Presuming that they belong at this level at all; they may
+ // belong on some sort of policy object).
+ //
+ // TODO(mpuryear): Spec methods/events which can be used to report policy
+ // induced gain/ducking changes. (Presuming that they belong at this level
+ // at all; they may belong on some sort of policy object).
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.media/meta.json
new file mode 100644
index 0000000..0864c46
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media/meta.json
@@ -0,0 +1,27 @@
+{
+ "deps": [
+ "fuchsia.images",
+ "fuchsia.media.audio",
+ "fuchsia.sysmem"
+ ],
+ "name": "fuchsia.media",
+ "root": "fidl/fuchsia.media",
+ "sources": [
+ "fidl/fuchsia.media/activity_reporter.fidl",
+ "fidl/fuchsia.media/audio.fidl",
+ "fidl/fuchsia.media/audio_capturer.fidl",
+ "fidl/fuchsia.media/audio_consumer.fidl",
+ "fidl/fuchsia.media/audio_core.fidl",
+ "fidl/fuchsia.media/audio_device_enumerator.fidl",
+ "fidl/fuchsia.media/audio_renderer.fidl",
+ "fidl/fuchsia.media/metadata.fidl",
+ "fidl/fuchsia.media/profile_provider.fidl",
+ "fidl/fuchsia.media/stream.fidl",
+ "fidl/fuchsia.media/stream_common.fidl",
+ "fidl/fuchsia.media/stream_processor.fidl",
+ "fidl/fuchsia.media/stream_type.fidl",
+ "fidl/fuchsia.media/timeline_function.fidl",
+ "fidl/fuchsia.media/usage_reporter.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media/metadata.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media/metadata.fidl
new file mode 100644
index 0000000..fd4804a
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media/metadata.fidl
@@ -0,0 +1,32 @@
+// Copyright 2018 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.
+
+library fuchsia.media;
+
+// Describes media.
+struct Metadata {
+ vector<Property> properties;
+};
+
+struct Property {
+ string label;
+ string value;
+};
+
+const string METADATA_LABEL_TITLE = "fuchsia.media.title";
+const string METADATA_LABEL_ARTIST = "fuchsia.media.artist";
+const string METADATA_LABEL_ALBUM = "fuchsia.media.album";
+const string METADATA_LABEL_TRACK_NUMBER = "fuchsia.media.track_number";
+const string METADATA_LABEL_PUBLISHER = "fuchsia.media.publisher";
+const string METADATA_LABEL_GENRE = "fuchsia.media.genre";
+const string METADATA_LABEL_COMPOSER = "fuchsia.media.composer";
+const string METADATA_LABEL_SUBTITLE = "fuchsia.media.subtitle";
+const string METADATA_LABEL_RELEASE_DATE = "fuchsia.media.release_date";
+const string METADATA_LABEL_EPISODE = "fuchsia.media.episode";
+const string METADATA_LABEL_SEASON = "fuchsia.media.season";
+const string METADATA_LABEL_STUDIO = "fuchsia.media.studio";
+
+/// The title of the source of the media, e.g. a player, streaming service, or
+/// website.
+const string METADATA_SOURCE_TITLE = "fuchsia.media.source_title";
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media/profile_provider.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media/profile_provider.fidl
new file mode 100644
index 0000000..e3298b2
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media/profile_provider.fidl
@@ -0,0 +1,22 @@
+// Copyright 2020 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.
+
+library fuchsia.media;
+
+using zx;
+
+[Discoverable, Layout = "Simple"]
+protocol ProfileProvider {
+ /// Register a thread as a media thread. This notifies the media subsystem
+ /// that this thread should have an elevated scheduling profile applied to
+ /// it in order to meet audio or video deadlines.
+ ///
+ /// `name` is the name of the component requesting the profile.
+ /// `period` is the suggested interval to be scheduled at.
+ ///
+ /// Returns the period and capacity that was applied, if a deadline profile
+ /// was selected. Returns 0 if no deadline profile was selected.
+ RegisterHandler(handle<thread> thread_handle, string:64 name, zx.duration period)
+ -> (zx.duration period, zx.duration capacity);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media/stream.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media/stream.fidl
new file mode 100644
index 0000000..b72b0d1
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media/stream.fidl
@@ -0,0 +1,167 @@
+// Copyright 2018 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.
+
+library fuchsia.media;
+
+// fuchsia.media contains definitions shared by the various fuchsia.media.*
+// libraries. Definitions in this file concern the transport of elementary
+// streams between clients and services.
+
+/// Manages a set of payload buffers for a stream. This interface is typically
+/// inherited along with `StreamSink` or `StreamSource` to enable the transport
+/// of elementary streams between clients and services.
+protocol StreamBufferSet {
+ /// Adds a payload buffer to the current buffer set associated with the
+ /// connection. A `StreamPacket` struct reference a payload buffer in the
+ /// current set by ID using the `StreamPacket.payload_buffer_id` field.
+ ///
+ /// A buffer with ID `id` must not be in the current set when this method is
+ /// invoked, otherwise the service will close the connection.
+ AddPayloadBuffer(uint32 id, handle<vmo> payload_buffer);
+
+ /// Removes a payload buffer from the current buffer set associated with the
+ /// connection.
+ ///
+ /// A buffer with ID `id` must exist in the current set when this method is
+ /// invoked, otherwise the service will will close the connection.
+ RemovePayloadBuffer(uint32 id);
+};
+
+/// Consumes a stream of packets. This interface is typically inherited along
+/// with `StreamBufferSet` to enable the transport of elementary streams from
+/// clients to services.
+protocol StreamSink {
+ /// Sends a packet to the service. The response is sent when the service is
+ /// done with the associated payload memory.
+ ///
+ /// `packet` must be valid for the current buffer set, otherwise the service
+ /// will close the connection.
+ SendPacket(StreamPacket packet) -> ();
+
+ /// Sends a packet to the service. This interface doesn't define how the
+ /// client knows when the sink is done with the associated payload memory.
+ /// The inheriting interface must define that.
+ ///
+ /// `packet` must be valid for the current buffer set, otherwise the service
+ /// will close the connection.
+ SendPacketNoReply(StreamPacket packet);
+
+ /// Indicates the stream has ended. The precise semantics of this method are
+ /// determined by the inheriting interface.
+ EndOfStream();
+
+ /// Discards packets previously sent via `SendPacket` or `SendPacketNoReply`
+ /// and not yet released. The response is sent after all packets have been
+ /// released.
+ DiscardAllPackets() -> ();
+
+ /// Discards packets previously sent via `SendPacket` or `SendPacketNoReply`
+ /// and not yet released.
+ DiscardAllPacketsNoReply();
+};
+
+/// Produces a stream of packets. This interface is typically inherited along
+/// with `StreamBufferSet` to enable the transport of elementary streams from
+/// services to clients.
+protocol StreamSource {
+ /// Delivers a packet produced by the service. When the client is done with
+ /// the payload memory, the client must call `ReleasePacket` to release the
+ /// payload memory.
+ -> OnPacketProduced(StreamPacket packet);
+
+ /// Indicates that the stream has ended.
+ -> OnEndOfStream();
+
+ /// Releases payload memory associated with a packet previously delivered
+ /// via `OnPacketProduced`.
+ ReleasePacket(StreamPacket packet);
+
+ // These methods were mistakenly copied from `StreamSink` and are intended
+ // to be analogs of the `StreamSink` methods. In order to function as
+ // analogs, they would need to be an event (e.g., `OnDiscardAllPackets`).
+ // That event would notify the client that it should release all packets
+ // delivered via `OnPacketProduced` that have not already been released.
+ // Currently, these methods are used in `AudioCapturer` to indicate that
+ // the service should cancel all unfulfilled `CaptureAt` requests. A
+ // new method should be created for that purpose.
+ // TODO(dalesat): This should be an event.
+ DiscardAllPackets() -> ();
+ DiscardAllPacketsNoReply();
+};
+
+/// A StreamSink that uses StreamBufferSet for buffer management.
+protocol SimpleStreamSink {
+ compose StreamBufferSet;
+ compose StreamSink;
+};
+
+/// Describes a packet consumed by `StreamSink` or produced by `StreamSource`.
+struct StreamPacket {
+ /// Time at which the packet is to be presented, according to the
+ /// presentation clock.
+ int64 pts = NO_TIMESTAMP;
+
+ /// ID of the payload buffer used for this packet.
+ ///
+ /// When this struct is used with `StreamBufferSet`, this field is the ID of
+ /// a payload buffer provided via `StreamBufferSet.AddPayloadBuffer`. In
+ /// that case, this value must identify a payload buffer in the current set.
+ /// Other interfaces may define different semantics for this field.
+ uint32 payload_buffer_id;
+
+ /// Offset of the packet payload in the payload buffer.
+ ///
+ /// This value plus the `payload_size` value must be less than or equal to
+ /// the size of the referenced payload buffer.
+ uint64 payload_offset;
+
+ /// Size in bytes of the payload.
+ ///
+ /// This value plus the `payload_offest` value must be less than or equal to
+ /// the size of the referenced payload buffer.
+ uint64 payload_size;
+
+ /// An bitwise-or'ed set of flags (see constants below) describing
+ /// properties of this packet.
+ uint32 flags = 0;
+
+ /// The buffer configuration associated with this packet. The semantics of
+ /// this field depend on the interface with which this struct is used.
+ /// In many contexts, this field is not used. This field is intended for
+ /// situations in which buffer configurations (i.e. sets of payload buffers)
+ /// are explicitly identified. In such cases, the `payload_buffer_id` refers
+ /// to a payload buffer in the buffer configuration identified by this
+ /// field.
+ uint64 buffer_config = 0;
+
+ /// The stream segment associated with this packet. The semantics of this
+ /// field depend on the interface with which this struct is used. In many
+ /// contexts, this field is not used. This field is intended to distinguish
+ /// contiguous segments of the stream where stream properties (e.g.
+ /// encoding) may differ from segment to segment.
+ uint64 stream_segment_id = 0;
+};
+
+/// When used as a `StreamPacket.pts` value, indicates that the packet has no
+/// specific presentation timestamp. The effective presentation time of such a
+/// packet depends on the context in which the `StreamPacket` is used.
+const int64 NO_TIMESTAMP = 0x7fffffffffffffff;
+
+// `StreamPacket.flags` values.
+//
+/// Indicates that the packet can be understood without reference to other
+/// packets in the stream. This is typically used in compressed streams to
+/// identify packets that contain key frames.
+const uint32 STREAM_PACKET_FLAG_KEY_FRAME = 0x01;
+
+/// Indicates that all other packets in the stream can be understood without
+/// reference to this packet. This is typically used in compressed streams to
+/// identify packets containing frames that may be discarded without affecting
+/// other frames.
+const uint32 STREAM_PACKET_FLAG_DROPPABLE = 0x02;
+
+/// Indicates a discontinuity in an otherwise continuous-in-time sequence of
+/// packets. The precise semantics of this flag depend on the context in which
+/// the `StreamPacket` is used.
+const uint32 STREAM_PACKET_FLAG_DISCONTINUITY = 0x04;
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media/stream_common.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media/stream_common.fidl
new file mode 100644
index 0000000..e421ecd
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media/stream_common.fidl
@@ -0,0 +1,713 @@
+// Copyright 2018 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.
+
+library fuchsia.media;
+
+using fuchsia.sysmem;
+
+const uint32 MAX_KEY_ID_SIZE = 16;
+const uint32 MAX_INIT_VECTOR_SIZE = 16;
+const uint32 MAX_ENCRYPTION_SCHEME_SIZE = 100;
+
+/// Value
+///
+/// Generic "value" for use within generic "Parameter" struct.
+union Value {
+ 1: bool bool_value;
+ 2: uint64 uint64_value;
+ 3: int64 int64_value;
+ 4: string string_value;
+ // Prefer using oob_bytes instead.
+ 5: bytes bytes_value;
+};
+
+/// Parameter
+///
+/// Generic parameter.
+///
+/// We want to minimize use of this generic "Parameter" structure by natively
+/// defining as many stream-specific parameter semantics as we can.
+///
+// TODO: When possible, describe the very limited scenarios in which it would
+// still be reasonable to use a generic Parameter.
+struct Parameter {
+ // Some indication of the scope of applicability of this Parameter.
+ string scope;
+ // Specific name of this parameter, without the scope prefix.
+ string name;
+ // The particular value of this parameter.
+ Value value;
+};
+
+/// StreamError
+///
+/// This error code encapsulates various errors that might emanate from a
+/// StreamProcessor server. It can be sent either as an OnStreamFailed event or
+/// as an epitaph for the channel.
+enum StreamError : uint32 {
+ // Common errors 0x00
+ /// An internal error with an unspecified reason.
+ UNKNOWN = 0x00000001;
+ /// The client provided invalid input format details.
+ INVALID_INPUT_FORMAT_DETAILS = 0x00000002;
+ /// The server received buffers that are not suitable for the operation to
+ /// be performed. An example of this would be if a Decoder received output
+ /// buffers that are too small to decode a frame into.
+ INCOMPATIBLE_BUFFERS_PROVIDED = 0x00000003;
+ /// Processing of input EOS (end of stream) failed, so the stream failed.
+ /// Currently this can occur if a core codec watchdog fires while processing
+ /// EOS.
+ EOS_PROCESSING = 0x00000004;
+
+ // Decoder errors 0x01
+ /// An internal decoder error with an unspecified reason.
+ DECODER_UNKNOWN = 0x01000001;
+ /// Input data that can't be parsed. Only some parsing problems/errors are
+ /// reported this way. Corrupt input data may be reported as other
+ /// StreamError, or may not cause a StreamError.
+ DECODER_DATA_PARSING = 0x01000002;
+
+ // Encoder errors 0x02
+ /// An internal encoder error with an unspecified reason.
+ ENCODER_UNKNOWN = 0x02000001;
+
+ // Decryptor errors 0x03
+ /// An internal decryptor error with an unspecified reason.
+ DECRYPTOR_UNKNOWN = 0x03000001;
+ /// The requested KeyId is not available for use by the Decryptor. The
+ /// client may try again later if that key becomes available.
+ DECRYPTOR_NO_KEY = 0x03000002;
+};
+
+flexible union AudioCompressedFormat {
+ 1: AudioCompressedFormatAac aac;
+ 2: AudioCompressedFormatSbc sbc;
+};
+
+enum AudioBitrateMode {
+ // Used mainly when a client is configuring an encoder's output format. May
+ // also be present in an OnOutputConstraints() message from an encoder, but
+ // should not be relied upon to be present by any consumer downstream of an
+ // encoder.
+ UNSPECIFIED = 0;
+ CBR = 1;
+ VBR = 2;
+};
+
+struct AudioCompressedFormatAac {
+};
+
+struct AudioCompressedFormatSbc {
+};
+
+/// AudioPcmMode
+///
+// TODO(dustingreen): Keep or discard any non-linear formats for purposes of the
+// Codec interface?
+enum AudioPcmMode {
+ // 16 bit signed int linear or 32 bit float linear, for now
+ // 1-N channels ok, with "A.B" channels designated as A+B channel_count -
+ // the channel map is separately specified. So 5.1 becomes channel_count 6.
+ LINEAR = 0;
+ // G.711 8 bit format-defined waveform semantics
+ // 1 channel
+ ALAW = 1;
+ // G.711 8 bit format-defined waveform semantics
+ // 1 channel
+ MULAW = 2;
+};
+
+/// AudioChannelId
+///
+/// Used in specifying which audio channel is for which speaker location / type.
+///
+/// TODO(dustingreen): Do we need more channel IDs than this?
+///
+// TODO(dustingreen): Check with mpuryear@ re. naming consistency for "S" vs.
+// "R" as we move these to a common definition. Also the ordering of LS/RS vs.
+// LR/RR - probably LR/RR being first would make more sense re. how channels
+// get added incrementally, but changing the order would no longer match
+// Android's ordering.
+enum AudioChannelId {
+ SKIP = 0; // unused channel
+ LF = 1; // left front
+ RF = 2; // right front
+ CF = 3; // center front
+ LS = 4; // left surround
+ RS = 5; // right surround
+ LFE = 6; // low frequency effects
+ CS = 7; // back surround
+ LR = 8; // left rear
+ RR = 9; // right rear
+ // This is the last explicitly-defined value + 1. This name will be
+ // re-defined in future if we add more defined channel IDs above.
+ END_DEFINED = 10;
+ // This is where format-specific (or ad-hoc) channel ID values should go, to
+ // avoid colliding with any additional values allocated above. The values
+ // here are not guaranteed to avoid collision across different formats.
+ EXTENDED_CHANNEL_ID_BASE = 0x6f000000;
+ // Extended channel IDs should be <= Max.
+ MAX = 0x7fffffff;
+};
+
+/// PcmFormat
+///
+/// PCM audio format details.
+///
+// TODO(dustingreen): Discuss with mpuryear@ re. where definitions for these
+// details go and make sure the common details can specify at least this much.
+struct PcmFormat {
+ // Implicit details:
+ // * For bits_per_sample > 8, host-endian is implied.
+ // * At least for now, for channel_count >= 2, interleaved layout is
+ // implied.
+
+ AudioPcmMode pcm_mode;
+
+ // bits_per_sample
+ //
+ // A "sample" is for a single channel.
+ //
+ // For example, CD quality is 16. See PcmMode comments, as the mode
+ // constrains this value.
+ uint32 bits_per_sample;
+
+ // frames_per_second
+ //
+ // A "frame" is one datapoint (one "sample") for each channel. Each channel
+ // is sampled this many times per second. For example, CD quality is 44100.
+ uint32 frames_per_second;
+
+ // channel_map
+ //
+ // channel_map.size() is the channel count. See PcmMode comments, as some
+ // modes constrain the channel count to 1.
+ //
+ // Values from AudioChannelId should be used if they are suitable.
+ //
+ // If a channel has no suitable AudioChannelId, an ad-hoc value can be used
+ // in a range starting from AudioChannel_ExtendedChannelIdBase.
+ vector<AudioChannelId>:16 channel_map;
+
+ // TODO(dustingreen): Add unsigned 8 bit, float 32 bit, maybe others. FWIW,
+ // AOSP appears to support signed 16 bit, unsigned 8 bit, and float 32 bit
+ // under "Pcm", AFAICT based on OMX_NUMERICALDATATYPE and ACodec.cpp code.
+};
+
+/// AudioUncompressedFormat
+///
+// Uncompressed audio format details.
+union AudioUncompressedFormat {
+ 1: PcmFormat pcm;
+};
+
+/// AudioFormat
+///
+// Audio format details.
+union AudioFormat {
+ 1: AudioCompressedFormat compressed;
+ 2: AudioUncompressedFormat uncompressed;
+};
+
+/// VideoCompressedFormat
+///
+/// Compressed video format details.
+///
+// If a compressed video format has no fields here, it's because it's a good
+// format and is already self-describing given the mime_type + format-defined
+// oob_bytes as appropriate + in-band data.
+union VideoCompressedFormat {
+ // TODO(dustingreen): Any compressed video formats that aren't sufficiently
+ // self-describing to select and create a Codec instance to decode it?
+
+ // TODO(dustingreen): temp field to make the compiler happy until we have at
+ // least one real field.
+ 1: uint32 temp_field_todo_remove;
+};
+
+enum VideoColorSpace {
+ // TODO(dustingreen): add to this list
+ INVALID = 0;
+};
+
+/// VideoUncompressedFormat
+///
+/// Uncompressed video format details.
+///
+// TODO(dustingreen): Integrate with a system-wide structure for this purpose.
+// In progress - see image_format field below which will take the place of this
+// struct/table.
+struct VideoUncompressedFormat {
+ // TODO(dustingreen): This will replace VideoUncompressedFormat (after
+ // struct to table change merges).
+ fuchsia.sysmem.ImageFormat_2 image_format;
+
+ // fourcc
+ //
+ // A human-readable fourcc like RGBA should be 0x41424752 in the fourcc
+ // field (regardless of host endian-ness). Note that the R (first character)
+ // of the fourcc is in the low-order byte of this fourcc field.
+ //
+ // There are some fourcc codes that don't format nicely as a string. While
+ // I don't foresee any use of any of the purely numeric fourcc codes (not
+ // corresponding to packed ascii character values), those would be stored
+ // such that their numeric value has it's low-order byte in the low-order
+ // byte of this fourcc value. So a fourcc with "hex value" 0x00000001 would
+ // have the numeric value 1 in this field.
+ //
+ // The endian-ness of fourcc values stored in files or in network packets is
+ // outside the scope of these comments, other than to state that regardless
+ // of the source of the fourcc code and the order that storage /
+ // transmission format stores these bytes, a human-readable fourcc should
+ // have its human-read first ascii character value in the low order byte of
+ // this field.
+ uint32 fourcc;
+
+ // For formats with different planes having different resolution, this is
+ // the resolution of the highest-resolution plane(s). Else it's the
+ // resolution of all the planes.
+ uint32 primary_width_pixels;
+ uint32 primary_height_pixels;
+
+ // For formats where the secondary planes are the same resolution, these
+ // fields will be the same as primary_width_pixels and
+ // primary_height_pixels. For formats with smaller secondary resolutions,
+ // these indicate that resolution.
+ uint32 secondary_width_pixels;
+ uint32 secondary_height_pixels;
+
+ // Planar means the various planes are separately stored in their own chunks
+ // of memory.
+ bool planar;
+
+ // If a format is swizzled, the swizzling parameters are not directly here.
+ bool swizzled;
+
+ uint32 primary_line_stride_bytes;
+ // Formats with the same stride for all planes will have this field equal to
+ // primary_line_stride_bytes.
+ uint32 secondary_line_stride_bytes;
+
+ // R or Y
+ uint32 primary_start_offset;
+ // G or U
+ uint32 secondary_start_offset;
+ // B or V
+ uint32 tertiary_start_offset;
+
+ uint32 primary_pixel_stride;
+ // For formats with the same pixel stride for all planes, this field will be
+ // equal to primary_pixel_stride.
+ uint32 secondary_pixel_stride;
+
+ // These override the primary_width_pixels and primary_height_pixels for
+ // purposes of display (but not for purposes of determining the pixel layout
+ // in memory). These can crop on the right and bottom. These must be <=
+ // the corresponding coded dimension.
+ //
+ // This value must be <= primary_width_pixels.
+ uint32 primary_display_width_pixels;
+ // This value must be <= primary_height_pixels.
+ uint32 primary_display_height_pixels;
+
+ // The pixel_aspect_ratio_width : pixel_aspect_ratio_height is the pixel
+ // aspect ratio (AKA sample aspect ratio aka SAR) for the luma (AKA Y)
+ // samples. A pixel_aspect_ratio of 1:1 mean square pixels. A
+ // pixel_aspect_ratio of 2:1 would mean pixels that are displayed twice as
+ // wide as they are tall. Codec implementation should ensure these two
+ // values are relatively prime by reducing the fraction (dividing both by
+ // GCF) if necessary.
+ //
+ // When has_pixel_aspect_ratio == false, pixel_aspect_ratio_width and
+ // pixel_aspect_ratio_height will both be 1, but in that case the
+ // pixel_aspect_ratio_width : pixel_aspect_ratio_height of 1:1 is just a
+ // very weak suggestion re. reasonable-ish handling, not in any way
+ // authoritative. In this case (or in any case really) the receiver of this
+ // message may have other OOB means to determine the actual
+ // pixel_aspect_ratio.
+ bool has_pixel_aspect_ratio = false;
+ uint32 pixel_aspect_ratio_width = 1;
+ uint32 pixel_aspect_ratio_height = 1;
+};
+
+/// VideoFormat
+///
+/// Video (compress or uncompressed) format details. In this context,
+/// "uncompressed" can include block-based image compression formats that still
+/// permit fairly fast random access to image data.
+union VideoFormat {
+ 1: VideoCompressedFormat compressed;
+ 2: VideoUncompressedFormat uncompressed;
+};
+
+// Encryption schemes as defined by ISO 23001-7: Common encryption in ISO base
+// media file format files. These are defined as strings rather than enums so as
+// to not limit the encryption schemes that an implementation supports to the
+// constants that are defined here.
+using EncryptionScheme = string:MAX_ENCRYPTION_SCHEME_SIZE;
+const string ENCRYPTION_SCHEME_UNENCRYPTED = "unencrypted";
+const string ENCRYPTION_SCHEME_CENC = "cenc";
+const string ENCRYPTION_SCHEME_CBC1 = "cbc1";
+const string ENCRYPTION_SCHEME_CENS = "cens";
+const string ENCRYPTION_SCHEME_CBCS = "cbcs";
+
+using KeyId = bytes:MAX_KEY_ID_SIZE;
+using InitVector = bytes:MAX_INIT_VECTOR_SIZE;
+
+/// SubsampleEntry
+///
+/// A subsample is a byte range within a sample consisting of a clear byte range
+/// followed by an encrypted byte range. This structure specifies the size of
+/// each range in the subsample.
+struct SubsampleEntry {
+ uint32 clear_bytes;
+ uint32 encrypted_bytes;
+};
+
+/// EncryptionPattern
+///
+/// Pattern encryption utilizes a pattern of encrypted and clear 16 byte blocks
+/// over the protected range of a subsample (the encrypted_bytes of a
+/// `SubsampleEntry`). This structure specifies the number of encrypted data
+/// blocks followed by the number of clear data blocks.
+struct EncryptionPattern {
+ uint32 clear_blocks;
+ uint32 encrypted_blocks;
+};
+
+/// EncryptedFormat
+///
+/// The stream format details payload of a decrypting stream processor. This is
+/// a sparsely populated table to specify parameters necessary for decryption
+/// other than the data stream. It is only necessary to update fields if they
+/// changed, but not an error if the same value is repeated.
+table EncryptedFormat {
+ 1: reserved;
+ 2: reserved;
+ 7: reserved;
+
+ /// `scheme` specifies which encryption scheme to use, such as
+ /// `fuchsia.media.ENCRYPTION_SCHEME_CENC`.
+ /// Usage:
+ /// - It is required to be set prior to delivery of input packets.
+ /// - Changing the scheme mid-stream is only permitted in some scenarios.
+ /// Once an encrypted scheme is selected for a stream, the scheme may
+ /// only be set to `fuchsia.media.ENCRYPTION_SCHEME_UNENCRYPTED` or that
+ /// same initial encrypted scheme. The scheme may be set to
+ /// `fuchsia.media.ENCRYPTION_SCHEME_UNENCRYPTED` at any point.
+ 6: string scheme;
+
+ /// `key_id` identifies the key that should be used for decrypting
+ /// subsequent data.
+ /// Usage:
+ /// - It is required to be set prior to delivery of input packets to a
+ /// decryptor.
+ /// - This may be changed multiple times during a data stream.
+ 8: KeyId key_id;
+
+ /// `init_vector` is used in combination with a key and a block of content
+ /// to create the first cipher block in a chain and derive subsequent cipher
+ /// blocks in a cipher block chain.
+ /// Usage:
+ /// - It is required to be set prior to the delivery of input packets to a
+ /// decryptor.
+ /// - This may be changed multiple times during a data stream.
+ 3: InitVector init_vector;
+
+ /// `subsamples` is used to identify the clear and encrypted portions of a
+ /// subsample.
+ /// Usage:
+ /// - For whole sample encryption, this parameter should not be sent.
+ /// - This may be changed multiple times during a data stream.
+ 4: vector<SubsampleEntry> subsamples;
+
+ /// `pattern` is used to identify the clear and encrypted blocks for pattern
+ /// based encryption.
+ /// Usage:
+ /// - This is not allowed for CENC and CBC1 and required for CENS and CBCS.
+ /// - If required, it must be set prior to the delivery of input packets to
+ /// a decryptor.
+ /// - This may be changed multiple times during a data stream.
+ 5: EncryptionPattern pattern;
+};
+
+/// DecryptedFormat
+///
+/// This describes the format of the decrypted content. It is required to be
+/// sent by the StreamProcessor server prior to the delivery of output packets.
+/// Currently, there is no additional format details for decrypted output.
+table DecryptedFormat {
+ // TODO(FIDL-709): Empty tables cause dart analysis error. Remove this
+ // unused field once the issue is resolved.
+ 1: bool ignore_this_field;
+};
+
+/// CryptoFormat
+///
+/// Crypto (encrypted or decrypted) format details.
+flexible union CryptoFormat {
+ 1: EncryptedFormat encrypted;
+ 2: DecryptedFormat decrypted;
+};
+
+/// DomainFormat
+///
+// Domain-specific format details (audio or video, compressed or uncompressed).
+union DomainFormat {
+ 1: AudioFormat audio;
+ 2: VideoFormat video;
+ 3: CryptoFormat crypto;
+};
+
+const uint64 kMaxOobBytesSize = 8192;
+
+enum SbcSubBands {
+ SUB_BANDS_4 = 4;
+ SUB_BANDS_8 = 8;
+};
+
+enum SbcBlockCount {
+ BLOCK_COUNT_4 = 4;
+ BLOCK_COUNT_8 = 8;
+ BLOCK_COUNT_12 = 12;
+ BLOCK_COUNT_16 = 16;
+};
+
+enum SbcAllocation {
+ ALLOC_LOUDNESS = 0;
+ ALLOC_SNR = 1;
+};
+
+enum SbcChannelMode {
+ MONO = 0;
+ DUAL = 1;
+ STEREO = 2;
+ JOINT_STEREO = 3;
+};
+
+/// Settings for an SBC Encoder.
+///
+/// SBC Encoders take signed little endian 16 bit linear PCM samples and
+/// return encoded SBC frames. SBC encoder PCM data in batches of
+/// `sub_bands * block_count` PCM frames. This encoder will accept PCM data on
+/// arbitrary frame boundaries, but the output flushed when EOS is queued may be
+/// zero-padded to make a full batch for encoding.
+struct SbcEncoderSettings {
+ SbcSubBands sub_bands = SbcSubBands.SUB_BANDS_8;
+ SbcAllocation allocation = SbcAllocation.ALLOC_LOUDNESS;
+ SbcBlockCount block_count = SbcBlockCount.BLOCK_COUNT_4;
+ SbcChannelMode channel_mode;
+ /// SBC bit pool value.
+ uint64 bit_pool;
+};
+
+/// Raw AAC access units.
+struct AacTransportRaw {
+};
+
+/// AAC inside LATM
+struct AacTransportLatm {
+ /// Whether MuxConfiguration stream element is present
+ bool mux_config_present;
+};
+
+/// AAC inside ADTS
+struct AacTransportAdts {
+};
+
+flexible union AacTransport {
+ 1: AacTransportRaw raw;
+ 2: AacTransportLatm latm;
+ 3: AacTransportAdts adts;
+};
+
+enum AacChannelMode {
+ MONO = 0;
+ STEREO = 2;
+};
+
+struct AacConstantBitRate {
+ /// Bits per second
+ uint32 bit_rate;
+};
+
+/// Variable bit rate modes. The actual resulting bitrate
+/// varies based on input signal and other encoding settings.
+///
+/// See https://wiki.hydrogenaud.io/index.php?title=Fraunhofer_FDK_AAC#Bitrate_Modes
+enum AacVariableBitRate {
+ V1 = 1;
+ V2 = 2;
+ V3 = 3;
+ V4 = 4;
+ V5 = 5;
+};
+
+union AacBitRate {
+ 1: AacConstantBitRate constant;
+ 2: AacVariableBitRate variable;
+};
+
+enum AacAudioObjectType {
+ /// MPEG-2 Low Complexity
+ MPEG2_AAC_LC = 0;
+};
+
+struct AacEncoderSettings {
+ AacTransport transport;
+ AacChannelMode channel_mode;
+ AacBitRate bit_rate;
+ AacAudioObjectType aot;
+};
+
+table H264EncoderSettings {
+};
+
+/// Settings for encoders that tell them how to encode raw
+/// formats.
+flexible union EncoderSettings {
+ 1: SbcEncoderSettings sbc;
+ 2: AacEncoderSettings aac;
+ 3: H264EncoderSettings h264;
+};
+
+/// FormatDetails
+///
+/// This describes/details the format on input or output of a StreamProcessor
+/// (separate instances for input vs. output).
+//
+// The purpose of FormatDetails is to fill in additional details not
+// conveyed via other means.
+//
+// For decoder input, the format details tend to be fairly sparse, since most
+// compressed formats tend to be mostly self-describing.
+//
+// For decoder output and encoder input, the format details need to include all
+// the out-of-band information regarding the uncompressed data, which tends not
+// to be self-describing.
+//
+// Settings that are completely redundant with the data in the format itself
+// should not be in a required field here. An encoder may set oob_bytes on its
+// output.
+//
+// This stuff should be limited to things we need to know to properly process the
+// data which we can't already determine from the data itself, and which isn't
+// already covered by a format's defined OOB binary config blob, which is
+// conveyed in oob_bytes.
+//
+// Most decoders can have FormatDetails.domain null.
+table FormatDetails {
+ // Particular instances of FormatDetails will set this field to make it
+ // easier for a receiver to determine if any part of the format has changed
+ // vs. the last FormatDetails received for the same context.
+ 1: uint64 format_details_version_ordinal;
+
+ // "mime_type" strings used by particular decoders / encoders so far:
+ //
+ // SW AAC decoder:
+ // * input:
+ // * "audio/aac-adts" - ATDS AAC; self-contained format, but
+ // implementation for now requires oob_bytes to contain
+ // AudioSpecificConfig() reconstructed from ADTS header data - see
+ // also make_AudioSpecificConfig_from_ADTS_header() for now.
+ // * output:
+ // * "audio/raw" - stereo linear 16 bit integer PCM
+ //
+ // TODO(dustingreen): avoid requiring oob_bytes when using SoftAAC2.cpp
+ // for AAC ADTS.
+ //
+ // TODO(dustingreen): Add non-ADTS AAC support (which naturally needs
+ // oob_bytes).
+ //
+ // TODO(dustingreen): Consider "pseudo_mime_type", or an enum, + "domain"
+ // details as needed instead, since calling this "mime_type" could lead to
+ // confusion.
+ 2: string mime_type;
+
+ // Some streams have their own binary configuration structure. For those
+ // streams we allow that binary structure to be directly conveyed to the
+ // stream processor here.
+ //
+ // audio/aac - this is an AudioSpecificConfig().
+ // audio/aac-adts - this is not set.
+ // TODO(dustingreen): make the audio/aac-adts statement true soon. At the
+ // moment we set this with make_AudioSpecificConfig_from_ADTS_header(), but
+ // that should not be the client's job for ADTS.
+ //
+ // For some formats whose "ES" data format is self-contained, or for which
+ // there is no format-defined binary OOB config, this is null.
+ //
+ // A server can close the channel if the count of bytes is >
+ // kMaxOobBytesSize or is larger than makes any sense for the stream
+ // processor. If any stream actually needs more than kMaxOobBytesSize
+ // bytes here, we could potentially increase this restriction some, but
+ // this interface isn't designed to support OOB config blobs that approach
+ // ZX_CHANNEL_MAX_MSG_BYTES.
+ 3: bytes oob_bytes;
+
+ // Decoder input format:
+ //
+ // If a format is not self-describing given the mime_type and a
+ // format-spec-defined oob_bytes, this domain field can be set to
+ // provide the additional compressed-format-specific details. This is
+ // expected to be fairly rare, so most compressed input formats will have
+ // only the mime_type and possibly oob_bytes set, with domain typically
+ // null. If an encoder is upstream however, domain may be set to convey the
+ // encoder settings that were used, but a decoder consumer doesn't need to
+ // look at those.
+ //
+ // Encoder output format:
+ //
+ // The encoder's compressed data output typically needs some configuration
+ // (provided in this field) that's convenient to provide in a form that's
+ // not oob_bytes, and the codec can convert that config to oob_bytes on
+ // encoder output via OnOutputConstraints(). We retain these encoder settings
+ // in the output FormatDetails to allow for cases where a downstream
+ // consumer knowing the encoder settings could be useful.
+ //
+ // TODO(dustingreen): Decide if we want to retain this, or if we'd prefer to
+ // split out config settings and maybe only represent a few encoder settings
+ // as best-effort optional aux data, like bitrate.
+ //
+ // Encoder input format / decoder output format:
+ //
+ // This field contains fairly detailed information re. uncompressed data
+ // format details, which tends to _not_ be self-describing in-band.
+ 4: DomainFormat domain;
+
+ // See comments above on Parameter. At the time we lock relevant FIDL
+ // interfaces, there should be zero use of this field outside tests, but
+ // this is here in case we need to allow a stream processor client to
+ // convey additional config parameters to/from a stream processor which we
+ // didn't anticipate before locking.
+ //
+ // If there are any known "official" exceptions to the previous paragraph,
+ // we'll list them here by corresponding mime_type (none so far):
+ // * "<mime_type>" - <usage_description>
+ //
+ // For streams that define their own stream-specific config/OOB data, put
+ // that in oob_bytes above instead of this field.
+ 5: vector<Parameter> pass_through_parameters;
+
+ /// Instructs an encoder on how to encode raw data.
+ ///
+ /// Decoders may ignore this field but are entitled to rejected requests with
+ /// this field set because it doesn't make sense.
+ 6: EncoderSettings encoder_settings;
+
+ /// The number of ticks of the timebase of input packet timestamp_ish values
+ /// per second.
+ ///
+ /// The timebase is only used used for optional extrapolation of timestamp_ish
+ /// values when an input timestamp which applies to byte 0 of the valid portion
+ /// of the input packet does not correspond directly to byte 0 of the valid
+ /// portion of any output packet.
+ ///
+ /// Leave unset if timestamp extrapolation is not needed, either due to lack of
+ /// timestamps on input, or due to input being provided in increments of the
+ /// encoder's input chunk size (based on the encoder settings and calculated
+ /// independently by the client). Set if timestamp extrapolation is known to be
+ /// needed or known to be acceptable to the client.
+ 7: uint64 timebase;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media/stream_processor.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media/stream_processor.fidl
new file mode 100644
index 0000000..9676c7a
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media/stream_processor.fidl
@@ -0,0 +1,1545 @@
+// Copyright 2018 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.
+
+library fuchsia.media;
+
+using fuchsia.sysmem;
+
+/// StreamBufferConstraints
+///
+/// This struct helps ensure that packet count and buffer space are sufficient
+/// to avoid major problems. For example, a video decoder needs sufficient
+/// video frame buffers to hold all potential reference frames concurrently +
+/// one more video buffer to decode into. Else, the whole video decode pipe can
+/// easily deadlock.
+///
+/// The secondary purpose of this struct is to help ensure that packet count and
+/// buffer space are sufficient to achieve reasonably performant operation.
+///
+/// There are separate instances of this struct for stream input and stream
+/// output.
+///
+/// Notes about fields:
+///
+/// For uncompressed video, separate and complete frames in their
+/// separate buffers (buffer-per-packet mode) are always a requirement.
+///
+/// per_packet_buffer_bytes.*: These per-packet buffer bytes constraints apply to
+/// both buffer-per-packet mode and single-buffer mode (see `single_buffer_mode`).
+/// If buffer-per-packet mode, the constraints apply to each buffer separately.
+/// If single-buffer mode, the constraints need to be multiplied by the number
+/// of packets to determine the constraints on the single buffer.
+//
+// TODO(dustingreen): Some of the buffer-focused fields in this structure will
+// go away in favor of using sysmem for those aspects. The packet count fields
+// will stay. The single-buffer fields will stay.
+table StreamBufferConstraints {
+ /// This is a version number the server sets on the constraints to allow the
+ /// server to determine when the client has caught up with the latest
+ /// constraints sent by the server. The server won't emit output data until
+ /// the client has configured output settings and buffers with a
+ /// buffer_constraints_version_ordinal >= the latest
+ /// buffer_constraints_version_ordinal that had
+ /// buffer_constraints_action_required true. See
+ /// buffer_constraints_action_required comments for more.
+ ///
+ /// A buffer_constraints_version_ordinal of 0 is not permitted, to simplify
+ /// initial state handling. Other than 0, both odd and even version ordinals
+ /// are allowed (in contrast to the stream_lifetime_ordinal, neither the
+ /// client nor server ever has a reason to consider the latest version to be
+ /// stale, so there would be no benefit to disallowing even values).
+ 1: uint64 buffer_constraints_version_ordinal;
+
+ /// default_settings
+ ///
+ /// These settings are "default" settings, not "recommended" settings.
+ ///
+ /// These "default" settings can be passed to SetInputBufferSettings() /
+ /// SetOutputBufferSettings() as-is without modification, but a client doing
+ /// that must still obey the semantics of packet_count_for_client, despite
+ /// the stream processor server not having any way to really know the proper
+ /// setting for that field.
+ ///
+ /// For StreamBufferConstraints fields whose names end in "recommended", the
+ /// default_settings will have the corresponding setting field set to that
+ /// recommended value.
+ ///
+ /// The stream processor promises that these default settings as-is (except
+ /// for buffer_lifetime_ordinal) are guaranteed to satisfy the constraints
+ /// indicated by the other fields of StreamBufferConstraints. While
+ /// client-side checking that these settings are within the constraints is
+ /// likely unnecessary in the client, the client should still check that
+ /// these values are within client-side reasonable-ness bounds before using
+ /// these values, to avoid letting a stream processor server cause problems
+ /// for the client.
+ ///
+ /// This structure will always have `single_buffer_mode` false. See
+ /// `single_buffer_mode_allowed` for whether `single_buffer_mode` true is
+ /// allowed.
+ ///
+ /// The client must set the buffer_lifetime_ordinal field to a proper value
+ /// before sending back to the server. The 0 initially in this field will
+ /// be rejected by the server if sent back as-is. See comments on
+ /// StreamBufferSettings.buffer_lifetime_ordinal.
+ 2: StreamBufferSettings default_settings;
+
+ /// If a client is using buffer per packet mode, each buffer must be at least
+ /// this large. If a client is using single-buffer mode, the one buffer must
+ /// be at least per_packet_buffer_bytes_min * packet_count_for_server_min in
+ /// size.
+ 3: uint32 per_packet_buffer_bytes_min;
+ /// Must be >= per_packet_buffer_bytes_min. Delivering more than
+ /// this per input packet might not perform any better, and in fact might
+ /// perform worse.
+ 4: uint32 per_packet_buffer_bytes_recommended;
+ /// Must be >= per_packet_buffer_bytes_recommended. Can be 0xFFFFFFFF if
+ /// there is no explicitly-enforced limit.
+ 5: uint32 per_packet_buffer_bytes_max;
+
+ /// Minimum number of packet_count_for_server.
+ ///
+ /// Re. input and output:
+ ///
+ /// This is a strict min for packet_count_for_server, but a client can use
+ /// more packets overall if the client wants to, by using a larger value for
+ /// packet_count_for_server and/or using a non-zero packets_for_client. A
+ /// good reason to do the former would be if the client might occasionally
+ /// deliver a few not-very-full buffers - or to have a few
+ /// extra packets within which to satisfy stream_input_bytes_min. A good
+ /// reason to do the latter would be if a client needs to hold onto some
+ /// packets for any extra duration.
+ ///
+ /// If a client specifies a larger packet_count_for_server value than
+ /// packet_count_for_server_min, a server is permitted (but not encouraged)
+ /// to not make progress until packet_count_for_server are with the server,
+ /// not merely packet_count_for_server_min.
+ ///
+ /// For decoder input and audio encoder input: The
+ /// packet_count_for_server_min may or may not contain enough data to allow
+ /// the stream processor to make progress without copying into an internal
+ /// side buffer. If there isn't enough data delivered in
+ /// packet_count_for_server_min packets to permit progress, the stream
+ /// processor must copy into its own side buffer internally to make
+ /// progress.
+ ///
+ /// If a client intends to use extra packets for client-side purposes, the
+ /// client should specify the extra packets in packets_for_client instead of
+ /// packet_count_for_server, but packet_count_for_server must still be >=
+ /// packet_count_for_server_min.
+ 6: uint32 packet_count_for_server_min;
+
+ /// This must be at least packet_count_for_server_min and at most
+ /// packet_count_for_server_recommended_max.
+ ///
+ /// This value is likely to be used as-is by most clients, so if having one
+ /// additional packet is a big performance win in a large percentage of
+ /// scenarios, it can be good for the server to include that additional
+ /// packet in this value.
+ 7: uint32 packet_count_for_server_recommended;
+
+ /// This can be the same as packet_count_for_server_max or can be lower.
+ /// Values above this value and <= packet_count_for_server_max are not
+ /// recommended by the stream processor, but should still work given
+ /// sufficient resources available to both the client and the stream
+ /// processor.
+ 8: uint32 packet_count_for_server_recommended_max;
+
+ /// This can be 0xFFFFFFFF if there's no stream processor-enforced max, but
+ /// stream processors are encouraged to set a large but still
+ /// plausibly-workable max, and clients are encouraged to request a number
+ /// of packets that isn't excessively large for the client's scenario.
+ 9: uint32 packet_count_for_server_max;
+
+ /// Normally this would be an implicit 0, but for now we have a min so we can
+ /// force the total number of packets to be a specific number that we know
+ /// works for the moment.
+ 10: uint32 packet_count_for_client_min;
+
+ /// The client must set packet_count_for_client to be <=
+ /// packet_count_for_client_max.
+ ///
+ /// This value must be at least 1. This can be 0xFFFFFFFF if there's no
+ /// stream-processor-enforced max. Clients are encouraged to request a
+ /// number of packets that isn't excessively large for the client's
+ /// scenario.
+ 11: uint32 packet_count_for_client_max;
+
+ /// `single_buffer_mode_allowed` false allows a stream processor that's not
+ /// required to support single-buffer mode for a given input or output the
+ /// ability to decline to support single-buffer mode on that input/output.
+ ///
+ /// All encoder output, regardless of audio or video: server support for
+ /// single-buffer mode is optional.
+ ///
+ /// Audio decoder output: server support for single-buffer mode is required.
+ ///
+ /// Video decoder output: There is little reason for a video decoder to
+ /// support single-buffer mode on output. Nearly all video decoders will set
+ /// this to false for their output.
+ ///
+ /// All decoder inputs: Servers must support single-buffer mode on input.
+ /// The client is responsible for managing the input buffer space such that
+ /// filling an input packet doesn't over-write any portion of an input
+ /// packet already in flight to the stream processor.
+ ///
+ /// Encoder inputs: Server support for single-buffer mode on encoder input is
+ /// optional. This is more often useful for audio than for video.
+ ///
+ /// Support for buffer-per-packet mode is always required on both input and
+ /// output, regardless of stream processor type.
+ 12: bool single_buffer_mode_allowed;
+
+ /// If true, the buffers need to be physically contiguous pages, such as those
+ /// allocated using zx_vmo_create_contiguous().
+ 13: bool is_physically_contiguous_required;
+
+ /// VERY TEMPORARY HACK / KLUDGE - we want the BufferAllocator (or one of
+ /// the participant drivers that needs physically contiguous buffers) to
+ /// call zx_vmo_create_contiguous(), definitely not the StreamProcessor
+ /// client, but until the BufferAllocator can be reached from a driver, this
+ /// is to grant the client special powers it really shouldn't have, very
+ /// temporarily until BufferAllocator is hooked up properly at which point
+ /// this can be removed. Strictly speaking we could reverse which end
+ /// allocates buffers in the StreamProcessor interface to avoid this hack
+ /// even before BufferAllocator, but the overall path seems shorter if we
+ /// jump directly from this to using BufferAllocator.
+ ///
+ // TODO(dustingreen): remove once zero clients need this (zero clients that
+ // need to allocate physically contiguous buffers directly / all relevant
+ // clients using sysmem).
+ 14: handle very_temp_kludge_bti_handle;
+};
+
+/// The stream-processor-controlled output configuration, including both
+/// StreamBufferConstraints for the output and FormatDetails for the output.
+//
+// TODO(dustingreen): Need a better name for this struct, but still short
+// hopefully. It's stuff the stream processor gets to control, not the client.
+// It's different than output buffer settings, which the client does get to
+// control to some extent. It's different than any configurable output
+// settings the client might specify for output of an encoder.
+table StreamOutputConstraints {
+ /// A client which always immediately re-configures output buffers on
+ /// receipt of OnOutputConstraints() with buffer_constraints_action_required
+ /// true can safely ignore this field.
+ ///
+ /// A client is permitted to ignore an OnOutputConstraints() message even with
+ /// buffer_constraints_action_required true if the client knows the server
+ /// has already been told to discard the remainder of the stream with the
+ /// same stream_lifetime_ordinal or if this stream_lifetime_ordinal field is
+ /// set to 0. The server is required to re-send needed output config via
+ /// OnOutputConstraints() with new stream_lifetime_ordinal and
+ /// buffer_constraints_action_required true, if the most recent completed
+ /// server-side output config isn't what the server wants/needs yet for the
+ /// new stream.
+ 1: uint64 stream_lifetime_ordinal;
+
+ /// When the buffer constraints are delivered, they indicate whether action
+ /// is required. A false value here permits delivery of constraints which
+ /// are fresher without forcing a buffer reconfiguration. If this is false,
+ /// a client cannot assume that it's safe to immediately re-configure output
+ /// buffers. If this is true, the client can assume it's safe to
+ /// immediately configure output buffers once.
+ ///
+ /// A client is permitted to ignore buffer constraint versions which have
+ /// buffer_constraints_action_required false. The server is not permitted
+ /// to change buffer_constraints_action_required from false to true for the
+ /// same buffer_constraints_version_ordinal.
+ ///
+ /// For each configuration, a client must use new buffers, never buffers
+ /// that were previously used for anything else, and never buffers
+ /// previously used for any other StreamProcessor purposes. This rule
+ /// exists for multiple good reasons, relevant to both mid-stream changes,
+ /// and changes on stream boundaries. A client should just use new buffers
+ /// each time.
+ ///
+ /// When this is true, the server has already de-refed as many low-level
+ /// output buffers as the server can while still performing efficient
+ /// transition to the new buffers and will de-ref the rest asap. A Sync()
+ /// is not necessary to achieve non-overlap of resource usage to the extent
+ /// efficiently permitted by the formats involved.
+ ///
+ /// If buffer_constraints_action_required is true, the server _must_ not
+ /// deliver more output data until after output buffers have been configured
+ /// (or re-configured) by the client.
+ 2: bool buffer_constraints_action_required;
+ 3: StreamBufferConstraints buffer_constraints;
+};
+
+table StreamOutputFormat {
+ /// A client is permitted to ignore an OnOutputFormat() message even with
+ /// buffer_constraints_action_required true if the client knows the server
+ /// has already been told to discard the remainder of the stream with the
+ /// same stream_lifetime_ordinal or if this stream_lifetime_ordinal field is
+ /// set to 0. The server is required to re-send needed output config via
+ /// OnOutputConstraints() with new stream_lifetime_ordinal and
+ /// buffer_constraints_action_required true, if the most recent completed
+ /// server-side output config isn't what the server wants/needs yet for the
+ /// new stream.
+ ///
+ /// The server is required to send an OnOutputFormat() before the first
+ /// output packet of a stream.
+ 1: uint64 stream_lifetime_ordinal;
+
+ /// If format_details.format_details_version_ordinal changes, the client
+ /// should inspect the new format details and determine if it must adjust to
+ /// the new format. The server guarantees that if the format has changed, then
+ /// format_details.format_details_version_ordinal will change, but a change
+ /// to format_details.format_details_version_ordinal does not guarantee that
+ /// the format details actually changed. Servers are strongly encouraged to
+ /// not change format_details.format_details_version_ordinal other than
+ /// before the first output data of a stream unless there is a real
+ /// mid-stream format change in the stream. Unnecessary mid-stream format
+ /// changes can cause simpler clients that have no need to handle mid-stream
+ /// format changes to just close the channel. Format changes before the
+ /// first output data of a stream are not "mid-stream" in this context -
+ /// those can be useful for stream format detection / setup reasons.
+ ///
+ /// Note that in case output buffers don't really need to be re-configured
+ /// despite a format change, a server is encouraged, but not required, to
+ /// set buffer_constraints_action_required false on the message that conveys
+ /// the new format details. Simpler servers may just treat the whole output
+ /// situation as one big thing and demand output buffer reconfiguration on
+ /// any change in the output situation.
+ ///
+ /// A client may or may not actually handle a new buffer_constraints with
+ /// buffer_constraints_action_required false, but the client should always
+ /// track the latest format_details.
+ ///
+ /// An updated format_details is ordered with respect to emitted output
+ /// packets, and applies to all subsequent packets until the next
+ /// format_details with larger version_ordinal. A simple client that does
+ /// not intend to handle mid-stream format changes should still keep track
+ /// of the most recently received format_details until the first output
+ /// packet arrives, then lock down the format details, handle those format
+ /// details, and verify that any
+ /// format_details.format_details_version_ordinal received from the server
+ /// is the same as the locked-down format_details, until the client is done
+ /// with the stream. Even such a simple client must tolerate
+ /// format_details.format_details_version_ordinal changing multiple times
+ /// before the start of data output from a stream (any stream - the first
+ /// stream or a subsequent stream). This allows a stream processor to
+ /// request that output buffers and output format be configured
+ /// speculatively, and for the output config to be optionally adjusted by
+ /// the server before the first data output from a stream after the server
+ /// knows everything it needs to know to fully establish the initial output
+ /// format details. This simplifies stream processor server implementation,
+ /// and allows a clever stream processor server to guess it's output config
+ /// for lower latency before any input data, while still being able to fix
+ /// the output config (including format details) if the guess turns out to
+ /// be wrong.
+ ///
+ /// Whether the format_details.format_details_version_ordinal will actually
+ /// change mid-stream is a per-stream-processor and per-stream detail that
+ /// is not specified in comments here, and in most cases also depends on
+ /// whether the format changes on the input to the stream processor.
+ /// Probably it'll be fairly common for a client to use a format which
+ /// technically supports mid-stream format change, but the client happens to
+ /// know that none of the streams the client intends to process will ever
+ /// have a mid-stream format change.
+ 2: FormatDetails format_details;
+};
+
+[Deprecated = "Use StreamOutputFormat instead."]
+table StreamOutputConfig {
+ 1: uint64 stream_lifetime_ordinal;
+ 2: bool buffer_constraints_action_required;
+ 3: StreamBufferConstraints buffer_constraints;
+ 4: FormatDetails format_details;
+};
+
+/// Default values for input and output
+/// StreamBufferConstraints.default_settings.packet_count_for_server.
+///
+/// These are defined as "const" in FIDL to avoid all server implementations
+/// needing to separately define their own values, and these should be
+/// reasonable as default values, but strictly speaking this is not intended to
+/// promise that this value won't change from build to build. If a client cares
+/// about a specific number, the client should separately define what that
+/// number is and ensure that StreamBufferSettings.packet_count_for_client is
+/// at least large enough.
+///
+/// In contrast to packet_count_for_client, the packet_count_for_server is much
+/// more stream-processor-specific, so this file has no numbers for that - each
+/// stream processor will set those as appropriate for the specific stream
+/// processor.
+///
+/// These are not "recommended" values, only "default" values, in the sense that
+/// the stream processor doesn't really know what the correct setting for these
+/// values is for a given client, and if the default is not appropriate for a
+/// client, large problems could result such as deadlock. See the comments on
+/// packet_count_for_client.
+///
+/// Despite these defaults, every client should ideally care about the
+/// packet_count_for_client setting and should ensure that the setting is at
+/// least large enough to cover the number of packets the client might ever need
+/// to camp on for any non-transient duration concurrently. The defaults are
+/// only intended to be plausible for some clients, not all clients.
+///
+/// One for the client to be filling and one in transit.
+const uint32 kDefaultInputPacketCountForClient = 2;
+/// One for the client to be rendering, and one in transit.
+const uint32 kDefaultOutputPacketCountForClient = 2;
+
+/// For input, this is the default on a fairly arbitrary basis.
+//
+// TODO(dustingreen): Do we want the default for audio encoding to be
+// `single_buffer_mode` true instead? If so, we may split this up by audio/video
+// encoder/decoder.
+const bool kDefaultInputIsSingleBufferMode = false;
+const bool kDefaultOutputIsSingleBufferMode = false;
+
+/// See relevant corresponding constraints in StreamBufferConstraints. The
+/// settings must satisfy the constraints.
+///
+/// The client informs the stream processor of these settings and then
+/// separately informs the stream processor of each buffer.
+///
+/// The total packet count is split into two pieces to disambiguate how many
+/// packets are allocated for the client to hold onto for whatever reason,
+/// vs. how many packets are allocated for the server to hold onto for
+/// whatever reason.
+///
+/// Extra packets to provide slack for performance reasons can be in either
+/// category, but typically packet_count_for_server_recommended will already
+/// include any performance-relevant slack for the server's benefit.
+table StreamBufferSettings {
+ /// The containing message starts a new buffer_lifetime_ordinal.
+ ///
+ /// There is a separate buffer_lifetime_ordinal for input vs. output.
+ ///
+ /// Re-use of the same value is not allowed. Values must be odd. Values
+ /// must only increase (increasing by more than 2 is permitted).
+ ///
+ /// A buffer_lifetime_ordinal lifetime starts at SetInputBufferSettings() or
+ /// SetOutputBufferSettings(), and ends at the earlier of
+ /// CloseCurrentStream() with release_input_buffers/release_output_buffers
+ /// set or SetOutputBufferSettings() with new buffer_lifetime_ordinal in the
+ /// case of mid-stream output config change.
+ 1: uint64 buffer_lifetime_ordinal;
+
+ /// This value indicates which version of constraints the client is/was aware
+ /// of so far.
+ ///
+ /// For input, this must always be 0 because constraints don't change for
+ /// input (settings can change, but there's no settings vs current
+ /// constraints synchronization issue on input).
+ ///
+ /// For output, this allows the server to know when the client is
+ /// sufficiently caught up before the server will generate any more output.
+ ///
+ /// When there is no active stream, a client is permitted to re-configure
+ /// buffers again using the same buffer_constraints_version_ordinal.
+ 2: uint64 buffer_constraints_version_ordinal;
+
+ /// How many packets the client is allocating for the stream processor
+ /// server's use. This must be >=
+ /// StreamBufferConstraints.packet_count_for_server_min. If constraints
+ /// change such that this would no longer be true, the server will send an
+ /// OnOutputConstraints() event.
+ ///
+ /// The stream processor server is allowed to demand that all of
+ /// packet_count_for_server become free before making further progress, even
+ /// if packet_count_for_server is > packet_count_for_server_min.
+ ///
+ /// A reasonable value for this is
+ /// StreamBufferConstraints.packet_count_for_server_recommended.
+ 3: uint32 packet_count_for_server;
+
+ /// This must be at least 1. The server will close the channel if this is 0.
+ ///
+ /// How many packets the client is allocating for the client's use. The
+ /// client may hold onto this many packets for arbitrarily-long duration
+ /// without handing these packets to the stream processor, and despite doing
+ /// so, the stream processor will continue to make progress and function
+ /// normally without getting stuck. The client holding onto additional
+ /// packets transiently is ok, but the client needs to hand those additional
+ /// packets back to the stream processor eventually if the client wants the
+ /// stream processor to make further progress.
+ ///
+ /// In addition to this value needing to include at least as many packets as
+ /// the client ever intends to concurrently camp on indefinitely, any extra
+ /// slack to benefit client-side performance should also be included here.
+ ///
+ /// A typical value for this could be at least 2, but it depends strongly on
+ /// client implementation and overall client buffering goals. It is up to
+ /// the client to determine how many packets are needed in this category by
+ /// any parts of the overall system that will be holding onto packets for
+ /// any reason. Those parts of the system should have a documented and
+ /// possibly queryable defined value to help determine this number. Setting
+ /// this value lower than it actually needs to be can result in the stream
+ /// processor not making progress as it sits waiting for packets, with the
+ /// client unable to recycle any more packets to the stream processor. That
+ /// situation can be difficult to diagnose, while excessively-large values
+ /// here are wasteful, so care is warranted to set this value properly.
+ 4: uint32 packet_count_for_client;
+
+ /// In buffer-per-packet mode, we require that each buffer have usable bytes
+ /// equal to per_packet_buffer_bytes. Use of differently-sized low-level
+ /// buffers is possible, but the size of the portion used via the
+ /// StreamProcessor interface per StreamBuffer must be the same for all the
+ /// buffers.
+ ///
+ /// In single-buffer mode, we require the portion of the low-level buffer
+ /// used via the StreamProcessor interface to be size
+ /// (packet_count_for_server + packet_count_for_client) *
+ /// per_packet_buffer_bytes.
+ //
+ // TODO(dustingreen): determine if we need to relax these restrictions a bit
+ // for convenience when using gralloc video buffers.
+ 5: uint32 per_packet_buffer_bytes;
+
+ /// If true there is only one buffer, with index 0, which all packets
+ /// must explicitly refer to with buffer_index == 0.
+ ///
+ /// While it's possible to set up `single_buffer_mode` false with each buffer
+ /// referring to the same underlying VMO, `single_buffer_mode` true is more
+ /// efficient for that case since only one mapping is created.
+ 6: bool single_buffer_mode;
+};
+
+/// This struct is used instead of StreamBufferSettings when sysmem is used to
+/// allocate buffers. The settings in StreamBufferSettings that are missing from
+/// StreamBufferPartialSettings can be conveyed from the client directly to
+/// sysmem.
+//
+// TODO(dustingreen): Consider renaming this to StreamBufferSettings once that's
+// an option.
+table StreamBufferPartialSettings {
+ /// The containing message starts a new buffer_lifetime_ordinal.
+ ///
+ /// There is a separate buffer_lifetime_ordinal for input vs. output.
+ ///
+ /// Re-use of the same value is not allowed. Values must be odd. Values
+ /// must only increase (increasing by more than 2 is permitted).
+ ///
+ /// A buffer_lifetime_ordinal lifetime starts at SetInputBufferSettings() or
+ /// SetOutputBufferSettings(), and ends at the earlier of
+ /// CloseCurrentStream() with release_input_buffers/release_output_buffers
+ /// set or SetOutputBufferSettings() with new buffer_lifetime_ordinal in the
+ /// case of mid-stream output config change.
+ 1: uint64 buffer_lifetime_ordinal;
+
+ /// This value indicates which version of constraints the client is/was aware
+ /// of so far.
+ ///
+ /// For input, this must always be 0 because constraints don't change for
+ /// input (settings can change, but there's no settings vs current
+ /// constraints synchronization issue on input).
+ ///
+ /// For output, this allows the server to know when the client is
+ /// sufficiently caught up before the server will generate any more output.
+ ///
+ /// When there is no active stream, a client is permitted to re-configure
+ /// buffers again using the same buffer_constraints_version_ordinal.
+ 2: uint64 buffer_constraints_version_ordinal;
+
+ /// If true, there is only one buffer, but still typically more than one
+ /// packet. If false, the # of packets == the number of buffers.
+ ///
+ /// While it's possible to set up `single_buffer_mode` false with each buffer
+ /// referring to the same underlying VMO, `single_buffer_mode` true is more
+ /// efficient for that case since only one mapping is created.
+ ///
+ /// This setting is specified by the client, and influences the constraints
+ /// delivered from the StreamProcessor to sysmem (whether there's more than
+ /// one buffer allocated overall or not). For `single_buffer_mode` true, the
+ /// StreamProcessor is the one to ask sysmem for a buffer - the client should
+ /// refrain from doing so or the StreamProcessor will just fail when more
+ /// than one buffer gets allocated by sysmem.
+ 3: bool single_buffer_mode;
+
+ /// When `single_buffer_mode` is false:
+ ///
+ /// The actual packet count will be
+ /// max(packet_count_for_server + packet_count_for_client, sysmem_buffers).
+ /// The sysmem_buffers is BufferCollectionInfo.buffer_count from sysmem if
+ /// using sysmem, or 0 if not using sysmem.
+ ///
+ /// When `single_buffer_mode` is true:
+ ///
+ /// The actual packet count is packet_count_for_server +
+ /// packet_count_for_client.
+ ///
+ /// If not using sysmem, or if using `single_buffer_mode`, these fields must be
+ /// set and consistent with correpsonding fields in StreamBufferConstraints.
+ ///
+ /// If `single_buffer_mode` false and using sysmem, these fields can both be
+ /// non-set, or can both be set and consistent with correpsonding fields in
+ /// StreamBufferConstraints. If not set, the value used for the fields in
+ /// the "max" expression above is 0, so buffer_count.
+ // TODO(FIDL-609): Default to 0.
+ 4: uint32 packet_count_for_server;
+
+ // TODO(FIDL-609): Default to 0.
+ 5: uint32 packet_count_for_client;
+
+ /// The client end of a BufferCollectionToken channel, which the
+ /// StreamProcessor will use to deliver constraints to sysmem and learn of
+ /// buffers allocated by sysmem.
+ ///
+ /// The client guarantees that the token is already known to sysmem (via
+ /// BufferCollectionToken.Sync(), BufferCollection.Sync(), or
+ /// BufferCollectionEvents.OnDuplicatedTokensKnownByServer()).
+ 6: fuchsia.sysmem.BufferCollectionToken sysmem_token;
+};
+
+/// The StreamBuffer struct represents a pre-configured buffer.
+///
+/// Both input and output uses StreamBuffer(s), but the two sets of buffers are
+/// separate.
+///
+/// The client uses SetInputBufferSettings() + AddInputBuffer() * N to inform
+/// the stream processor about all the input buffers.
+///
+/// The client uses SetOutputBufferSettings() + AddOutputBuffer() * N to inform
+/// the stream processor about all the output buffers.
+///
+/// When `single_buffer_mode` is true, there is only buffer_index 0 shared by all
+/// packet(s) of the relevant input or output.
+table StreamBuffer {
+ /// When using AddOutputBuffer()/AddInputBuffer(), this must match the
+ /// buffer_lifetime_ordinal of the most recent
+ /// SetOutputBufferSettings()/SetInputBufferSettings().
+ 1: uint64 buffer_lifetime_ordinal;
+
+ /// Buffers must be added via AddOutputBuffer() / AddInputBuffer() in order
+ /// by buffer_index. The buffer_index is always equal to 0 if
+ /// `single_buffer_mode` is true.
+ 2: uint32 buffer_index;
+
+ /// For each new buffer_lifetime_ordinal, a client must use new low-level
+ /// buffers. This rule exists for multiple very good reasons, and is
+ /// relevant to mid-stream changes, changes on stream boundaries, and both
+ /// input and output buffers. A new buffer_lifetime_ordinal needs new
+ /// low-level buffers, not just new StreamBuffer(s). If you find yourself
+ /// copying compressed input data into new low-level input buffers solely
+ /// due to this rule, consider asking the source of the data for the ability
+ /// to directly fill new VMOs. The rule exists for good reasons, even for
+ /// input buffers.
+ ///
+ /// The previous paragraph does not prohibit carving up VMOs into sub-pieces
+ /// and using different sub-pieces as different StreamBuffer(s), with some
+ /// VMOs used for more than one StreamBuffer and possibly others used for
+ /// only one StreamBuffer. While this is permitted and enables some
+ /// optimizations, it's not expected to be particularly common.
+ 3: StreamBufferData data;
+};
+
+/// For the moment, a VMO per buffer is the only type of buffer.
+///
+/// This is extremely likely to change significantly when adding gralloc stuff,
+/// but the idea with this union is to have a struct per logical way of storing
+/// the data. Any multi-domain storage within a gralloc buffer will likely be
+/// only indirectly represented here.
+union StreamBufferData {
+ 1: StreamBufferDataVmo vmo;
+
+ // TODO(dustingreen): add the gralloc way
+};
+
+/// StreamBufferDataVmo
+///
+/// Details for a buffer backed by a VMO.
+table StreamBufferDataVmo {
+ /// The same VMO can be used by more than one StreamBuffer (only of the same
+ /// buffer_lifetime_ordinal), but each vmo_handle must be a separate handle.
+ 1: handle<vmo> vmo_handle;
+
+ /// Offset within the VMO of the first usable byte. Must be < the VMO's size
+ /// in bytes.
+ 2: uint64 vmo_usable_start;
+
+ /// VMO-relative offset that's one past the last usable byte. This can point
+ /// one byte beyond the end of the VMO if desired. In other words, this can
+ /// be equal to the VMO's size, to indicate that the last byte of the VMO is
+ /// usable (and possibly many byte before that, depending on
+ /// vmo_usable_start).
+ 3: uint64 vmo_usable_size;
+};
+
+/// PacketHeader
+///
+/// When referring to a free packet, we use PacketHeader alone instead of
+/// Packet, since while a packet is free it doesn't really have meaningful
+/// offset or length etc.
+///
+/// A populated Packet also has a PacketHeader.
+table PacketHeader {
+ /// This is which buffer configuration lifetime this header is referring to.
+ ///
+ /// A packet_index is only really meaningful with respect to a particular
+ /// buffer_lifetime_ordinal.
+ ///
+ /// See StreamBufferSettings.buffer_lifetime_ordinal.
+ ///
+ /// For QueueInputPacket(), a server receiving a buffer_lifetime_ordinal that
+ /// isn't the current input buffer_lifetime_ordinal will close the channel.
+ ///
+ /// For OnFreeInputPacket() and RecycleOutputPacket(), the receiver (client
+ /// or server) must ignore a message with stale buffer_lifetime_ordinal.
+ 1: uint64 buffer_lifetime_ordinal;
+
+ /// The overall set of packet_index values is densely packed from 0..count-1
+ /// for input and output separately. They can be queued in any order.
+ ///
+ /// Both the client and server should validate the packet_index against the
+ /// known bound and disconnect if it's out of bounds.
+ ///
+ /// When running in single-buffer mode, the buffer index is always 0.
+ ///
+ /// The packet_index values don't imply anything about order of use of
+ /// packets. The client should not expect the ordering to remain the same
+ /// over time - the stream processor is free to hold on to an input or
+ /// output packet for a while during which other packet_index values may be
+ /// used multiple times.
+ ///
+ /// For a given properly-functioning StreamProcessor instance, packet_index
+ /// values will be unique among concurrently-outstanding packets. Servers
+ /// should validate that a client isn't double-using a packet and clients
+ /// should validate as necessary to avoid undefined or unexpected client
+ /// behavior.
+ 2: uint32 packet_index;
+};
+
+/// A Packet represents a chunk of input or output data to or from a stream
+/// processor.
+///
+/// stream processor output:
+///
+/// While the Packet is outstanding with the client via OnOutputPacket(), the
+/// stream processor will avoid modifying the referenced output data. After the
+/// client calls RecycleOutputPacket(packet_index), the stream processor is
+/// notified that the client is again ok with the referenced data changing.
+///
+/// stream processor input:
+///
+/// The client initially has all packet_index(es) available to fill, and later
+/// gets packet_index(s) that are again ready to fill via OnFreeInputPacket().
+/// The client must not modify the referenced data in between QueueInputPacket()
+/// and OnFreeInputPacket().
+table Packet {
+ 1: PacketHeader header;
+
+ /// Which buffer this packet refers to. For single-buffer mode this will
+ /// always be 0, but for multi-buffer mode, a given in-flight interval of a
+ /// packet can refer to any buffer. The packet has an associated buffer only
+ /// while the packet is in-flight, not while the packet is free.
+ ///
+ /// The default value makes accidental inappropriate use of index 0 less
+ /// likely (will tend to complain in an obvious way if not filled out
+ /// instead of a non-obvious data corruption when decoding buffer 0
+ /// repeatedly instead of the correct buffers).
+ ///
+ /// TODO(dustingreen): Try to make FIDL table defaults have meaning, and not
+ /// complain about !has when accessing the field. For now the default
+ /// specified here does nothing.
+ // TODO(FIDL-609): Default to 0x80000000.
+ 2: uint32 buffer_index;
+
+ /// The value 1 is the lowest permitted value after stream processor
+ /// creation. Values sent by the client must be odd. Values must only
+ /// increase.
+ ///
+ /// A stream_lifetime_ordinal represents the lifetime of a stream. All
+ /// messages that are specific to a stream have the stream_lifetime_ordinal
+ /// value and the value is the same for all messages relating to a given
+ /// stream.
+ 3: uint64 stream_lifetime_ordinal;
+
+ /// Which part of the relevant buffer is this packet using. These are valid
+ /// for input data that's in-flight to the stream processor, and are valid
+ /// for output data from the stream processor.
+ ///
+ /// For compressed formats and uncompressed audio, the data in
+ /// [start_offset, start_offset + valid_length_bytes) is the contiguously
+ /// valid data referred to by this packet.
+ ///
+ /// For uncompressed video frames, FormatDetails is the primary means of
+ /// determining which bytes are relevant. The offsets in FormatDetails
+ /// are relative to the start_offset here. The valid_length_bytes must be
+ /// large enough to include the full last line of pixel data, including the
+ /// full line stride of the last line (not just the width in pixels of the
+ /// last line).
+ ///
+ /// Despite these being filled out, some uncompressed video buffers are of
+ /// types that are not readable by the CPU. These fields being here don't
+ /// imply there's any way for the CPU to read an uncompressed frame.
+ //
+ // TODO(dustingreen): Do we have any reason to require that these be filled
+ // out for opaque uncompressed video frames that the CPU can't read? In
+ // that case do we want to require them just so they can be potentially
+ // passed on to a HW renderer in case the HW renderer has any use for them?
+ // Or more likely, it may just be that these tend to refer to the whole
+ // size of an uncompressed buffer, with format_details taking care of
+ // specifying which bytes are actually relevant.
+ 4: uint32 start_offset;
+
+ /// This must be > 0.
+ ///
+ /// The semantics for valid data per packet vary depending on data type as
+ /// follows.
+ ///
+ /// uncompressed video - A video frame can't be split across packets. Each
+ /// packet is one video frame.
+ ///
+ /// uncompressed audio - Regardless of float or int, linear or uLaw, or
+ /// number of channels, a packet must contain an non-negative number of
+ /// complete audio frames, where a single audio frame consists of data for
+ /// all the channels for the same single point in time. Any
+ /// stream-processor-specific internal details re. lower rate sampling for
+ /// LFE channel or the like should be hidden by the StreamProcessor server
+ /// implementation.
+ ///
+ /// compressed data input - A packet must contain at least one byte of data.
+ /// See also stream_input_bytes_min. Splitting AUs at arbitrary byte
+ /// boundaries is permitted, including at boundaries that are in AU headers.
+ ///
+ /// compressed data output - The stream processor is not required to fully
+ /// fill each output packet's buffer.
+ 5: uint32 valid_length_bytes;
+
+ /// This value is not strictly speaking a timestamp. It is an arbitrary
+ /// unsigned 64-bit number that, under some circumstances, will be passed by
+ /// a stream processor unmodified from an input packet to the
+ /// exactly-corresponding output packet.
+ ///
+ /// For timestamp_ish values to be propagated from input to output the
+ /// following conditions must be true:
+ /// * promise_separate_access_units_on_input must be true
+ /// * has_timestamp_ish must be true for a given input packet, to have that
+ /// timestamp_ish value (potentially) propagate through to an output
+ /// * the StreamProcessor instance itself decides (async) that the input
+ /// packet generates an output packet - if a given input never generates
+ /// an output packet then the timestamp_ish value on the input will never
+ /// show up on any output packet - depending on the characteristics of the
+ /// input and output formats, and whether a decoder is willing to join
+ /// mid-stream, etc this can be more or less likely to occur, but clients
+ /// should be written to accommodate timestamp_ish values that are fed on
+ /// input but never show up on output, at least to a reasonable degree
+ /// (not crashing, not treating as an error).
+ 6: uint64 timestamp_ish;
+
+ /// start_access_unit
+ ///
+ /// If promise_separate_access_units_on_input (TODO(dustingreen): or any
+ /// similar mode for output) is true, this bool must be set appropriately
+ /// depending on whether byte 0 _is_ or _is not_ the start of an access
+ /// unit. The client is required to know, and required to set this boolean
+ /// properly. The server is allowed to infer that when this boolean is
+ /// false, byte 0 is the first byte of a continuation of a
+ /// previously-started AU. (The byte at start_offset is "byte 0".)
+ ///
+ /// If promise_separate_access_units_on_input is false, this boolean is
+ /// ignored.
+ 7: bool start_access_unit;
+
+ /// known_end_access_unit
+ ///
+ /// A client is never required to set this boolean to true.
+ ///
+ /// If promise_separate_access_units_on_input is true, for input data, this
+ /// boolean must be false if the last byte of this packet is not the last
+ /// byte of an AU, and this boolean _may_ be true if the last byte of this
+ /// packet is the last byte of an AU. A client delivering one AU at a time
+ /// that's interested in the lowest possible latency via the decoder should
+ /// set this boolean to true when it can be set to true.
+ ///
+ /// If promise_separate_access_units_on_input is false, this boolean is
+ /// ignored.
+ 8: bool known_end_access_unit;
+};
+
+/// Overview of operation:
+///
+/// 1. Create
+/// * create via CodecFactory - see CodecFactory
+/// * create via LicenseSession - see LicenseSession
+/// 2. Get input constraints
+/// * OnInputConstraints() - sent unsolicited by stream processor shortly after
+/// stream processor creation.
+/// 3. Provide input buffers
+/// * SetInputBufferPartialSettings() (current way)
+/// * SetInputBufferSettings() / AddInputBuffer() (old deprecated way)
+/// 4. Deliver input data
+/// * QueueInputPacket() + OnFreeInputPacket(), for as long as it takes,
+/// possibly working through all input packets repeatedly before...
+/// 5. Get output constraints and format
+/// * OnOutputConstraints()
+/// * This is not sent until after at least one QueueInput* message is sent by
+/// the client, even if the underlying processor behind the StreamProcessor
+/// doesn't fundamentally need any input data to determine its output
+/// constraints. This server behavior prevents clients taking an incorrect
+/// dependency on the output constraints showing up before input is
+/// delivered.
+/// * A client must tolerate this arriving as late as after substantial input
+/// data has been delivered, including lots of input packet recycling via
+/// OnFreeInputPacket().
+/// * This message can arrive more than once before the first output data.
+/// 6. Provide output buffers
+/// * SetOutputBufferPartialSettings() / CompleteOutputBufferPartialSettings()
+/// (current way)
+/// * SetOutputBufferSettings() / AddOutputBuffer()
+/// (old deprecated way)
+/// 7. Data flows, with optional EndOfStream
+/// * OnOutputPacket() / RecycleOutputPacket() / QueueInputPacket() /
+/// OnFreeInputPacket() / QueueInputEndOfStream() / OnOutputEndOfStream()
+///
+/// Semi-trusted StreamProcessor server - SW decoders run in an isolate (with
+/// very few capabilities) just in case the decoding SW has a vulnerability
+/// which could be used to take over the StreamProcessor server. Clients of the
+/// stream processor interface using decoders and processing streams of separate
+/// security contexts, to a greater extent than some other interfaces, need to
+/// protect themselves against invalid server behavior, such as double-free of a
+/// packet_index and any other invalid server behavior. Having fed in
+/// compressed data of one security context, don't place too much trust in a
+/// single StreamProcessor instance to not mix data among any buffers that
+/// StreamProcessor server has ever been told about. Instead, create separate
+/// StreamProcessor instances for use by security-separate client-side contexts.
+/// While the picture for HW-based decoders looks somewhat different and is out
+/// of scope of this paragraph, the client should always use separate
+/// StreamProcessor instances for security-separate client-side contexts.
+///
+/// Descriptions of actions taken by methods of this protocol and the states of
+/// things are given as if the methods are synchronously executed by the stream
+/// processor server, but in reality, as is typical of FIDL interfaces, the
+/// message processing is async. The states described are to be read as the
+/// state from the client's point of view unless otherwise stated. Events
+/// coming back from the server are of course delivered async, and a client that
+/// processes more than one stream per StreamProcessor instance needs to care
+/// whether a given event is from the current stream vs. some older
+/// soon-to-be-gone stream.
+///
+/// The Sync() method's main purpose is to enable the client to robustly prevent
+/// having both old and new buffers allocated in the system at the same time,
+/// since media buffers can be significantly large, depending. The Sync() method
+/// achieves this by only delivering it's response when all previous calls to
+/// the StreamProcessor protocol have actually taken effect in the
+/// StreamControl ordering domain. Sync() can also be used to wait for the
+/// stream processor server to catch up if there's a possibility that a client
+/// might otherwise get too far ahead of the StreamProcessor server, by for
+/// example requesting creation of a large number of streams in a row. It can
+/// also be used during debugging to ensure that a stream processor server
+/// hasn't gotten stuck. Calling Sync() is entirely optional and never required
+/// for correctness - only potentially required to de-overlap resource usage.
+///
+/// It's possible to re-use a StreamProcessor instance for another stream, and
+/// doing so can sometimes skip over re-allocation of buffers. This can be a
+/// useful thing to do for cases like seeking to a new location - at the
+/// StreamProcessor interface that can look like switching to a new stream.
+protocol StreamProcessor {
+ /// Permit the server to use OnStreamFailed() instead of the server just
+ /// closing the whole StreamProcessor channel on stream failure.
+ ///
+ /// If the server hasn't seen this message by the time a stream fails, the
+ /// server will close the StreamProcessor channel instead of sending
+ /// OnStreamFailed().
+ EnableOnStreamFailed();
+
+ /// The stream has failed, but the StreamProcessor instance is still usable
+ /// for a new stream.
+ ///
+ /// This message is only ever sent by the server if the client previously
+ /// sent EnableOnStreamFailed(). If the client didn't send
+ /// EnableOnStreamFailed() then the server closes the StreamProcessor
+ /// channel instead.
+ ///
+ /// StreamProcessor server implementations are encouraged to handle stream
+ /// errors (and ideally to also report them via error_ bools of
+ /// OnOutputPacket() and OnOutputEndOfStream()) without failing the whole
+ /// stream, but if a stream processor server is unable to do that, but still
+ /// can cleanly contain the failure to the stream, the stream processor
+ /// server can (assuming EnableOnStreamFailed() was called) use
+ /// OnStreamFailed() to indicate the stream failure to the client without
+ /// closing the StreamProcessor channel.
+ ///
+ /// An ideal StreamProcessor server handles problems with input data without
+ /// sending this message, but sending this message is preferred vs. closing
+ /// the server end of the StreamProcessor channel if the StreamProcessor
+ /// server can 100% reliably contain the stream failure to the stream,
+ /// without any adverse impact to any later stream.
+ ///
+ /// No further messages will arrive from the server regarding the failed
+ /// stream. This includes any OnOutputEndOfStream() that the client would
+ /// have otherwise expected.
+ -> OnStreamFailed(uint64 stream_lifetime_ordinal, StreamError error);
+
+ /// The server sends this shortly after StreamProcessor creation to indicate
+ /// input buffer constraints. The "min" and "max" input constraints don't
+ /// change for the life of the StreamProcessor.
+ ///
+ /// The "max" values for buffer size and count are large enough to support
+ /// the most demanding format the server supports on input. The
+ /// "recommended" values should be workable for use with the input
+ /// FormatDetails conveyed during StreamProcessor creation. The
+ /// "recommended" values are not necessarily suitable if the client uses
+ /// QueueInputFormatDetails() to change the input format. In that case it's
+ /// up to the client to determine suitable values, either by creating a new
+ /// StreamProcessor instance instead, or knowing suitable values outside the
+ /// scope of this protocol.
+ ///
+ /// See comments on StreamBufferConstraints.
+ ///
+ /// This message is guaranteed to be sent unsolicited to the StreamProcessor
+ /// client during or shortly after StreamProcessor creation. Clients should
+ /// not depend on this being the very first message to arrive at the client.
+ ///
+ /// The "min" and "max" input constraints are guaranteed not to change for a
+ /// given StreamProcessor instance. The "recommended" values may
+ /// effectively change when the server processes QueueInputFormatDetails().
+ /// There is not any way in the protocol short of creating a new
+ /// StreamProcessor instance for the client to get those new "recommended"
+ /// values.
+ //
+ // TODO(dustingreen): Maybe provide a way for the client to get updated
+ // "recommended" values for input, maybe only on request rather than via
+ // this event, to keep things simpler for simpler clients. Maybe separate
+ // the recommendations from the constraints.
+ -> OnInputConstraints(StreamBufferConstraints input_constraints);
+
+ /// Clients should use SetInputBufferPartialSettings() instead.
+ ///
+ /// Configuring input buffers (the old way) consists of calling
+ /// SetInputBufferSettings() followed by a number of calls to
+ /// AddInputBuffer() equal to the number of buffers set via
+ /// SetInputBufferSettings(). In buffer-per-packet mode, this is the same as
+ /// the number of packets. In single-buffer mode, this is 1.
+ ///
+ /// After OnInputConstraints(), the client uses these two methods to set up
+ /// input buffers and packets.
+ ///
+ /// Configuring input buffers is required before QueueInputPacket().
+ ///
+ /// The client can also re-set-up input buffers any time there is no current
+ /// stream. The client need not wait until all previously-set-up input
+ /// buffers are with the client via OnFreeInputPacket(). The old
+ /// buffer_lifetime_ordinal just ends.
+ ///
+ /// The recommended way to de-overlap resource usage (when/if the client
+ /// wants to) is to send CloseCurrentStream() with release_input_buffers
+ /// true then send Sync() and wait for its response before allocating any
+ /// new buffers. How to cause other parts of the system to release their
+ /// references on low-level buffers is outside the scope of this interface.
+ ///
+ /// This call ends any previous buffer_lifetime_ordinal, and starts a new
+ /// one.
+ [Deprecated = "Use SetInputBufferPartialSettings instead."]
+ SetInputBufferSettings(StreamBufferSettings input_settings);
+
+ /// The client is required to add all the input buffers before sending any
+ /// message that starts a new stream else the stream processor will close
+ /// the StreamProcessor channel.
+ ///
+ /// When the last buffer is added with this message, all the input packets
+ /// effectively jump from non-existent to free with the client. The
+ /// StreamProcessor will not generate an OnFreeInputPacket() for each new
+ /// input packet. The client can immediately start sending
+ /// QueueInputPacket() after sending the last AddInputBuffer().
+ [Deprecated = "Use SetInputBufferPartialSettings instead."]
+ AddInputBuffer(StreamBuffer buffer);
+
+ /// This is the replacement for SetInputBufferSettings().
+ ///
+ /// When the client is using sysmem to allocate buffers, this message is
+ /// used instead of SetInputBufferSettings()+AddInputBuffer(). Instead, a
+ /// single SetInputBufferPartialSettings() provides the StreamProcessor with
+ /// the client-specified input settings and a BufferCollectionToken which
+ /// the StreamProcessor will use to convey constraints to sysmem. Both the
+ /// client and the StreamProcessor will be informed of the allocated buffers
+ /// directly by sysmem via their BufferCollection channel (not via the
+ /// StreamProcessor channel).
+ ///
+ /// The client must not QueueInput...() until after sysmem informs the client
+ /// that buffer allocation has completed and was successful.
+ ///
+ /// The server should be prepared to see QueueInput...() before the server
+ /// has necessarily heard from sysmem that the buffers are allocated - the
+ /// server must tolerate either ordering, as the QueueInput...() and
+ /// notification of sysmem allocation completion arrive on different
+ /// channels, so the client having heard that allocation is complete doesn't
+ /// mean the server knows that allocation is complete yet. However, the
+ /// server can expect that allocation is in fact complete and can expect to
+ /// get the allocation information from sysmem immediately upon requesting
+ /// the information from sysmem.
+ SetInputBufferPartialSettings(StreamBufferPartialSettings input_settings);
+
+ /// This event informs the client of new output constraints.
+ ///
+ /// This message is ordered with respect to other output (such as output
+ /// packets, output format, output end-of-stream).
+ ///
+ /// Before the first OnOutputPacket() of a stream, the server guarantees that
+ /// at least one OnOutputConstraints() and exactly one OnOutputFormat() will
+ /// be sent. The server may not set buffer_constraints_action_required true
+ /// in OnOutputConstraints() if the buffer config is already suitable for the
+ /// stream (buffer_constraints_action_required false means the buffer config
+ /// is already fine). The client must tolerate multiple
+ /// OnOutputConstraints() (and 1 OnOutputFormat() message) before the first
+ /// output packet. As long as the client hasn't moved to a new stream, the
+ /// server won't send another OnOutputConstraints() until after the client
+ /// has configured output buffers.
+ ///
+ /// This message can be sent mid-stream by a server. If
+ /// buffer_constraints_action_required false, the message is safe to
+ /// ignore, but a client may choose to stash the new constraints for
+ /// later use the next time the client wants to unilaterally re-configure
+ /// buffers (when allowed). If later the server needs the output config to
+ /// change, the server may send a new OnOutputConstraints() with
+ /// buffer_constraints_action_required true.
+ ///
+ /// On buffer_constraints_action_required true, a client that does not wish
+ /// to fully handle mid-stream output buffer config changes should either
+ /// give up completely on the processing, or at least re-config the output
+ /// as specified before starting a new stream (and possibly re-delivering
+ /// input data, if the client wants). This avoids useless retry with a new
+ /// stream starting from just before the output buffer config change which
+ /// would hit the same mid-stream output config change again.
+ ///
+ /// Similarly, some servers may only partly support mid-stream format
+ /// changes, or only support a mid-stream format change if the buffers are
+ /// already large enough to handle both before and after the format change.
+ /// Such servers should still indicate buffer_constraints_action_required
+ /// true, but then send OnStreamFailed() after the client has re-configured
+ /// output buffers (seamlessly dealing with the mid-stream output config
+ /// change is even better of course, but is not always feasible depending on
+ /// format). When the client retries with a new stream starting from a
+ /// nearby location in the client's logical overall media timeline, the
+ /// output buffers will already be suitable for the larger size output, so
+ /// the new stream will not need any mid-stream output buffer re-config,
+ /// only a mid-stream OnOutputFormat(). This strategy avoids the problem
+ /// that would otherwise occur if a client were to retry with a new stream
+ /// starting just before the mid-stream output buffer config change (the
+ /// retry wouldn't be effective since the same need for an output buffer
+ /// config change would be hit again). Servers are discouraged from sending
+ /// OnStreamFailed() solely due to a mid-stream need for different output
+ /// buffer config without first sending OnOutputConstraints() with
+ /// buffer_constraints_action_required true and waiting for the client to
+ /// re-configure output buffers (to avoid the useless client retry with a
+ /// new stream from a logical location before the config change).
+ ///
+ /// When buffer_constraints_action_required true, the server will not send
+ /// any OnOutputPacket() for this stream until after the client has
+ /// configured/re-configured output buffers.
+ ///
+ /// A client that gives up on processing a stream on any mid-stream
+ /// OnOutputConstraints() or mid-stream OnOutputFormat() should completely
+ /// ignore any OnOutputConstraints() with buffer_constraints_action_required
+ /// false. Otherwise the client may needlessly fail processing, or server
+ /// implementations might not be able to use
+ /// buffer_constraints_action_required false for fear of simpler clients
+ /// just disconnecting.
+ ///
+ /// All clients, even those which don't want to support any mid-stream
+ /// output buffer re-config or mid-stream OnOutputFormat() are required to
+ /// deal with 1..multiple OnOutputConstraints() messages before the first
+ /// output packet, and 1 OnOutputFormat() messages before the first output
+ /// packet.
+ ///
+ /// This message is ordered with respect to output packets, and with respect
+ /// to OnOutputFormat().
+ -> OnOutputConstraints(StreamOutputConstraints output_config);
+
+ /// This message is sent by the server before the first output packet of any
+ /// stream, and potentially mid-stream between output packets of the stream,
+ /// ordered with respect to output packets, and ordered with respect to
+ /// OnOutputConstraints().
+ ///
+ /// The server guarantees that the first packet of every stream will be
+ /// preceeded by an OnOutputFormat().
+ ///
+ /// The server guarantees that there will be an OnOutputFormat() between an
+ /// OnOutputConstraints() with buffer_constraints_action_required true and an
+ /// OnOutputPacket(). In other words, the client is essentially allowed to
+ /// forget what the output format is on any OnOutputConstraints() with
+ /// buffer_constraints_action_required true, because the server promises a
+ /// subsequent OnOutputFormat() before any OnOutputPacket().
+ ///
+ /// If the server sets buffer_constraints_action_required true in
+ /// OnOutputConstraints(), the server won't send OnOutputFormat() (and
+ /// therefore also won't send OnOutputPacket()) until the client has
+ /// re-configured output buffers.
+ ///
+ /// The server is allowed to send an OnOutputFormat() mid-stream between two
+ /// output packets.
+ ///
+ /// A server won't send two adjacent OnOutputFormat() messages without any
+ /// output packet in between. However an OnOutputFormat() message doesn't
+ /// guarantee a subsequent packet, because for example the server could send
+ /// OnOutputEndOfStream() or OnStreamFailed() instead.
+ ///
+ /// A client that does not wish to seamlessly handle mid-stream output format
+ /// changes should either ensure that no stream processed by the client
+ /// ever has any mid-stream format change, or the client should ensure that
+ /// any retry of processing starts the new attempt at a point logically at or
+ /// after the point where the old format has ended and the new format starts,
+ /// else the client could just hit the same mid-stream format change again.
+ ///
+ /// An example of this message being sent mid-stream is mid-stream change
+ /// of dimensions of video frames output from a video decoder.
+ ///
+ /// Not all servers will support seamless handling of format change. Those
+ /// that do support seamless handling of format change may require that the
+ /// format change not also require output buffer re-config, in order for the
+ /// handling to be seamless. See the comment block for OnOutputConstraints()
+ /// for more discussion of how servers and clients should behave - in
+ /// particular when they don't seamlessly handle output constraint change
+ /// and/or output format change.
+ ///
+ /// If this message isn't being sent by the server when expected at the
+ /// start of a stream, the most common reason is that a OnOutputConstraints()
+ /// with buffer_constraints_action_required true hasn't been processed by the
+ /// client (by configuring output buffers using
+ /// SetOutputBufferPartialSettings() etc).
+ -> OnOutputFormat(StreamOutputFormat output_format);
+
+ /// These are not permitted until after the first OnOutputConstraints().
+ ///
+ /// Roughly speaking, these messages are sent in response to
+ /// OnOutputConstraints() with buffer_constraints_action_required true.
+ ///
+ /// Configuring output buffers consists of calling SetOutputBufferSettings()
+ /// followed by a number of calls to AddOutputBuffer() equal to the number
+ /// of buffers set via SetOutputBufferSettings(). In buffer-per-packet
+ /// mode, this is the same as the number of packets. In single-buffer mode,
+ /// this is 1.
+ ///
+ /// Configuring output buffers is _required_ after OnOutputConstraints() is
+ /// received by the client with buffer_constraints_action_required true and
+ /// stream_lifetime_ordinal equal to the client's current
+ /// stream_lifetime_ordinal (even if there is an active stream), and is
+ /// _permitted_ any time there is no current stream.
+ ///
+ /// Closing the current stream occurs on the StreamControl ordering domain,
+ /// so after a CloseCurrentStream() or FlushEndOfStreamAndCloseStream(), a
+ /// subsequent Sync() completion must be received by the client before the
+ /// client knows that there's no longer a current stream.
+ [Deprecated = "Use SetOutputBufferPartialSettings instead."]
+ SetOutputBufferSettings(StreamBufferSettings output_settings);
+ [Deprecated = "Use SetOutputBufferPartialSettings instead."]
+ AddOutputBuffer(StreamBuffer buffer);
+
+ /// This is the replacement for SetOutputBufferSettings().
+ ///
+ /// When the client is using sysmem to allocate buffers, this message is
+ /// used instead of SetOutputBufferSettings()+AddOutputBuffer(). Instead, a
+ /// single SetOutputBufferPartialSettings() provides the StreamProcessor
+ /// with the client-specified output settings and a BufferCollectionToken
+ /// which the StreamProcessor will use to convey constraints to sysmem.
+ /// Both the client and the StreamProcessor will be informed of the
+ /// allocated buffers directly by sysmem via their BufferCollection channel
+ /// (not via the StreamProcessor channel).
+ ///
+ /// Configuring output buffers is _required_ after OnOutputConstraints() is
+ /// received by the client with buffer_constraints_action_required true and
+ /// stream_lifetime_ordinal equal to the client's current
+ /// stream_lifetime_ordinal (even if there is an active stream), and is
+ /// _permitted_ any time there is no current stream.
+ ///
+ /// Closing the current stream occurs on the StreamControl ordering domain,
+ /// so after a CloseCurrentStream() or FlushEndOfStreamAndCloseStream(), a
+ /// subsequent Sync() completion must be received by the client before the
+ /// client knows that there's no longer a current stream.
+ ///
+ /// See also CompleteOutputBufferPartialSettings().
+ SetOutputBufferPartialSettings(StreamBufferPartialSettings output_settings);
+
+ /// After SetOutputBufferPartialSettings(), the server won't send
+ /// OnOutputConstraints(), OnOutputFormat(), OnOutputPacket(), or
+ /// OnOutputEndOfStream() until after the client sends
+ /// CompleteOutputBufferPartialSettings().
+ ///
+ /// Some clients may be able to send
+ /// CompleteOutputBufferPartialSettings() immediately after
+ /// SetOutputBufferPartialSettings() - in that case the client needs to be
+ /// prepared to receive output without knowing the buffer count or packet
+ /// count yet - such clients may internally delay processing the received
+ /// output until the client has heard from sysmem (which is when the client
+ /// will learn the buffer count and packet count).
+ ///
+ /// Other clients may first wait for sysmem to allocate, prepare to receive
+ /// output, and then send CompleteOutputBufferPartialSettings().
+ CompleteOutputBufferPartialSettings(uint64 buffer_lifetime_ordinal);
+
+ /// This message is optional.
+ ///
+ /// This message is only valid after QueueInputEndOfStream() for this stream.
+ /// The stream_lifetime_ordinal input parameter must match the
+ /// stream_lifetime_ordinal of the QueueInputEndOfStream(), else the server
+ /// will close the channel.
+ ///
+ /// A client can use this message to flush through (not discard) the last
+ /// input data of a stream so that the stream processor server generates
+ /// corresponding output data for all the input data before the server moves
+ /// on to the next stream, without forcing the client to wait for
+ /// OnOutputEndOfStream() before queueing data of another stream.
+ ///
+ /// The difference between QueueInputEndOfStream() and
+ /// FlushEndOfStreamAndCloseStream(): QueueInputEndOfStream() is a promise
+ /// from the client that there will not be any more input data for the
+ /// stream (and this info is needed by some stream processors for the stream
+ /// processor to ever emit the very last output data). The
+ /// QueueInputEndOfStream() having been sent doesn't prevent the client from
+ /// later completely discarding the rest of the current stream by closing
+ /// the current stream (with or without a stream switch). In contrast,
+ /// FlushEndOfStreamAndCloseStream() is a request from the client that all
+ /// the previously-queued input data be processed including the logical
+ /// "EndOfStream" showing up as OnOutputEndOfStream() (in success case)
+ /// before moving on to any newer stream - this essentially changes the
+ /// close-stream handling from discard to flush-through for this stream
+ /// only.
+ ///
+ /// A client using this message can start providing input data for a new
+ /// stream without that causing discard of old stream data. That's the
+ /// purpose of this message - to allow a client to flush through (not
+ /// discard) the old stream's last data (instead of the default when closing
+ /// or switching streams which is discard).
+ ///
+ /// Because the old stream is not done processing yet and the old stream's
+ /// data is not being discarded, the client must be prepared to continue to
+ /// process OnOutputConstraints() messages until the stream_lifetime_ordinal
+ /// is done. The client will know the stream_lifetime_ordinal is done when
+ /// OnOutputEndOfStream(), OnStreamFailed(), or the StreamProcessor channel
+ /// closes.
+ FlushEndOfStreamAndCloseStream(uint64 stream_lifetime_ordinal);
+
+ /// This "closes" the current stream, leaving no current stream. In
+ /// addition, this message can optionally release input buffers or output
+ /// buffers.
+ ///
+ /// If there has never been any active stream, the stream_lifetime_ordinal
+ /// must be zero or the server will close the channel. If there has been an
+ /// active stream, the stream_lifetime_ordinal must be the most recent
+ /// active stream whether that stream is still active or not. Else the
+ /// server will close the channel.
+ ///
+ /// Multiple of this message without any new active stream in between is not
+ /// to be considered an error, which allows a client to use this message to
+ /// close the current stream to stop wasting processing power on a stream the
+ /// user no longer cares about, then later decide that buffers should be
+ /// released and send this message again with release_input_buffers and/or
+ /// release_output_buffers true to get the buffers released, if the client is
+ /// interested in trying to avoid overlap in resource usage between old
+ /// buffers and new buffers (not all clients are).
+ ///
+ /// See also Sync().
+ CloseCurrentStream(
+ uint64 stream_lifetime_ordinal,
+ bool release_input_buffers,
+ bool release_output_buffers);
+
+ /// On completion, all previous StreamProcessor calls have done what they're
+ /// going to do server-side, _except_ for processing of data queued using
+ /// QueueInputPacket().
+ ///
+ /// The main purpose of this call is to enable the client to wait until
+ /// CloseCurrentStream() with release_input_buffers and/or
+ /// release_output_buffers set to true to take effect, before the client
+ /// allocates new buffers and re-sets-up input and/or output buffers. This
+ /// de-overlapping of resource usage can be worthwhile for media buffers
+ /// which can consume resource types whose overall pools aren't necessarily
+ /// vast in comparison to resources consumed. Especially if a client is
+ /// reconfiguring buffers multiple times.
+ ///
+ /// Note that Sync() prior to allocating new media buffers is not alone
+ /// sufficient to achieve non-overlap of media buffer resource usage system
+ /// wide, but it can be a useful part of achieving that.
+ ///
+ /// The Sync() transits the Output ordering domain and the StreamControl
+ /// ordering domain, but not the InputData ordering domain.
+ ///
+ /// This request can be used to avoid hitting kMaxInFlightStreams which is
+ /// presently 10. A client that stays <= 8 in-flight streams will
+ /// comfortably stay under the limit of 10. While the protocol permits
+ /// repeated SetInputBufferSettings() and the like, a client that spams the
+ /// channel can expect that the channel will just close if the server or the
+ /// channel itself gets too far behind.
+ Sync() -> ();
+
+ /// This is how the stream processor emits an output packet to the stream
+ /// processor client.
+ ///
+ /// Order is significant.
+ ///
+ /// The client should eventually call RecycleOutputPacket() (possibly after
+ /// switching streams multiple times), unless the buffer_lifetime_ordinal
+ /// has moved on. A stream change doesn't change which packets are busy
+ /// with the client vs. free with the server.
+ ///
+ /// The relevant buffer is always the one specified in the packet's buffer_index field.
+ ///
+ /// For low-level buffer types that support it, a StreamProcessor is free to
+ /// emit an output packet before the low-level buffer actually has any
+ /// usable data in the buffer, with the mechanism for signalling the
+ /// presence of data separate from the OnOutputPacket() message. For such
+ /// low-level buffer types, downstream consumers of data from the emitted
+ /// packet must participate in the low-level buffer signalling mechanism to
+ /// know when it's safe to consume the data. This is most likely to be
+ /// relevant when using a video decoder and gralloc-style buffers.
+ ///
+ /// The error_ bool(s) allow (but do not require) a StreamProcessor server
+ /// to report errors that happen during an AU or between AUs.
+ ///
+ /// The scope of error_detected_before starts at the end of the last
+ /// delivered output packet on this stream, or the start of stream if there
+ /// were no previous output packets on this stream. The scope ends at the
+ /// start of the output_packet.
+ ///
+ /// The error_detected_before bool is separate so that discontinuities can be
+ /// indicated separately from whether the current packet is damaged.
+ ///
+ /// The scope of error_detected_during is from the start to the end of this
+ /// output_packet.
+ -> OnOutputPacket(
+ Packet output_packet,
+ bool error_detected_before,
+ bool error_detected_during);
+
+ /// After the client is done with an output packet, the client needs to tell
+ /// the stream processor that the output packet can be re-used for more
+ /// output, via this method.
+ ///
+ /// It's not permitted to recycle an output packet that's already free with
+ /// the stream processor server. It's permitted but discouraged for a
+ /// client to recycle an output packet that has been deallocated by an
+ /// explicit or implicit output buffer de-configuration(). See
+ /// buffer_lifetime_ordinal for more on that. A server must ignore any such
+ /// stale RecycleOutputPacket() calls.
+ RecycleOutputPacket(PacketHeader available_output_packet);
+
+ /// After QueueInputEndOfStream() is sent by the StreamProcessor client,
+ /// within a reasonable duration the corresponding OnOutputEndOfStream()
+ /// will be sent by the StreamProcessor server. Similar to
+ /// QueueInputEndOfStream(), OnOutputEndOfStream() is sent a maximum of once
+ /// per stream.
+ ///
+ /// No more stream data for this stream will be sent after this message. All
+ /// input data for this stream was processed.
+ ///
+ /// While a StreamProcessor client is not required to
+ /// QueueInputEndOfStream() (unless the client wants to use
+ /// FlushEndOfStreamAndCloseStream()), if a StreamProcessor server receives
+ /// QueueInputEndOfStream(), and the client hasn't closed the stream, the
+ /// StreamProcessor server must generate a corresponding
+ /// OnOutputEndOfStream() if nothing went wrong, or must send
+ /// OnStreamFailed(), or must close the server end of the StreamProcessor
+ /// channel. An ideal StreamProcessor server would handle and report stream
+ /// errors via the error_ flags and complete stream processing without
+ /// sending OnStreamFailed(), but in any case, the above-listed options are
+ /// the only ways that an OnOutputEndOfStream() won't happen after
+ /// QueueInputEndOfStream().
+ ///
+ /// There will be no more OnOutputPacket() or OnOutputConstraints() messages
+ /// for this stream_lifetime_ordinal after this message - if a server doesn't
+ /// follow this rule, a client should close the StreamProcessor channel.
+ ///
+ /// The error_detected_before bool has the same semantics as the
+ /// error_detected_before bool in OnOutputPacket().
+ -> OnOutputEndOfStream(
+ uint64 stream_lifetime_ordinal,
+ bool error_detected_before);
+
+ // TODO(dustingreen): Rename from QueueInputFormatDetails() to
+ // QueueInputFormat().
+ //
+ /// If the input format details are still the same as specified during
+ /// StreamProcessor creation, this message is unnecessary and does not need
+ /// to be sent.
+ ///
+ /// If the stream doesn't exist yet, this message creates the stream.
+ ///
+ /// The server won't send OnOutputConstraints() until after the client has
+ /// sent at least one QueueInput* message.
+ ///
+ /// All servers must permit QueueInputFormatDetails() at the start of a
+ /// stream without failing, as long as the new format is supported by the
+ /// StreamProcessor instance. Technically this allows for a server to only
+ /// support the exact input format set during StreamProcessor creation, and
+ /// that is by design. A client that tries to switch formats and gets a
+ /// StreamProcessor channel failure should try again one more time with a
+ /// fresh StreamProcessor instance created with CodecFactory using the new
+ /// input format during creation, before giving up.
+ ///
+ /// These format details override the format details specified during stream
+ /// processor creation for this stream only. The next stream will default
+ /// back to the format details set during stream processor creation.
+ ///
+ /// This message is permitted at the start of the first stream (just like at
+ /// the start of any stream). The format specified need not match what was
+ /// specified during stream processor creation, but if it doesn't match, the
+ /// StreamProcessor channel might close as described above.
+ QueueInputFormatDetails(
+ uint64 stream_lifetime_ordinal, FormatDetails format_details);
+
+ /// This message queues input data to the stream processor for processing.
+ ///
+ /// If the stream doesn't exist yet, this message creates the new stream.
+ ///
+ /// The server won't send OnOutputConstraints() until after the client has
+ /// sent at least one QueueInput* message.
+ ///
+ /// The client must continue to deliver input data via this message even if
+ /// the stream processor has not yet generated the first OnOutputConstraints(),
+ /// and even if the StreamProcessor is generating OnFreeInputPacket() for
+ /// previously-queued input packets. The input data must continue as long
+ /// as there are free packets to be assured that the server will ever
+ /// generate the first OnOutputConstraints().
+ QueueInputPacket(Packet packet);
+
+ /// The server sends this message when the stream processor is done
+ /// consuming this packet and the packet can be re-filled by the client.
+ ///
+ /// This is not sent for all packets when a new buffer_lifetime_ordinal
+ /// starts as in that case all the packets are initially free with the
+ /// client.
+ ///
+ /// After receiving the available input buffer via this event, the stream
+ /// processor client can call later call QueueInputBuffer with appropriate
+ /// offset and length set.
+ //
+ // TODO(dustingreen): At the moment, there is no guarantee re. the order of
+ // these messages with respect to the order of QueueInputPacket(), but at
+ // least for decoders, it might be worthwhile to require that servers
+ // preserve the order vs. QueueInputPacket(), to make it easier to feed
+ // input from a ring buffer or similar. For audio encoders it might still
+ // make sense. For video encoders probably not.
+ -> OnFreeInputPacket(PacketHeader free_input_packet);
+
+ /// Inform the server that all QueueInputPacket() messages for this stream
+ /// have been sent.
+ ///
+ /// If the stream isn't closed first (by the client, or by OnStreamFailed(),
+ /// or StreamProcessor channel closing), there will later be a corresponding
+ /// OnOutputEndOfStream().
+ ///
+ /// The corresponding OnOutputEndOfStream() message will be generated only if
+ /// the server finishes processing the stream before the server sees the
+ /// client close the stream (such as by starting a new stream). A way to
+ /// force the server to finish the stream before closing is to use
+ /// FlushEndOfStreamAndCloseStream() after QueueInputEndOfStream() before any
+ /// new stream. Another way to force the server to finish the stream before
+ /// closing is to wait for the OnOutputEndOfStream() before taking any action
+ /// that closes the stream.
+ ///
+ /// In addition to serving as an "EndOfStream" marker to make it obvious
+ /// client-side when all input data has been processed, if a client never
+ /// sends QueueInputEndOfStream(), no amount of waiting will necessarily
+ /// result in all input data getting processed through to the output. Some
+ /// stream processors have some internally-delayed data which only gets
+ /// pushed through by additional input data _or_ by this EndOfStream marker.
+ /// In that sense, this message can be viewed as a flush-through at
+ /// InputData domain level, but the flush-through only takes effect if the
+ /// stream processor even gets that far before the stream is just closed at
+ /// StreamControl domain level. This message is not alone sufficient to act
+ /// as an overall flush-through at StreamControl level. For that, send this
+ /// message first and then send FlushEndOfStreamAndCloseStream() (at which
+ /// point it becomes possible to queue input data for a new stream without
+ /// causing discard of this older stream's data), or wait for the
+ /// OnOutputEndOfStream() before closing the current stream.
+ ///
+ /// If a client sends QueueInputPacket(), QueueInputFormatDetails(),
+ /// QueueInputEndOfStream() for this stream after the first
+ /// QueueInputEndOfStream() for this stream, a server should close the
+ /// StreamProcessor channel.
+ QueueInputEndOfStream(uint64 stream_lifetime_ordinal);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media/stream_type.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media/stream_type.fidl
new file mode 100644
index 0000000..684a40f
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media/stream_type.fidl
@@ -0,0 +1,155 @@
+// Copyright 2018 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.
+
+library fuchsia.media;
+
+// fuchsia.media contains definitions shared by the various fuchsia.media.*
+// libraries. Definitions in this file concern the representation of type
+// (i.e. format or encoding) for elementary streams.
+
+using fuchsia.images;
+
+/// Describes the type of an elementary stream.
+struct StreamType {
+ /// Medium-specific type information.
+ MediumSpecificStreamType medium_specific;
+
+ /// Encoding (see constants below). This value is represented as a string
+ /// so that new encodings can be introduced without modifying this file.
+ string:255 encoding;
+
+ /// Encoding-specific parameters, sometimes referred to as 'out-of-band
+ /// data'. Typically, this data is associated with a compressed stream and
+ /// provides parameters required to decompress the stream. This data is
+ /// generally opaque to all parties except the producer and consumer of the
+ /// stream.
+ vector<uint8>? encoding_parameters;
+};
+
+/// A union of all medium-specific stream type structs.
+union MediumSpecificStreamType {
+ 1: AudioStreamType audio;
+ 2: VideoStreamType video;
+ 3: TextStreamType text;
+ 4: SubpictureStreamType subpicture;
+};
+
+/// Audio encodings.
+const string AUDIO_ENCODING_AAC = "fuchsia.media.aac";
+const string AUDIO_ENCODING_AACLATM = "fuchsia.media.aaclatm";
+const string AUDIO_ENCODING_AMRNB = "fuchsia.media.amrnb";
+const string AUDIO_ENCODING_AMRWB = "fuchsia.media.amrwb";
+const string AUDIO_ENCODING_APTX = "fuchsia.media.aptx";
+const string AUDIO_ENCODING_FLAC = "fuchsia.media.flac";
+const string AUDIO_ENCODING_GSMMS = "fuchsia.media.gsmms";
+const string AUDIO_ENCODING_LPCM = "fuchsia.media.lpcm";
+const string AUDIO_ENCODING_MP3 = "fuchsia.media.mp3";
+const string AUDIO_ENCODING_PCMALAW = "fuchsia.media.pcmalaw";
+const string AUDIO_ENCODING_PCMMULAW = "fuchsia.media.pcmmulaw";
+const string AUDIO_ENCODING_SBC = "fuchsia.media.sbc";
+const string AUDIO_ENCODING_VORBIS = "fuchsia.media.vorbis";
+const string AUDIO_ENCODING_OPUS = "fuchsia.media.opus";
+
+/// Video encodings.
+const string VIDEO_ENCODING_H263 = "fuchsia.media.h263";
+const string VIDEO_ENCODING_H264 = "fuchsia.media.h264";
+const string VIDEO_ENCODING_MPEG4 = "fuchsia.media.mpeg4";
+const string VIDEO_ENCODING_THEORA = "fuchsia.media.theora";
+const string VIDEO_ENCODING_UNCOMPRESSED = "fuchsia.media.uncompressed_video";
+const string VIDEO_ENCODING_VP3 = "fuchsia.media.vp3";
+const string VIDEO_ENCODING_VP8 = "fuchsia.media.vp8";
+const string VIDEO_ENCODING_VP9 = "fuchsia.media.vp9";
+
+/// Describes the compression applied to a stream. This type can be used in conjunction with
+/// `AudioStreamType` or `VideoStreamType` to represent a medium-specific compressed type.
+struct Compression {
+ /// The type of compression applied to the stream. This is generally one of the *_ENCODING_*
+ /// values, though `AUDIO_ENCODING_LPCM` and `VIDEO_ENCODING_UNCOMPRESSED` must not be used,
+ /// because those encodings are regarded as uncompressed.
+ CompressionType type;
+
+ /// Type-specific, opaque ‘out-of-band’ parameters describing the compression of the stream.
+ bytes:8192? parameters;
+};
+
+/// An identifier for compression types.
+using CompressionType = string:256;
+
+// /////////////////////////////////////////////////////////////////////////////
+// Audio
+
+/// Describes the type of an audio elementary stream.
+struct AudioStreamType {
+ AudioSampleFormat sample_format;
+ uint32 channels;
+ uint32 frames_per_second;
+ // TODO(mpuryear): Add channel config.
+};
+
+/// Enumerates the supported audio sample formats.
+enum AudioSampleFormat {
+ /// 8-bit unsigned samples, sample size 1 byte.
+ UNSIGNED_8 = 1;
+
+ /// 16-bit signed samples, host-endian, sample size 2 bytes.
+ SIGNED_16 = 2;
+
+ /// 24-bit signed samples in 32 bits, host-endian, sample size 4 bytes.
+ SIGNED_24_IN_32 = 3;
+
+ /// 32-bit floating-point samples, sample size 4 bytes.
+ FLOAT = 4;
+};
+
+// /////////////////////////////////////////////////////////////////////////////
+// Video
+
+/// Describes the type of a video elementary stream.
+struct VideoStreamType {
+ fuchsia.images.PixelFormat pixel_format;
+ // TODO(dalesat): Use fuchsia.images.ColorSpace.
+ ColorSpace color_space;
+
+ /// Dimensions of the video frames as displayed in pixels.
+ uint32 width;
+ uint32 height;
+
+ /// Dimensions of the video frames as encoded in pixels. These values must
+ /// be equal to or greater than the respective width/height values.
+ uint32 coded_width;
+ uint32 coded_height;
+
+ /// The aspect ratio of a single pixel as frames are intended to be
+ /// displayed.
+ uint32 pixel_aspect_ratio_width;
+ uint32 pixel_aspect_ratio_height;
+
+ /// The number of bytes per 'coded' row in the primary video plane.
+ uint32 stride;
+};
+
+// TODO(dalesat): Replace with fuchsia.images.ColorSpace.
+enum ColorSpace {
+ UNKNOWN = 0;
+ NOT_APPLICABLE = 1;
+ JPEG = 2;
+ HD_REC709 = 3;
+ SD_REC601 = 4;
+};
+
+// /////////////////////////////////////////////////////////////////////////////
+// Text
+
+/// Describes the type of a text elementary stream.
+struct TextStreamType {
+ // TODO(dalesat): Define.
+};
+
+// /////////////////////////////////////////////////////////////////////////////
+// Subpicture
+
+/// Describes the type of a subpicture elementary stream.
+struct SubpictureStreamType {
+ // TODO(dalesat): Define.
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media/timeline_function.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media/timeline_function.fidl
new file mode 100644
index 0000000..ec1c093
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media/timeline_function.fidl
@@ -0,0 +1,55 @@
+// Copyright 2018 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.
+
+library fuchsia.media;
+
+/// A TimelineFunction represents a relationship between a subject timeline and a
+/// reference timeline with a linear relation.
+///
+/// For example, consider a common use case in which reference time is the
+/// monotonic clock of a system and subject time is intended presentation time
+/// for some media such as a video.
+///
+/// `reference_time` is the value of the monotonic clock at the beginning of
+/// playback. `subject_time` is 0 assuming playback starts at the beginning of
+/// the media. We then choose a `reference_delta` and `subject_delta` so that
+/// `subject_delta` / `reference_delta` represents the desired playback rate,
+/// e.g. 0/1 for paused and 1/1 for normal playback.
+///
+/// ## Formulas
+///
+/// With a function we can determine the subject timeline value `s` in terms of
+/// reference timeline value `r` with this formula (where `reference_delta` > 0):
+///
+/// s = (r - reference_time) * (subject_delta / reference_delta) + subject_time
+///
+/// And similarly we can find the reference timeline value `r` in terms of
+/// subject timeline value `s` with this formula (where `subject_delta` > 0):
+///
+/// r = (s - subject_time) * (reference_delta / subject_delta) + referenc_time
+///
+/// ## Choosing time values
+///
+/// Time values can be arbitrary and our linear relation will of course be the
+/// same, but we can use them to represent the bounds of pieces in a piecewise
+/// linear relation.
+///
+/// For example, if a user performs skip-chapter, we might want to describe
+/// this with a TimelineFunction whose `subject_time` is the time to skip to,
+/// `reference_time` is now plus some epsilon, and delta ratio is 1/1 for normal
+/// playback rate.
+struct TimelineFunction {
+ /// A value from the subject timeline that correlates to reference_time.
+ int64 subject_time = 0;
+
+ /// A value from the reference timeline that correlates to subject_time.
+ int64 reference_time = 0;
+
+ /// The change in the subject timeline corresponding to reference_delta.
+ uint32 subject_delta = 0;
+
+ /// The change in the reference timeline corresponding to subject_delta.
+ /// Cannot be zero.
+ uint32 reference_delta = 1;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.media/usage_reporter.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.media/usage_reporter.fidl
new file mode 100644
index 0000000..180b907
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.media/usage_reporter.fidl
@@ -0,0 +1,82 @@
+// 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.
+
+//TODO(36191): Move to fuchsia.media.audio
+
+library fuchsia.media;
+
+/// A state of audio usages in which no policy actions are taken on any streams with the usage.
+table UsageStateUnadjusted {
+};
+
+/// A state of audio usages in which a policy decision has been made to temporarily
+/// lower the volume of all streams with this usage.
+table UsageStateDucked {
+};
+
+/// A state of audio usages in which a policy decision has been made to temporarily
+/// mute the volume of all streams with this usage.
+table UsageStateMuted {
+};
+
+/// The state of audio policy enforcement on a stream or set of streams.
+flexible union UsageState {
+ 1: UsageStateUnadjusted unadjusted;
+ 2: UsageStateDucked ducked;
+ 3: UsageStateMuted muted;
+};
+
+/// A protocol for listening to changes to the policy state of an audio usage.
+///
+/// User actions, such as lowering the volume or muting a stream, are not reflected in this
+/// API.
+protocol UsageWatcher {
+ /// Called on first connection and whenever the watched usage changes. The provided
+ /// usage will always be the bound usage; it is provided so that an implementation of
+ /// this protocol may be bound to more than one usage.
+ ///
+ /// Clients must respond to acknowledge the event. Clients that do not acknowledge their
+ /// events will eventually be disconnected.
+ OnStateChanged(Usage usage, UsageState state) -> ();
+};
+
+/// A protocol for setting up watchers of audio usages.
+[Discoverable]
+protocol UsageReporter {
+ Watch(
+ Usage usage,
+ UsageWatcher usage_watcher);
+};
+
+/// A protocol for setting up watchers of usage gain.
+[Discoverable]
+protocol UsageGainReporter {
+ /// Connects a listener to a stream of usage gain setting changes
+ /// for `usage` on the device identified by `device_token`. Usage
+ /// Gain is not set directly by any client; it is a translation of
+ /// the usage volume setting for each device.
+ ///
+ /// Devices may map the same volume level to different dbfs, so
+ /// a `device_unique_id` is needed to indentify the device.
+ ///
+ /// `AudioDeviceEnumerator` provides programmatic access to devices
+ /// and their unique ids if it is necessary for a client to select
+ /// an id at runtime.
+ RegisterListener(
+ string:36 device_unique_id,
+ Usage usage,
+ UsageGainListener usage_gain_listener);
+};
+
+/// A protocol for watching changes to usage gain settings.
+///
+/// The channel will close when the device is not present.
+protocol UsageGainListener {
+ /// Called immediately on connection and afterward any time
+ /// the usage gain setting changes.
+ ///
+ /// Clients must respond to acknowledge the event. Clients that do not acknowledge their
+ /// events will eventually be disconnected.
+ OnGainMuteChanged(bool muted, float32 gain_dbfs) -> ();
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.mediacodec/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.mediacodec/BUILD.gn
new file mode 100644
index 0000000..9dbd488
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.mediacodec/BUILD.gn
@@ -0,0 +1,26 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.mediacodec") {
+ library_name = "mediacodec"
+ namespace = "fuchsia"
+ public_deps = [
+ "../fuchsia.media",
+ ]
+ sources = [
+ "codec_factory.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.mediacodec",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.mediacodec/codec_factory.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.mediacodec/codec_factory.fidl
new file mode 100644
index 0000000..e7b0be9
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.mediacodec/codec_factory.fidl
@@ -0,0 +1,310 @@
+// Copyright 2018 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.
+
+library fuchsia.mediacodec;
+
+using fuchsia.media;
+
+// CreateDecoder_Params
+//
+// Input parameters for creating a decoder (audio or video).
+//
+
+/// Whether buffers need to be secure. If not specified, the default is OFF.
+///
+/// This enum may have additional values added later; code handling this type
+/// should be written with this in mind. For example, in C++, having a
+/// "default" case in any switch statement on this type will avoid compilation
+/// warnings/errors when a new value is added.
+//
+// Later we can add DYNAMIC, as needed.
+enum SecureMemoryMode : uint32 {
+ // Normal memory. This is the default if a field of this type is not set.
+ OFF = 0;
+ // Secure memory.
+ ON = 1;
+};
+
+table CreateDecoder_Params {
+ /// Input mime type for a decoder.
+ ///
+ /// The recognized mime types for now:
+ /// video/h264
+ /// video/vp9
+ /// audio/aac
+ /// input_details.oob_bytes must be an AudioSpecificConfig() as defined
+ /// by AAC spec.
+ /// audio/sbc
+ /// input_details.oob_bytes must be Codec Specific Information Elements
+ /// for SBC as defined by the A2DP spec.
+ 1: fuchsia.media.FormatDetails input_details;
+
+ // The settings below nail down more details.
+
+ /// This must be true in order for the client to be permitted to put a
+ /// timestamp on an input packet, which is in turn required to get any
+ /// timestamps on any output packets.
+ ///
+ /// It is always legal to provide separate Access Units (henceforth AUs) to a
+ /// decoder, but this boolean must be true for a decoder to accept and
+ /// propagate timestamp values.
+ ///
+ /// This must be true when creating a video encoder, or the CodecFactory
+ /// channel will close.
+ // TODO(FIDL-609): Default to false.
+ 2: bool promise_separate_access_units_on_input;
+
+ // "require" fields:
+ //
+ // Specifying any of these "require" fields can result in failure to get a
+ // Codec if there's no suitable codec. None of these correspond to any
+ // required features of a codec server.
+ //
+ // TODO(dustingreen): implement filtering codecs based on these fields.
+
+ /// Require that the selected codec be capable of accepting input where
+ /// AUs are not separated into separate packets.
+ ///
+ /// This does not imply that the decoder can find the start of the first AU;
+ /// for that see require_can_find_start. This does not imply that the decoder
+ /// can re-sync on its own if the stream data is damaged; for that see
+ /// require_can_re_sync.
+ ///
+ /// If both promise_separate_access_units_on_input and
+ /// require_can_stream_bytes_input are true, the CodecFactory channel will
+ /// close.
+ ///
+ /// If this is false, the client must feed separate AUs on the fuchsia.ui.input. This
+ /// must be false for a video encoder, and if true the CodecFactory channel
+ /// will close.
+ ///
+ /// Unless a client demands a decoder capable of taking concatenated AUs
+ /// (require_can_stream_bytes_input true), the client must feed a decoder
+ /// separate AUs. This means the client cannot have parts of two separate AUs
+ /// in the same packet, unless require_can_stream_bytes_input is true.
+ // TODO(FIDL-609): Default to false.
+ 3: bool require_can_stream_bytes_input;
+
+ /// A decoder is allowed to be capable of streaming bytes but not capable of
+ /// searching for the start of the first usable AU. To require both, set both
+ /// require_can_stream_bytes_input and require_can_find_start. Setting
+ /// require_can_find_start without require_can_stream_bytes_input is invalid.
+ ///
+ /// With require_can_stream_bytes_input true but require_can_find_start false,
+ /// the client must start the first packet with the start of an AU, but can
+ /// send a stream of bytes after that.
+ // TODO(FIDL-609): Default to false.
+ 4: bool require_can_find_start;
+
+ /// On problematic input data, all decoders are expected to at least be able to
+ /// close the channel rather than getting stuck in a failed and/or broken
+ /// state.
+ ///
+ /// A decoder returned from a request with require_can_re_sync is potentially
+ /// able to handle damaged input without closing the Codec channel. Such a
+ /// Codec is encouraged, but not required, to also satisfy requirements of
+ /// require_report_all_detected_errors.
+ // TODO(FIDL-609): Default to false.
+ 5: bool require_can_re_sync;
+
+ /// Sometimes a client would rather fail an overall use of a decoder than fail
+ /// to notice data corruption. For such scenarios, the client can specify
+ /// require_report_all_detected_errors. For any codec returned from a
+ /// request with require_report_all_detected_errors set, on detection of
+ /// any input data corruption the codec will report in one or more of these
+ /// ways:
+ /// * closing the Codec channel
+ /// * OnStreamFailed()
+ /// * error_detected_before
+ /// * error_detected_during
+ ///
+ /// If false, a codec may silently skip past corrupted input data.
+ ///
+ /// No decoder can detect all corruption, because some corruption can look like
+ /// valid stream data. This requirement is only to request a codec that
+ /// is written to attempt to detect _and report_ input stream corruption.
+ ///
+ /// This flag is not intended to be 100% bulletproof. If a client needs robust
+ /// assurance that _all_ detectable stream corruption is _always_ detected,
+ /// this flag is not enough of a guarantee to achieve that. Since some stream
+ /// corruption is inherently non-detectable in any case, such a client should
+ /// consider using stronger techniques upstream to ensure that corruption can
+ /// be detected with the needed probability very close to 1.
+ ///
+ /// This flag being true doesn't imply anything about whether the codec will
+ /// discard damaged data vs. producing corresponding damaged output. Only that
+ /// the codec will set error_detected_* bools to true when appropriate.
+ ///
+ /// Regardless of this setting, not all timestamp_ish values provided on input
+ /// are guaranteed to show up on output.
+ // TODO(FIDL-609): Default to false.
+ 6: bool require_report_all_detected_errors;
+
+ /// If true, require that the returned codec is HW-accelerated.
+ // TODO(FIDL-609): Default to false.
+ 7: bool require_hw;
+
+ /// permit_lack_of_split_header_handling
+ ///
+ /// This field is a temporary field that will be going away.
+ ///
+ /// TODO(dustingreen): Remove this field once we're down to zero codecs with
+ /// problems handling split headers.
+ ///
+ /// By default, a Codec instance is required to handle "split headers", meaning
+ /// that a client is allowed to deliver parts of an AU one byte at a time,
+ /// including parts near the beginning of the AU, and the codec is required to
+ /// tolerate and handle that properly. However, unfortunately not all codecs
+ /// properly support split headers. If a client is willing to permit such a
+ /// codec to be used, the client can set this to true. Clients are not
+ /// encouraged to set this, but setting it may be necessary to find a codec for
+ /// some formats _for now_. If a client sets this to true, the client should
+ /// deliver data of each AU with many contiguous non-split bytes from the start
+ /// of each AU. The client is not strictly required to deliver one AU at a
+ /// time, only to ensure that either all the AU bytes are in a single packet or
+ /// that many bytes at the start of each AU are in a single packet.
+ ///
+ /// The specification for how a client should use this and how a client should
+ /// behave if setting this to true is intentionally vague, because lack of
+ /// support for header splitting is not ideal, and is expected to be
+ /// temporary, and all codecs should handle split headers in the long run.
+ /// The main intent of this field is to avoid giving an innocent client using
+ /// default value of false here a codec that can't properly handle split
+ /// headers. This is not an attempt at a mechanism to fully work around a
+ /// codec that doesn't handle split headers.
+ // TODO(dustingreen): In the near term, wire this up so that SoftAAC2.cpp
+ // used for ADTS is not selected when this field is false, even if there is
+ // no other suitable codec. In the long term, fix or work around the header
+ // handling behavior of SoftAAC2 when used in ADTS mode (and any other
+ // similar issues in other codecs) and remove this field.
+ // TODO(FIDL-609): Default to false.
+ 8: bool permit_lack_of_split_header_handling;
+
+ /// If set to ON, the decoder must support secure buffers on output, and
+ /// must reject non-secure buffers on output.
+ ///
+ /// If set to OFF or not set, the created decoder will reject secure buffers
+ /// on output by closing the StreamProcessor channel.
+ ///
+ /// If secure_input_mode ON, secure_output_mode must also be ON.
+ 9: SecureMemoryMode secure_output_mode;
+
+ /// If set to ON, the decoder must support secure buffers on input and must
+ /// reject non-secure buffers on input.
+ ///
+ /// If set to OFF or not set, the created decoder will reject secure buffers
+ /// on input by closing the StreamProcessor channel.
+ ///
+ /// If secure_input_mode ON, secure_output_mode must also be ON.
+ 10: SecureMemoryMode secure_input_mode;
+};
+
+/// Parameters used to request an encoder.
+table CreateEncoder_Params {
+ /// The format of the uncompressed input data.
+ ///
+ /// This field should be a raw mime_type (e.g. 'video/raw') and uncompressed
+ /// format details for the encoder to use when reading buffers.
+ ///
+ /// To be elibigible an encoder must support the input format.
+ 1: fuchsia.media.FormatDetails input_details;
+
+ /// If true, require that the returned codec is HW-accelerated.
+ // TODO(FIDL-609): Default to false.
+ 2: bool require_hw;
+};
+
+enum CodecType {
+ DECODER = 0;
+ ENCODER = 1;
+};
+
+struct CodecDescription {
+ // Decoder or encoder.
+ CodecType codec_type;
+ // The mime type of the compressed format. For decoders this is the mime
+ // type of the input. For encoders, this is the mime type of the output.
+ string mime_type;
+
+ // TODO(dustingreen): All these fields should be optional.
+ //
+ // TODO(dustingreen): Re-evaluate this for encoders.
+ //
+ // For each of these fields, the default is the most-capable setting, but if a
+ // codec doesn't support the most-capable behavior, then the codec must
+ // override the default.
+ bool can_stream_bytes_input = true;
+ bool can_find_start = true;
+ bool can_re_sync = true;
+ bool will_report_all_detected_errors = true;
+ bool is_hw = true;
+ bool split_header_handling = true;
+};
+
+// CodecFactory
+//
+// The purpose of the media::CodecFactory interface is to create media::Codec
+// instances.
+//
+// The interface methods don't attempt to homogenize all codec types, preferring
+// to have a separate dedicated message for decoders. TBD whether calls for
+// creating encoders will split up audio vs. video encoders, or be combined.
+//
+
+// Each create request is self-contained, in the sense that the interface is not
+// stateful between create requests.
+[Discoverable]
+protocol CodecFactory {
+ // Driver-based local CodecFactory(s) will send this once shortly after the
+ // main CodecFactory connects to the driver-local CodecFactory.
+ //
+ // For now, the main CodecFactory will not send this.
+ //
+ // A SW-based local CodecFactory(s) will not send this event.
+ //
+ // Each codec in the list must be separately-described, for clean aggregation.
+ -> OnCodecList(vector<CodecDescription> codecs);
+
+ // Rough sequence to create a decoder:
+ //
+ // factory = ConnectToEnvironmentService(CodecFactory);
+ // CreateDecoder_Params params;
+ // [fill out params]
+ // CreateDecoder(params, decoder_request);
+ //
+ // See use_media_decoder code for more detail.
+ //
+ // TODO(dustingreen): More detail in this comment block.
+
+ // Requests:
+
+ // CreateDecoder:
+ //
+ // decoder_params - See CreateDecoder_Params comments for required
+ // and optional parameters for creating a decoder.
+ //
+ // decoder - a Codec.NewRequest() which will hopefully be connected to
+ // a Codec server, or the Codec channel will get closed if no suitable codec
+ // can be found. We don't return any additional Codec-specific status here
+ // because finding the Codec is allowed to be fully async, so we don't
+ // necessarily yet know on return from this method which Codec will be
+ // selected, if any.
+ CreateDecoder(
+ CreateDecoder_Params decoder_params,
+ request<fuchsia.media.StreamProcessor> decoder);
+
+ // CreateEncoder:
+ //
+ // encoder_params - See CreateEncoder_Params comments for required
+ // and optional parameters for creating a decoder.
+ //
+ // encoder - a Codec.NewRequest() which will hopefully be connected to
+ // a Codec server, or the Codec channel will get closed if no suitable codec
+ // can be found. We don't return any additional Codec-specific status here
+ // because finding the Codec is allowed to be fully async, so we don't
+ // necessarily yet know on return from this method which Codec will be
+ // selected, if any.
+ CreateEncoder(CreateEncoder_Params encoder_params,
+ request<fuchsia.media.StreamProcessor> encoder);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.mediacodec/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.mediacodec/meta.json
new file mode 100644
index 0000000..7a45491
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.mediacodec/meta.json
@@ -0,0 +1,11 @@
+{
+ "deps": [
+ "fuchsia.media"
+ ],
+ "name": "fuchsia.mediacodec",
+ "root": "fidl/fuchsia.mediacodec",
+ "sources": [
+ "fidl/fuchsia.mediacodec/codec_factory.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.mem/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.mem/BUILD.gn
new file mode 100644
index 0000000..add1cd6
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.mem/BUILD.gn
@@ -0,0 +1,26 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.mem") {
+ library_name = "mem"
+ namespace = "fuchsia"
+ public_deps = [
+ ]
+ sources = [
+ "buffer.fidl",
+ "range.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.mem",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.mem/buffer.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.mem/buffer.fidl
new file mode 100644
index 0000000..7a180c7
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.mem/buffer.fidl
@@ -0,0 +1,40 @@
+// Copyright 2017 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.
+
+library fuchsia.mem;
+
+/// A buffer for data whose size is not necessarily a multiple of the page
+/// size.
+///
+/// VMO objects have a physical size that is always a multiple of the page
+/// size. As such, VMO alone cannot serve as a buffer for arbitrarly sized
+/// data. `fuchsia.mem.Buffer` is a standard struct that aggregate the VMO
+/// and its size.
+struct Buffer {
+ /// The vmo that contains the buffer.
+ handle<vmo> vmo;
+
+ /// The number of bytes in the buffer.
+ ///
+ /// The content of the buffer begin at the start of the VMO and continue
+ /// for `size` bytes. To specify a range of bytes that do not start at
+ /// the beginning of the VMO, use `Range` rather than buffer.
+ ///
+ /// This size must not be greater than the physical size of the VMO.
+ uint64 size;
+};
+
+/// Binary data that might be stored inline or in a VMO.
+///
+/// Useful for performance-sensitive protocols that sometimes receive small
+/// amounts of binary data (i.e., which is more efficient to provide using
+/// `bytes`) but also need to support arbitrary amounts of data (i.e., which
+/// need to be provided out-of-line in a `Buffer`).
+flexible union Data {
+ /// The binary data provided inline in the message.
+ 1: bytes bytes;
+
+ /// The binary data provided out-of-line in a `Buffer`.
+ 2: Buffer buffer;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.mem/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.mem/meta.json
new file mode 100644
index 0000000..99a6ce4
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.mem/meta.json
@@ -0,0 +1,10 @@
+{
+ "deps": [],
+ "name": "fuchsia.mem",
+ "root": "fidl/fuchsia.mem",
+ "sources": [
+ "fidl/fuchsia.mem/buffer.fidl",
+ "fidl/fuchsia.mem/range.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.mem/range.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.mem/range.fidl
new file mode 100644
index 0000000..2adda7b
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.mem/range.fidl
@@ -0,0 +1,27 @@
+// 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.
+
+library fuchsia.mem;
+
+/// A range of bytes within a VMO.
+struct Range {
+ /// The vmo that contains the bytes.
+ handle<vmo> vmo;
+
+ /// The offset of the first byte within the range relative to the start of
+ /// the VMO.
+ ///
+ /// For example, if `offset` is zero, then the first byte in the range is
+ /// the first byte in the VMO.
+ uint64 offset;
+
+ /// The number of bytes in the range.
+ ///
+ /// For example, if the offset is 3 and the size is 2, and the VMO starts
+ /// with "abcdefg...", then the range contains "de".
+ ///
+ /// The sum of the offset and the size must not be greater than the
+ /// physical size of the VMO.
+ uint64 size;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.memorypressure/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.memorypressure/BUILD.gn
new file mode 100644
index 0000000..503f35c
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.memorypressure/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.memorypressure") {
+ library_name = "memorypressure"
+ namespace = "fuchsia"
+ public_deps = [
+ ]
+ sources = [
+ "memorypressure.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.memorypressure",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.memorypressure/memorypressure.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.memorypressure/memorypressure.fidl
new file mode 100644
index 0000000..c012f81
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.memorypressure/memorypressure.fidl
@@ -0,0 +1,99 @@
+// Copyright 2020 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.
+library fuchsia.memorypressure;
+
+/// Indicates the memory pressure level.
+enum Level {
+ /// The memory pressure level is healthy.
+ ///
+ /// Registered clients are free to hold on to caches and allocate memory
+ /// unrestricted.
+ ///
+ /// However, clients should take care to not proactively re-create caches on a
+ /// transition back to the NORMAL level, causing a memory spike that immediately
+ /// pushes the level over to WARNING again.
+ NORMAL = 1;
+
+ /// The memory pressure level is somewhat constrained, and might cross over to
+ /// the critical pressure range if left unchecked.
+ ///
+ /// Registered clients are expected to optimize their operation to limit memory
+ /// usage, rather than for best performance, for example, by reducing cache sizes
+ /// and non-essential memory allocations.
+ ///
+ /// Clients must take care to regulate the amount of work they undertake in
+ /// order to reclaim memory, and ensure that it does not cause visible
+ /// performance degradation. There exists some memory pressure, but not enough
+ /// to justify trading off user responsiveness to reclaim memory.
+ WARNING = 2;
+
+ /// The memory pressure level is very constrained.
+ ///
+ /// Registered clients are expected to drop all non-essential memory, and refrain
+ /// from allocating more memory. Failing to do so might result in the job
+ /// getting terminated, or the system being rebooted in the case of global
+ /// memory pressure.
+ ///
+ /// Clients may undertake expensive work to reclaim memory if required, since
+ /// failing to do so might result in termination. The client might decide that a
+ /// performance hit is a fair tradeoff in this case.
+ CRITICAL = 3;
+};
+
+/// Registration protocol
+[Discoverable]
+protocol Provider {
+ /// Used to register for memory pressure level changes.
+ /// `watcher`: memory pressure `Watcher` channel that the `Provider` will use to send
+ /// level change messages to the client.
+ ///
+ /// The current memory pressure level is immediately sent to the watcher
+ /// when this method is called.
+ ///
+ /// It is recommended that the root job in a component tree register for changes,
+ /// rather than having individual jobs further down the tree register individually.
+ /// A low client count will help minimize system churn due to a large number of
+ /// memory pressure messages in transit at the same time.
+ /// Also, the more context a job has, the better equipped it will be to react to
+ /// memory pressure by controlling the behavior of children jobs in its tree.
+ RegisterWatcher(Watcher watcher);
+};
+
+/// Watcher protocol
+/// To be implemented by clients who wish to be notified on memory pressure level changes.
+protocol Watcher {
+ /// Sent to the registered client when the memory pressure level changes.
+ /// `level`: indicates the current memory pressure level.
+ ///
+ /// Will also be invoked on initial connection via `RegisterWatcher`, so that a newly
+ /// registered client can discover the current memory pressure level.
+ ///
+ /// The watcher must immediately reply with a message to acknowledge that it has
+ /// received the level change notification, and has initiated required actions as a
+ /// result. It may then continue to reclaim memory asynchronously after sending
+ /// the acknowledgement.
+ ///
+ /// Some helpful guidelines for clients:
+ /// 1. The watcher will be notified of new pressure level changes only after a reply
+ /// corresponding to the previous message has been received by the provider.
+ /// If multiple level transitions occur during that time, the watcher will be
+ /// notified of the latest pressure level.
+ ///
+ /// 2. The level changes are edge-triggered, and clients are expected to maintain
+ /// local state to track the current pressure level, if required. For example,
+ /// a job might be notified of a CRITICAL level and drop all its caches as a result.
+ /// Some time after this, it might want to trigger an activity that causes a
+ /// fair amount of memory to be allocated. At this point, the job is expected to
+ /// remember that the last pressure level it saw was CRITICAL, and refrain from
+ /// triggering the memory-intensive activity.
+ ///
+ /// 3. As a performance optimization, the provider may decide to skip sending
+ /// messages for some pressure level changes. For example, when oscillating across
+ /// the NORMAL / WARNING boundary, it might not be worth notifying clients of every
+ /// single transition. The provider might rate-limit messages in this case.
+ /// On a similar note, the provider may decide to send repeated messages at the
+ /// same pressure level, particularly CRITICAL, to indicate that further action
+ /// needs to be taken.
+ OnLevelChanged(Level level) -> ();
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.memorypressure/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.memorypressure/meta.json
new file mode 100644
index 0000000..8e44e9d
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.memorypressure/meta.json
@@ -0,0 +1,9 @@
+{
+ "deps": [],
+ "name": "fuchsia.memorypressure",
+ "root": "fidl/fuchsia.memorypressure",
+ "sources": [
+ "fidl/fuchsia.memorypressure/memorypressure.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.migration/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.migration/BUILD.gn
new file mode 100644
index 0000000..6b81020
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.migration/BUILD.gn
@@ -0,0 +1,26 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.migration") {
+ library_name = "migration"
+ namespace = "fuchsia"
+ public_deps = [
+ "../fuchsia.io",
+ ]
+ sources = [
+ "migration.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.migration",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.migration/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.migration/meta.json
new file mode 100644
index 0000000..b634b11
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.migration/meta.json
@@ -0,0 +1,11 @@
+{
+ "deps": [
+ "fuchsia.io"
+ ],
+ "name": "fuchsia.migration",
+ "root": "fidl/fuchsia.migration",
+ "sources": [
+ "fidl/fuchsia.migration/migration.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.migration/migration.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.migration/migration.fidl
new file mode 100644
index 0000000..1620d78
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.migration/migration.fidl
@@ -0,0 +1,52 @@
+// 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.
+
+library fuchsia.migration;
+using fuchsia.io;
+
+enum MigrationStatus {
+ UNKNOWN = 1;
+ IN_PROGRESS = 2;
+ COMPLETE = 3;
+ ENCOUNTERED_ERROR = 4;
+};
+
+/// Table for state of migration operations.
+table MigrationState {
+ 1: MigrationStatus status;
+ 2: uint8 progress_percentage;
+};
+
+protocol Provider {
+ Get(request<fuchsia.io.Directory> dir);
+ Processed();
+};
+
+[Discoverable]
+protocol CastProvider {
+ compose Provider;
+};
+
+[Discoverable]
+protocol KronkProvider {
+ compose Provider;
+};
+
+[Discoverable]
+protocol DisplayProvider {
+ compose Provider;
+};
+
+[Discoverable]
+protocol UltrasoundProvider {
+ compose Provider;
+};
+
+/// Protocol to watch for changes when a migration of system data is started.
+[Discoverable]
+protocol State {
+ /// Hanging get. Will return immediatedly on first call per connection
+ /// and then on change after that.
+ Watch() -> (MigrationState state);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular.auth/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.modular.auth/BUILD.gn
new file mode 100644
index 0000000..a419b6c
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular.auth/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.modular.auth") {
+ library_name = "auth"
+ namespace = "fuchsia.modular"
+ public_deps = [
+ ]
+ sources = [
+ "account/account.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.modular.auth",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular.auth/account/account.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular.auth/account/account.fidl
new file mode 100644
index 0000000..92473ee
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular.auth/account/account.fidl
@@ -0,0 +1,55 @@
+// Copyright 2017 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.
+
+library fuchsia.modular.auth;
+
+/// Stores attributes related to an account that is exposed to base shell.
+/// A list of existing account(s) can be obtained via
+/// UserProvider.PreviousUsers() and a new account can be added via
+/// UserProvider.AddAccount().
+struct Account {
+ /// A randomly generated identifier that is used to identify this
+ /// account on this device. This is meant to be used by base shell when it
+ /// wants to login as a user who has previously logged in.
+ string id;
+
+ /// The identity provider that was used to authenticate the user on this
+ /// device.
+ IdentityProvider identity_provider;
+
+ /// Unique identifier configured for the given user at the Identity provider.
+ /// Profile id is fetched from user profile attributes as configured by the
+ /// user at the given identity provider.
+ string profile_id;
+
+ /// The name that is displayed on the base shell while logging in. Display
+ /// name is fetched from user profile attributes as configured by the user at
+ /// the given identity provider.
+ string display_name;
+
+ /// User's profile url that is used by the base shell while logging in.
+ /// Profile url is fetched from user profile attributes as configured by the
+ /// user at the given identity provider.
+ string url;
+
+ /// User's profile image url that is used by the base shell while logging in.
+ /// Profile image url is fetched from user profile attributes as configured by
+ /// the user at the given identity provider.
+ string image_url;
+};
+
+/// The currently supported identity providers. An identity provider provides
+/// identifiers for users to interact with the system and may provide information
+/// about the user that is known to the provider.
+enum IdentityProvider {
+ /// An identity provider that's used for development and testing. If this
+ /// identity provider is chosen, the Framework will continue as if it has
+ /// identified the user. Note that the users that use this id provider would
+ /// not get cloud ledger access (unless done via a side channel).
+ DEV = 0;
+
+ /// Uses Google as the identity provider. Doing this requires a working network
+ /// connection and a web view.
+ GOOGLE = 1;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular.auth/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.modular.auth/meta.json
new file mode 100644
index 0000000..698efff
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular.auth/meta.json
@@ -0,0 +1,9 @@
+{
+ "deps": [],
+ "name": "fuchsia.modular.auth",
+ "root": "fidl/fuchsia.modular.auth",
+ "sources": [
+ "fidl/fuchsia.modular.auth/account/account.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular.session/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.modular.session/BUILD.gn
new file mode 100644
index 0000000..e31a281
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular.session/BUILD.gn
@@ -0,0 +1,28 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.modular.session") {
+ library_name = "session"
+ namespace = "fuchsia.modular"
+ public_deps = [
+ "../fuchsia.io",
+ "../fuchsia.sys",
+ "../fuchsia.ui.policy",
+ ]
+ sources = [
+ "modular_config.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.modular.session",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular.session/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.modular.session/meta.json
new file mode 100644
index 0000000..fccfe83
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular.session/meta.json
@@ -0,0 +1,13 @@
+{
+ "deps": [
+ "fuchsia.sys",
+ "fuchsia.ui.policy",
+ "fuchsia.io"
+ ],
+ "name": "fuchsia.modular.session",
+ "root": "fidl/fuchsia.modular.session",
+ "sources": [
+ "fidl/fuchsia.modular.session/modular_config.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular.session/modular_config.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular.session/modular_config.fidl
new file mode 100644
index 0000000..2fb7a03
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular.session/modular_config.fidl
@@ -0,0 +1,164 @@
+// 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.
+
+library fuchsia.modular.session;
+
+using fuchsia.io;
+using fuchsia.ui.policy;
+using fuchsia.sys;
+
+/// Descriptions and defaults for these configurations are echoed in
+/// peridot/docs/modular/guide/config.md.
+table BasemgrConfig {
+ /// When set to false, Cobalt statistics are disabled.
+ /// Default: true
+ 1: bool enable_cobalt;
+
+ /// When set to true, wait for persistent data to initialize.
+ /// Default: true
+ 2: bool use_minfs;
+
+ /// Create story shells through StoryShellFactory exposed by the session
+ /// shell instead of creating separate story shell components. When set,
+ /// `story_shell_url` and any story shell args are ignored.
+ /// Default: false
+ 3: bool use_session_shell_for_story_shell_factory;
+
+ /// Launch configurations specific to base shell.
+ 4: BaseShellConfig base_shell;
+
+ /// A map of launch configurations specific to session shells.
+ 5: vector<SessionShellMapEntry> session_shell_map;
+
+ /// Launch configurations specific to story shell.
+ 6: StoryShellConfig story_shell;
+
+ /// Temporary placeholder to pass configurations to sessionmgr. Will be
+ /// removed with the completion of MF-10.
+ 7: AppConfig sessionmgr;
+};
+
+table BaseShellConfig {
+ /// Contains the fuchsia package url and arguments to pass to the shell.
+ 1: AppConfig app_config;
+
+ /// When set to true, the base shell is kept alive after a log in. This is
+ /// used for testing because current integration tests expect base shell
+ /// to always be running.
+ /// Default: false
+ 2: bool keep_alive_after_login;
+};
+
+table SessionShellMapEntry {
+ /// The name of the session shell represented by its url.
+ 1: string:fuchsia.io.MAX_PATH name;
+
+ /// The launch configurations for the session shell.
+ 2: SessionShellConfig config;
+};
+
+table SessionShellConfig {
+ /// Contains the fuchsia package url and arguments to pass to the shell.
+ 1: AppConfig app_config;
+
+ /// The display usage policy for this session shell.
+ ///
+ /// Optional: defaults to DisplayUsage::kUnknown.
+ 2: fuchsia.ui.policy.DisplayUsage display_usage;
+
+ /// The screen height in millimeters for the session shell's display.
+ ///
+ /// Optional: defaults to full screen.
+ 3: float32 screen_height;
+
+ /// The screen width in millimeters for the session shell's display.
+ ///
+ /// Optional: defaults to full screen.
+ 4: float32 screen_width;
+};
+
+table StoryShellConfig {
+ /// Contains the fuchsia package url and arguments to pass to the shell.
+ 1: AppConfig app_config;
+};
+
+table SessionmgrConfig {
+ 1: CloudProvider cloud_provider;
+
+ /// When set to false, Cobalt statistics are disabled. This is used for
+ /// testing.
+ /// Default: true
+ 2: bool enable_cobalt;
+
+ /// When set to false, StoryShell instances are not warmed up as a startup
+ /// latency optimization. This is used for testing.
+ /// Default: true
+ 3: bool enable_story_shell_preload;
+
+ /// Tells the sessionmgr whether it should host+pass a memfs-backed
+ /// directory to the ledger for the user's repository, or to use
+ /// /data/LEDGER.
+ /// Default: false
+ 4: bool use_memfs_for_ledger;
+
+ /// A list of fuchsia package urls that specify which agents to launch at
+ /// startup.
+ 5: vector<string:fuchsia.io.MAX_PATH> startup_agents;
+
+ /// A list of fuchsia package urls that specify which agents to launch at
+ /// startup with PuppetMaster and FocusProvider services.
+ 6: vector<string:fuchsia.io.MAX_PATH> session_agents;
+
+ /// The fuchsia package url for which story shell to use.
+ 7: string:fuchsia.io.MAX_PATH story_shell_url;
+
+ /// A map of agents to the arguments they should be started with.
+ 8: vector<AppConfig> component_args;
+
+ /// Deprecated
+ 9: bool use_parent_runner_for_story_realm;
+
+ /// A list of supported services and the URL of the agent known to provide
+ /// that service. Used by the Session Manager to implement
+ /// `ComponentContext` method ConnectToAgentService().
+ 10: vector<AgentServiceIndexEntry> agent_service_index;
+};
+
+/// Used to pass around configuration references to apps such as base shell,
+/// session shell, story shell, and agents.
+table AppConfig {
+ /// The fuchsia package url for app.
+ 1: string:fuchsia.io.MAX_PATH url;
+
+ /// The arguments for the app.
+ 2: vector<string> args;
+};
+
+/// A service and the URL of the agent known to provide that service.
+table AgentServiceIndexEntry {
+ /// The service name.
+ 1: string service_name;
+
+ /// The fuchsia component url for agent.
+ 2: fuchsia.sys.component_url agent_url;
+};
+
+enum CloudProvider {
+ /// Use a cloud provider configured by Ledger.
+ LET_LEDGER_DECIDE = 1;
+
+ /// Use a cloud provider available in the incoming namespace, rather than
+ /// initializing and instance within sessionmgr. This can be used to inject
+ /// a custom cloud provider.
+ FROM_ENVIRONMENT = 2;
+
+ NONE = 3;
+};
+
+/// Contains the configurations for the modular framework components.
+table ModularConfig {
+ 1: BasemgrConfig basemgr_config;
+
+ 2: SessionmgrConfig sessionmgr_config;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular.testing/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.modular.testing/BUILD.gn
new file mode 100644
index 0000000..bbb05a0
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular.testing/BUILD.gn
@@ -0,0 +1,29 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.modular.testing") {
+ library_name = "testing"
+ namespace = "fuchsia.modular"
+ public_deps = [
+ "../fuchsia.mem",
+ "../fuchsia.modular",
+ "../fuchsia.modular.session",
+ "../fuchsia.sys",
+ ]
+ sources = [
+ "test_harness.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.modular.testing",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular.testing/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.modular.testing/meta.json
new file mode 100644
index 0000000..333e86b
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular.testing/meta.json
@@ -0,0 +1,14 @@
+{
+ "deps": [
+ "fuchsia.modular",
+ "fuchsia.modular.session",
+ "fuchsia.sys",
+ "fuchsia.mem"
+ ],
+ "name": "fuchsia.modular.testing",
+ "root": "fidl/fuchsia.modular.testing",
+ "sources": [
+ "fidl/fuchsia.modular.testing/test_harness.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular.testing/test_harness.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular.testing/test_harness.fidl
new file mode 100644
index 0000000..016e2c1
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular.testing/test_harness.fidl
@@ -0,0 +1,214 @@
+// 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.
+
+library fuchsia.modular.testing;
+
+using fuchsia.mem;
+using fuchsia.modular;
+using fuchsia.modular.session;
+using fuchsia.sys;
+
+/// The `TestHarness` service is used to run the modular runtime under a
+/// hermetic environment and drive integration tests under it. Tests may use
+/// this service to intercept components and assume their role. Additionally,
+/// tests may use `TestHarness/ConnectToModularService()` to get capabilities
+/// for controlling stories (using PuppetMaster) and connecting to agents
+/// (using ComponentContext).
+///
+/// Closing the `TestHarness` connection will kill the `TestHarness` environment
+/// including the modular runtime running under it.
+///
+/// On error, this connection is closed with the following epitaphs:
+/// * `ZX_ERR_INVALID_ARGS`: Run() failed to execute succesfully.
+/// * `ZX_ERR_BAD_STATE`: Other methods are called before Run() is called.
+/// * `ZX_ERR_ALREADY_BOUND`: Run() was already called.
+/// * `ZX_ERR_ALREADY_EXISTS`: The same environment service is being provided
+/// twice.
+[Discoverable]
+protocol TestHarness {
+ /// Initializes an instance of the modular runtime in an enclosed
+ /// environment, configured with parameters provided in `spec`. Closing the
+ /// `TestHarness` connection will kill the enclosed environment.
+ ///
+ /// This protocol connection is closed if Run() fails, with the following
+ /// epitaphs:
+ /// * `ZX_ERR_INVALID_ARGS`: `spec` is mal-formed.
+ /// * `ZX_ERR_ALREADY_EXISTS`: The same environment service is being provided
+ /// twice in `spec.env_services`
+ /// * `ZX_ERR_ALREADY_BOUND`: Run() was already called.
+ Run(TestHarnessSpec spec);
+
+ /// This event is sent when a component specified in
+ /// `TestHarnessSpec.components_to_intercept` is created.
+ /// `startup_info.launch_info.url` contains the component URL.
+ ///
+ /// Closing `intercepted_component` will signal to the component manager
+ /// that this component has exited unexpectedly. Prefer to use
+ /// InterceptedComponent/Exit to provide exit code and reason.
+ -> OnNewComponent(fuchsia.sys.StartupInfo startup_info,
+ InterceptedComponent intercepted_component);
+
+ /// Tests may use this method to connect to services provided by the modular
+ /// runtime. These services share the same component namespace for any
+ /// resources they create (e.g., entities, message queues, and module
+ /// names).
+ ///
+ /// This protocol connection is closed with the following epitaphs:
+ /// * `ZX_ERR_BAD_STATE`: if `ConnectToModularService()` is called before
+ /// `Run()`.
+ /// * `ZX_ERR_INVALID_ARGS`: if `service` is not set to a value.
+ ConnectToModularService(ModularService service);
+
+ /// Connects to environment services injected into the TestHarness
+ /// environment.
+ ConnectToEnvironmentService(string service_name, handle<channel> request);
+
+ /// Parses a JSON modular configuration string into BasemgrConfig and
+ /// SessionmgrConfig. This method may be called before `Run()` is called.
+ ParseConfig(string config)
+ -> (fuchsia.modular.session.BasemgrConfig basemgr_config,
+ fuchsia.modular.session.SessionmgrConfig sessionmgr_config);
+};
+
+/// Describes which service to connect to using `ConnectToModularService()`.
+union ModularService {
+ 1: request<fuchsia.modular.PuppetMaster> puppet_master;
+ 2: request<fuchsia.modular.ComponentContext> component_context;
+ 3: request<fuchsia.modular.AgentContext> agent_context;
+};
+
+/// InterceptedComponent represents an intercepted component's lifecycle.
+/// Closing this connection causes the component to be killed, and is
+/// equivalent in behaviour to the `ComponentController` being closed.
+protocol InterceptedComponent {
+ /// Signals that component has exit'd with the specified exit code. The
+ /// values here are bubbled up to the
+ /// `fuchsia.sys.ComponentController.OnTerminated` event. The `OnKill` event
+ /// is sent, and this InterceptedComponent handle is closed.
+ Exit(int64 exit_code, fuchsia.sys.TerminationReason reason);
+
+ /// The event is sent when the component is killed by the associated
+ /// `fuchsia.sys.ComponentController`, or when `Exit()` is called.
+ -> OnKill();
+};
+
+/// Defines the setup of an environment running an instance of the modular
+/// framework used for testing purposes. This table is supplied to
+/// `TestHarness.Run()`. A malformed `TestHarnessSpec` will cause `TestHarness`
+/// connection to close with an epitaph of `ZX_ERR_INVALID_ARGS`.
+///
+/// By default, the following services are made available to the hermetic
+/// environment:
+/// * fuchsia.identity.account.AccountManager
+/// * fuchsia.devicesettings.DeviceSettingsManager
+///
+/// Additional services may be supplied using using
+/// `TestHarnessSpec.env_services_to_inherit` and
+/// `TestHarnessSpec.injected_services`. Additional services override the
+/// default services listed above.
+table TestHarnessSpec {
+ /// Configuration for basemgr. See `fuchsia.modular.session.BasemgrConfig`
+ /// for a description of the defaults.
+ ///
+ /// The test harness will amend `basemgr_config` before passing it off to
+ /// the modular runtime in the following way:
+ /// * If `basemgr_config.base_shell.app_config.url` is not set, the test
+ /// harness will use a base shell which automatically logs into the
+ /// session.
+ /// * If `basemgr_config.session_shell_map[0].config.app_config.url` is not
+ /// set, the test harness will use a shell which automatically starts new
+ /// stories.
+ /// * If `basemgr_config.story_shell.app_config.url` is not set, the test
+ /// harness use a minimally functioning story shell which displays all
+ /// mods in a story.
+ ///
+ /// To intercept and mock the shells, users may provide fake URLs for the
+ /// shells and specify that the fake URL be intercepted using
+ /// `components_to_intercept`.
+ 1: fuchsia.modular.session.BasemgrConfig basemgr_config;
+
+ /// Configuration for sessionmgr. See
+ /// `fuchsia.modular.session.SessionmgrConfig` for a description of the
+ /// defaults.
+ 2: fuchsia.modular.session.SessionmgrConfig sessionmgr_config;
+
+ /// List of component URLs (and additional .cmx contents) to intercept.
+ 4: vector<InterceptSpec> components_to_intercept;
+
+ /// Options to configure the test harness environment. Use this to inject
+ /// services into the environment.
+ ///
+ /// Optional.
+ 6: EnvironmentServicesSpec env_services;
+
+ /// Suffix to the environment name.
+ /// The default environment name is 'mth_{random number from 0 to 99999}'.
+ /// When provided, the environment_suffix additionally appends a '_' and
+ /// the string to the end of the environment name. The overall name gets
+ /// truncated at 32 characters.
+ ///
+ /// Optional.
+ 7: string environment_suffix;
+
+ /// DEPRECATED. Use `env_services.service_dir` to pass through services from
+ /// parent environment.
+ 3: vector<string> env_services_to_inherit;
+
+ 5: reserved;
+};
+
+/// Options for configuring the test harness environment with services.
+///
+/// If the same service is provided in more than one place, `TestHarness`
+/// connection is closed with a `ZX_ERR_ALREADY_EXISTS` epitaph.
+table EnvironmentServicesSpec {
+ /// A directory of services to be provided to the test harness environment.
+ ///
+ /// Optional.
+ 1: handle<channel> service_dir;
+
+ /// A list of services provided by components to inject into the test
+ /// harness environment. Multiple services may be provided by the same
+ /// component, but only one instance of the component is launched to serve
+ /// its services. Components are started when one of their services is
+ /// requested, and are kept alive for the duration of the test harness
+ /// environment's life.
+ ///
+ /// Optional.
+ 2: vector<ComponentService> services_from_components;
+};
+
+/// Describes a service to be provided by a component instance.
+struct ComponentService {
+ /// Name of the service.
+ string name;
+
+ /// URL of the component which will provide the service.
+ /// The service is retrieved from this component's /out/svc namespace.
+ fuchsia.sys.component_url url;
+};
+
+/// Describes a component to intercept. Malformed parameters result in closing
+/// `TestHarness` with a `ZX_ERR_INVALID_ARGS` epitaph.
+table InterceptSpec {
+ /// Required. Must be a valid component URL (e.g., fuchsia-pkg://..), or is
+ /// considered malformed.
+ 1: fuchsia.sys.component_url component_url;
+
+ /// The .cmx contents of this component's manifest. A minimal manifest is
+ /// constructed by default. If set, the contents of `extra_cmx_contents`
+ /// override the default constructed manifest, which only has the required
+ /// "program.binary" field defined.
+ ///
+ /// `extra_cmx_contents` must be a valid .cmx JSON. Example:
+ ///
+ /// {
+ /// "sandbox": {
+ /// "services": [
+ /// "fuchsia.sys.Launcher",
+ /// ]
+ /// }
+ /// }
+ 2: fuchsia.mem.Buffer extra_cmx_contents;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.modular/BUILD.gn
new file mode 100644
index 0000000..dca9a11
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/BUILD.gn
@@ -0,0 +1,62 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.modular") {
+ library_name = "modular"
+ namespace = "fuchsia"
+ public_deps = [
+ "../fuchsia.auth",
+ "../fuchsia.mem",
+ "../fuchsia.modular.auth",
+ "../fuchsia.sys",
+ "../fuchsia.ui.policy",
+ "../fuchsia.ui.views",
+ ]
+ sources = [
+ "agent/agent.fidl",
+ "agent/agent_context.fidl",
+ "agent/agent_controller/agent_controller.fidl",
+ "annotation/annotation.fidl",
+ "basemgr/base_shell.fidl",
+ "basemgr/user_provider.fidl",
+ "component/component_context.fidl",
+ "config/config.fidl",
+ "intent/intent.fidl",
+ "lifecycle/lifecycle.fidl",
+ "module/link_path.fidl",
+ "module/module_context.fidl",
+ "module/module_controller.fidl",
+ "module/module_data.fidl",
+ "module/module_manifest.fidl",
+ "module/module_state.fidl",
+ "session/focus.fidl",
+ "session/session_restart_controller.fidl",
+ "session/session_shell.fidl",
+ "story/create_link.fidl",
+ "story/create_module_parameter_map.fidl",
+ "story/puppet_master.fidl",
+ "story/story_command.fidl",
+ "story/story_controller.fidl",
+ "story/story_info.fidl",
+ "story/story_options.fidl",
+ "story/story_provider.fidl",
+ "story/story_shell.fidl",
+ "story/story_shell_factory.fidl",
+ "story/story_state.fidl",
+ "story/story_visibility_state.fidl",
+ "surface/surface.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.modular",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/agent/agent.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/agent/agent.fidl
new file mode 100644
index 0000000..6e2e6b7
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/agent/agent.fidl
@@ -0,0 +1,61 @@
+// Copyright 2017 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.
+
+library fuchsia.modular;
+
+using fuchsia.sys;
+
+/// An agent is a component whose lifecycle is not tied to any Story.
+///
+/// - An agent is a singleton instance.
+/// - Components can connect to an Agent using the
+/// fuchsia.modular.ComponentContext capability.
+/// - An agent vends services to components that connect to it over a
+/// ServiceProvider.
+/// - An agent is started when someone wants to connect to it, or when a task it
+/// has scheduled has triggered.
+///
+/// This FIDL interface should be implemented by a component that is meant to be
+/// run as an Agent.
+///
+/// When an agent application implements the `Lifecycle` interface, it can
+/// receive a signal for when it should stop. An agent may be stopped for the
+/// following reasons:
+///
+/// (1) All `AgentController` connections associated with this agent are closed.
+///
+/// (2) The system wants to optimize for resources.
+///
+/// Once the framework delivers a `Lifecycle.Terminate()`, the agent application
+/// may exit itself, or is killed by framework after a timeout.
+///
+/// For more info see:
+/// - fuchsia.modular.AgentContext and fuchsia.modular.ComponentContext for
+/// capabilities an agent has.
+/// - fuchsia.modular.Lifecycle for how Components get lifecycle events.
+[Discoverable] // Created by each agent.
+protocol Agent {
+ /// Called when some component tries to connect to this agent. `requestor_url`
+ /// identifies the requesting client. Different client roles are identified differently:
+ /// * For Module clients in the general case, `requestor_url` will be the name provided at
+ /// Module create time (ie, in calls to StoryPuppetMaster's StoryCommand.AddMod/mod_name)
+ /// with :'s escaped (see below for a complete explanation).
+ /// * For all other clients (Agents and Shells), `requestor_url` is set to the requesting
+ /// component's URL.
+ ///
+ /// `services` must be connected to an implementation of fuchsia.sys.ServiceProvider offering
+ /// services specific to the requesting client.
+ ///
+ /// Details on module naming: modules are named hierarchically based on what client created
+ /// them. This is called a module path. If created by 1) an agent or 2) an existing module, the
+ /// path is constructed differently.
+ ///
+ /// In the case of (2), the module path is the concatenation of the existing module's path with
+ /// the new module's name, as provided by the parent module. In the case of (1), the module
+ /// path is the concatenation of StoryCommand.AddMod/mod_name and
+ /// StoryCommand.AddMod/surface_relation_parent.
+ ///
+ /// The full path is encoded into `requestor_url` as escape_colons(module_path).join(':').
+ Connect(string requestor_url, request<fuchsia.sys.ServiceProvider> services);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/agent/agent_context.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/agent/agent_context.fidl
new file mode 100644
index 0000000..13e3a99
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/agent/agent_context.fidl
@@ -0,0 +1,18 @@
+// Copyright 2017 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.
+
+library fuchsia.modular;
+
+using fuchsia.auth;
+
+/// An instance of this service is exposed to agents in their namespace.
+[Discoverable]
+protocol AgentContext {
+ /// DEPRECATED: ComponentContext is now available in the
+ /// namespace/environment for Modules.
+ GetComponentContext(request<ComponentContext> request);
+
+ /// The auth token manager this Agent may use for accessing external services.
+ GetTokenManager(request<fuchsia.auth.TokenManager> request);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/agent/agent_controller/agent_controller.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/agent/agent_controller/agent_controller.fidl
new file mode 100644
index 0000000..9da4a50
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/agent/agent_controller/agent_controller.fidl
@@ -0,0 +1,13 @@
+// Copyright 2017 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.
+
+library fuchsia.modular;
+
+/// This interface is used by the caller of ComponentContext::ConnectToAgent() to
+/// tell the framework that it is still interested in keeping this Agent running.
+///
+/// The system counts AgentController connections and terminates this Agent if
+/// the count goes to zero.
+protocol AgentController {
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/annotation/annotation.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/annotation/annotation.fidl
new file mode 100644
index 0000000..c9f56c8
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/annotation/annotation.fidl
@@ -0,0 +1,73 @@
+// 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.
+
+library fuchsia.modular;
+
+using fuchsia.mem;
+
+/// A user-defined annotation for a story or module.
+struct Annotation {
+ /// An identfier for this annotation.
+ AnnotationKey key;
+
+ /// The contents of this annotation.
+ AnnotationValue? value;
+};
+
+/// Maximum number of annotations on a single story.
+const uint32 MAX_ANNOTATIONS_PER_STORY = 100;
+
+/// Maximum number of annotations on a single module.
+const uint32 MAX_ANNOTATIONS_PER_MODULE = 100;
+
+/// Maximum number of annotations that can be passed to either method
+/// Annotate() AnnotateModule() in fuchsia.modular protocols that support
+/// annotations.
+const uint32 MAX_ANNOTATIONS_PER_UPDATE = 50;
+
+/// Maximum length of [`fuchsia.modular/AnnotationKey`].
+const uint32 MAX_ANNOTATION_KEY_LENGTH = 256;
+
+/// Maximum length of [`fuchsia.modular/AnnotationValue`] fields:
+/// `text` and `bytes`.
+const uint32 MAX_ANNOTATION_VALUE_LENGTH = 1024;
+
+/// Maximum length of the [`fuchsia.modular/AnnotationValue.buffer`] field, in
+/// bytes.
+///
+/// Does not apply to other fields; see [`MAX_ANNOTATION_VALUE_LENGTH`].
+const uint32 MAX_ANNOTATION_VALUE_BUFFER_LENGTH_BYTES = 102400;
+
+/// An identifier for an [`fuchsia.modular/Annotation`].
+using AnnotationKey = string:MAX_ANNOTATION_KEY_LENGTH;
+
+/// The value of a [`fuchsia.modular/Annotation`].
+///
+/// The actual field used depends on the type of annotation, which is
+/// user-defined, and not enforced by the framework.
+///
+/// The size of `buffer` is limited to
+/// `MAX_ANNOTATION_VALUE_BUFFER_LENGTH_BYTES` bytes.
+flexible union AnnotationValue {
+ 1: string:MAX_ANNOTATION_VALUE_LENGTH text;
+ 2: vector<uint8>:MAX_ANNOTATION_VALUE_LENGTH bytes;
+ 3: fuchsia.mem.Buffer buffer;
+};
+
+/// Error returned from calls to Annotate().
+enum AnnotationError {
+ /// The `AnnotationValue.buffer` size exceeds the maximum length,
+ /// `MAX_ANNOTATION_VALUE_BUFFER_LENGTH_BYTES`.
+ VALUE_TOO_BIG = 1;
+
+ /// The total number of annotations on the story or module being annotated
+ /// exceeds `MAX_ANNOTATIONS_PER_STORY` or `MAX_ANNOTATIONS_PER_MODULE`.
+ TOO_MANY_ANNOTATIONS = 2;
+
+ /// The resource to be annotated was not found and could not be resolved
+ /// by, for example, waiting, or creating the missing resource automatically.
+ /// This error may be returned by StoryPuppetMaster.AnnotateModule(), which
+ /// can wait for a missing Module, but requires the Module's Story exist.
+ NOT_FOUND = 3;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/basemgr/base_shell.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/basemgr/base_shell.fidl
new file mode 100644
index 0000000..b77cf24
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/basemgr/base_shell.fidl
@@ -0,0 +1,45 @@
+// Copyright 2016 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.
+
+library fuchsia.modular;
+
+using fuchsia.auth;
+using fuchsia.ui.policy;
+
+/// This interface is implemented by a base shell. Dependencies are passed to it
+/// in Initialize() on startup. The base shell is also expected to implement
+/// Lifecycle in order to receive a Terminate() call on teardown.
+///
+/// In one component instance there can only be one BaseShell service instance.
+/// The ViewOwner request is sent to the separate ViewProvider service. This way,
+/// the base shell may be implemented as a flutter component.
+[Discoverable]
+protocol BaseShell {
+ Initialize(BaseShellContext base_shell_context,
+ BaseShellParams base_shell_params);
+
+ /// This method may be invoked by the basemgr to request an
+ /// AuthenticationUIContext. `request` will then be used to request the base
+ /// shell to show login screen during a UserProvider.AddUser() or if a token
+ /// needs to be refreshed.
+ GetAuthenticationUIContext(request<fuchsia.auth.AuthenticationUIContext> request);
+};
+
+/// This interface allows the `BaseShell` to request capabilities from the
+/// `Basemgr` in a way that is more explicit about the services that are
+/// offered than a generic `ServiceProvider`.
+protocol BaseShellContext {
+ /// Acquires the user provider service, which is used to add/remove/list and
+ /// authenticate users.
+ GetUserProvider(request<UserProvider> request);
+
+ /// Acquires the presentation service, which is assumed to already be
+ /// connected to the presenter.
+ GetPresentation(request<fuchsia.ui.policy.Presentation> presentation);
+};
+
+// TODO(alexmin): Delete BaseShellParams here and from BaseShell.Initialize().
+struct BaseShellParams {
+ fuchsia.ui.policy.Presentation? presentation;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/basemgr/user_provider.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/basemgr/user_provider.fidl
new file mode 100644
index 0000000..3882eae
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/basemgr/user_provider.fidl
@@ -0,0 +1,59 @@
+// Copyright 2016 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.
+
+library fuchsia.modular;
+
+using fuchsia.modular.auth;
+
+/// Given by the `Basemgr` to the `BaseShell` at Initialize() so the
+/// `BaseShell` can get information about the users of this device from the
+/// `Basemgr`, and act on the provided information (including extending the
+/// user database).
+protocol UserProvider {
+ /// Adds information of a user that can be used to authenticate her/him to this
+ /// device. Once successfully added, the user can login to the same device via
+ /// Login().
+ ///
+ /// `identity_provider` is the identity provider to use for identification.
+ ///
+ /// `device_name` is what the user wants to name the device. If null or empty
+ /// the device's current hostname will be used.
+ ///
+ /// `account` is NULL if there was an error during identification and
+ /// `error_code` is set.
+ AddUser(fuchsia.modular.auth.IdentityProvider identity_provider)
+ -> (fuchsia.modular.auth.Account? account, string? error_code);
+
+ /// Removes information of a user from the local user database.
+ ///
+ /// `account_id` is received from either AddUser() or PreviousUsers().
+ RemoveUser(string account_id) -> (string? error_code);
+
+ /// Uses the credentials provided in AddUser() to start a user session. This
+ /// would mean syncing with the user's ledger instance and displaying a user
+ /// shell with all of the user's stories.
+ // TODO(alhaad): In the future, we want to protect Login() with a password,
+ // Android lock pattern, etc.
+ Login(UserLoginParams user_login_params);
+ /// DEPRECATED: For transitional purposes only.
+ [Transitional]
+ Login2(UserLoginParams2 user_login_params);
+
+ /// List of all users who have authenticated to this device in the past.
+ PreviousUsers() -> (vector<fuchsia.modular.auth.Account> accounts);
+};
+
+/// Used to specify arguments to log into a user session.
+struct UserLoginParams {
+ /// `account_id` is received from either AddUser() or PreviousUsers(). It
+ /// can be NULL which means logging-in using incognito mode.
+ string? account_id;
+};
+
+/// DEPRECATED, for backwards compatibility only
+struct UserLoginParams2 {
+ /// `account_id` is received from either AddUser() or PreviousUsers(). It
+ /// can be NULL which means logging-in in an incognito mode.
+ string? account_id;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/component/component_context.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/component/component_context.fidl
new file mode 100644
index 0000000..087312b
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/component/component_context.fidl
@@ -0,0 +1,58 @@
+// Copyright 2017 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.
+
+library fuchsia.modular;
+
+using fuchsia.sys;
+
+/// Provided to all component instances in their respective initialization
+/// information by the framework. For example, a Module gets it from its
+/// ModuleContext and an Agent gets it from its AgentContext.
+[Discoverable]
+protocol ComponentContext {
+ /// DEPRECATED: use the component's incoming namespace (for C++, see sys.ComponentContext)
+ /// to connect to services provided by agents. See
+ /// /docs/concepts/modular/guide/how_to_write_an_agent_cc.md for an example.
+ ///
+ /// Used to start an agent in the user scope if it isn't already running, and
+ /// connect to it.
+ ConnectToAgent(string url,
+ request<fuchsia.sys.ServiceProvider> incoming_services,
+ request<AgentController> controller);
+
+ /// DEPRECATED: use the component's incoming namespace (for C++, see sys.ComponentContext)
+ /// to connect to services provided by agents. See
+ /// /docs/concepts/modular/guide/how_to_write_an_agent_cc.md for an example.
+ ///
+ /// Connects to an agent that provides the given `request.service_name`, and
+ /// then connects the given `request.channel` to that service.
+ /// `request.agent_controller` must be kept alive until the service is no
+ /// longer required.
+ ///
+ /// If an error is encountered, the `request.channel` will be closed with
+ /// a status code, such as:
+ /// * `ZX_ERR_NOT_FOUND` -- if a `request.handler` agent URL is not
+ /// specified, and an agent for the `request.service_name` is not found
+ /// * `ZX_ERR_PEER_CLOSED` -- if `request.service_name` is not available from
+ /// the agent (either specified or discovered)
+ [Transitional]
+ ConnectToAgentService(AgentServiceRequest request);
+};
+
+/// Used by ComponentContext.ConnectToAgentService
+table AgentServiceRequest {
+ /// The name of the requested service.
+ 1: string service_name;
+
+ /// The channel that will be used to communicate with the requested service.
+ 2: handle<channel> channel;
+
+ /// The component URL of the Agent that is to provide the specified service.
+ /// If no handler is specified, the framework will perform resolution to
+ /// find an appropriate handler.
+ 3: fuchsia.sys.component_url handler;
+
+ /// The AgentController that keeps the agent alive.
+ 4: request<AgentController> agent_controller;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/config/config.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/config/config.fidl
new file mode 100644
index 0000000..7339d4c
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/config/config.fidl
@@ -0,0 +1,12 @@
+// Copyright 2017 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.
+
+library fuchsia.modular;
+
+/// Used to pass around configuration references to apps such as user
+/// shell, base shell, story shell.
+struct AppConfig {
+ string url;
+ vector<string>? args;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/intent/intent.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/intent/intent.fidl
new file mode 100644
index 0000000..4355013
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/intent/intent.fidl
@@ -0,0 +1,63 @@
+// Copyright 2017 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.
+
+library fuchsia.modular;
+
+using fuchsia.mem;
+
+/// The Intent struct is a runtime descriptor for an abstract action to be initiated
+/// in Fuchsia. For details please see docs/intent.md.
+struct Intent {
+ /// The name of the action represented by this Intent.
+ ///
+ /// This is nullable for backwards compatibility.
+ // TODO(MI4-1100): Make action non-nullable.
+ string? action;
+
+ /// An explicit handler for the Intent. Specified as the component URL of the
+ /// module.
+ string? handler;
+
+ /// NON-FUNCTIONAL: `parameters` is no longer supported but must remain for ABI compatibility.
+ vector<IntentParameter>? parameters;
+};
+
+/// NON-FUNCTIONAL: `IntentParameter` is no longer supported but must remain for ABI compatibility.
+/// A struct representing a parameter that is passed to the handler of an Intent's
+/// Action.
+struct IntentParameter {
+ /// The name of the parameter. The handler (i.e. selected mod) will be provided
+ /// with the data for this parameter under a link called `name`.
+ string? name;
+
+ /// The data that will be passed to the intent handler.
+ IntentParameterData data;
+};
+
+/// NON-FUNCTIONAL: `IntentParameterData` is no longer supported but must remain defined for
+/// `IntentParameter`'s ABI compatibility.
+union IntentParameterData {
+ /// Set this if you already have an Entity reference at runtime.
+ /// Entity.getTypes() will be used to set the constraints for this noun during
+ /// resolution.
+ 1: string entity_reference;
+
+ /// Set this if you have structured JSON data. Values typically are a JSON
+ /// object with a "@type" attribute and other associated data. TODO(thatguy):
+ /// We need to decide if we want to keep this in place, or deprecate this
+ /// eventually and move entirely to using Entity references.
+ ///
+ /// DEPRECATED: Use `entity_reference`.
+ 2: fuchsia.mem.Buffer json;
+
+ /// Set this if you want to explicitly define this noun's allowed types. This
+ /// is also useful in the cases where the noun has a 'direction' of type
+ /// 'output', and you wish to set the allowable output types from the Module
+ /// (see docs/modular/manifests/action_template.md for a definition of
+ /// 'direction').
+ ///
+ /// Only one entry in `entity_type` must match the constraint specified by
+ /// the Module for the constraint to be considered satisfied.
+ 3: vector<string> entity_type;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/lifecycle/lifecycle.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/lifecycle/lifecycle.fidl
new file mode 100644
index 0000000..9240382
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/lifecycle/lifecycle.fidl
@@ -0,0 +1,16 @@
+// Copyright 2017 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.
+
+library fuchsia.modular;
+
+/// An interface implemented by applications that wish to terminate gracefully.
+[Discoverable]
+protocol Lifecycle {
+ /// The client of this application has requested that this application
+ /// terminate gracefully.
+ ///
+ /// If the application does not terminate itself in a timely manner, the client
+ /// may forcibly terminate the application.
+ Terminate();
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.modular/meta.json
new file mode 100644
index 0000000..d591a6f
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/meta.json
@@ -0,0 +1,47 @@
+{
+ "deps": [
+ "fuchsia.auth",
+ "fuchsia.modular.auth",
+ "fuchsia.sys",
+ "fuchsia.ui.policy",
+ "fuchsia.ui.views",
+ "fuchsia.mem"
+ ],
+ "name": "fuchsia.modular",
+ "root": "fidl/fuchsia.modular",
+ "sources": [
+ "fidl/fuchsia.modular/agent/agent.fidl",
+ "fidl/fuchsia.modular/agent/agent_context.fidl",
+ "fidl/fuchsia.modular/agent/agent_controller/agent_controller.fidl",
+ "fidl/fuchsia.modular/annotation/annotation.fidl",
+ "fidl/fuchsia.modular/basemgr/base_shell.fidl",
+ "fidl/fuchsia.modular/basemgr/user_provider.fidl",
+ "fidl/fuchsia.modular/component/component_context.fidl",
+ "fidl/fuchsia.modular/config/config.fidl",
+ "fidl/fuchsia.modular/intent/intent.fidl",
+ "fidl/fuchsia.modular/lifecycle/lifecycle.fidl",
+ "fidl/fuchsia.modular/module/link_path.fidl",
+ "fidl/fuchsia.modular/module/module_context.fidl",
+ "fidl/fuchsia.modular/module/module_controller.fidl",
+ "fidl/fuchsia.modular/module/module_data.fidl",
+ "fidl/fuchsia.modular/module/module_manifest.fidl",
+ "fidl/fuchsia.modular/module/module_state.fidl",
+ "fidl/fuchsia.modular/session/focus.fidl",
+ "fidl/fuchsia.modular/session/session_restart_controller.fidl",
+ "fidl/fuchsia.modular/session/session_shell.fidl",
+ "fidl/fuchsia.modular/story/create_link.fidl",
+ "fidl/fuchsia.modular/story/create_module_parameter_map.fidl",
+ "fidl/fuchsia.modular/story/puppet_master.fidl",
+ "fidl/fuchsia.modular/story/story_command.fidl",
+ "fidl/fuchsia.modular/story/story_controller.fidl",
+ "fidl/fuchsia.modular/story/story_info.fidl",
+ "fidl/fuchsia.modular/story/story_options.fidl",
+ "fidl/fuchsia.modular/story/story_provider.fidl",
+ "fidl/fuchsia.modular/story/story_shell.fidl",
+ "fidl/fuchsia.modular/story/story_shell_factory.fidl",
+ "fidl/fuchsia.modular/story/story_state.fidl",
+ "fidl/fuchsia.modular/story/story_visibility_state.fidl",
+ "fidl/fuchsia.modular/surface/surface.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/module/link_path.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/module/link_path.fidl
new file mode 100644
index 0000000..24510d9
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/module/link_path.fidl
@@ -0,0 +1,15 @@
+// Copyright 2017 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.
+
+library fuchsia.modular;
+
+/// Addresses a Link within a story. A LinkPath struct should be treated as an
+/// opaque unique identifier of a link instance. The `module_path` and
+/// `link_name` components are leftovers from legacy code and have no external
+/// meaning.
+/// TODO(thatguy,lindkvist): Replace this structure with a vector<>. MI4-1021
+struct LinkPath {
+ vector<string> module_path;
+ string? link_name;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/module/module_context.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/module/module_context.fidl
new file mode 100644
index 0000000..de94303
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/module/module_context.fidl
@@ -0,0 +1,64 @@
+// Copyright 2016 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.
+
+library fuchsia.modular;
+
+using fuchsia.ui.views;
+
+/// This interface is exposed to all Module instances in a story. It allows to
+/// create Link instances and run more Module instances.
+[Discoverable]
+protocol ModuleContext {
+ /// Starts a new Module instance and adds it to the story. The Module to
+ /// execute is identified by the contents of [intent] and the Module instance
+ /// is given a [name] in the scope of the starting Module instance. The view
+ /// for the Module is given to the story shell for display.
+ ///
+ /// Providing a [surface_relation] advises the StoryShell how to layout
+ /// surfaces that the new module creates. If [surface_relation] is null then
+ /// a default relation is used.
+ ///
+ /// If the method is called again with the same [name] by the same Module
+ /// instance, but with different arguments, the existing Module instance is
+ /// restarted with the changed arguments. If the other arguments don't
+ /// change, just an additional ModuleController connection is made.
+ AddModuleToStory(string name, Intent intent,
+ request<ModuleController> module_controller,
+ SurfaceRelation? surface_relation)
+ -> (StartModuleStatus status);
+
+ /// Like AddModuleToStory(), but passes a [view_token] explicitly to embed
+ /// the view of the requested Module instance in the view of the requesting
+ /// Module instance, instead of relying on the story shell for display. If a
+ /// Module instance with the same [name] and [intent] is already running,
+ /// [view_token] is destroyed.
+ [Transitional]
+ EmbedModule(string name, Intent intent,
+ request<ModuleController> module_controller,
+ fuchsia.ui.views.ViewToken view_token)
+ -> (StartModuleStatus status);
+
+ /// When a module calls [RemoveSelfFromStory()] the framework will stop the
+ /// module and remove it from the story. If there are no more running modules
+ /// in the story the story will be deleted.
+ RemoveSelfFromStory();
+};
+
+/// Communicates the status of an Intent to a Module.
+enum StartModuleStatus {
+ SUCCESS = 0;
+ NO_MODULES_FOUND = 1;
+};
+
+/// This interface defines the protocol over which a Module can communicate about
+/// an ongoing activity to the framework. It is provided to Modules via
+/// ModuleContext.StartOngoingActivity().
+protocol OngoingActivity {
+};
+
+enum OngoingActivityType {
+ UNSPECIFIED = 0;
+ VIDEO = 1;
+ AUDIO = 2;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/module/module_controller.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/module/module_controller.fidl
new file mode 100644
index 0000000..4c087c4
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/module/module_controller.fidl
@@ -0,0 +1,30 @@
+// Copyright 2016 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.
+
+library fuchsia.modular;
+
+/// This interface is used by the caller of ModuleContext.StartModule() to
+/// control the started Module instance.
+///
+/// Closing this connection doesn't affect its Module instance; it just
+/// relinquishes the ability of the caller to control the Module instance.
+protocol ModuleController {
+ /// Requests that this module become the focused module in the story.
+ Focus();
+
+ /// Requests that this module be hidden in the story.
+ Defocus();
+
+ /// Requests the Module instance to stop. The running Module component's
+ /// Lifecycle::Terminate() method is called, the instance is shut down and
+ /// state within the framework is cleaned up.
+ ///
+ /// The result callback is called once the Module's runtime has been torn down.
+ Stop() -> ();
+
+ /// Called with the current state when it changes.
+ /// DEPRECATED: Do not use this. ModuleState is a framework-internal concept
+ /// and should not be exposed outside.
+ -> OnStateChange(ModuleState new_state);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/module/module_data.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/module/module_data.fidl
new file mode 100644
index 0000000..3f52fad
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/module/module_data.fidl
@@ -0,0 +1,76 @@
+// Copyright 2017 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.
+
+library fuchsia.modular;
+
+/// Information about a Module instance in a story.
+table ModuleData {
+ /// The URL of the Module binary.
+ 1: string module_url;
+
+ /// The named path leading up to this Module instance. The last name in this
+ /// array is the name by which the Module was started by the parent Module
+ /// instance calling StartModule().
+ 2: vector<string> module_path;
+
+ /// Contains the mapping of Mod parameter name to Link instances for this mod.
+ 3: ModuleParameterMap parameter_map;
+
+ /// The way in which this Module instance was first started in the story,
+ /// either by request from another Module instance (INTERNAL) or by request
+ /// from outside the story (i.e. by suggestion from an agent - EXTERNAL).
+ 4: ModuleSource module_source;
+
+ /// The `surface_relation` that was used to start this Module instance with.
+ /// The same is used when re-inflating the Module instance when the story is
+ /// resumed. A SurfaceRelation value of null represents an embedded Module
+ /// instance (started by EmbedModule()) that is not managed by the story shell.
+ 5: SurfaceRelation surface_relation;
+
+ /// True if this module was removed from its story either through
+ /// ModuleController.Stop() or ModuleContext.RemoveSelfFromStory().
+ 6: bool module_deleted;
+
+ /// The intent that was issued to start add this Module instance to the story.
+ /// Some Module instances may have been added not by an Intent, for example as
+ /// the initial module of a story. For those the field may be null.
+ ///
+ /// TODO(thatguy,mesch): This field should now always be set, so make it
+ /// required once the framework is cleaned up enough to guarantee this
+ /// statement.
+ 7: Intent intent;
+
+ /// If true, this module was started by a parent module using
+ /// ModuleContext.EmbedModule(), and its view is not managed by the
+ /// StoryShell.
+ 8: bool is_embedded;
+
+ /// Collection of user-defined key-value attributes that describe this surface (module).
+ ///
+ /// The `Annotation.value` field of each `Annotation` is always set.
+ 9: vector<Annotation>:MAX_ANNOTATIONS_PER_MODULE annotations;
+};
+
+enum ModuleSource {
+ /// Module that was added to the story from within the story by another
+ /// module using ModuleContext.AddModuleToStory() or
+ /// ModuleContext.EmbedModule().
+ INTERNAL = 0;
+
+ /// Module that was added to the story from outside the story using
+ /// PuppetMaster.
+ EXTERNAL = 1;
+};
+
+struct ModuleParameterMap {
+ vector<ModuleParameterMapEntry> entries;
+};
+
+struct ModuleParameterMapEntry {
+ /// A null [name] is allowed for backwards compatibility with default links.
+ /// TODO(thatguy); When no modules use null link names any more, make this
+ /// required.
+ string? name;
+ LinkPath link_path;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/module/module_manifest.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/module/module_manifest.fidl
new file mode 100644
index 0000000..208e8a1
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/module/module_manifest.fidl
@@ -0,0 +1,84 @@
+// Copyright 2018 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.
+
+library fuchsia.modular;
+
+/// Metadata that define the runtime properties of a Module.
+struct ModuleManifest {
+ /// The relative path from the root of the package where the Module executable
+ /// file can be found.
+ /// TODO(MF-94): Extract a module's URL from its cmx manifest instead of
+ /// here.
+ string binary;
+
+ /// A human-readable string that can be used when suggesting this Module.
+ /// DEPRECATED.
+ string? suggestion_headline;
+
+ /// A list of intents that this module is able to handle.
+ vector<IntentFilter>? intent_filters;
+
+ /// Identifies the pattern with which to compose this module with others.
+ string? composition_pattern;
+
+ /// Defines the color of the placeholder widget used while the module loads.
+ string? placeholder_color;
+};
+
+/// This struct is used to describe an intent that a module is able to handle.
+struct IntentFilter {
+ /// The action this module is able to handle.
+ string action;
+
+ /// Includes the name and types of entities for the parameters required to
+ /// execute specified [action].
+ vector<ParameterConstraint> parameter_constraints;
+
+ /// Defines presentation properties for suggestions of this action.
+ ActionDisplay action_display;
+};
+
+struct ParameterConstraint {
+ string name;
+ /// The entity type that is valid for this parameter.
+ string type;
+};
+
+/// Defines how a suggestion of an action will be presented.
+table ActionDisplay {
+ /// Defines presentation fields for a suggestion. The string fields might be
+ /// templated and will be filled from data in `parameter_mapping`.
+ /// For example: "Listen to $artistName"
+ 1: DisplayInfo display_info;
+
+ /// Fields to be replaced in the given `display_info` templated strings.
+ /// In the example above, we would map name=artistName to the intent field
+ /// artist.name where artist is the intent parameter name and name a field
+ /// of it.
+ 2: vector<ParameterMapping> parameter_mapping;
+};
+
+/// Presentation information about the suggestion.
+table DisplayInfo {
+ /// The title of the suggestion.
+ 1: string title;
+
+ /// A subtitle for the suggestion.
+ 2: string subtitle;
+
+ /// A url from which to fetch the icon of the suggestion.
+ 3: string icon;
+};
+
+/// Defines pairs that will be replaced in the DisplayInfo.
+table ParameterMapping {
+ /// The name of the variable to be replaced in the template.
+ 1: string name;
+
+ /// The path in the intent parameter to get that name.
+ /// `PARAMETER_PROPERTY` = string | string . `PARAMETER_PROPERTY`
+ /// The first string in the dot-separated string is the name of the intent
+ /// parameter and the following are nested subfields.
+ 2: string parameter_property;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/module/module_state.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/module/module_state.fidl
new file mode 100644
index 0000000..f2934c9
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/module/module_state.fidl
@@ -0,0 +1,30 @@
+// Copyright 2017 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.
+
+library fuchsia.modular;
+
+/// State used to notify about state transitions of a Module
+/// instance. This is very similar to the StoryState, however it's not entirely
+/// the same and hence a separate type. A module cannot have an INITIAL state,
+/// because it's started as soon as it is created, and it gets deleted as soon as
+/// it reaches the STOPPED state, whileas a story can be restarted.
+///
+/// Currently possible state transitions (and the events that cause
+/// them) are:
+///
+/// -> RUNNING ModuleContext.AddModuleToStory() or
+/// ModuleContext.EmbedModule() or
+/// StoryController.AddModule()
+/// RUNNING -> STOPPED ModuleController.Stop() or StoryController.Stop()
+/// RUNNING -> ERROR application exits
+enum ModuleState {
+ /// Module instance was created.
+ RUNNING = 2;
+ /// Module instance is stopped after Module.Stop(). No further transitions are
+ /// to be expected.
+ STOPPED = 4;
+ /// Connection to the Module instance was closed without Stop() request. No
+ /// further transitions are to be expected.
+ ERROR = 5;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/session/focus.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/session/focus.fidl
new file mode 100644
index 0000000..e883d8e
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/session/focus.fidl
@@ -0,0 +1,72 @@
+// Copyright 2016 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.
+library fuchsia.modular;
+
+/// This file has interfaces for 2 pieces of information: (1) The story
+/// that is currently in focus and (2) stories that are visible to the
+/// user. Names of interfaces follow the usual patterns:
+///
+/// {Focus,VisibleStories}Controller is used by session shell to update
+/// information whenever changes take place.
+///
+/// FocusProvider is used by session shell to
+/// query and get updates on which story is in focus on which device
+/// and visible stories on this device.
+///
+/// Implemented by sessionmgr. Given to session shell through its namespace.
+// NOTE(alhaad): The information about visible stories can be used by
+// sessionmgr to stop / pause stories that are not visible to the
+// user.
+protocol FocusController {
+ // Sets the focus on this device.
+ Set(string? focused_story_id);
+ WatchRequest(FocusRequestWatcher watcher);
+};
+
+/// Implemented by session shell. OnFocusRequest() gets called whenever there
+/// is a new request to change focus on this device. Requests can be
+/// made via FocusProvider.Request().
+protocol FocusRequestWatcher {
+ OnFocusRequest(string story_id);
+};
+
+/// Implemented by sessionmgr. Given to session shell and session agents through
+/// their namespace. Focus is persisted on the ledger.
+[Discoverable]
+protocol FocusProvider {
+ /// Returns the stories that are focused across all devices.
+ Query() -> (vector<FocusInfo> focused_stories);
+
+ /// Watches for change in focus on any of the user's devices.
+ Watch(FocusWatcher watcher);
+
+ /// Requests session shell to change focus on this device. If session shell
+ /// responds to this request, focus shall be taken away from
+ /// previously focused story and an update will be sent on
+ /// FocusWatcher.OnFocusChange(). If `story_id` is NULL, the timeline
+ /// is brought back into focus.
+ ///
+ // TODO(alhaad): Consider making this available for remote devices as
+ // well.
+ Request(string? story_id);
+};
+
+/// Implemented by anyone who is interested in getting updates when focus
+/// changes.
+protocol FocusWatcher {
+ OnFocusChange(FocusInfo? focus_info);
+};
+
+/// Specifies the focused story of a device.
+struct FocusInfo {
+ /// The id of the device.
+ string device_id;
+
+ /// The id of the focused story. If null, no stories are focused.
+ string? focused_story_id;
+
+ /// The time the focused story on the device `device_id` was last
+ /// changed. 0 if no focus has ever been set for device `device_id`.
+ uint64 last_focus_change_timestamp;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/session/session_restart_controller.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/session/session_restart_controller.fidl
new file mode 100644
index 0000000..fa889dd
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/session/session_restart_controller.fidl
@@ -0,0 +1,13 @@
+// Copyright 2020 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.
+
+library fuchsia.modular;
+
+/// A capability, typically offered from `sessionmgr` to select child components,
+/// allowing them to request the session to be restarted.
+[Discoverable]
+protocol SessionRestartController {
+ /// Requests to cleanly terminate and then immediately restart the session.
+ Restart();
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/session/session_shell.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/session/session_shell.fidl
new file mode 100644
index 0000000..31d5dd0
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/session/session_shell.fidl
@@ -0,0 +1,87 @@
+// Copyright 2016 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.
+
+library fuchsia.modular;
+
+using fuchsia.ui.policy;
+using fuchsia.ui.views;
+
+/// This interface is implemented by a session shell and is used by the
+/// sessionmgr to hand to the session shell views of stories, or to notify that
+/// the view of a story is about to be closed.
+[Discoverable]
+protocol SessionShell {
+ /// Displays the given story view. The story this view belongs to is
+ /// identified by `view_id.story_id`.
+ /// DEPRECATED. For transitional purposes only.
+ [Transitional]
+ AttachView(ViewIdentifier view_id, fuchsia.ui.views.ViewHolderToken view_holder_token);
+ [Transitional]
+ AttachView2(ViewIdentifier view_id, fuchsia.ui.views.ViewHolderToken view_holder_token);
+
+ /// Instructs the session shell to detach the view identified by `view_id`
+ /// that was previously provided by AttachView() from the UI of the session
+ /// shell. The view will be closed soon after DetachView() returns, or when a
+ /// timeout is reached.
+ ///
+ /// It is customary for the session shell to display a placeholder before a
+ /// view is attached for a given view identifier, or after it was detached.
+ ///
+ /// If the story identified by `view_id.story_id` is about to be deleted, the
+ /// Shell will observe a call to StoryProviderWatcher.OnDelete() sometime
+ /// after DetachView() returns.
+ ///
+ /// If the session for which this session shell is responsible for is being
+ /// terminated, or the session shell is stopped because it's replaced by
+ /// another session shell, DetachView() will *not* be called at all, and the
+ /// shell will rather observe a call to Lifecycle.Terminate().
+ DetachView(ViewIdentifier view_id) -> ();
+};
+
+/// Identifies a view provided to a session shell. The values of the `story_id`
+/// field match those used in the `StoryProvider` interface, allowing
+/// identification of the same story across interfaces.
+///
+/// This is a struct rather than a naked string to allow for future evolution of
+/// the identifier without changing the `SessionShell` API itself.
+struct ViewIdentifier {
+ string story_id;
+};
+
+/// This interface allows a `SessionShell` to request capabilities from its
+/// creator in a way that is more explicit about the services that are
+/// offered than a generic `ServiceProvider`.
+[Discoverable]
+protocol SessionShellContext {
+ GetComponentContext(request<ComponentContext> request);
+ GetFocusController(request<FocusController> request);
+ GetFocusProvider(request<FocusProvider> request);
+ GetPresentation(request<fuchsia.ui.policy.Presentation> request);
+ GetStoryProvider(request<StoryProvider> request);
+
+ /// Requests logout of the user. This causes the basemgr to tear down the
+ /// `Sessionmgr` instance of the user.
+ Logout();
+
+ /// Restarts the session without logging out the user.
+ Restart();
+};
+
+/// Session shell provides this service to the framework which may plumb it to
+/// different subscribers, such as story shell and intelligence provider.
+///
+/// EXPERIMENTAL Service that allows consumers of a given story to get a
+/// connection to a Presentation, and visual state services provided by the user
+/// shell. This allows story shell implementations to coordinate event and focus
+/// handling. An analog mechanism exists between BaseShell and SessionShell.
+[Discoverable] // Created by session shell components.
+protocol SessionShellPresentationProvider {
+ /// When a StoryShell calls StoryShellContext.GetPresentation(), this request
+ /// arrives here.
+ GetPresentation(string story_id, request<fuchsia.ui.policy.Presentation> request);
+
+ /// When a StoryShell calls StoryShellContext.WatchVisualState(), this request
+ /// arrives here.
+ WatchVisualState(string story_id, StoryVisualStateWatcher watcher);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/create_link.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/create_link.fidl
new file mode 100644
index 0000000..e90d03b
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/create_link.fidl
@@ -0,0 +1,27 @@
+// Copyright 2017 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.
+
+library fuchsia.modular;
+
+using fuchsia.mem;
+
+/// Defines the attributes for a Link when the Link is created.
+struct CreateLinkInfo {
+ /// Passed as root_json argument to StoryProvider.CreateStoryWithInfo()
+ /// Link.Set() to set the value in the root link of the new Story's primary
+ /// module.
+ fuchsia.mem.Buffer initial_data;
+
+ /// If `allowed_types` is null, the Link contains JSON. No schema validation
+ /// is performed.
+ LinkAllowedTypes? allowed_types;
+};
+
+struct LinkAllowedTypes {
+ /// The Link must contain an Entity (see Link.SetEntity()) that has at least
+ /// one of `allowed_entity_types` in its `Entity.GetTypes()` return value.
+ ///
+ /// If empty, allows any Entity type.
+ vector<string> allowed_entity_types;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/create_module_parameter_map.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/create_module_parameter_map.fidl
new file mode 100644
index 0000000..51fb33e
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/create_module_parameter_map.fidl
@@ -0,0 +1,23 @@
+// Copyright 2017 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.
+
+library fuchsia.modular;
+
+/// Module parameters are named pointers to link instances.
+struct CreateModuleParameterMapInfo {
+ /// Contains instructions to create each name in the parameter map.
+ vector<CreateModuleParameterMapEntry>? property_info;
+};
+
+struct CreateModuleParameterMapEntry {
+ string? key;
+ CreateModuleParameterInfo value;
+};
+
+union CreateModuleParameterInfo {
+ /// Instructs parameter map initialization to either use an existing Link
+ /// (`link_path` is set) or create a new Link (`create_link` is set).
+ 1: LinkPath link_path;
+ 2: CreateLinkInfo create_link;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/puppet_master.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/puppet_master.fidl
new file mode 100644
index 0000000..dcc02de
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/puppet_master.fidl
@@ -0,0 +1,116 @@
+// Copyright 2018 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.
+
+library fuchsia.modular;
+
+enum ExecuteStatus {
+ OK = 0;
+
+ // Encountered an invalid command.
+ INVALID_COMMAND = 1;
+
+ // The `story_id` provided does not exist or is not visible
+ // to this client.
+ INVALID_STORY_ID = 2;
+
+ // A story must contain at least one mod, and the commands given
+ // either don't add one, or remove the last one.
+ STORY_MUST_HAVE_MODS = 3;
+
+ // The mod name specified in AddMod, RemoveMod or SendModCommand
+ // was not found, or is invalid.
+ INVALID_MOD = 4;
+
+ // Resolution of the intent provided in AddMod returned zero results.
+ NO_MODULES_FOUND = 5;
+
+ // Some error happened while executing the command.
+ INTERNAL_ERROR = 6;
+};
+
+enum ConfigureStoryError : int32 {
+ /// The story cannot be (re)configured because it was already created.
+ ERR_STORY_ALREADY_CREATED = 1;
+};
+
+struct ExecuteResult {
+ ExecuteStatus status;
+ string? story_id;
+ string? error_message;
+};
+
+// Enables control of a session. A session, conceptually, is a single
+// full-screen experience of a Fuchsia device. A device can run multiple
+// sessions (ie, when one device powers multiple kiosks); that said, sessions
+// are siloed from each other.
+//
+// A session, concretely, is a collection of stories, their state, the modules
+// within them, any agents that run to support the mods and the various UI
+// shells (session and story shells).
+[Discoverable]
+protocol PuppetMaster {
+ // Requests a capability to control a story by name. The name acts as the
+ // story's unique ID. Calling ControlStory() for the same story name will
+ // control the same story.
+ //
+ // The story name, as well as modification to the story, are durable and
+ // persist across device reboots. This allows the client to assign its own
+ // identifiers to stories. Clients wishing to guarantee a new story is
+ // created should generate a UUIDv4 or similar.
+ //
+ // `request` is closed if control cannot be granted.
+ //
+ // TODO(thatguy): We want story names to be scoped to the client's namespace.
+ ControlStory(string story_name, request<StoryPuppetMaster> request);
+
+ // Deletes a story associated to `story_name`.
+ // Any active StoryPuppetMaster connections to the Story will be closed.
+ DeleteStory(string story_name) -> ();
+
+ // Returns a list of all the names of stories in the session.
+ GetStories() -> (vector<string> story_names);
+};
+
+protocol StoryPuppetMaster {
+ // Enqueues the given `commands` in the order they are given.
+ // Can be called as many times as necessary to specify the full
+ // set of changes to the story.
+ //
+ // To execute all enqueued commands, call Execute().
+ Enqueue(vector<StoryCommand> commands);
+
+ // Executes the commands enqueued so far by Enqueue() in order and as
+ // a batch: no other commands from other clients will be interleaved.
+ //
+ // If an error occurs, execution is stopped and an error code
+ // and message are returned in `result`.
+ Execute() -> (ExecuteResult result);
+
+ // Set the `StoryInfo` extra field for a story that is to be
+ // created. This should be called before the first call to Execute().
+ // Any subsequent calls (either on the same channel or on a new
+ // StoryPuppetMaster for an existing story) are ignored.
+ // See story_info.fidl for details.
+ //
+ // DEPRECATED. This method is a no-op and will never return an error.
+ [Transitional = "Deprecated, no-op"]
+ SetStoryInfoExtra(vector<StoryInfoExtraEntry> story_info_extra)
+ -> () error ConfigureStoryError;
+
+ /// Attach the `annotations` to the story. If the story does not yet exist,
+ /// it will be created.
+ ///
+ /// Existing annotations with the same key will be overwritten, or
+ /// deleted if new value is null.
+ Annotate(vector<Annotation>:MAX_ANNOTATIONS_PER_UPDATE annotations)
+ -> () error AnnotationError;
+
+ /// Attach the `annotations` to the module with the given `id`.
+ /// The module can be annotated before being added to the story, but if the
+ /// story does not yet exist, AnnotationError.NOT_FOUND is returned.
+ ///
+ /// Existing annotations with the same key will be overwritten.
+ AnnotateModule(string module_id, vector<Annotation>:MAX_ANNOTATIONS_PER_UPDATE annotations)
+ -> () error AnnotationError;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/story_command.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/story_command.fidl
new file mode 100644
index 0000000..fa848c1
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/story_command.fidl
@@ -0,0 +1,119 @@
+// Copyright 2018 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.
+
+library fuchsia.modular;
+
+using fuchsia.mem;
+
+/// StoryCommands are POD structures that describe the set of operations that
+/// can be performed on a story by components outside the modular framework. All commands are:
+///
+/// (1) Scoped to a single story
+/// (2) Idempotent: issuing the same command twice yields the same result
+/// (3) Symmetrical with observation: the same structures are used to describe
+/// operations to watchers of a story (through SessionWatcher) as are used
+/// to control a story.
+union StoryCommand {
+ /// Sets the focus state of the story to `set_focus_state.focused`.
+ 1: SetFocusState set_focus_state;
+
+ /// Adds a Mod.
+ 2: AddMod add_mod;
+
+ /// Removes an existing Mod.
+ 3: RemoveMod remove_mod;
+
+ /// Sets the value of a Link.
+ /// DEPRECATED. This command is a no-op.
+ 4: SetLinkValue set_link_value;
+
+ /// Brings focus to a mod.
+ 5: FocusMod focus_mod;
+
+ /// Updates the kind_of_proto_story option in a story.
+ /// DEPRECATED. This command is a no-op.
+ 6: SetKindOfProtoStoryOption set_kind_of_proto_story_option;
+};
+
+struct SetFocusState {
+ bool focused;
+};
+
+/// Adds a mod described by `intent` to the story with name `mod_name`. If
+/// `mod_name` already exists in the story, the mod is updated.
+struct AddMod {
+ /// The name of the mod within the story. The mod's name acts as the unique
+ /// ID of the mod, scoped to the story in which it is contained. Since
+ /// AddMod is reused for observation and mod names are vector<string>
+ /// inside the framework, they are vector<string> here as well.
+ ///
+ /// Clients should treat the full vector as a single opaque value.
+ ///
+ /// Clients should provide `mod_name_transitional` instead.
+ /// If both are provided, `mod_name` is ignored.
+ ///
+ // TODO(MF-148): Convert to string
+ vector<string> mod_name;
+
+ /// The name of the mod within the story. This should be used instead of
+ /// `mod_name`. If provided, it is equivalent to passing `mod_name` with
+ /// a single item. If both are provided, `mod_name` is ignored.
+ ///
+ // TODO(MF-148): Remove
+ string? mod_name_transitional;
+
+ Intent intent;
+
+ /// `surface_relation` defines the visual relationship between this mod and the
+ /// mod at `surface_parent_mod_name`.
+ SurfaceRelation surface_relation;
+ vector<string>? surface_parent_mod_name;
+};
+
+/// Removes the mod under `mod_name` from the story.
+struct RemoveMod {
+ /// The name of the mod within the story.
+ ///
+ /// Clients should provide `mod_name_transitional` instead.
+ /// If both are provided, `mod_name` is ignored.
+ ///
+ // TODO(MF-148): Convert to string
+ vector<string> mod_name;
+
+ /// The name of the mod within the story. This should be used instead of
+ /// `mod_name`. If provided, it is equivalent to passing `mod_name` with
+ /// a single item. If both are provided, `mod_name` is ignored.
+ ///
+ // TODO(MF-148): Remove
+ string? mod_name_transitional;
+};
+
+/// Sets the value of link at `path` to `value`.
+struct SetLinkValue {
+ LinkPath path;
+ fuchsia.mem.Buffer? value;
+};
+
+/// Instructs the session shell to focus the mod under `mod_name`.
+struct FocusMod {
+ /// The name of the mod within the story.
+ ///
+ /// Clients should provide `mod_name_transitional` instead.
+ /// If both are provided, `mod_name` is ignored.
+ ///
+ // TODO(MF-148): Convert to string
+ vector<string> mod_name;
+
+ /// The name of the mod within the story. This should be used instead of
+ /// `mod_name`. If provided, it is equivalent to passing `mod_name` with
+ /// a single item. If both are provided, `mod_name` is ignored.
+ ///
+ // TODO(MF-148): Remove
+ string? mod_name_transitional;
+};
+
+/// Updates the kind_of_proto_story option in a story.
+struct SetKindOfProtoStoryOption {
+ bool value;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/story_controller.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/story_controller.fidl
new file mode 100644
index 0000000..49a30c3
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/story_controller.fidl
@@ -0,0 +1,55 @@
+// Copyright 2016 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.
+
+library fuchsia.modular;
+
+/// Used by the clients of StoryProvider (SessionShell) to interact with a single
+/// story. Created by StoryProvider.
+///
+/// If `StoryController` is closed, the `StoryState` associated with this story
+/// does not change.
+protocol StoryController {
+ /// Gets information associated with the story.
+ [Transitional = "Use GetInfo2 instead"]
+ GetInfo() -> (StoryInfo info, StoryState state);
+ /// For transition purposes only.
+ [Transitional = "Only use while GetInfo2 is transitional"]
+ GetInfo2() -> (StoryInfo2 info, StoryState state);
+
+ /// Requests to run the story controlled by this `StoryController` instance.
+ /// When the story starts, if not yet running, the view of the newly started
+ /// story shell will be passed in a call to SessionShell.AttachView().
+ RequestStart();
+
+ /// Requests to stop the story controlled by this `StoryController`. If Start()
+ /// requests are pending when this request is issued, the request is queued
+ /// until the Start() requests complete. Before stopping the story, a snapshot
+ /// of the story will be taken and saved. Returns when the story is stopped.
+ Stop() -> ();
+
+ /// Registers a watcher for changes of the story state.
+ ///
+ /// Note that stories can stop themselves at any time and it is advisable
+ /// for the holder of a StoryController to provide a watcher.
+ Watch(StoryWatcher watcher);
+
+ /// Attach the `annotations` to the story.
+ ///
+ /// Existing annotations with the same key will be overwritten.
+ Annotate(vector<Annotation>:MAX_ANNOTATIONS_PER_UPDATE annotations)
+ -> () error AnnotationError;
+};
+
+/// Implemented by the client calling StoryController.Watch().
+protocol StoryWatcher {
+ /// Called with the current state right after registration, and subsequently
+ /// when the state changes.
+ OnStateChange(StoryState new_state);
+
+ /// DEPRECATED
+ OnModuleAdded(ModuleData module_data);
+
+ /// DEPRECATED
+ OnModuleFocused(vector<string> module_path);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/story_info.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/story_info.fidl
new file mode 100644
index 0000000..1ca1c18
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/story_info.fidl
@@ -0,0 +1,50 @@
+// Copyright 2016 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.
+
+library fuchsia.modular;
+
+/// Information about a story as provided to the SessionShell.
+struct StoryInfo {
+ /// URL of the first module run in this story. This module is free to
+ /// run more modules in the story. Used for display purposes only.
+ // TODO(thatguy): Remove this. It is not being set any more.
+ string? url;
+
+ /// The ID of the Story, used to reference it in method arguments.
+ string id;
+
+ /// Wallclock time when the story was last focused. From
+ /// `ZX_CLOCK_UTC`, thus nanoseconds since UNIX epoch (1970-01-01 00:00 UTC).
+ ///
+ /// A value of zero means the story has never been focused.
+ int64 last_focus_time;
+
+ /// Data the SessionShell wants to keep associated with this Story, like
+ /// title, a color, or a display rank.
+ vector<StoryInfoExtraEntry>? extra;
+};
+
+/// Information about a story as provided to the SessionShell.
+/// For transition purposes only.
+table StoryInfo2 {
+ /// The ID of the Story, used to reference it in method arguments.
+ 1: string id;
+
+ /// Wallclock time when the story was last focused. From
+ /// ZX_CLOCK_UTC, thus nanoseconds since UNIX epoch (1970-01-01 00:00 UTC).
+ ///
+ /// A value of zero means the story has never been focused.
+ 2: int64 last_focus_time;
+
+ /// Collection of user-defined key-value attributes that describe
+ /// this story.
+ ///
+ /// The `Annotation.value` field of each `Annotation` is always set.
+ 3: vector<Annotation>:MAX_ANNOTATIONS_PER_STORY annotations;
+};
+
+struct StoryInfoExtraEntry {
+ string key;
+ string value;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/story_options.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/story_options.fidl
new file mode 100644
index 0000000..572cb58
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/story_options.fidl
@@ -0,0 +1,11 @@
+// Copyright 2018 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.
+
+library fuchsia.modular;
+
+struct StoryOptions {
+ /// Whether or not the story will be hidden on a call to
+ /// StoryProvider#GetStories.
+ bool kind_of_proto_story;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/story_provider.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/story_provider.fidl
new file mode 100644
index 0000000..f6dd4c5
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/story_provider.fidl
@@ -0,0 +1,86 @@
+// Copyright 2016 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.
+
+library fuchsia.modular;
+
+/// Sessionmgr passes a connection to this service to the SessionShell so it can
+/// operate on stories for the user.
+///
+/// Closing a `StoryProvider` connection has no effect on the state of the
+/// framework.
+[Discoverable]
+protocol StoryProvider {
+ /// Returns a list of existing stories. If `watcher` is provided, the client will
+ /// be notified of story changes (new stories, deleted stories, runtime
+ /// state changes).
+ [Transitional = "Use GetStories2 instead"]
+ GetStories(StoryProviderWatcher? watcher) -> (vector<StoryInfo> story_infos);
+ /// For transition purposes only.
+ [Transitional = "Only use while GetStories is transitional"]
+ GetStories2(StoryProviderWatcher? watcher) -> (vector<StoryInfo2> story_infos);
+
+ /// Requests detailed information about the given story. If the story doesn't
+ /// exist, returns null.
+ [Transitional = "Use GetStoryInfo2 instead"]
+ GetStoryInfo(string story_id) -> (StoryInfo? story_info);
+ /// For transition purposes only.
+ [Transitional = "Use only while GetStoryInfo is transitional"]
+ GetStoryInfo2(string story_id) -> (StoryInfo2 story_info);
+
+ /// Obtains a controller for a previously created story identified by its story
+ /// ID. Obtaining the controller doesn't run it yet. If the story doesn't
+ /// exist, the interface request is closed.
+ GetController(string story_id, request<StoryController> request);
+
+ /// Registers a watcher for changes in the story collection.
+ /// DEPRECATED: In favor of GetStories().
+ Watch(StoryProviderWatcher watcher);
+};
+
+/// Implemented by clients of StoryProvider.
+protocol StoryProviderWatcher {
+ /// Called in three different situations:
+ ///
+ /// * Immediately when a new watcher is registered with one OnChange()
+ /// invocation with the current infor and state of each story known on the
+ /// current device.
+ ///
+ /// * Every time a change to StoryInfo is applied to the record of the story
+ /// kept on the current device, including a new story created on another
+ /// device becoming known on this device for the first time.
+ ///
+ /// * Every time the StoryState of the story changes on this device. The
+ /// StoryState on another device of a story known on this device is not made
+ /// known on this device.
+ ///
+ /// * Every time the StoryVisibilityState of the story changes on this device.
+ /// The StoryVisibilityState on another device of a story known on this
+ /// device is not made known on this device.
+ ///
+ /// I.e. if the story is started or stopped on *another* device, it does
+ /// *not* cause an OnChange() call on *this* device. Cf. OnDelete() below.
+ ///
+ /// The ID of the story the notifications are about are part of StoryInfo.
+ ///
+ /// `story_state` is STOPPED if the story was just created or just became known
+ /// on this device and was not yet started on the current device. It's RUNNING
+ /// when the story is started on the current device.
+ ///
+ /// `story_visibility_state` is DEFAULT until a mod on the current device
+ /// requests for the visibility state to be changed.
+ [Transitional = "Implement OnChange2 instead"]
+ OnChange(StoryInfo story_info, StoryState story_state,
+ StoryVisibilityState story_visibility_state);
+ /// For transition purposes only.
+ [Transitional = "Implement only while OnChange is transitional"]
+ OnChange2(StoryInfo2 story_info, StoryState story_state,
+ StoryVisibilityState story_visibility_state);
+
+ /// Called when a story record is permanently deleted. The deletion could
+ /// have originated on this or on another device.
+ ///
+ /// If the story is running on this device at the time it is deleted,
+ /// OnChange() will not be called first.
+ OnDelete(string story_id);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/story_shell.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/story_shell.fidl
new file mode 100644
index 0000000..bfe9f74
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/story_shell.fidl
@@ -0,0 +1,162 @@
+// Copyright 2017 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.
+
+library fuchsia.modular;
+
+using fuchsia.ui.policy;
+using fuchsia.ui.views;
+
+/// This interface is implemented by a story shell. Dependencies are passed to it
+/// in Initialize() on startup. The story shell is also expected to implement
+/// Lifecycle in order to receive a Terminate() call on teardown.
+///
+/// In one component instance there can only be one StoryShell service instance.
+/// The view token is sent to the separate View service. This way, the story
+/// shell may be implemented as a flutter component.
+///
+/// Teardown may occur via the session shell calling StoryController.Stop(), the
+/// sessionmgr being terminated, or by the system shutting down.
+[Discoverable] // Created by story shell applications.
+protocol StoryShell {
+ Initialize(StoryShellContext story_shell_context);
+
+ /// Adds a new Surface and its corresponding view to be displayed by the
+ /// StoryShell. More context that allows the story shell to decide how
+ /// to layout will be added later. Also, interface to influence life cycle and
+ /// focus is obviously missing.
+ /// `view_connection` the new view and the associated Surface ID.
+ /// `surface_info` metadata relating to the Surface.
+ [Transitional = "Implement AddSurface3 instead"]
+ AddSurface(ViewConnection view_connection, SurfaceInfo surface_info);
+ /// DEPRECATED. For transition purposes only.
+ [Transitional = "Implement AddSurface3 instead"]
+ AddSurface2(ViewConnection2 view_connection, SurfaceInfo surface_info);
+ /// For transition purposes only.
+ [Transitional = "Only implement while AddSurface is transitional"]
+ AddSurface3(ViewConnection view_connection, SurfaceInfo2 surface_info);
+
+ /// Focuses the surface with surface_id, bringing it to the foreground.
+ FocusSurface(string surface_id);
+
+ /// Defocuses the surface with surface_id, dismissing it to the background.
+ DefocusSurface(string surface_id) -> ();
+
+ /// Notify when a Surface is focused in the story. The focus could be from
+ /// a user interaction or requested by the framework through
+ /// StoryController#FocusModule.
+ /// EXPERIMENTAL
+ -> OnSurfaceFocused(string surface_id);
+
+ /// Remove the Surface with surface_id from the StoryShell entirely. This is
+ /// final. The Surface is removed from the graph. If necessary, the
+ /// associated Surface is defocused. There is no expectation that
+ /// DefocusSurface is called before this.
+ RemoveSurface(string surface_id);
+
+ /// Update the surface
+ /// This is called when the intent is to update the surface metadata in the
+ /// story graph in place. Any fields, except for the surface_id can be
+ /// updated. If no value or null is passed for a field it remains unchanged.
+ /// This includes the `view_holder_token` inside the connection.
+ ///
+ /// E.g called when an intent resolves to a module that is known by the
+ /// caller to already be running, to update associated metadata.
+ [Transitional = "Implement UpdateSurface3 instead"]
+ UpdateSurface(ViewConnection view_connection, SurfaceInfo surface_info);
+ /// DEPRECATED. For transition purposes only.
+ [Transitional = "Implement UpdateSurface3 instead"]
+ UpdateSurface2(ViewConnection2 view_connection, SurfaceInfo surface_info);
+ /// For transition purposes only.
+ [Transitional = "Only implement while UpdateSurface is transitional"]
+ UpdateSurface3(ViewConnection view_connection, SurfaceInfo2 surface_info);
+};
+
+/// A pair mapping a surface ID to a view (via `view_holder_token`).
+struct ViewConnection {
+ /// The ID for the surface
+ string surface_id;
+
+ /// Token for embedding the new view corresponding to the surface.
+ fuchsia.ui.views.ViewHolderToken view_holder_token;
+};
+
+/// DEPRECATED, for transition purposes only.
+struct ViewConnection2 {
+ /// The ID for the surface
+ string surface_id;
+
+ /// Token for embedding the new view corresponding to the surface.
+ fuchsia.ui.views.ViewHolderToken view_holder_token;
+};
+
+/// Contains metadata for a Surface.
+struct SurfaceInfo {
+ /// ID of the view that is parent of this Surface.
+ string parent_id;
+
+ /// The relationship between the parent Surface and this new Surface. Used
+ /// for layout optimization.
+ SurfaceRelation? surface_relation;
+
+ /// Information about the module populates the view.
+ ModuleManifest? module_manifest;
+
+ /// How the Surface was generated. By an action internal to the story or by
+ /// an external action.
+ ModuleSource module_source;
+};
+
+/// Contains metadata for a Surface.
+table SurfaceInfo2 {
+ /// ID of the view that is parent of this Surface.
+ 1: string parent_id;
+
+ /// The relationship between the parent Surface and this new Surface. Used
+ /// for layout optimization.
+ 2: SurfaceRelation surface_relation;
+
+ /// Information about the module populates the view.
+ 3: ModuleManifest module_manifest;
+
+ /// How the Surface was generated. By an action internal to the story or by
+ /// an external action.
+ 4: ModuleSource module_source;
+
+ /// Collection of user-defined key-value attributes that describe this surface (module).
+ ///
+ /// The `Annotation.value` field of each `Annotation` is always set.
+ 5: vector<Annotation>:MAX_ANNOTATIONS_PER_MODULE annotations;
+
+ /// The view ref associated with the surface, if one is present.
+ 6: fuchsia.ui.views.ViewRef view_ref;
+};
+
+/// This interface provides the StoryShell instance with everything it needs to
+/// know or be able to do about the Story. Not much right now, but we expect this
+/// to increase.
+protocol StoryShellContext {
+ /// Requests a Presentation connection from the SessionShell. See
+ /// SessionShellPresenationProvider in session_shell.fidl.
+ GetPresentation(request<fuchsia.ui.policy.Presentation> request);
+
+ /// Starts watching Story shell's visual state.
+ WatchVisualState(StoryVisualStateWatcher watcher);
+
+ /// Requests a view for a Surface.
+ /// Requests that a view for `surface_id` is provided through
+ /// StoryShell.ReconnectView().
+ RequestView(string surface_id);
+};
+
+/// Implemented by StoryShell to get notified about visual state changes.
+protocol StoryVisualStateWatcher {
+ OnVisualStateChange(StoryVisualState visual_state);
+};
+
+/// Defines the visual state of the Story shell.
+enum StoryVisualState {
+ MINIMIZED = 0;
+ MAXIMIZED = 1;
+ MAXIMIZED_OVERLAYED = 2;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/story_shell_factory.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/story_shell_factory.fidl
new file mode 100644
index 0000000..0b8ddc0
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/story_shell_factory.fidl
@@ -0,0 +1,18 @@
+// 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.
+
+library fuchsia.modular;
+
+/// StoryShellFactory creates or returns an existing `StoryShell` for a particular story.
+/// This is intended to be implemented by session shells that want to implement
+/// StoryShell functionality themselves.
+[Discoverable]
+protocol StoryShellFactory {
+ /// Requests a StoryShell for the story with the given `story_id`.
+ AttachStory(string story_id, request<StoryShell> story_shell);
+
+ /// Instructs the session shell to teardown the story shell with the given `story_id`.
+ /// This will be called before the story is stopped.
+ DetachStory(string story_id) -> ();
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/story_state.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/story_state.fidl
new file mode 100644
index 0000000..c88e1bf
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/story_state.fidl
@@ -0,0 +1,25 @@
+// Copyright 2017 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.
+
+library fuchsia.modular;
+
+/// State of a Story. A story is either running, stopping, or stopped, separately
+/// on every device of the user. If it's running, it can also be focused, but
+/// that's tracked in a separate service, cf. FocusProvider in focus.fidl.
+///
+/// Possible state transitions are:
+///
+/// STOPPED -> RUNNING
+/// RUNNING -> STOPPING
+/// STOPPING -> STOPPED
+enum StoryState {
+ /// Story was started using StoryController.Start().
+ RUNNING = 1;
+ /// Story is in the middle of stopping after StoryController.Stop() was
+ /// called.
+ STOPPING = 2;
+ /// Story was not yet run, or Story was stopped after StoryController.Stop()
+ /// was called.
+ STOPPED = 3;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/story_visibility_state.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/story_visibility_state.fidl
new file mode 100644
index 0000000..6413411
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/story/story_visibility_state.fidl
@@ -0,0 +1,22 @@
+// Copyright 2018 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.
+
+library fuchsia.modular;
+
+/// Visibility state of a Story within the session shell.
+/// This state describes how a story should be displayed within the session shell,
+/// regardless of whether the story is in focus or not. Focus state and
+/// visibility state are orthogonal concepts.
+/// E.g A story can be out-of-focus and be in IMMERSIVE state at the same time
+/// if a user was playing a video, exits, then re-enters the story. The
+/// expectation in this scenario is that the story is in IMMERSIVE state upon
+/// re-enter.
+///
+/// All state transitions are possible.
+enum StoryVisibilityState {
+ /// Default state for a story.
+ DEFAULT = 1;
+ /// Full-screen user experience, e.g. playing a video.
+ IMMERSIVE = 2;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.modular/surface/surface.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.modular/surface/surface.fidl
new file mode 100644
index 0000000..652c9e6
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.modular/surface/surface.fidl
@@ -0,0 +1,49 @@
+// Copyright 2017 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.
+
+// This file contains the definition of SurfaceRelation and its properties.
+
+library fuchsia.modular;
+
+/// Describes the relationship between two Surfaces.
+/// Provides information to the StoryShell for layout optimization.
+struct SurfaceRelation {
+ /// Advice on arranging these surfaces on the screen together.
+ SurfaceArrangement arrangement = SurfaceArrangement.NONE;
+
+ /// Advice for dismissal of surfaces to be linked.
+ SurfaceDependency dependency = SurfaceDependency.NONE;
+
+ /// Relative emphasis of the child surface, relative to the parent.
+ /// Influences relative areas of surfaces on screen.
+ float32 emphasis = 1.0;
+};
+
+/// Expresses arrangement type.
+enum SurfaceArrangement {
+ /// No arrangement specified.
+ NONE = 0;
+
+ /// Desire to present simultaneously.
+ COPRESENT = 1;
+
+ /// The parent prefers to not be presented simultaneously with its child.
+ /// (The child may still become part of a simultaneous presentation depending
+ /// on the relationships between it and subsequently added surfaces).
+ SEQUENTIAL = 2;
+
+ /// Place this surface on top of and obscuring the parent surface. This is a
+ /// complete replacement, not a modal or inset presentation.
+ ONTOP = 3;
+};
+
+/// Links surface dismissal.
+enum SurfaceDependency {
+ /// No dependency specified.
+ NONE = 0;
+
+ /// Child is dependent on parent.
+ /// If parent is dismissed, child is dismissed as well.
+ DEPENDENT = 1;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.net.dhcp/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.net.dhcp/BUILD.gn
new file mode 100644
index 0000000..fe8295d
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.net.dhcp/BUILD.gn
@@ -0,0 +1,28 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.net.dhcp") {
+ library_name = "dhcp"
+ namespace = "fuchsia.net"
+ public_deps = [
+ "../fuchsia.net",
+ ]
+ sources = [
+ "client.fidl",
+ "options.fidl",
+ "server.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.net.dhcp",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.net.dhcp/client.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.net.dhcp/client.fidl
new file mode 100644
index 0000000..2b21ae2
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.net.dhcp/client.fidl
@@ -0,0 +1,32 @@
+// 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.
+
+library fuchsia.net.dhcp;
+
+using zx;
+
+/// Client provides control operations on a DHCP client.
+protocol Client {
+ /// Start runs the DHCP client represented by this protocol.
+ ///
+ /// # Errors
+ ///
+ /// In the case that the interface this client represents no longer exists,
+ /// the server end of this protocol's channel will be closed.
+ ///
+ /// Start returns no other errors currently, but callers should check the error
+ /// value in case new errors are returned in the future.
+ Start() -> () error zx.status;
+
+ /// Stops the DHCP client (if it is running).
+ ///
+ /// # Errors
+ ///
+ /// In the case that the interface this client represents no longer exists,
+ /// the server end of this protocol's channel will be closed.
+ ///
+ /// Stop returns no other errors currently, but callers should check the error
+ /// value in case new errors are returned in the future.
+ Stop() -> () error zx.status;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.net.dhcp/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.net.dhcp/meta.json
new file mode 100644
index 0000000..6326c35
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.net.dhcp/meta.json
@@ -0,0 +1,13 @@
+{
+ "deps": [
+ "fuchsia.net"
+ ],
+ "name": "fuchsia.net.dhcp",
+ "root": "fidl/fuchsia.net.dhcp",
+ "sources": [
+ "fidl/fuchsia.net.dhcp/client.fidl",
+ "fidl/fuchsia.net.dhcp/options.fidl",
+ "fidl/fuchsia.net.dhcp/server.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.net.dhcp/options.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.net.dhcp/options.fidl
new file mode 100644
index 0000000..dce4974
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.net.dhcp/options.fidl
@@ -0,0 +1,401 @@
+// 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.
+library fuchsia.net.dhcp;
+
+using fuchsia.net;
+
+/// A DHCP duration value, in seconds. As specified in
+/// https://tools.ietf.org/html/rfc2131#section-3.3, DHCP duration values are
+/// relative times.
+using Duration = uint32;
+/// A list of IP addresses. The vector bounds of this list are MAX_OPTION_LEN /
+/// len(Ipv4Address), where MAX_OPTION_LEN is the maximum byte length of a value
+/// for a DHCP option as defined in https://tools.ietf.org/html/rfc2132#section-2:
+/// "All other options are variable-length with a length octet following the tag octet."
+using Addresses = vector<fuchsia.net.Ipv4Address>:63;
+
+/// An ASCII string with a length limit of 255. All DHCP Option values must have
+/// a length that can fit in an octet, cf. "All other options are variable-length with a length octet following the tag octet."
+/// from https://tools.ietf.org/html/rfc2132#section-2. Similarly all DHCP Option
+/// string values must be limited to the ASCII character set. Should non-ASCII
+/// characters be sent in a `AsciiString` to Server, Server will close the channel to
+/// the client.
+using AsciiString = string:255;
+
+/// A indication of which DHCP message field should be used to store additional options.
+enum OptionOverloadValue : byte {
+ /// The file DHCP field.
+ FILE = 1;
+ /// The sname DHCP field.
+ SNAME = 2;
+ /// Both file and sname DHCP fields.
+ BOTH = 3;
+};
+
+/// A NetBIOS over TCP/IP node type as defined in RFC 1001/1002. This bitflag is for use with the
+/// NetBiosOverTcpipNodeType option.
+bits NodeTypes : byte {
+ /// A B node type.
+ B_NODE = 0x1;
+ /// A P node type.
+ P_NODE = 0x2;
+ /// A M node type.
+ M_NODE = 0x4;
+ /// A H node type.
+ H_NODE = 0x8;
+};
+
+/// The type of DHCP message. The DHCP protocol requires that all messages identify
+/// their type by including the MessageType option. These values are specified
+/// in https://tools.ietf.org/html/rfc2132#section-9.6.
+enum MessageType : byte {
+ /// A DHCP Discover message.
+ DHCPDISCOVER = 1;
+ /// A DHCP Offer message.
+ DHCPOFFER = 2;
+ /// A DHCP Request message.
+ DHCPREQUEST = 3;
+ /// A DHCP Decline message.
+ DHCPDECLINE = 4;
+ /// A DHCP Ack message.
+ DHCPACK = 5;
+ /// A DHCP Nak message;
+ DHCPNAK = 6;
+ /// A DHCP Release message;
+ DHCPRELEASE = 7;
+ /// A DHCP Inform message.
+ DHCPINFORM = 8;
+};
+
+/// A generic representation of client configuration parameters and DHCP settings. Options are the
+/// mechanism by which the DHCP protocol communicates configuration parameters from a repository on
+/// a DHCP server to DHCP clients, or by which DHCP clients and servers communicate data relevant to
+/// a DHCP transaction.
+/// All DHCP option values must have a length which can fit within a single byte, i.e. less than 256.
+/// Options for which there is no reasonable administrator-configurable value have been omitted
+/// from this xunion. The omitted options are:
+/// * Pad - never has a value
+/// * End - never has a value
+/// * RequestedIpAddress - value always selected by the DHCP client.
+/// * DhcpMessageType - value always determined by state of transaction between DHCP client and server.
+/// * ServerIdentifier - value always determined by address to which the server is bound.
+/// * ParameterRequestList - value always selected by the DHCP client.
+/// * Message - value determined in response to runtime error.
+/// * VendorClassIdentifer - value always selected by the DHCP client.
+/// * ClientIdentifier - value always selected by the DHCP client.
+flexible union Option {
+ /// A 32-bit IPv4 subnet mask.
+ 1: fuchsia.net.Ipv4Address subnet_mask;
+
+ /// The client's offset from UTC in seconds. A positive offset is east of the zero meridian, and
+ /// a negative offset is west of the zero meridian.
+ 2: int32 time_offset;
+
+ /// A list of the routers in a client's subnet, listed in order of preference.
+ 3: Addresses router;
+
+ /// A list of time servers available to the client, in order of preference.
+ 4: Addresses time_server;
+
+ /// A list of IEN 116 Name servers available to the client, in order of preference.
+ 5: Addresses name_server;
+
+ /// A list of Domain Name System servers available to the client, in order of preference;
+ 6: Addresses domain_name_server;
+
+ /// A list of MIT-LCS UDP Log servers available to the client, in order of preference.
+ 7: Addresses log_server;
+
+ /// A list of RFC 865 Cookie servers available to the client, in order of preference.
+ 8: Addresses cookie_server;
+
+ /// A list of RFC 1179 Line Printer servers available to the client, in order of preference.
+ 9: Addresses lpr_server;
+
+ /// A list of Imagen Impress servers available to the client, in order of preference.
+ 10: Addresses impress_server;
+
+ /// A list of RFC 887 Resource Location servers available to the client, in order of preference.
+ 11: Addresses resource_location_server;
+
+ /// The host name of the client, which may or may not be qualified with the local domain name.
+ 12: AsciiString host_name;
+
+ /// The size of the client's default boot image in 512-octet blocks.
+ 13: uint16 boot_file_size;
+
+ /// The path name to the client's core dump in the event the client crashes.
+ 14: AsciiString merit_dump_file;
+
+ /// The client's domain name for use in resolving hostnames in the DNS.
+ 15: AsciiString domain_name;
+
+ /// The address of the client's swap server.
+ 16: fuchsia.net.Ipv4Address swap_server;
+
+ /// The path name to the client's root disk.
+ 17: AsciiString root_path;
+
+ /// The path name to a TFTP-retrievable file. This file contains data which can be interpreted
+ /// as the BOOTP vendor-extension field. Unlike the BOOTP vendor-extension field, this file has
+ /// an unconstrained length and any references to Tag 18 are ignored.
+ 18: AsciiString extensions_path;
+
+ /// A flag which will enabled IP layer packet forwarding when true.
+ 19: bool ip_forwarding;
+
+ /// A flag which will enable forwarding of IP packets with non-local source routes.
+ 20: bool non_local_source_routing;
+
+ /// Policy filters for non-local source routing.
+ /// A list of IP Address and Subnet Mask pairs. If an incoming source-routed packet has a
+ /// next-hop that does not match one of these pairs, then the packet will be dropped.
+ 21: Addresses policy_filter;
+
+ /// The maximum sized datagram that the client should be able to reassemble, in octets. The
+ /// minimum legal value is 576.
+ 22: uint16 max_datagram_reassembly_size;
+
+ /// The default time-to-live to use on outgoing IP datagrams. The value must be between 1 and
+ /// 255.
+ 23: byte default_ip_ttl;
+
+ /// The timeout to be used when aging Path MTU values by the mechanism in RFC 1191.
+ 24: Duration path_mtu_aging_timeout;
+
+ /// Table of MTU sizes for Path MTU Discovery.
+ /// A list of MTU sizes, ordered from smallest to largest. The smallest value cannot be smaller
+ /// than 68.
+ 25: vector<uint16>:127 path_mtu_plateau_table;
+
+ /// The MTU for the client's interface. Minimum value of 68.
+ 26: uint16 interface_mtu;
+
+ /// A flag indicating if all subents of the IP network to which the client is connected have the
+ /// same MTU.
+ 27: bool all_subnets_local;
+
+ /// The broadcast address of the client's subnet. Legal values are defined in RFC 1122.
+ 28: fuchsia.net.Ipv4Address broadcast_address;
+
+ /// A flag indicating whether the client should perform subnet mask discovery via ICMP.
+ 29: bool perform_mask_discovery;
+
+ /// A flag indicating whether the client should respond to subnet mask discovery requests via
+ /// ICMP.
+ 30: bool mask_supplier;
+
+ /// A flag indicating whether the client should solicit routers using Router Discovery as
+ /// defined in RFC 1256.
+ 31: bool perform_router_discovery;
+
+ /// The address to which the client should transmit Router Solicitation requests.
+ 32: fuchsia.net.Ipv4Address router_solicitation_address;
+
+ /// Static Routes which the host should put in its routing cache.
+ /// A list of Destination address/Next-hop address pairs defining static routes for the client's
+ /// routing table. The routes should be listed in descending order of priority. It is illegal
+ /// to use 0.0.0.0 as the destination in a static route.
+ 33: Addresses static_route;
+
+ /// A flag specifying whether the client negotiate the use of trailers when using ARP, per RFC
+ /// 893.
+ 34: bool trailer_encapsulation;
+
+ /// The timeout for ARP cache entries.
+ 35: Duration arp_cache_timeout;
+
+ /// A flag specifying that the client should use Ethernet v2 encapsulation when false, and IEEE
+ /// 802.3 encapsulation when true.
+ 36: bool ethernet_encapsulation;
+
+ /// The default time-to-live that the client should use for outgoing TCP segments. The minimum
+ /// value is 1.
+ 37: byte tcp_default_ttl;
+
+ /// The interval the client should wait before sending a TCP keepalive message. A
+ /// value of 0 indicates that the client should not send keepalive messages unless specifically
+ /// requested by an application.
+ 38: Duration tcp_keepalive_interval;
+
+ /// A flag specifying whether the client should send TCP keepalive messages with an octet of
+ /// garbage for compatibility with older implementations.
+ 39: bool tcp_keepalive_garbage;
+
+ /// The name of the client's Network Information Service domain.
+ 40: AsciiString network_information_service_domain;
+
+ /// A list of Network Information Service server addresses available to the client, listed in
+ /// order of preference.
+ 41: Addresses network_information_servers;
+
+ /// A list of Network Time Protocol (NTP) server addresses available to the client, listed in
+ /// order of preference.
+ 42: Addresses network_time_protocol_servers;
+
+ /// An opaque object of octets for exchanging vendor-specific information.
+ 43: bytes:255 vendor_specific_information;
+
+ /// A list of NetBIOS name server addresses available to the client, listed in order of
+ /// preference.
+ 44: Addresses netbios_over_tcpip_name_server;
+
+ /// A list of NetBIOS datagram distribution servers available to the client, listed in order of
+ /// preference.
+ 45: Addresses netbios_over_tcpip_datagram_distribution_server;
+
+ /// The NetBIOS node type which should be used by the client.
+ 46: NodeTypes netbios_over_tcpip_node_type;
+
+ /// The NetBIOS over TCP/IP scope parameter, as defined in RFC 1001, for the client.
+ 47: AsciiString netbios_over_tcpip_scope;
+
+ /// A list of X Window System Font server addresses available to the client, listed in order of
+ /// preference.
+ 48: Addresses x_window_system_font_server;
+
+ /// A list of X Window System Display Manager system addresses available to the client, listed
+ /// in order of preference.
+ 49: Addresses x_window_system_display_manager;
+
+ /// The name of the client's Network Information System+ domain.
+ 50: AsciiString network_information_service_plus_domain;
+
+ /// A list of Network Information System+ server addresses available to the client, listed in
+ /// order of preference.
+ 51: Addresses network_information_service_plus_servers;
+
+ /// A list of mobile IP home agent addresses available to the client, listed in order of
+ /// preference.
+ 52: Addresses mobile_ip_home_agent;
+
+ /// A list of Simple Mail Transport Protocol (SMTP) server address available to the client,
+ /// listed in order of preference.
+ 53: Addresses smtp_server;
+
+ /// A list of Post Office Protocol (POP3) server addresses available to the client, listed in
+ /// order of preference.
+ 54: Addresses pop3_server;
+
+ /// A list Network News Transport Protocol (NNTP) server addresses available to the client,
+ /// listed in order of preference.
+ 55: Addresses nntp_server;
+
+ /// A list of default World Wide Web (WWW) server addresses available to the client, listed in
+ /// order of preference.
+ 56: Addresses default_www_server;
+
+ /// A list of default Finger server addresses available to the client, listed in order of
+ /// preference.
+ 57: Addresses default_finger_server;
+
+ /// A list of Internet Relay Chat server addresses available to the client, listed in order of
+ /// preference.
+ 58: Addresses default_irc_server;
+
+ /// A list of StreetTalk server addresses available to the client, listed in order of
+ /// preference.
+ 59: Addresses streettalk_server;
+
+ /// A list of StreetTalk Directory Assistance server addresses available to the client, listed
+ /// in order of preference.
+ 60: Addresses streettalk_directory_assistance_server;
+
+ /// An option specifying whether the `sname`, `file`, or both fields have been overloaded to
+ /// carry DHCP options. If this option is present, the client interprets the additional fields
+ /// after it concludes interpreting standard option fields.
+ 61: OptionOverloadValue option_overload;
+
+ /// The TFTP server name available to the client. This option should be used when the `sname`
+ /// field has been overloaded to carry options.
+ 62: AsciiString tftp_server_name;
+
+ /// The bootfile name for the client. This option should be used when the `file` field has been
+ /// overloaded to carry options.
+ 63: AsciiString bootfile_name;
+
+ /// The maximum length in octets of a DHCP message that the participant is willing to accept.
+ /// The minimum value is 576.
+ 64: uint16 max_dhcp_message_size;
+
+ /// The time interval after address assignment at which the client will transition
+ /// to the Renewing state.
+ 65: Duration renewal_time_value;
+
+ /// The time interval after address assignment at which the client will transition
+ /// to the Rebinding state.
+ 66: Duration rebinding_time_value;
+};
+
+/// The code of a DHCP option to be retrieved by Server.GetOption(). The code
+/// values are from https://tools.ietf.org/html/rfc2132 and the enum variants
+/// have been listed in the order they are presented in the RFC.
+enum OptionCode {
+ SUBNET_MASK = 1;
+ TIME_OFFSET = 2;
+ ROUTER = 3;
+ TIME_SERVER = 4;
+ NAME_SERVER = 5;
+ DOMAIN_NAME_SERVER = 6;
+ LOG_SERVER = 7;
+ COOKIE_SERVER = 8;
+ LPR_SERVER = 9;
+ IMPRESS_SERVER = 10;
+ RESOURCE_LOCATION_SERVER = 11;
+ HOST_NAME = 12;
+ BOOT_FILE_SIZE = 13;
+ MERIT_DUMP_FILE = 14;
+ DOMAIN_NAME = 15;
+ SWAP_SERVER = 16;
+ ROOT_PATH = 17;
+ EXTENSIONS_PATH = 18;
+ IP_FORWARDING = 19;
+ NON_LOCAL_SOURCE_ROUTING = 20;
+ POLICY_FILTER = 21;
+ MAX_DATAGRAM_REASSEMBLY_SIZE = 22;
+ DEFAULT_IP_TTL = 23;
+ PATH_MTU_AGING_TIMEOUT = 24;
+ PATH_MTU_PLATEAU_TABLE = 25;
+ INTERFACE_MTU = 26;
+ ALL_SUBNETS_LOCAL = 27;
+ BROADCAST_ADDRESS = 28;
+ PERFORM_MASK_DISCOVERY = 29;
+ MASK_SUPPLIER = 30;
+ PERFORM_ROUTER_DISCOVERY = 31;
+ ROUTER_SOLICITATION_ADDRESS = 32;
+ STATIC_ROUTE = 33;
+ TRAILER_ENCAPSULATION = 34;
+ ARP_CACHE_TIMEOUT = 35;
+ ETHERNET_ENCAPSULATION = 36;
+ TCP_DEFAULT_TTL = 37;
+ TCP_KEEPALIVE_INTERVAL = 38;
+ TCP_KEEPALIVE_GARBAGE = 39;
+ NETWORK_INFORMATION_SERVICE_DOMAIN = 40;
+ NETWORK_INFORMATION_SERVERS = 41;
+ NETWORK_TIME_PROTOCOL_SERVERS = 42;
+ VENDOR_SPECIFIC_INFORMATION = 43;
+ NETBIOS_OVER_TCPIP_NAME_SERVER = 44;
+ NETBIOS_OVER_TCPIP_DATAGRAM_DISTRIBUTION_SERVER = 45;
+ NETBIOS_OVER_TCPIP_NODE_TYPE = 46;
+ NETBIOS_OVER_TCPIP_SCOPE = 47;
+ X_WINDOW_SYSTEM_FONT_SERVER = 48;
+ X_WINDOW_SYSTEM_DISPLAY_MANAGER = 49;
+ NETWORK_INFORMATION_SERVICE_PLUS_DOMAIN = 64;
+ NETWORK_INFORMATION_SERVICE_PLUS_SERVERS = 65;
+ MOBILE_IP_HOME_AGENT = 68;
+ SMTP_SERVER = 69;
+ POP3_SERVER = 70;
+ NNTP_SERVER = 71;
+ DEFAULT_WWW_SERVER = 72;
+ DEFAULT_FINGER_SERVER = 73;
+ DEFAULT_IRC_SERVER = 74;
+ STREETTALK_SERVER = 75;
+ STREETTALK_DIRECTORY_ASSISTANCE_SERVER = 76;
+ OPTION_OVERLOAD = 52;
+ TFTP_SERVER_NAME = 66;
+ BOOTFILE_NAME = 67;
+ MAX_DHCP_MESSAGE_SIZE = 57;
+ RENEWAL_TIME_VALUE = 58;
+ REBINDING_TIME_VALUE = 59;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.net.dhcp/server.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.net.dhcp/server.fidl
new file mode 100644
index 0000000..cd8ab6a
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.net.dhcp/server.fidl
@@ -0,0 +1,174 @@
+// 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.
+library fuchsia.net.dhcp;
+
+using fuchsia.net;
+using zx;
+
+/// The pool of addresses managed by a DHCP server and from which leases are supplied.
+table AddressPool {
+ /// The network ID of the address pool's subnet.
+ 1: fuchsia.net.Ipv4Address network_id;
+ /// The broadcast address of the address pool's subnet.
+ 2: fuchsia.net.Ipv4Address broadcast;
+ /// The subnet mask of the address pool's network.
+ 3: fuchsia.net.Ipv4Address mask;
+ /// The starting address, inclusive, of the range of addresses which the DHCP server
+ /// will lease to clients. This address must be in the subnet defined by the network_id
+ /// and mask members of the AddressPool.
+ 4: fuchsia.net.Ipv4Address pool_range_start;
+ /// The ending address, inclusive, of the range of addresses which the server will
+ /// to clients. This address must be in the subnet defined by the network_id and mask
+ /// members of the AddressPool.
+ 5: fuchsia.net.Ipv4Address pool_range_stop;
+};
+
+/// The duration of leases offered by the server.
+table LeaseLength {
+ /// The default lease length to be issued to clients. This field must have a value.
+ 1: Duration default;
+ /// The maximum lease length value which the server will issue to clients who
+ /// have requested a specific lease length. If omitted, the max lease length is
+ /// equivalent to the default lease length.
+ 2: Duration max;
+};
+
+/// A static IP address assignment for a host or device on the network managed by Server.
+table StaticAssignment {
+ /// The MAC address of the host or device which will have the static IP address assignment.
+ 1: fuchsia.net.MacAddress host;
+ /// The IP address which the host or device will always be assigned by dhcpd.
+ 2: fuchsia.net.Ipv4Address assigned_addr;
+};
+
+/// The configurable server parameters.
+flexible union Parameter {
+ /// The IP addresses to which the server is bound. The vector bound has been
+ /// arbitrarily selected as a generous upper limit.
+ 1: vector<fuchsia.net.Ipv4Address>:256 ip_addrs;
+ /// The server's pool of managed addresses. Changing the address pool will not cancel existing
+ /// leases because the DHCP protocol does not provide a mechanism for doing so. Administrators
+ /// should take care when changing the address pool for a server with active leases.
+ 2: AddressPool address_pool;
+ /// The duration of leases issued by dhcpd.
+ 3: LeaseLength lease;
+ /// The client MAC addresses which the server will issue leases to. By default,
+ /// the server will not have a permitted MAC list, in which case it will attempt to
+ /// issue a lease to every client which requests one. If permitted_macs has a non-zero length
+ /// then the server will only respond to lease requests from clients with a MAC in the list. The
+ /// vector bound has been arbitrarily selected as a generous upper limit.
+ 4: vector<fuchsia.net.MacAddress>:256 permitted_macs;
+ /// Addresses statically assigned to specific hosts or devices. Typically, a network
+ /// administrator will statically assign addresses to always-on network
+ /// devices which should always have the same IP address, such as network printers. The vector
+ /// bound has been arbitrarily selected as a generous upper limit.
+ 5: vector<StaticAssignment>:256 statically_assigned_addrs;
+ /// Enables server behavior where the server ARPs an IP address prior to issuing
+ /// it in a lease. If the server receives a response, the server will mark the
+ /// address as in-use and try again with a different address.
+ 6: bool arp_probe;
+ /// The names of the interface to which the server will listen. If this
+ /// vector is empty, the server will listen on all interfaces and will
+ /// process incoming DHCP messages regardless of the interface on which
+ /// they arrive. If this vector is not empty, then the server will only
+ /// listen for incoming DHCP messages on the named interfaces contained by
+ /// this vector. The string and vectors bounds have been arbitrarily
+ /// selected as generous upper limits.
+ 7: vector<string:256>:256 bound_device_names;
+};
+
+/// The name of the Parameter to be retrieved by Server.GetParameter().
+enum ParameterName {
+ IP_ADDRS = 0;
+ ADDRESS_POOL = 1;
+ LEASE_LENGTH = 2;
+ PERMITTED_MACS = 3;
+ STATICALLY_ASSIGNED_ADDRS = 4;
+ ARP_PROBE = 5;
+ BOUND_DEVICE_NAMES = 6;
+};
+
+/// Provides methods for DHCP Server configuration.
+[Discoverable]
+protocol Server {
+ /// Returns the requested Option if it is supported.
+ ///
+ /// + request `code` the code of an Option whose value has been requested.
+ /// - response `value` the value of the requested Option.
+ /// * error a zx.status indicating why the value could not be retrieved.
+ GetOption(OptionCode code) -> (Option value) error zx.status;
+
+ /// Returns the requested Parameter if it is supported.
+ ///
+ /// + request `name` the name of a Parameter whose value has been requested.
+ /// - response `value` the value of the requested Parameter.
+ /// * error a zx.status indicating why the value could not be retrieved.
+ GetParameter(ParameterName name) -> (Parameter value) error zx.status;
+
+ /// Sets the Option to the argument. On success, a SetOption will take
+ /// effect immediately.
+ ///
+ /// + request `value` an Option whose value will be set to the value of this
+ /// argument.
+ /// * error a zx.status indicating the cause of failure.
+ SetOption(Option value) -> () error zx.status;
+
+ /// Sets the Parameter to the argument. On success, the new parameter value
+ /// can be queried by GetParameter or ListParameter immediately. However,
+ /// the server may require a restart in order for the new Parameter value to
+ /// take effect. To ensure expected operation, administrators should restart
+ /// the server after mutating its parameters with SetParameter or
+ /// ResetParameters.
+ ///
+ /// + request `value` a Parameter whose value will be set to the value of
+ /// this argument.
+ /// * error a zx.status indicating the cause of failure.
+ SetParameter(Parameter value) -> () error zx.status;
+
+ /// Lists all DHCP options for which the Server has a value. Any option
+ /// which does not have a value will be omitted from the returned list.
+ /// ListOptions provides administrators a means to print a server's
+ /// configuration as opposed to querying the value of a single Option.
+ ///
+ /// - response `options` a vector containing all of the options for which
+ /// the Server has a value. Bounded to 256 as options are identified by a 1
+ /// octet code and 256 is the maximum number of such codes.
+ /// * error a zx.status indicating the cause of failure.
+ ListOptions() -> (vector<Option>:256 options) error zx.status;
+
+ /// Lists all DHCP server parameters. ListParameters provides administrators
+ /// a means to print a server's configuration as opposed to querying the
+ /// value of a single Parameter.
+ ///
+ /// - response `parameter` a vector containing the values of all of the
+ /// Server's parameters. Bounded to 256 to provide a generous upper limit
+ /// on the number of server parameters while being of the same size as
+ /// ListOptions.
+ /// * error a zx.status indicating the cause of failure.
+ ListParameters() -> (vector<Parameter>:256 parameters) error zx.status;
+
+ /// Resets all DHCP options to have no value. On success, ResetOptions will
+ /// take effect immediately.
+ ///
+ /// * error a zx.status indicating the cause of failure.
+ ResetOptions() -> () error zx.status;
+
+ /// Resets all DHCP server parameters to their default value. On success,
+ /// the reset parameter values can be queried immediately with GetParameter
+ /// or ListParameters. However, the server must be restarted before all new
+ /// parameter values take effect. To ensure expected operation,
+ /// administrators should restart the server after mutating its parameters
+ /// with SetParameter or ResetParameters.
+ ///
+ /// * error a zx.status indicating the cause of failure.
+ ResetParameters() -> () error zx.status;
+
+ /// Clears all leases maintained by the Server. On success, ClearLeases will
+ /// take effect immediately. Server administrators should take care when
+ /// calling this method as the DHCP protocol does not provide a mechanism by
+ /// which a Server can notify a client that its lease has been cleared.
+ ///
+ /// * error a zx.status indicating the cause of failure.
+ ClearLeases() -> () error zx.status;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.net.http/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.net.http/BUILD.gn
new file mode 100644
index 0000000..584148f
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.net.http/BUILD.gn
@@ -0,0 +1,27 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.net.http") {
+ library_name = "http"
+ namespace = "fuchsia.net"
+ public_deps = [
+ "../fuchsia.mem",
+ "../fuchsia.url",
+ ]
+ sources = [
+ "client.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.net.http",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.net.http/client.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.net.http/client.fidl
new file mode 100644
index 0000000..2c321f9
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.net.http/client.fidl
@@ -0,0 +1,152 @@
+// Copyright 2018 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.
+
+library fuchsia.net.http;
+
+using fuchsia.mem;
+using fuchsia.url;
+using zx;
+
+using Method = string:1024;
+
+/// An error occurred during the HTTP transaction.
+enum Error {
+ /// Some other problem occurred that cannot be classified using one of the
+ /// more specific statuses. Retry is optional.
+ INTERNAL = 1;
+
+ /// An HTTP parse error.
+ UNABLE_TO_PARSE = 2;
+
+ /// Indicates a channel (client or body sender) is closed.
+ CHANNEL_CLOSED = 3;
+
+ /// Error occurred while connecting.
+ CONNECT = 4;
+
+ /// The deadline specified in Request has passed
+ DEADLINE_EXCEEDED = 5;
+};
+
+/// An HTTP header field.
+struct Header {
+ /// The name of the header field.
+ bytes name;
+
+ /// The value of the header field.
+ bytes value;
+};
+
+/// The body of an HTTP request.
+union Body {
+ /// A buffer that will contain the complete request or response body.
+ 1: fuchsia.mem.Buffer buffer;
+
+ /// A socket that will contain the streaming request or response body.
+ 2: handle<socket> stream;
+};
+
+/// An HTTP request.
+table Request {
+ /// The HTTP method if applicable.
+ ///
+ /// Defaults to "GET".
+ 1: Method method;
+
+ /// The URL to load.
+ ///
+ /// Required.
+ 2: fuchsia.url.Url url;
+
+ /// Additional HTTP request headers.
+ 3: vector<Header>:MAX headers;
+
+ /// The payload for the request body. For HTTP requests, the method must be
+ /// set to "POST" or "PUT". If a buffer is used for the body, a
+ /// Content-Length header will automatically be added.
+ 4: Body body;
+
+ /// Determines when to give up on waiting for a response from the server. If no deadline is
+ /// provided, the implementation will provide a reasonable default.
+ 5: zx.time deadline;
+};
+
+/// A description of the redirect the server requested.
+///
+/// The semantics of an HTTP redirect vary according to the status code use to
+/// generate the redirect. This structure ensures that the loader and its client
+/// agree on the interpretation of the redirect response from the server.
+table RedirectTarget {
+ /// The HTTP method the server suggested for the redirect.
+ 1: Method method;
+
+ /// The URL the server suggested for the redirect.
+ 2: fuchsia.url.Url url;
+
+ /// The referrer the server suggested for the redirect.
+ 3: fuchsia.url.Url referrer;
+};
+
+/// A response to an HTTP request.
+table Response {
+ /// If the response resulted in a network level error, this field will be
+ /// set.
+ 1: Error error;
+
+ /// The response body.
+ 2: handle<socket> body;
+
+ /// The final URL of the response, after redirects have been followed.
+ 3: fuchsia.url.Url final_url;
+
+ /// The HTTP status code.
+ 4: uint32 status_code;
+
+ /// The HTTP status line.
+ 5: bytes status_line;
+
+ /// The HTTP response headers.
+ 6: vector<Header>:MAX headers;
+
+ /// A description of the redirect the server requested, if any.
+ 7: RedirectTarget redirect;
+};
+
+/// An HTTP loader.
+///
+/// The loader can service many HTTP requests concurrently. The loader tracks
+/// all the outstanding requests and will cancel them all if the client closes
+/// the loader interface.
+[Discoverable]
+protocol Loader {
+ /// Initiate the given HTTP request, follow redirects, and return the final
+ /// response.
+ ///
+ /// The loader will follow redirects (up to an implementation-defined limit)
+ /// and return the final response as a reply to this message. To cancel the
+ /// request, either close the loader interface or close the peer to the
+ /// `event` included in the `request`.
+ Fetch(Request request) -> (Response response);
+
+ /// Initiate the given HTTP request and return all intermediate responses to
+ /// the given client.
+ ///
+ /// Unlike `Fetch`, `Start` does not automatically follow all redirects.
+ /// Instead, each individual response along the redirect chain is delivered
+ /// to the `LoaderClient`.
+ Start(Request request, LoaderClient client);
+};
+
+/// A client interface used with `Loader.Start`.
+///
+/// Closing the underlying channel will cancel the associated HTTP transaction.
+protocol LoaderClient {
+ /// Called by the loader when the loader receives an HTTP response.
+ ///
+ /// If the server has requested a redirect, then `redirect` in `response`
+ /// table will describe the target the server requested. To follow the
+ /// redirect, reply to this message. To not follow the redirect, close the
+ /// underlying channel.
+ OnResponse(Response response) -> ();
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.net.http/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.net.http/meta.json
new file mode 100644
index 0000000..3ee534c
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.net.http/meta.json
@@ -0,0 +1,12 @@
+{
+ "deps": [
+ "fuchsia.url",
+ "fuchsia.mem"
+ ],
+ "name": "fuchsia.net.http",
+ "root": "fidl/fuchsia.net.http",
+ "sources": [
+ "fidl/fuchsia.net.http/client.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.net.mdns/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.net.mdns/BUILD.gn
new file mode 100644
index 0000000..9168879
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.net.mdns/BUILD.gn
@@ -0,0 +1,26 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.net.mdns") {
+ library_name = "mdns"
+ namespace = "fuchsia.net"
+ public_deps = [
+ "../fuchsia.net",
+ ]
+ sources = [
+ "mdns.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.net.mdns",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.net.mdns/mdns.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.net.mdns/mdns.fidl
new file mode 100644
index 0000000..e55e2d5
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.net.mdns/mdns.fidl
@@ -0,0 +1,308 @@
+// Copyright 2017 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.
+
+library fuchsia.net.mdns;
+
+using fuchsia.net;
+using zx;
+
+// TODO(dalesat): Soft transition in progress.
+// 1) Add the following definitions:
+// Subscriber.SubscribeToService2
+// ServiceSubscriber2
+// Publisher.PublishServiceInstance2
+// PublicationResponder2
+// 2) Transition all clients to the '2' versions.
+// 3) Change the originals to be identical to the '2' versions.
+// 4) Transition all clients to the original names.
+// 5) Remove the '2' versions.
+
+// TODO(FIDL-580): Make these alias comments doc comments.
+
+/// Identifies a host. Host names consist of one or more labels separated by
+/// '.'s. A host name must not end with a '.'. Labels must each be 63 characters
+/// or less (not including the separator) and are UTF-8-encoded. A complete host
+/// name, including separators, must be 255 characters or less.
+using host_name = string:255;
+
+/// Identifies a (type of) service being published. Service names consist of
+/// two labels, both terminated with a '.'. The first label must start with an
+/// underscore and be 16 characters or less, including the underscore. The
+/// second label must be either '_tcp' or '_udp'. Labels do not contain '.'s.
+/// With underscores and terminators, that makes for a maximum of 22 characters.
+/// Service names are UTF-8-encoded.
+using service_name = string:22;
+
+/// Identifies a specific instance of a service being published. Instance names
+/// consist of a single label, which is at most 63 characters long and which
+/// contains no '.'s. Instance names are UTF-8-encoded.
+using instance_name = string:63;
+
+/// Identifies a subtype of a service. Subtype names consist of a single label,
+/// which is at most 63 characters long and which contains no '.'s. Subtype
+/// names are UTF-8-encoded.
+using subtype_name = string:63;
+
+/// Provides description relating to a service instance. In typical use, TXT
+/// strings consist of a key and value separated by '='. TXT strings must be
+/// at most 255 characters long and are UTF-8-encoded.
+using txt_string = string:255;
+
+/// Discoverable protocol for resolving host names to IP addresses.
+[Discoverable]
+protocol Resolver {
+ /// Gets the addresses for the specified host. `timeout` specifies how long
+ /// the service should wait before giving up when waiting for a response to
+ /// a resolution query. In typical use, a timeout of two or three seconds
+ /// is recommended.
+ ///
+ /// A successful resolution may return one or both addresses. An
+ /// unsuccessful resolution is indicated when both addresses are null.
+ ResolveHostName(host_name host, zx.duration timeout)
+ -> (fuchsia.net.Ipv4Address? v4_address,
+ fuchsia.net.Ipv6Address? v6_address);
+};
+
+/// Discoverable protocol for finding service instances.
+[Discoverable]
+protocol Subscriber {
+ /// Subscribes to a service. The subscription lasts until `subscriber` is
+ /// unbound.
+ [Transitional, Deprecated]
+ SubscribeToService(service_name service, ServiceSubscriber subscriber);
+
+ /// Subscribes to a service. The subscription lasts until `subscriber` is
+ /// unbound.
+ [Transitional]
+ SubscribeToService2(service_name service, ServiceSubscriber2 subscriber);
+};
+
+/// Discoverable protocol for publishing service instances.
+[Discoverable]
+protocol Publisher {
+ /// Publishes a service instance. `publication_responder` is consulted via its
+ /// `OnPublication` method for initial announcements and to answer queries.
+ /// The service is published until the `publication_responder` channel closes. In
+ /// addition to announcements and queries for the service type, all queries
+ /// for subtypes are answered subject to filtering through the responder.
+ /// `perform_probe` indicates whether a probe for a conflicting instance
+ /// should be performed before publishing the instance. This value should
+ /// be `true` unless the instance name is known to be unique.
+ [Transitional, Deprecated]
+ PublishServiceInstance(service_name service,
+ instance_name instance,
+ bool perform_probe,
+ PublicationResponder publication_responder) -> () error Error;
+
+ /// Publishes a service instance. `publication_responder` is consulted via its
+ /// `OnPublication` method for initial announcements and to answer queries.
+ /// The service is published until the `publication_responder` channel closes. In
+ /// addition to announcements and queries for the service type, all queries
+ /// for subtypes are answered subject to filtering through the responder.
+ /// `perform_probe` indicates whether a probe for a conflicting instance
+ /// should be performed before publishing the instance. This value should
+ /// be `true` unless the instance name is known to be unique.
+ [Transitional]
+ PublishServiceInstance2(service_name service,
+ instance_name instance,
+ bool perform_probe,
+ PublicationResponder2 publication_responder) -> () error Error;
+};
+
+/// Error values for instance publishing.
+enum Error : int32 {
+ /// The specified service name is invalid.
+ INVALID_SERVICE_NAME = 1;
+
+ /// The specified instance name is invalid.
+ INVALID_INSTANCE_NAME = 2;
+
+ /// The specified service instance is already being published by this
+ /// mDNS implementation.
+ ALREADY_PUBLISHED_LOCALLY = 3;
+
+ /// The specified service instance is already being published by another
+ /// host on the subnet. This result occurs when an initial probe discovers
+ /// a conflicting instance.
+ ALREADY_PUBLISHED_ON_SUBNET = 4;
+};
+
+/// Client-implemented interface for subscribers. Method replies are used to
+/// throttle traffic. The service won't necessarily wait for a reply before
+/// calling another method.
+protocol ServiceSubscriber {
+ /// Notifies the subscriber that a service instance has been discovered.
+ OnInstanceDiscovered(ServiceInstance instance) -> ();
+
+ /// Notifies the subscriber that addresses or text for a known service
+ /// instance have changed.
+ OnInstanceChanged(ServiceInstance instance) -> ();
+
+ /// Notifies the subscriber that a known service instance has been lost.
+ OnInstanceLost(service_name service, instance_name instance) -> ();
+};
+
+/// Client-implemented interface for subscribers. Method replies are used to
+/// throttle traffic. The service won't necessarily wait for a reply before
+/// calling another method.
+protocol ServiceSubscriber2 {
+ /// Notifies the subscriber that a service instance has been discovered.
+ OnInstanceDiscovered(ServiceInstance2 instance) -> ();
+
+ /// Notifies the subscriber that addresses or text for a known service
+ /// instance have changed.
+ OnInstanceChanged(ServiceInstance2 instance) -> ();
+
+ /// Notifies the subscriber that a known service instance has been lost.
+ OnInstanceLost(service_name service, instance_name instance) -> ();
+
+ /// Notifies the subscriber that a PTR query has been sent.
+ OnQuery(ResourceType resource_type) -> ();
+};
+
+/// DNS resource types.
+enum ResourceType {
+ /// Domain name pointer.
+ PTR = 12;
+ /// Any (wildcard) type.
+ ANY = 255;
+};
+
+/// Describes a service instance.
+struct ServiceInstance {
+ /// The name of the service.
+ service_name service;
+
+ /// The name of the service instance.
+ instance_name instance;
+
+ /// Endpoints for the service. If two endpoints are supplied, one will be a
+ /// V4 and the other will be a V6.
+ vector<fuchsia.net.Endpoint>:2 endpoints;
+
+ /// Text strings describing the instance.
+ vector<txt_string>:MAX_TEXT_STRINGS text;
+
+ /// The priority of the SRV resource record for this publication. See
+ /// [RFC6763](https://tools.ietf.org/html/rfc6763) for details.
+ uint16 srv_priority;
+
+ /// The weight of the SRV resource record for this publication. See
+ /// [RFC6763](https://tools.ietf.org/html/rfc6763) for details.
+ uint16 srv_weight;
+};
+
+/// Describes a service instance.
+table ServiceInstance2 {
+ /// The name of the service.
+ 1: service_name service;
+
+ /// The name of the service instance.
+ 2: instance_name instance;
+
+ /// IPv4 socket address for the service. May be unset.
+ 3: fuchsia.net.Ipv4SocketAddress ipv4_endpoint;
+
+ /// IPv6 socket address for the service. May be unset.
+ 4: fuchsia.net.Ipv6SocketAddress ipv6_endpoint;
+
+ /// Text strings describing the instance.
+ 5: vector<txt_string>:MAX_TEXT_STRINGS text;
+
+ /// The priority of the SRV resource record for this publication. See
+ /// [RFC6763](https://tools.ietf.org/html/rfc6763) for details.
+ 6: uint16 srv_priority;
+
+ /// The weight of the SRV resource record for this publication. See
+ /// [RFC6763](https://tools.ietf.org/html/rfc6763) for details.
+ 7: uint16 srv_weight;
+};
+
+/// Client-supplied publication responder interface.
+protocol PublicationResponder {
+ /// Provides instance information for initial announcements and query
+ /// responses relating to the service instance specified in
+ /// `Publisher.PublishServiceInstance`. `query` indicates whether data is
+ /// requested for an initial announcement (false) or in response to a query
+ /// (true). If the publication relates to a subtype of the service,
+ /// `subtype` contains the subtype, otherwise it is null. If `publication`
+ /// is null, no announcement or response is transmitted. Strings in `text`
+ /// are transmitted in the TXT record.
+ OnPublication(bool query, subtype_name? subtype) -> (Publication? publication);
+
+ /// Sets the subtypes for the service instance. The specified subtypes will
+ /// be announced subject to filtering through the responder. The initial
+ /// subtype collection is empty.
+ -> SetSubtypes(vector<subtype_name>:MAX_SUBTYPES subtypes);
+
+ /// Initiates reannouncement of the service instance due to a change in the
+ /// instance's port number or text strings. All announcements are filtered
+ /// through `OnPublication`, which replies with the new port and text
+ /// values.
+ -> Reannounce();
+};
+
+/// Client-supplied publication responder interface.
+protocol PublicationResponder2 {
+ /// Provides instance information for initial announcements and query
+ /// responses relating to the service instance specified in
+ /// `Publisher.PublishServiceInstance`. `query` indicates whether data is
+ /// requested for an initial announcement (false) or in response to a query
+ /// (true). If the publication relates to a subtype of the service,
+ /// `subtype` contains the subtype, otherwise it is null. If `publication`
+ /// is null, no announcement or response is transmitted. Strings in `text`
+ /// are transmitted in the TXT record.
+ OnPublication(
+ bool query, subtype_name? subtype, vector<fuchsia.net.IpAddress>:64 source_addresses)
+ -> (Publication? publication);
+
+ /// Sets the subtypes for the service instance. The specified subtypes will
+ /// be announced subject to filtering through the responder. The initial
+ /// subtype collection is empty.
+ -> SetSubtypes(vector<subtype_name>:MAX_SUBTYPES subtypes);
+
+ /// Initiates reannouncement of the service instance due to a change in the
+ /// instance's port number or text strings. All announcements are filtered
+ /// through `OnPublication`, which replies with the new port and text
+ /// values.
+ -> Reannounce();
+};
+
+/// Describes an initial instance announcement or query response. In typical
+/// use, the default SRV priority, SRV weight and TTL values should be used. TTL
+/// values are rounded down to the nearest second. TTL values less than one
+/// second are not permitted and will result in the `PublicationResponder`
+/// channel being closed.
+struct Publication {
+ /// The port at which the service instance is addressable.
+ uint16 port;
+
+ /// Text strings describing the instance.
+ vector<txt_string>:MAX_TEXT_STRINGS text;
+
+ /// The priority of the SRV resource record for this publication. See
+ /// [RFC6763](https://tools.ietf.org/html/rfc6763) for details.
+ uint16 srv_priority = DEFAULT_SRV_PRIORITY;
+
+ /// The weight of the SRV resource record for this publication. See
+ /// [RFC6763](https://tools.ietf.org/html/rfc6763) for details.
+ uint16 srv_weight = DEFAULT_SRV_WEIGHT;
+
+ /// Time-to-live for PTR resource records.
+ zx.duration ptr_ttl = DEFAULT_PTR_TTL;
+
+ /// Time-to-live for SRV resource records.
+ zx.duration srv_ttl = DEFAULT_SRV_TTL;
+
+ /// Time-to-live for TXT resource records.
+ zx.duration txt_ttl = DEFAULT_TXT_TTL;
+};
+
+const uint16 DEFAULT_SRV_PRIORITY = 0;
+const uint16 DEFAULT_SRV_WEIGHT = 0;
+const zx.duration DEFAULT_PTR_TTL = 4500000000000; // 75 minutes
+const zx.duration DEFAULT_SRV_TTL = 120000000000; // 2 minutes
+const zx.duration DEFAULT_TXT_TTL = 4500000000000; // 75 minutes
+const uint32 MAX_TEXT_STRINGS = 256;
+const uint32 MAX_SUBTYPES = 256;
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.net.mdns/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.net.mdns/meta.json
new file mode 100644
index 0000000..ea5abee
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.net.mdns/meta.json
@@ -0,0 +1,11 @@
+{
+ "deps": [
+ "fuchsia.net"
+ ],
+ "name": "fuchsia.net.mdns",
+ "root": "fidl/fuchsia.net.mdns",
+ "sources": [
+ "fidl/fuchsia.net.mdns/mdns.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.net.oldhttp/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.net.oldhttp/BUILD.gn
new file mode 100644
index 0000000..beaa2ea
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.net.oldhttp/BUILD.gn
@@ -0,0 +1,32 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.net.oldhttp") {
+ library_name = "oldhttp"
+ namespace = "fuchsia.net"
+ public_deps = [
+ "../fuchsia.mem",
+ ]
+ sources = [
+ "http_error.fidl",
+ "http_header.fidl",
+ "http_service.fidl",
+ "url_body.fidl",
+ "url_loader.fidl",
+ "url_request.fidl",
+ "url_response.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.net.oldhttp",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.net.oldhttp/http_error.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.net.oldhttp/http_error.fidl
new file mode 100644
index 0000000..bf1d26f
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.net.oldhttp/http_error.fidl
@@ -0,0 +1,10 @@
+// Copyright 2015 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.
+
+library fuchsia.net.oldhttp;
+
+struct HttpError {
+ int32 code;
+ string? description;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.net.oldhttp/http_header.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.net.oldhttp/http_header.fidl
new file mode 100644
index 0000000..57f1db8
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.net.oldhttp/http_header.fidl
@@ -0,0 +1,10 @@
+// Copyright 2015 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.
+
+library fuchsia.net.oldhttp;
+
+struct HttpHeader {
+ string name;
+ string value;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.net.oldhttp/http_service.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.net.oldhttp/http_service.fidl
new file mode 100644
index 0000000..1d0f02a
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.net.oldhttp/http_service.fidl
@@ -0,0 +1,10 @@
+// Copyright 2015 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.
+
+library fuchsia.net.oldhttp;
+
+[Discoverable]
+protocol HttpService {
+ CreateURLLoader(request<URLLoader> loader);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.net.oldhttp/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.net.oldhttp/meta.json
new file mode 100644
index 0000000..e7cad49
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.net.oldhttp/meta.json
@@ -0,0 +1,17 @@
+{
+ "deps": [
+ "fuchsia.mem"
+ ],
+ "name": "fuchsia.net.oldhttp",
+ "root": "fidl/fuchsia.net.oldhttp",
+ "sources": [
+ "fidl/fuchsia.net.oldhttp/http_error.fidl",
+ "fidl/fuchsia.net.oldhttp/http_header.fidl",
+ "fidl/fuchsia.net.oldhttp/http_service.fidl",
+ "fidl/fuchsia.net.oldhttp/url_body.fidl",
+ "fidl/fuchsia.net.oldhttp/url_loader.fidl",
+ "fidl/fuchsia.net.oldhttp/url_request.fidl",
+ "fidl/fuchsia.net.oldhttp/url_response.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.net.oldhttp/url_body.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.net.oldhttp/url_body.fidl
new file mode 100644
index 0000000..0276868
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.net.oldhttp/url_body.fidl
@@ -0,0 +1,14 @@
+// Copyright 2016 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.
+
+library fuchsia.net.oldhttp;
+
+using fuchsia.mem;
+
+union URLBody {
+ /// A socket that will contain the streaming request or response body.
+ 1: handle<socket> stream;
+ /// A shared buffer that will contain the complete request or response body.
+ 2: fuchsia.mem.Buffer buffer;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.net.oldhttp/url_loader.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.net.oldhttp/url_loader.fidl
new file mode 100644
index 0000000..e93a799
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.net.oldhttp/url_loader.fidl
@@ -0,0 +1,34 @@
+// Copyright 2015 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.
+
+library fuchsia.net.oldhttp;
+
+struct URLLoaderStatus {
+ /// If the loader has failed due to a network level error, this field will be
+ /// set.
+ HttpError? error;
+
+ /// Set to true if the URLLoader is still working. Set to false once an error
+ /// is encountered or the response body is completely copied to the response
+ /// body stream.
+ bool is_loading;
+
+ // TODO(darin): Add further details about the stages of loading (e.g.,
+ // "resolving host") that happen prior to receiving bytes.
+};
+
+protocol URLLoader {
+ /// Loads the given `request`, asynchronously producing `response`. Consult
+ /// `response` to determine if the request resulted in an error, was
+ /// redirected, or has a response body to be consumed.
+ Start(URLRequest request) -> (URLResponse response);
+
+ /// If the request passed to `Start` had `auto_follow_redirects` set to false,
+ /// then upon receiving an URLResponse with a non-NULL `redirect_url` field,
+ /// `FollowRedirect` may be called to load the URL indicated by the redirect.
+ FollowRedirect() -> (URLResponse response);
+
+ /// Query status about the URLLoader.
+ QueryStatus() -> (URLLoaderStatus status);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.net.oldhttp/url_request.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.net.oldhttp/url_request.fidl
new file mode 100644
index 0000000..e6138ff
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.net.oldhttp/url_request.fidl
@@ -0,0 +1,64 @@
+// Copyright 2015 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.
+
+library fuchsia.net.oldhttp;
+
+/// Specify the cache behavior of the request.
+enum CacheMode {
+ /// Default behavior.
+ DEFAULT = 0;
+
+ /// The HTTP request will bypass the local cache and will have a
+ /// 'Cache-Control: nocache' header added in that causes any proxy servers
+ /// to also not satisfy the request from their cache. This has the effect
+ /// of forcing a full end-to-end fetch.
+ BYPASS_CACHE = 1;
+
+ /// The HTTP request will fail if it cannot serve the requested resource
+ /// from the cache (or some equivalent local store).
+ ONLY_FROM_CACHE = 2;
+};
+
+/// Specify the mechanism used to return the response body.
+enum ResponseBodyMode {
+ /// The complete response body should be returned in the `buffer` field of
+ /// the response body.
+ BUFFER = 0;
+ /// The response body should be streamed through the `stream` field of the
+ /// response body.
+ STREAM = 1;
+ /// The response body may be returned as a buffer or stream.
+ BUFFER_OR_STREAM = 2;
+};
+
+struct URLRequest {
+ /// The URL to load.
+ string url;
+
+ /// The HTTP method if applicable.
+ string method = "GET";
+
+ /// Additional HTTP request headers.
+ vector<HttpHeader>? headers;
+
+ /// The payload for the request body. For HTTP requests, the method must be set
+ /// to "POST" or "PUT". If a buffer is used for the body, a Content-Length
+ /// header will automatically be added.
+ URLBody? body;
+
+ /// The buffer size of the socket returned in URLResponse's `body` member.
+ /// A value of 0 indicates that the default buffer size should be used. This
+ /// value is just a suggestion. The URLLoader may choose to ignore this value.
+ uint32 response_body_buffer_size = 0;
+
+ /// If set to true, then redirects will be automatically followed. Otherwise,
+ /// when a redirect is encounterd, FollowRedirect must be called to proceed.
+ bool auto_follow_redirects = false;
+
+ /// The cache behavior for the request.
+ CacheMode cache_mode = CacheMode.DEFAULT;
+
+ /// The response body mode.
+ ResponseBodyMode response_body_mode = ResponseBodyMode.STREAM;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.net.oldhttp/url_response.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.net.oldhttp/url_response.fidl
new file mode 100644
index 0000000..b6dd1f4
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.net.oldhttp/url_response.fidl
@@ -0,0 +1,38 @@
+// Copyright 2015 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.
+
+library fuchsia.net.oldhttp;
+
+struct URLResponse {
+ /// If the response resulted in a network level error, this field will be set.
+ HttpError? error;
+
+ /// The response body.
+ URLBody? body;
+
+ /// The final URL of the response, after redirects have been followed.
+ string? url;
+
+ /// The HTTP status code. 0 if not applicable.
+ uint32 status_code;
+
+ /// The HTTP status line.
+ string? status_line;
+
+ /// The HTTP response headers.
+ vector<HttpHeader>? headers;
+
+ /// The MIME type of the response body.
+ string? mime_type;
+
+ /// The character set of the response body.
+ string? charset;
+
+ /// These fields are set to non-NULL if this response corresponds to a
+ /// redirect. Call the `FollowRedirect` method on the URLLoader instance to
+ /// follow this redirect.
+ string? redirect_method;
+ string? redirect_url;
+ string? redirect_referrer;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.net/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.net/BUILD.gn
new file mode 100644
index 0000000..793d10e
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.net/BUILD.gn
@@ -0,0 +1,28 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.net") {
+ library_name = "net"
+ namespace = "fuchsia"
+ public_deps = [
+ ]
+ sources = [
+ "connectivity.fidl",
+ "namelookup.fidl",
+ "net.fidl",
+ "socket.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.net",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.net/connectivity.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.net/connectivity.fidl
new file mode 100644
index 0000000..453434e
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.net/connectivity.fidl
@@ -0,0 +1,13 @@
+// Copyright 2018 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.
+
+library fuchsia.net;
+
+[Discoverable]
+protocol Connectivity {
+ /// This is triggered on a state change in network reachability. Clients
+ /// should expect that network requests will succeed when `reachable` is
+ /// true.
+ -> OnNetworkReachable(bool reachable);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.net/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.net/meta.json
new file mode 100644
index 0000000..9e6a887
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.net/meta.json
@@ -0,0 +1,12 @@
+{
+ "deps": [],
+ "name": "fuchsia.net",
+ "root": "fidl/fuchsia.net",
+ "sources": [
+ "fidl/fuchsia.net/connectivity.fidl",
+ "fidl/fuchsia.net/namelookup.fidl",
+ "fidl/fuchsia.net/net.fidl",
+ "fidl/fuchsia.net/socket.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.net/namelookup.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.net/namelookup.fidl
new file mode 100644
index 0000000..e40910e
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.net/namelookup.fidl
@@ -0,0 +1,49 @@
+// 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.
+
+library fuchsia.net;
+
+struct IpAddressInfo {
+ /// All of the IPv4 addresses for the requested hostname.
+ vector<Ipv4Address>:256 ipv4_addrs;
+ /// All of the IPv6 addresses for the requested hostname.
+ vector<Ipv6Address>:256 ipv6_addrs;
+ /// The canonical name of the requested hostname (usually the DNS CNAME record, if one exists).
+ string:256? canonical_name;
+};
+
+enum LookupError {
+ /// No result was found for this query.
+ NOT_FOUND = 1;
+ /// The lookup failed, but may succeed at a later time. For instance, the
+ /// network or DNS server may be unreachable.
+ TRANSIENT = 2;
+ /// The lookup failed due to an invalid argument (for instance, the hostname was not encoded
+ /// correctly, or was too long).
+ INVALID_ARGS = 3;
+ /// The lookup failed due to an internal error.
+ INTERNAL_ERROR = 4;
+};
+
+bits LookupIpOptions : uint8 {
+ /// If the lookup should return IPv4 addresses.
+ V4_ADDRS = 0b001;
+ /// If the lookup should return IPv6 addresses.
+ V6_ADDRS = 0b010;
+ /// If the lookup should return a canonical_name, if one exists.
+ CNAME_LOOKUP = 0b100;
+};
+
+const uint64 MAX_HOSTNAME_SIZE = 255;
+
+// TODO(49741): Move to fuchsia.net.name once build unification is done.
+[Discoverable]
+protocol NameLookup {
+ /// Look up a list of IP addresses by hostname.
+ ///
+ /// If `hostname` is an Internationalized Domain Name, it must be encoded as per RFC 3490.
+ LookupIp(string:MAX_HOSTNAME_SIZE hostname, LookupIpOptions options) -> (IpAddressInfo addr) error LookupError;
+ /// Look up a hostname by IP address.
+ LookupHostname(IpAddress addr) -> (string:MAX_HOSTNAME_SIZE hostname) error LookupError;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.net/net.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.net/net.fidl
new file mode 100644
index 0000000..a47f8c7
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.net/net.fidl
@@ -0,0 +1,53 @@
+// Copyright 2018 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.
+
+library fuchsia.net;
+
+/// Ipv4Address is expressed in network byte order, so the most significant byte
+/// ("127" in the address "127.0.0.1") will be at index 0.
+struct Ipv4Address {
+ array<uint8>:4 addr;
+};
+
+/// Ipv6Address is expressed in network byte order, so the most significant byte
+/// ("ff" in the address "ff02::1") will be at index 0.
+struct Ipv6Address {
+ array<uint8>:16 addr;
+};
+
+/// Represents an IP address that may be either v4 or v6.
+union IpAddress {
+ 1: Ipv4Address ipv4;
+ 2: Ipv6Address ipv6;
+};
+
+/// Endpoint describes an IP address and port. The network protocol associated
+/// with the Endpoint will be known from context or communicated through
+/// additional structures.
+struct Endpoint {
+ /// The IP address of the endpoint.
+ IpAddress addr;
+
+ /// The port number of the endpoint.
+ uint16 port;
+};
+
+/// Subnet describes an IP subnetwork, where all host IP addresses share the same most significant
+/// bits.
+struct Subnet {
+ /// The Ipv4 or Ipv6 address. Only the `prefix_len` most significant bits may be set in `addr`;
+ /// all bits in the host portion of the address must be zero.
+ IpAddress addr;
+
+ /// The prefix length of the netmask. E.g. for 192.168.1.0/24, the prefix
+ /// length is 24, corresponding to a netmask of 255.255.255.0.
+ /// For Ipv4, prefix_len must be in the range [0, 32].
+ /// For Ipv6, prefix_len must be in the range [0, 128].
+ uint8 prefix_len;
+};
+
+/// A MAC address used to identify a network interface on the data link layer within the network.
+struct MacAddress {
+ array<uint8>:6 octets;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.net/socket.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.net/socket.fidl
new file mode 100644
index 0000000..9c12453
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.net/socket.fidl
@@ -0,0 +1,47 @@
+// Copyright 2020 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.
+
+library fuchsia.net;
+
+/// An IPv4 socket address, composed of an IPv4 address and a port.
+///
+/// Inspired by the address definition in the [POSIX specification].
+///
+/// [POSIX specification]: https://pubs.opengroup.org/onlinepubs/9699919799/
+struct Ipv4SocketAddress {
+ /// IPv4 Address.
+ Ipv4Address address;
+ /// Transport-layer port.
+ uint16 port;
+};
+
+/// An IPV6 socket address, composed of an IPv6 address, a port, and a scope identifier.
+///
+/// Inspired by the address definition in the [POSIX specification].
+///
+/// [POSIX specification]: https://pubs.opengroup.org/onlinepubs/9699919799/
+struct Ipv6SocketAddress {
+ /// IPv6 Address.
+ Ipv6Address address;
+ /// Transport-layer port.
+ uint16 port;
+ /// Provides a means to identify to which zone a non-global address belongs.
+ ///
+ /// A node may have interfaces attached to different zones of the same scope, for example
+ /// different link-local zones are disambiguated by the use of a `zone_index` providing the
+ /// interface identifier.
+ ///
+ /// `zone_index` 0 is the default zone.
+ ///
+ /// See [RFC 4007] for terminology and examples.
+ ///
+ /// [RFC 4007]: https://tools.ietf.org/html/rfc4007
+ uint64 zone_index;
+};
+
+/// Represents an IP socket address that may be either v4 or v6.
+union SocketAddress {
+ 1: Ipv4SocketAddress ipv4;
+ 2: Ipv6SocketAddress ipv6;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.netstack/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.netstack/BUILD.gn
new file mode 100644
index 0000000..39e800d
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.netstack/BUILD.gn
@@ -0,0 +1,28 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.netstack") {
+ library_name = "netstack"
+ namespace = "fuchsia"
+ public_deps = [
+ "../fuchsia.hardware.ethernet",
+ "../fuchsia.net",
+ "../fuchsia.net.dhcp",
+ ]
+ sources = [
+ "netstack.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.netstack",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.netstack/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.netstack/meta.json
new file mode 100644
index 0000000..47b3015
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.netstack/meta.json
@@ -0,0 +1,13 @@
+{
+ "deps": [
+ "fuchsia.hardware.ethernet",
+ "fuchsia.net.dhcp",
+ "fuchsia.net"
+ ],
+ "name": "fuchsia.netstack",
+ "root": "fidl/fuchsia.netstack",
+ "sources": [
+ "fidl/fuchsia.netstack/netstack.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.netstack/netstack.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.netstack/netstack.fidl
new file mode 100644
index 0000000..d24f2cb
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.netstack/netstack.fidl
@@ -0,0 +1,186 @@
+// Copyright 2013 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.
+
+library fuchsia.netstack;
+
+using fuchsia.net;
+using fuchsia.net.dhcp;
+using fuchsia.hardware.ethernet;
+using zx;
+
+enum Protocol {
+ UNSPECIFIED = 0;
+ UDP = 1;
+ TCP = 2;
+};
+
+enum Status {
+ OK = 0;
+ UNKNOWN_ERROR = 1;
+ DNS_ERROR = 2;
+ PARSE_ERROR = 3;
+ IPV4_ONLY = 4;
+ UNKNOWN_INTERFACE = 5;
+};
+
+struct NetErr {
+ Status status;
+ string message;
+};
+
+struct InterfaceConfig {
+ string name;
+
+ /// An unstable file path corresponding to the interface. Used in watching the creation
+ /// and destruction of the interface, or in accessing the interface using netdump.
+ string filepath;
+
+ uint32 metric;
+ /// Deprecated; to configure a network interface, use SetDhcpClientStatus
+ /// and SetInterfaceAddress instead.
+ IpAddressConfig ip_address_config;
+};
+
+union IpAddressConfig {
+ 1: fuchsia.net.Subnet static_ip;
+ 2: bool dhcp;
+};
+
+/// https://linux.die.net/man/7/netdevice
+struct NetInterface {
+ uint32 id;
+ uint32 flags;
+ uint32 features;
+ uint32 configuration;
+ string name;
+ /// addr is one of the interface's IPv4 addresses, even if the interface
+ /// holds multiple. No guarantees are made about which address is used when
+ /// an interface has multiple IPv4 addresses.
+ ///
+ /// If the interface does not have an IPv4 address, addr is the unspecified
+ /// IPv4 address (0.0.0.0).
+ fuchsia.net.IpAddress addr;
+ /// netmask is addr's corresponding network mask.
+ ///
+ /// If the interface does not have an IPv4 address, netmask is the 0 netmask
+ /// (0.0.0.0).
+ fuchsia.net.IpAddress netmask;
+ /// netmask is addr's corresponding network's broadcast address.
+ ///
+ /// If the interface does not have an IPv4 address, broadaddr is the
+ /// unspecified IPv4 address (0.0.0.0).
+ fuchsia.net.IpAddress broadaddr;
+ vector<fuchsia.net.Subnet> ipv6addrs;
+ bytes hwaddr;
+};
+
+/// New version that includes a metric value.
+// TODO(NET-2078): Move this to NetInterface once Chromium stops using
+// netstack.fidl.
+struct NetInterface2 {
+ uint32 id;
+ uint32 flags;
+ uint32 features;
+ uint32 configuration;
+ uint32 metric;
+ string name;
+ /// addr is one of the interface's IPv4 addresses, even if the interface
+ /// holds multiple. No guarantees are made about which address is used when
+ /// an interface has multiple IPv4 addresses.
+ ///
+ /// If the interface does not have an IPv4 address, addr is the unspecified
+ /// IPv4 address (0.0.0.0).
+ fuchsia.net.IpAddress addr;
+ /// netmask is addr's corresponding network mask.
+ ///
+ /// If the interface does not have an IPv4 address, netmask is the 0 netmask
+ /// (0.0.0.0).
+ fuchsia.net.IpAddress netmask;
+ /// netmask is addr's corresponding network's broadcast address.
+ ///
+ /// If the interface does not have an IPv4 address, broadaddr is the
+ /// unspecified IPv4 address (0.0.0.0).
+ fuchsia.net.IpAddress broadaddr;
+ vector<fuchsia.net.Subnet> ipv6addrs;
+ bytes hwaddr;
+};
+
+/// Flags for NetInterface.flags.
+const uint32 NetInterfaceFlagUp = 0x01; // Set if the interface is up.
+const uint32 NetInterfaceFlagDhcp = 0x02; // Set if DHCP is enabled.
+
+struct RouteTableEntry {
+ fuchsia.net.IpAddress destination;
+ fuchsia.net.IpAddress netmask;
+ fuchsia.net.IpAddress gateway;
+ uint32 nicid;
+};
+
+/// New version that includes a metric value.
+// TODO(NET-2078): Move this to NetInterface once Chromium stops using
+// netstack.fidl.
+struct RouteTableEntry2 {
+ fuchsia.net.IpAddress destination;
+ fuchsia.net.IpAddress netmask;
+ fuchsia.net.IpAddress? gateway;
+ uint32 nicid;
+ uint32 metric;
+};
+
+struct SocketAddress {
+ fuchsia.net.IpAddress addr;
+ uint16 port;
+};
+
+[Discoverable]
+protocol Netstack {
+ /// Returns the list of registered network interfaces.
+ GetInterfaces() -> (vector<NetInterface> interfaces);
+ GetInterfaces2() -> (vector<NetInterface2> interfaces);
+
+ // DEPRECATED: see devicesettings.fidl
+ // Returns the netstack's node name.
+ // 5: GetNodeName() -> (string node_name);
+
+ /// Returns current route table.
+ GetRouteTable() -> (vector<RouteTableEntry> rt);
+ GetRouteTable2() -> (vector<RouteTableEntry2> rt);
+
+ /// Sets the status (up or down) for the interface with the given nicid.
+ SetInterfaceStatus(uint32 nicid, bool enabled);
+
+ /// Sets the address for the interface with the given nicid.
+ /// Masks off addr.PrefixLen bits from addr.Addr to set the subnet.
+ SetInterfaceAddress(uint32 nicid, fuchsia.net.IpAddress addr, uint8 prefixLen) -> (NetErr result);
+
+ /// Removes the address for the interface with the given nicid.
+ /// Masks off addr.PrefixLen bits from addr.Addr to set the subnet.
+ RemoveInterfaceAddress(uint32 nicid, fuchsia.net.IpAddress addr, uint8 prefixLen) -> (NetErr result);
+
+ /// Sets the route metric for the interface with the given nicid.
+ SetInterfaceMetric(uint32 nicid, uint32 metric) -> (NetErr result);
+
+ /// Creates a bridge and returns the newly created nicid or an
+ /// error if the creation fails.
+ BridgeInterfaces(vector<uint32> nicids) -> (NetErr result, uint32 nicid);
+
+ AddEthernetDevice(string topological_path, InterfaceConfig interfaceConfig, fuchsia.hardware.ethernet.Device device) -> (uint32 nicid);
+
+ // TODO(stijlist): re-home this protocol. GetDhcpClient should be a member
+ // of the protocol that eventually owns network interface management
+ // in general.
+ GetDhcpClient(uint32 nicid, request<fuchsia.net.dhcp.Client> client) -> () error zx.status;
+
+ /// Begin a route transaction for atomically getting and setting the route
+ /// table. Returns true if a transaction can be started.
+ StartRouteTableTransaction(request<RouteTableTransaction> routeTableTransaction) -> (zx.status status);
+
+ -> OnInterfacesChanged(vector<NetInterface> interfaces);
+};
+
+[Discoverable]
+protocol RouteTableTransaction {
+ AddRoute(RouteTableEntry2 r) -> (zx.status status);
+ DelRoute(RouteTableEntry2 r) -> (zx.status status);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.posix.socket/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.posix.socket/BUILD.gn
new file mode 100644
index 0000000..2f778a7
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.posix.socket/BUILD.gn
@@ -0,0 +1,26 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.posix.socket") {
+ library_name = "socket"
+ namespace = "fuchsia.posix"
+ public_deps = [
+ "../fuchsia.io",
+ ]
+ sources = [
+ "socket.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.posix.socket",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.posix.socket/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.posix.socket/meta.json
new file mode 100644
index 0000000..ff0b330
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.posix.socket/meta.json
@@ -0,0 +1,11 @@
+{
+ "deps": [
+ "fuchsia.io"
+ ],
+ "name": "fuchsia.posix.socket",
+ "root": "fidl/fuchsia.posix.socket",
+ "sources": [
+ "fidl/fuchsia.posix.socket/socket.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.posix.socket/socket.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.posix.socket/socket.fidl
new file mode 100644
index 0000000..19d966c
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.posix.socket/socket.fidl
@@ -0,0 +1,99 @@
+// 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.
+
+library fuchsia.posix.socket;
+
+using fuchsia.io;
+using zx;
+
+/// Chosen to match `sizeof(struct sockaddr_storage)`.
+using sockaddr = bytes:128;
+
+/// Chosen to be large enough to hold whatever we might want to cram in it. So long as we support
+/// socket options, we don't have a good sense of what we might want to send as payload.
+// TODO(https://fxbug.dev/44347): replace C structures on the wire with FIDL types.
+using sockopt = bytes:900;
+
+/// An interface name as a sequence of bytes.
+// `sizeof((struct ifreq).ifr_name) == 16`; the last byte is reserved for the null terminator.
+using interface_name = string:15;
+
+/// A network socket.
+///
+/// Once a socket has been retrieved from a `Provider`, this interface is then used to further
+/// configure and use the socket. This interface is essentially POSIX. Its implementation must
+/// support Linux-specific arguments to {Get,Set}SockOpt.
+///
+/// All methods on this type are nonblocking; their exact behaviors match their Linux counterparts.
+///
+/// *Warning:* This protocol is not yet ready for direct use by clients. Instead, clients should
+/// use the BSD sockets API to interact with sockets. We plan to change this protocol substantially
+/// and clients that couple directly to this protocol will make those changes more difficult.
+protocol BaseSocket {
+ compose fuchsia.io.Node;
+
+ /// Sets the local address used for the socket.
+ Bind(sockaddr addr) -> () error int32;
+ /// Initiates a connection to a remote address.
+ Connect(sockaddr addr) -> () error int32;
+ /// Retrieves the local socket address.
+ GetSockName() -> (sockaddr addr) error int32;
+ /// Retrieves the remote socket address.
+ GetPeerName() -> (sockaddr addr) error int32;
+ /// Sets the value of a socket option.
+ SetSockOpt(int16 level, int16 optname, sockopt optval) -> () error int32;
+ /// Retrieves the value of a socket option.
+ GetSockOpt(int16 level, int16 optname) -> (sockopt optval) error int32;
+};
+
+/// A datagram socket.
+///
+/// This type's [`fuchsia.io.Node/Describe`] method returns an eventpair which is used to signal
+/// additional information about the state of the socket such as readiness or shutdown-ness.
+///
+/// All methods on this type are nonblocking; their exact behaviors match their Linux counterparts.
+protocol DatagramSocket {
+ compose BaseSocket;
+
+ /// Shuts down part of the socket.
+ Shutdown(int16 how) -> () error int32;
+ /// Receives a message from the socket.
+ RecvMsg(uint32 addr_len, uint32 data_len, uint32 control_len, int16 flags) -> (sockaddr addr, bytes data, bytes control, uint32 truncated) error int32;
+ /// Sends a message on the socket.
+ SendMsg(sockaddr addr, vector<bytes>:MAX data, bytes control, int16 flags) -> (int64 len) error int32;
+ /// Sends a message on the socket.
+ SendMsg2(sockaddr addr, bytes:MAX data, bytes control, int16 flags) -> (int64 len) error int32;
+};
+
+/// A stream socket.
+///
+/// This type's [`fuchsia.io.Node/Describe`] method returns a socket which is used to transfer data
+/// to and from the caller. Signals are used to communicate additional information about the state
+/// of the socket such as connectedness and the presence of incoming connections in the case of a
+/// listening socket.
+///
+/// All methods on this type are nonblocking; their exact behaviors match their Linux counterparts.
+protocol StreamSocket {
+ compose BaseSocket;
+
+ /// Begins listening for new incoming connections. At most `backlog` connections will be
+ /// buffered.
+ Listen(int16 backlog) -> () error int32;
+ /// Accepts a buffered incoming connection.
+ Accept(int16 flags) -> (StreamSocket s) error int32;
+};
+
+/// Provider implements the POSIX sockets API.
+[Discoverable]
+protocol Provider {
+ /// Requests a socket with the specified parameters. Error values are defined in errno.h.
+ Socket2(int16 domain, int16 type, int16 protocol) -> (BaseSocket s) error int32;
+
+ /// Looks up an interface by its index and returns its name. Returns `ZX_ERR_NOT_FOUND` if the
+ /// specified index doesn't exist.
+ InterfaceIndexToName(uint64 index) -> (interface_name name) error zx.status;
+ /// Looks up an interface by its name and returns its index. Returns `ZX_ERR_NOT_FOUND` if the
+ /// specified name doesn't exist.
+ InterfaceNameToIndex(interface_name name) -> (uint64 index) error zx.status;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.process/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.process/BUILD.gn
new file mode 100644
index 0000000..bdeb638
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.process/BUILD.gn
@@ -0,0 +1,28 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.process") {
+ library_name = "process"
+ namespace = "fuchsia"
+ public_deps = [
+ "../fuchsia.io",
+ "../fuchsia.ldsvc",
+ ]
+ sources = [
+ "launcher.fidl",
+ "resolver.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.process",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.process/launcher.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.process/launcher.fidl
new file mode 100644
index 0000000..c792ade
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.process/launcher.fidl
@@ -0,0 +1,161 @@
+// Copyright 2018 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.
+
+library fuchsia.process;
+
+using fuchsia.io;
+using zx;
+
+/// Information about a handle provided to a process at startup.
+///
+/// Processes are given a set of initial handles as part of the bootstrapping
+/// sequence. Some of these handles are associated with zx.procarg identifiers
+/// that designate their intended use by the new process.
+///
+/// This structure represents one such handle and its associated zx.procarg
+/// identifier.
+struct HandleInfo {
+ /// The handle to use for this process argument.
+ handle handle;
+
+ /// Process argument identifier.
+ ///
+ /// See <zircon/processargs.h> for definitions of well-known process
+ /// arguments.
+ zx.procarg id;
+};
+
+/// A namespace entry provided to a process at startup.
+///
+/// Processes are given a set of initial handles as part of the bootstrapping
+/// sequence. Some of these handles are associated with paths that designate
+/// their intended use by the new process as namespace entries.
+///
+/// This structure represents one such handle and its associated namespace path.
+struct NameInfo {
+ /// Path at which to install the associated directory.
+ ///
+ /// Must be an absolute path (i.e., start with '/').
+ string:fuchsia.io.MAX_PATH path;
+
+ /// The associated directory.
+ fuchsia.io.Directory directory;
+};
+
+/// The information needed to launch a process.
+struct LaunchInfo {
+ /// The executable to run in the process.
+ handle<vmo> executable;
+
+ /// The job in which to create the process.
+ handle<job> job;
+
+ /// The name to assign to the created process.
+ string:zx.MAX_NAME_LEN name;
+};
+
+/// The information required to start a process.
+///
+/// To start the process, call `zx_process_start` with the arguments provided.
+struct ProcessStartData {
+ /// The process that was created.
+ handle<process> process;
+
+ /// The vmar object that was created when the process was created.
+ ///
+ /// See <https://fuchsia.dev/fuchsia-src/reference/syscalls/process_create.md>.
+ handle<vmar> root_vmar;
+
+ /// The initial thread for the process.
+ ///
+ /// Should be passed to `zx_process_start` when starting the process.
+ handle<thread> thread;
+
+ /// The address of the initial entry point in the process.
+ ///
+ /// Should be passed to `zx_process_start` when starting the process.
+ zx.vaddr entry;
+
+ /// The stack pointer value for the initial thread of the process.
+ ///
+ /// Should be passed to `zx_process_start` when starting the process.
+ zx.vaddr stack;
+
+ /// The bootstrap channel to pass to the process on startup.
+ ///
+ /// Should be passed to `zx_process_start` when starting the process.
+ handle<channel> bootstrap;
+
+ /// The base address of the vDSO to pass to the process on startup.
+ ///
+ /// Should be passed to `zx_process_start` when starting the process.
+ zx.vaddr vdso_base;
+
+ /// The base load address of the ELF file loaded.
+ ///
+ /// Most often used by debuggers or other tools that inspect the process.
+ zx.vaddr base;
+};
+
+// TODO(fxb/37281): replace with built-in constant
+const uint32 MAX = 0xFFFFFFFF;
+
+/// A low-level interface for launching processes.
+///
+/// This interface is used for manually assembling a process. The caller supplies
+/// all the capabilities for the newly created process.
+///
+/// That create processes typically use `fdio_spawn` or `fdio_spawn_etc` rather
+/// than using this interface directly. The `fdio_spawn` and `fdio_spawn_etc`
+/// functions are implemented using this interface.
+///
+/// Debuggers and other clients that need to create processes in a suspended
+/// state often use this interface directly. These clients use the
+/// `CreateWithoutStarting` method to create the process without actually
+/// starting it.
+[Discoverable]
+protocol Launcher {
+ /// Creates and starts the process described by `info`.
+ ///
+ /// After processing this message, the `Launcher` is reset to its initial
+ /// state and is ready to launch another process.
+ ///
+ /// `process` is present if, and only if, `status` is `ZX_OK`.
+ Launch(LaunchInfo info) -> (zx.status status, handle<process>? process);
+
+ /// Creates the process described by `info` but does not start it.
+ ///
+ /// After processing this message, the `Launcher` is reset to its initial
+ /// state and is ready to launch another process.
+ ///
+ /// The caller is responsible for calling `zx_process_start` using the data
+ /// in `ProcessStartData` to actually start the process.
+ ///
+ /// `data` is present if, and only if, `status` is `ZX_OK`.
+ CreateWithoutStarting(LaunchInfo info) -> (zx.status status,
+ ProcessStartData? data);
+
+ /// Adds the given arguments to the command-line for the process.
+ ///
+ /// Calling this method multiple times concatenates the arguments.
+ AddArgs(vector<vector<uint8>:MAX>:MAX args);
+
+ /// Adds the given variables to the environment variables for the process.
+ ///
+ /// Calling this method multiple times concatenates the variables.
+ AddEnvirons(vector<vector<uint8>:MAX>:MAX environ);
+
+ /// Adds the given names to the namespace for the process.
+ ///
+ /// The paths in the namespace must be non-overlapping. See
+ /// <https://fuchsia.dev/fuchsia-src/concepts/framework/namespaces> for details.
+ ///
+ /// Calling this method multiple times concatenates the names.
+ AddNames(vector<NameInfo>:MAX names);
+
+ /// Adds the given handles to the startup handles for the process.
+ ///
+ /// Calling this method multiple times concatenates the handles.
+ AddHandles(vector<HandleInfo>:MAX handles);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.process/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.process/meta.json
new file mode 100644
index 0000000..1f0f000
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.process/meta.json
@@ -0,0 +1,13 @@
+{
+ "deps": [
+ "fuchsia.io",
+ "fuchsia.ldsvc"
+ ],
+ "name": "fuchsia.process",
+ "root": "fidl/fuchsia.process",
+ "sources": [
+ "fidl/fuchsia.process/launcher.fidl",
+ "fidl/fuchsia.process/resolver.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.process/resolver.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.process/resolver.fidl
new file mode 100644
index 0000000..41c0f7c
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.process/resolver.fidl
@@ -0,0 +1,44 @@
+// Copyright 2018 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.
+
+library fuchsia.process;
+
+using fuchsia.ldsvc;
+using zx;
+
+/// The maximum size for a name used by `Resolver`.
+const uint32 MAX_RESOLVE_NAME_SIZE = 2048;
+
+/// An interface for resolving names to executables and library loaders.
+///
+/// An executable itself is often not sufficient to create a working process
+/// because many executables also load shared libraries. On Fuchsia, there is no
+/// global pool of shared libraries. Instead, every process has an associated
+/// `fuchsia.ldsvc.Loader`, which provides access to a private pool of shared
+/// libraries appropriate for that process.
+///
+/// This interface provides a protocol for resolving a name into both the
+/// `handle<vmo>` for the executable and the `fuchsia.ldsvc.Loader` for its
+/// associated shared libraries.
+///
+/// This interface is rarely used directly. Instead, `fdio_spawn` and
+/// `fdio_spawn_etc` use this interface internally when they try to run a file
+/// with a `#!resolve` directive.
+[Discoverable, Layout = "Simple"]
+protocol Resolver {
+ /// Resolves the given `name` to an `executable` and an shared library
+ /// loader.
+ ///
+ /// If present, the `executable` is suitable for use as the `executable`
+ /// property of `LaunchInfo` -- in particular, it will have `ZX_RIGHT_EXECUTE`.
+ /// If present, the `ldsvc` is suitable for use as the `PA_LDSVC_LOADER`
+ /// handle when launching the process.
+ ///
+ /// For example, the resolver might locate the given `name` inside a package
+ /// and return the executable binary from the package as well as a shared
+ /// library loader scoped to that package.
+ Resolve(string:MAX_RESOLVE_NAME_SIZE name) -> (zx.status status,
+ handle<vmo>? executable,
+ fuchsia.ldsvc.Loader? ldsvc);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.recovery.ui/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.recovery.ui/BUILD.gn
new file mode 100644
index 0000000..7e949cb
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.recovery.ui/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.recovery.ui") {
+ library_name = "ui"
+ namespace = "fuchsia.recovery"
+ public_deps = [
+ ]
+ sources = [
+ "countdown.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.recovery.ui",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.recovery.ui/countdown.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.recovery.ui/countdown.fidl
new file mode 100644
index 0000000..0aeec1e
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.recovery.ui/countdown.fidl
@@ -0,0 +1,26 @@
+// 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.
+
+library fuchsia.recovery.ui;
+
+using zx;
+
+/// Information provided through the FactoryResetCountdown protocol on the
+/// current factory reset state.
+table FactoryResetCountdownState {
+ /// The time of when factory reset is scheduled to be triggered when a
+ /// countdown for factory reset is in progress with respect to the monotonic
+ /// clock. This field is left unpopulated if no reset is scheduled.
+ 1: zx.time scheduled_reset_time;
+};
+
+/// Protocol to watch for changes when a factory reset countdown is started or
+/// cancelled. An immediate factory reset does not start a countdown.
+[Discoverable]
+protocol FactoryResetCountdown {
+ /// Hanging get that returns when a factory reset is scheduled or a
+ /// scheduled factory reset is cancelled. Will return immediately on first
+ /// call per connection and then on change after that.
+ Watch() -> (FactoryResetCountdownState state);
+};
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.recovery.ui/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.recovery.ui/meta.json
new file mode 100644
index 0000000..336a427
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.recovery.ui/meta.json
@@ -0,0 +1,9 @@
+{
+ "deps": [],
+ "name": "fuchsia.recovery.ui",
+ "root": "fidl/fuchsia.recovery.ui",
+ "sources": [
+ "fidl/fuchsia.recovery.ui/countdown.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.recovery/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.recovery/BUILD.gn
new file mode 100644
index 0000000..9e08cbc
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.recovery/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.recovery") {
+ library_name = "recovery"
+ namespace = "fuchsia"
+ public_deps = [
+ ]
+ sources = [
+ "factory_reset.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.recovery",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.recovery/factory_reset.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.recovery/factory_reset.fidl
new file mode 100644
index 0000000..bb1750d
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.recovery/factory_reset.fidl
@@ -0,0 +1,15 @@
+// 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.
+
+library fuchsia.recovery;
+
+using zx;
+
+/// A protocol for intitiating a factory reset.
+[Discoverable]
+protocol FactoryReset {
+ /// Request an immediate factory reset. If unsuccessful will return an
+ /// error.
+ Reset() -> (zx.status status);
+};
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.recovery/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.recovery/meta.json
new file mode 100644
index 0000000..87cbc62
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.recovery/meta.json
@@ -0,0 +1,9 @@
+{
+ "deps": [],
+ "name": "fuchsia.recovery",
+ "root": "fidl/fuchsia.recovery",
+ "sources": [
+ "fidl/fuchsia.recovery/factory_reset.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.scenic.scheduling/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.scenic.scheduling/BUILD.gn
new file mode 100644
index 0000000..6be24fa
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.scenic.scheduling/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.scenic.scheduling") {
+ library_name = "scheduling"
+ namespace = "fuchsia.scenic"
+ public_deps = [
+ ]
+ sources = [
+ "prediction_info.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.scenic.scheduling",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.scenic.scheduling/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.scenic.scheduling/meta.json
new file mode 100644
index 0000000..c77cb07
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.scenic.scheduling/meta.json
@@ -0,0 +1,9 @@
+{
+ "deps": [],
+ "name": "fuchsia.scenic.scheduling",
+ "root": "fidl/fuchsia.scenic.scheduling",
+ "sources": [
+ "fidl/fuchsia.scenic.scheduling/prediction_info.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.scenic.scheduling/prediction_info.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.scenic.scheduling/prediction_info.fidl
new file mode 100644
index 0000000..9ee2eff
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.scenic.scheduling/prediction_info.fidl
@@ -0,0 +1,67 @@
+// 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.
+
+library fuchsia.scenic.scheduling;
+
+using zx;
+
+/// The times we predict for a future presentation, expressed in nanoseconds in
+/// the `CLOCK_MONOTONIC` timebase.
+table PresentationInfo {
+ /// The time where Scenic processes all pending updates to its scene graph
+ /// and render a new frame. Clients should aim to have all commands sent
+ /// and acquire fences reached in order to have their content be
+ /// presented at the corresponding `presentation_time`. The `latch_point`
+ /// is guaranteed to be less than `presentation_time`.
+ 1: zx.time latch_point;
+
+ /// The time in which the enqueued operations submitted before `latch_point`
+ /// take visible effect. This time is usually but not necessarily vsync.
+ 2: zx.time presentation_time;
+};
+
+/// The times we record for each Present2, expressed in nanoseconds in the
+/// `CLOCK_MONOTONIC` timebase.
+table PresentReceivedInfo {
+ /// The time Scenic receives the Present2 call.
+ 1: zx.time present_received_time;
+
+ /// The time Scenic latched the Present2 call to. This is guaranteed to be
+ /// greater than the `present_received_time`.
+ 2: zx.time latched_time;
+};
+
+/// The data type returned in `fuchsia.ui.scenic::RequestPresentationTimes`. See
+/// that method description for more information.
+struct FuturePresentationTimes {
+ /// The future estimated presentation times. They represent the times Scenic
+ /// intends to let the client's work be presented over the next few frames.
+ /// These values may change after they are queried.
+ ///
+ /// Clients who wish to minimize latency should use these values to schedule
+ /// their work accordingly.
+ vector<PresentationInfo>:8 future_presentations;
+
+ /// The amount of Present() calls the client is currently allowed. If the
+ /// client calls Present() when this number is zero, the session will be
+ /// shut down.
+ ///
+ /// This value is decremented every Present() call, and is incremented every
+ /// OnFramePresented() event.
+ int64 remaining_presents_in_flight_allowed;
+};
+
+struct FramePresentedInfo {
+ /// The time the frame was presented to the user. This value was captured
+ /// after the fact, differentiating it from the `presentation_time`s
+ /// included in `FuturePresentationTimes`.
+ zx.time actual_presentation_time;
+
+ /// The presentation informations for each Present2() that comprised the
+ /// content of this frame. These are ordered by present submission order.
+ vector<PresentReceivedInfo>:32 presentation_infos;
+
+ /// The number of times remaining that the client can call `Present2`.
+ uint64 num_presents_allowed;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.settings/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.settings/BUILD.gn
new file mode 100644
index 0000000..9756339
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.settings/BUILD.gn
@@ -0,0 +1,38 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.settings") {
+ library_name = "settings"
+ namespace = "fuchsia"
+ public_deps = [
+ "../fuchsia.intl",
+ "../fuchsia.media",
+ "../fuchsia.ui.types",
+ ]
+ sources = [
+ "accessibility.fidl",
+ "audio.fidl",
+ "device.fidl",
+ "display.fidl",
+ "do_not_disturb.fidl",
+ "intl.fidl",
+ "night_mode.fidl",
+ "privacy.fidl",
+ "settings.fidl",
+ "setup.fidl",
+ "system.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.settings",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.settings/accessibility.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.settings/accessibility.fidl
new file mode 100644
index 0000000..9d6a9de
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.settings/accessibility.fidl
@@ -0,0 +1,135 @@
+// 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.
+
+library fuchsia.settings;
+
+using fuchsia.ui.types;
+
+/// Modify or watch accessibility settings that are persisted.
+///
+/// Supported SettingsEpitaph enums:
+/// REQUEST_NOT_SUPPORTED, INTERNAL_SERVICE_ERROR, PERSISTENT_STORAGE_ERROR
+[Discoverable]
+protocol Accessibility {
+ /// This call may fail if AccessibilitySettings are not accessible, possibly because of file
+ /// system errors, not being supported on this product, or general service failures.
+ ///
+ /// DEPRECATED: new watches should use Watch2.
+ [Transitional = "Deprecated in favor of Watch2"]
+ Watch() -> (AccessibilitySettings settings) error Error;
+
+ /// Gets the current value of all accessibility settings. Returns
+ /// immediately on first call; subsequent calls return when any of the
+ /// values change.
+ ///
+ /// - `settings` all current values of the accessibility settings.
+ /// * see [`AccessibilitySettings`] for their meaning.
+ ///
+ /// If this call fails, it is considered a fatal error and the channel
+ /// will be closed.
+ [Transitional = "Replacement for Watch"]
+ Watch2() -> (AccessibilitySettings settings);
+
+ /// Sets [AccessibilitySettings] settings. Any field not explicitly set in the table performs a
+ /// no-op, and will not make any changes.
+ Set(AccessibilitySettings settings) -> () error Error;
+};
+
+/// Supported accessibility settings.
+table AccessibilitySettings {
+ /// For videos, use an alternative audio track (akin to changing languages)
+ /// that explains what is happening visually while there is no dialogue.
+ 1: bool audio_description;
+
+ /// Read aloud elements of the screen selected by the user.
+ 2: bool screen_reader;
+
+ /// Invert colors on the screen.
+ 3: bool color_inversion;
+
+ /// Interpret triple-tap on the touchscreen as a command to zoom in.
+ 4: bool enable_magnification;
+
+ /// What type of color-blindness, if any, to correct for.
+ 5: ColorBlindnessType color_correction;
+
+ /// What kind of sources get closed captions, and how they look.
+ 6: CaptionsSettings captions_settings;
+};
+
+enum ColorBlindnessType {
+ /// No color blindness.
+ NONE = 0;
+
+ /// Red-green color blindness due to reduced sensitivity to red light.
+ PROTANOMALY = 1;
+
+ /// Red-green color blindness due to reduced sensitivity to green light.
+ DEUTERANOMALY = 2;
+
+ /// Blue-yellow color blindness. It is due to reduced sensitivity to blue
+ /// light.
+ TRITANOMALY = 3;
+};
+
+/// What kind of sources get closed captions, and how they look.
+table CaptionsSettings {
+ /// Closed captions enabled for media sources of audio.
+ 1: bool for_media;
+
+ /// Closed captions enabled for Text-To-Speech sources of audio.
+ 2: bool for_tts;
+
+ /// Font style and color used for the closed captions text.
+ 3: CaptionFontStyle font_style;
+
+ /// Border color used around the closed captions window.
+ 4: fuchsia.ui.types.ColorRgba window_color;
+
+ /// Background color of the closed captions window.
+ 5: fuchsia.ui.types.ColorRgba background_color;
+};
+
+/// Font, size, and color of closed captions text.
+table CaptionFontStyle {
+ 1: CaptionFontFamily family;
+ /// 47 CFR §79.103(c)(2) requires at least 3-bit RGB for user override of
+ /// closed-captions color.
+ 2: fuchsia.ui.types.ColorRgba color;
+ /// Size of closed captions text relative to the default captions size. A
+ /// range of [0.5, 2] is guaranteed to be supported (as 47 CFR §79.103(c)(4)
+ /// establishes).
+ 3: float32 relative_size;
+ 4: EdgeStyle char_edge_style;
+};
+
+/// Font family groups for closed captions, specified by 47 CFR §79.102(k).
+enum CaptionFontFamily {
+ UNKNOWN = 0;
+ MONOSPACED_SERIF = 1;
+ PROPORTIONAL_SERIF = 2;
+ MONOSPACED_SANS_SERIF = 3;
+ PROPORTIONAL_SANS_SERIF = 4;
+ CASUAL = 5;
+ CURSIVE = 6;
+ SMALL_CAPITALS = 7;
+};
+
+/// Edge style for fonts as specified in 47 CFR §79.103(c)(7)
+enum EdgeStyle {
+ /// No border around fonts.
+ NONE = 0;
+
+ /// A shadow "behind" and slightly offset from each edge.
+ DROP_SHADOW = 1;
+
+ /// A bevel that mimics a 3D raised effect.
+ RAISED = 2;
+
+ /// A bevel that mimics a 3D depressed effect.
+ DEPRESSED = 3;
+
+ /// A plain border around each shapes.
+ OUTLINE = 4;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.settings/audio.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.settings/audio.fidl
new file mode 100644
index 0000000..77858b2
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.settings/audio.fidl
@@ -0,0 +1,78 @@
+// 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.
+
+library fuchsia.settings;
+
+using fuchsia.media;
+
+/// Settings related to audio.
+///
+/// Supported SettingsEpitaph enums:
+/// REQUEST_NOT_SUPPORTED, INTERNAL_SERVICE_ERROR, PERSISTENT_STORAGE_ERROR
+[Discoverable]
+protocol Audio {
+ /// DEPRECATED: new watches should use Watch2.
+ [Transitional = "Deprecated in favor of Watch2"]
+ Watch() -> (AudioSettings settings) error Error;
+
+ /// Gets the current [AudioSettings]. Returns immediately on first call;
+ /// subsequent calls return when the value changes.
+ ///
+ /// If this call fails, it is considered a fatal error and the channel
+ /// will be closed.
+ [Transitional = "Replacement for Watch"]
+ Watch2() -> (AudioSettings settings);
+
+ /// Sets audio settings. Any field not explicitly set in the table performs a
+ /// no-op, and will not make any changes.
+ Set(AudioSettings settings) -> () error Error;
+};
+
+/// The source of the volume settings. The volume is set according to the source.
+enum AudioStreamSettingSource {
+
+ /// The volume is set by the user. When the `source` in AudioStreamSettings is
+ /// set to this, the audio volume is set to `user_volume`.
+ USER = 0;
+
+ /// The system takes control of the volume. This is used when the system constantly
+ /// calculates and changes the volume. The volume is not stored for this source.
+ SYSTEM = 1;
+};
+
+table Volume {
+ /// The volume level ranged [0.0, 1.0]. The level maps to a dbfs value from a volume
+ /// curve in the setting service.
+ 1: float32 level;
+
+ /// True if the volume should be muted. If this is true, then the volume is silent,
+ /// regardless of `level`.
+ 2: bool muted;
+};
+
+table AudioStreamSettings {
+ /// The audio stream which the settings are applying to.
+ 1: fuchsia.media.AudioRenderUsage stream;
+
+ /// The volume of `stream` is set according to the volume settings from `source`.
+ 2: AudioStreamSettingSource source;
+
+ /// User level volume setting. If the `source` is USER, then the volume is set to
+ /// `user_volume`.
+ 3: Volume user_volume;
+};
+
+table AudioSettings {
+ /// Contains the volume setting for all audio stream settings. There should only be
+ /// one AudioStreamSettings for each fuchsia.media.AudioRenderUsage.
+ 1: vector<AudioStreamSettings>:5 streams;
+
+ /// Settings related to the audio input.
+ 2: AudioInput input;
+};
+
+table AudioInput {
+ /// Whether the audio input is muted. Takes into consideration the hardware state.
+ 1: bool muted;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.settings/device.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.settings/device.fidl
new file mode 100644
index 0000000..2548255
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.settings/device.fidl
@@ -0,0 +1,29 @@
+// 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.
+
+library fuchsia.settings;
+
+/// Settings related to device info.
+///
+/// Supported SettingsEpitaph enums:
+/// FILE_READ_ERROR, INTERNAL_SERVICE_ERROR
+[Discoverable]
+protocol Device {
+ /// Notifies of a change in information about the device.
+ ///
+ /// On a given connection, the first call will return the current `settings` value while
+ /// subsequent calls will only return the new `settings` value upon a value change. This
+ /// follows the hanging get pattern.
+ ///
+ /// If this call fails, it is considered a fatal error and the channel
+ /// will be closed.
+ Watch() -> (DeviceSettings device_settings);
+};
+
+/// Information about the device.
+table DeviceSettings {
+ /// The identifier representing the specific build that the device
+ /// is currently running. Read-only field, cannot be set by client.
+ 1: string:50 build_tag;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.settings/display.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.settings/display.fidl
new file mode 100644
index 0000000..7b0ce61
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.settings/display.fidl
@@ -0,0 +1,67 @@
+// 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.
+
+library fuchsia.settings;
+
+using fuchsia.ui.types;
+
+/// Settings related to display.
+///
+/// Supported SettingsEpitaph enums:
+/// REQUEST_NOT_SUPPORTED, INTERNAL_SERVICE_ERROR, PERSISTENT_STORAGE_ERROR
+[Discoverable]
+protocol Display {
+ /// DEPRECATED: new watches should use Watch2.
+ [Transitional = "Deprecated in favor of Watch2"]
+ Watch() -> (DisplaySettings settings) error Error;
+
+ /// Gets the current [DisplaySettings]. Returns immediately on first call;
+ /// subsequent calls return when the value changes.
+ ///
+ /// If this call fails, it is considered a fatal error and the channel
+ /// will be closed.
+ [Transitional = "Replacement for Watch"]
+ Watch2() -> (DisplaySettings settings);
+
+ /// DEPRECATED: new watches should use WatchLightSensor2.
+ [Transitional = "Deprecated in favor of WatchLightSensor2"]
+ WatchLightSensor(float32 delta) -> (LightSensorData light_sensor_data) error Error;
+
+ /// Obtains the current data from the light sensor. Returns immediately on
+ /// first call; subsequent calls return when the light sensor value changes
+ /// by a certain amount measured in lux.
+ ///
+ /// If this call fails, it is considered a fatal error and the channel
+ /// will be closed.
+ [Transitional = "Replacement for WatchLightSensor"]
+ WatchLightSensor2(float32 delta) -> (LightSensorData light_sensor_data);
+
+ /// Sets display settings. Any field not explicitly set in the table performs a
+ /// no-op, and will not make any changes.
+ Set(DisplaySettings settings) -> () error Error;
+};
+
+/// DisplaySettings are used to determine the output state of the display.
+/// The display can be toggled between two modes, auto-brightness on and
+/// auto-brightness off. When auto-brightness is on a manual offset to the
+/// total output brightness can be applied by setting `user_brightness_offset`.
+/// When auto-brightness is off the display brightness is set manually by
+/// setting brightness_value. All values can be set at any time to persist
+/// settings for either mode.
+table DisplaySettings {
+ /// Auto brightness enabled
+ 1: bool auto_brightness;
+ /// Manually set brightness value [0.0 - 1.0]
+ 2: float32 brightness_value;
+ /// User defined offset to the total auto brightness output [-1.0 - 1.0]
+ 3: float32 user_brightness_offset;
+};
+
+table LightSensorData {
+ /// Brightness from the light sensor measured in lux.
+ 1: float32 illuminance_lux;
+
+ /// Color measured by light sensor in rgb.
+ 2: fuchsia.ui.types.ColorRgb color;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.settings/do_not_disturb.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.settings/do_not_disturb.fidl
new file mode 100644
index 0000000..5ef63b5
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.settings/do_not_disturb.fidl
@@ -0,0 +1,53 @@
+// 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.
+
+library fuchsia.settings;
+
+/// Modify or watch do-not-disturb (DND) mode. While DND is active, distractions
+/// created by the device are reduced or eliminated. E.g. bootup is silent,
+/// incoming calls could be rejected or silent, and notifications could be
+/// paused, silent, or hidden. High-priority disruptions like alarms can be
+/// allowed.
+///
+/// Supported SettingsEpitaph enums:
+/// REQUEST_NOT_SUPPORTED, INTERNAL_SERVICE_ERROR, PERSISTENT_STORAGE_ERROR
+[Discoverable]
+protocol DoNotDisturb {
+ /// Gets the current [`DoNotDisturbSettings`]. Returns immediately on first
+ /// call; subsequent calls return when the values change.
+ ///
+ /// If this call fails, it is considered a fatal error and the channel
+ /// will be closed.
+ Watch() -> (DoNotDisturbSettings settings);
+
+ /// Sets [`DoNotDisturbSettings`] settings. Any field not explicitly set in
+ /// the table performs a no-op, and will not make any changes.
+ Set(DoNotDisturbSettings settings) -> () error Error;
+};
+
+/// Settings related to do-not-disturb (DND) mode.
+table DoNotDisturbSettings {
+ /// If true, the device is in do-not-disturb (DND) mode. Change this value
+ /// if you're directly responding to a user-initiated event.
+ ///
+ /// Note that the device could still be in DND mode even if this is set to
+ /// `false`, as [`night_mode_initiated_do_not_disturb`] might be `true`. To
+ /// actually disable DND mode, set both fields to `false`.
+ ///
+ /// To know whether DND is enabled, you need to do a boolean OR of both
+ /// fields.
+ 1: bool user_initiated_do_not_disturb;
+
+ /// If true, the device is in do-not-disturb (DND) mode. Change this value
+ /// if you're trying to enable or disable DND based on a nightly schedule.
+ ///
+ /// Note that the device could still be in DND mode even if this is set to
+ /// `false`, as [`user_initiated_do_not_disturb`] might be `true`. Do not
+ /// set that field to `false` unless you're directly responding to a
+ /// user-initiated event.
+ ///
+ /// To know whether DND is enabled, you need to do a boolean OR of both
+ /// fields.
+ 2: bool night_mode_initiated_do_not_disturb;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.settings/intl.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.settings/intl.fidl
new file mode 100644
index 0000000..ce20d2e
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.settings/intl.fidl
@@ -0,0 +1,65 @@
+// 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.
+
+library fuchsia.settings;
+
+using fuchsia.intl;
+
+/// Settings related to internationalization such as locale, time zone, and
+/// temperature units.
+///
+/// Supported SettingsEpitaph enums:
+/// REQUEST_NOT_SUPPORTED, INTERNAL_SERVICE_ERROR, PERSISTENT_STORAGE_ERROR,
+/// FILE_READ_ERROR
+[Discoverable]
+protocol Intl {
+ /// DEPRECATED: new watches should use Watch2.
+ [Transitional = "Deprecated in favor of Watch2"]
+ Watch() -> (IntlSettings settings) error Error;
+
+ /// Gets the current [IntlSettings]. Returns immediately on first call;
+ /// subsequent calls return when the value changes.
+ ///
+ /// If this call fails, it is considered a fatal error and the channel
+ /// will be closed.
+ [Transitional = "Replacement for Watch"]
+ Watch2() -> (IntlSettings settings);
+
+ /// Sets [IntlSettings] settings. Any field not explicitly set in the table performs a
+ /// no-op, and will not make any changes.
+ Set(IntlSettings settings) -> () error Error;
+};
+
+/// Whether if the time format should be using 12 hour or 24 hour clock. H indicates the
+/// maximum number that the hour indicator will ever show.
+enum HourCycle {
+ UNKNOWN = 0;
+
+ /// 12-hour clock, 0:10am after midnight.
+ H11 = 1;
+
+ /// 12-hour clock, 12:10am after midnight.
+ H12 = 2;
+
+ /// 24-hour clock, 0:10 after midnight.
+ H23 = 3;
+
+ /// 24-hour clock, 24:10 after midnight.
+ H24 = 4;
+};
+
+/// Collection of internationalization-related settings.
+table IntlSettings {
+ /// An ordered list of preferred locales.
+ 1: vector<fuchsia.intl.LocaleId>:10 locales;
+
+ /// The preferred temperature unit.
+ 2: fuchsia.intl.TemperatureUnit temperature_unit;
+
+ /// The currently set time zone.
+ 3: fuchsia.intl.TimeZoneId time_zone_id;
+
+ /// The preferred hour cycle.
+ 4: HourCycle hour_cycle;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.settings/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.settings/meta.json
new file mode 100644
index 0000000..2ae9c0b
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.settings/meta.json
@@ -0,0 +1,23 @@
+{
+ "deps": [
+ "fuchsia.intl",
+ "fuchsia.media",
+ "fuchsia.ui.types"
+ ],
+ "name": "fuchsia.settings",
+ "root": "fidl/fuchsia.settings",
+ "sources": [
+ "fidl/fuchsia.settings/accessibility.fidl",
+ "fidl/fuchsia.settings/audio.fidl",
+ "fidl/fuchsia.settings/device.fidl",
+ "fidl/fuchsia.settings/display.fidl",
+ "fidl/fuchsia.settings/do_not_disturb.fidl",
+ "fidl/fuchsia.settings/intl.fidl",
+ "fidl/fuchsia.settings/night_mode.fidl",
+ "fidl/fuchsia.settings/privacy.fidl",
+ "fidl/fuchsia.settings/settings.fidl",
+ "fidl/fuchsia.settings/setup.fidl",
+ "fidl/fuchsia.settings/system.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.settings/night_mode.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.settings/night_mode.fidl
new file mode 100644
index 0000000..c7ef742
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.settings/night_mode.fidl
@@ -0,0 +1,35 @@
+// Copyright 2020 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.
+
+library fuchsia.settings;
+
+/// Modify or watch Night Mode setting. Night mode puts the device in a
+/// restricted mode which can be overrided if the user prefers. During night
+/// mode, the following settings apply as per night mode parameters:
+/// 1. DoNotDisturb is enabled/not.
+/// 2. System volume is set to an override maximum.
+/// 3. LED Brightness is set to an overridable maximum.
+/// 4. Sleep mode is enabled/not.
+///
+/// Supported SettingsEpitaph enums:
+/// REQUEST_NOT_SUPPORTED, INTERNAL_SERVICE_ERROR, PERSISTENT_STORAGE_ERROR
+[Discoverable]
+protocol NightMode {
+ /// Gets the current [`NightModeSettings`]. Returns immediately on first
+ /// call; subsequent calls return when the values change.
+ ///
+ /// If this call fails, it is considered a fatal error and the channel
+ /// will be closed.
+ Watch() -> (NightModeSettings settings);
+
+ /// Sets [`NightModeSettings`] settings. Any field not explicitly set in
+ /// the table performs a no-op, and will not make any changes.
+ Set(NightModeSettings settings) -> () error Error;
+};
+
+/// Settings related to Night mode.
+table NightModeSettings {
+ /// If true, the device/user have opted in for NightMode routine.
+ 1: bool night_mode_enabled;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.settings/privacy.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.settings/privacy.fidl
new file mode 100644
index 0000000..5c996d1
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.settings/privacy.fidl
@@ -0,0 +1,37 @@
+// 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.
+
+library fuchsia.settings;
+
+/// Settings related to privacy.
+///
+/// Supported SettingsEpitaph enums:
+/// REQUEST_NOT_SUPPORTED, INTERNAL_SERVICE_ERROR, PERSISTENT_STORAGE_ERROR
+[Discoverable]
+protocol Privacy {
+ /// DEPRECATED: new watches should use Watch2.
+ [Transitional = "Deprecated in favor of Watch2"]
+ Watch() -> (PrivacySettings settings) error Error;
+
+ /// Notifies of a change in privacy settings.
+ ///
+ /// On a given connection, the server will return immediately if this is the first call made,
+ /// or if the `settings` value has changed since a previous call. Otherwise, the server will
+ /// wait on a value change before returning the new value. This follows the hanging get pattern.
+ ///
+ /// If this call fails, it is considered a fatal error and the channel will be closed.
+ [Transitional = "Replacement for Watch"]
+ Watch2() -> (PrivacySettings settings);
+
+ /// Sets the privacy settings.
+ ///
+ /// Any field not explicitly set in `settings` performs a no-op, and will not make any changes.
+ Set(PrivacySettings settings) -> () error Error;
+};
+
+table PrivacySettings {
+ /// Reflects the user consent to have their user data shared with the product owner, e.g., for
+ /// metrics collection and crash reporting.
+ 1: bool user_data_sharing_consent;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.settings/settings.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.settings/settings.fidl
new file mode 100644
index 0000000..582bb3a
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.settings/settings.fidl
@@ -0,0 +1,26 @@
+// 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.
+
+library fuchsia.settings;
+
+/// Common error code used across different settings.
+enum Error {
+ FAILED = 1;
+ UNSUPPORTED = 2;
+};
+
+/// Common epitaph messages used across different settings.
+enum SettingsEpitaph {
+ // The request to the service is not supported. The client should not try to reconnect.
+ REQUEST_NOT_SUPPORTED = 1;
+ // There was an unexpected error in the underlying service. The client may try to
+ // reconnect as it is unknown what type of error occurred.
+ INTERNAL_SERVICE_ERROR = 2;
+ // There was an error communicating with persistent storage. The client is not recommended
+ // to reconnect as the storage is not expected to fail.
+ PERSISTENT_STORAGE_ERROR = 3;
+ // Failed to read device information from file. The client is not recommended to try to
+ // reconnect as the file reads are not expected to fail.
+ FILE_READ_ERROR = 4;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.settings/setup.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.settings/setup.fidl
new file mode 100644
index 0000000..77b4f0b
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.settings/setup.fidl
@@ -0,0 +1,42 @@
+// 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.
+
+library fuchsia.settings;
+
+/// Settings that influence the device's setup behavior.
+///
+/// Supported SettingsEpitaph enums:
+/// REQUEST_NOT_SUPPORTED, INTERNAL_SERVICE_ERROR, PERSISTENT_STORAGE_ERROR
+[Discoverable]
+protocol Setup {
+ /// Gets the current [SetupSettings]. Returns immediately on first call;
+ /// subsequent calls return when the value changes.
+ ///
+ /// If this call fails, it is considered a fatal error and the channel
+ /// will be closed.
+ Watch() -> (SetupSettings settings);
+
+ /// Changes the settings specified in [SetupSettings]. Any field not set in
+ /// the table will not perform any system operation. An error will be
+ /// returned if the provided settings is an invalid change (for example, if
+ /// it is empty).
+ [Transitional = "Changes network interfaces configuration with reboot"]
+ Set(SetupSettings settings) -> () error Error;
+
+ [Transitional = "Changes network interfaces configuration with optional reboot"]
+ Set2(SetupSettings settings, bool reboot_device) -> () error Error;
+};
+
+table SetupSettings {
+ /// Specifies the network interfaces that the device can be configured
+ /// over during setup.
+ 1: ConfigurationInterfaces enabled_configuration_interfaces;
+};
+
+bits ConfigurationInterfaces : uint32 {
+ // Configuration over ethernet.
+ ETHERNET = 0x1;
+ // Configuration over WiFi.
+ WIFI = 0x2;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.settings/system.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.settings/system.fidl
new file mode 100644
index 0000000..50e6d6e
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.settings/system.fidl
@@ -0,0 +1,44 @@
+// 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.
+
+library fuchsia.settings;
+
+/// Settings related to the general system.
+///
+/// Supported SettingsEpitaph enums:
+/// REQUEST_NOT_SUPPORTED, INTERNAL_SERVICE_ERROR, PERSISTENT_STORAGE_ERROR
+[Discoverable]
+protocol System {
+ /// DEPRECATED: new watches should use Watch2.
+ [Transitional = "Deprecated in favor of Watch2"]
+ Watch() -> (SystemSettings settings) error Error;
+
+ /// Gets the current [SystemSettings]. Returns immediately on first call;
+ /// subsequent calls return when the value changes.
+ ///
+ /// If this call fails, it is considered a fatal error and the channel
+ /// will be closed.
+ [Transitional = "Replacement for Watch"]
+ Watch2() -> (SystemSettings settings);
+
+ /// Changes the settings specified in [SystemSettings]. Any field not set in the table will
+ /// not perform any system operation.
+ Set(SystemSettings settings) -> () error Error;
+};
+
+/// Settings related to the general system.
+table SystemSettings {
+ /// If set, indicates a login behavior specified at runtime.
+ 1: LoginOverride mode;
+};
+
+/// What preferred login behavior has been set.
+enum LoginOverride {
+ /// No override has been set.
+ NONE = 1;
+ /// Do not require an account and login always as guest.
+ AUTOLOGIN_GUEST = 2;
+ /// Requires a provisioned account through auth provider.
+ AUTH_PROVIDER = 3;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sys.test/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.sys.test/BUILD.gn
new file mode 100644
index 0000000..1b14509
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sys.test/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.sys.test") {
+ library_name = "test"
+ namespace = "fuchsia.sys"
+ public_deps = [
+ ]
+ sources = [
+ "cache.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.sys.test",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sys.test/cache.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.sys.test/cache.fidl
new file mode 100644
index 0000000..0356479
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sys.test/cache.fidl
@@ -0,0 +1,13 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library fuchsia.sys.test;
+
+/// An interface for interacting with the isolated system cache. Typically only
+/// accessed from tests.
+[Discoverable]
+protocol CacheControl {
+ /// Causes all isolated caches for the system to be cleared.
+ Clear() -> ();
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sys.test/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.sys.test/meta.json
new file mode 100644
index 0000000..5494512
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sys.test/meta.json
@@ -0,0 +1,9 @@
+{
+ "deps": [],
+ "name": "fuchsia.sys.test",
+ "root": "fidl/fuchsia.sys.test",
+ "sources": [
+ "fidl/fuchsia.sys.test/cache.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sys/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.sys/BUILD.gn
new file mode 100644
index 0000000..ff5d585
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sys/BUILD.gn
@@ -0,0 +1,35 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.sys") {
+ library_name = "sys"
+ namespace = "fuchsia"
+ public_deps = [
+ "../fuchsia.mem",
+ ]
+ sources = [
+ "component_controller.fidl",
+ "environment.fidl",
+ "environment_controller.fidl",
+ "flat_namespace.fidl",
+ "job_provider.fidl",
+ "launcher.fidl",
+ "loader.fidl",
+ "runner.fidl",
+ "service_provider.fidl",
+ "types.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.sys",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sys/component_controller.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.sys/component_controller.fidl
new file mode 100644
index 0000000..47fbe45
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sys/component_controller.fidl
@@ -0,0 +1,65 @@
+// Copyright 2016 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.
+
+library fuchsia.sys;
+
+enum TerminationReason {
+ /// The channel closed without giving a termination reason.
+ UNKNOWN = 0;
+ /// Component ran and exited with a given return_code.
+ EXITED = 1;
+ /// The given URL given to launch was invalid.
+ URL_INVALID = 2;
+ /// The requested package could not be found.
+ PACKAGE_NOT_FOUND = 3;
+ /// An internal error happened during the launch process.
+ INTERNAL_ERROR = 4;
+ /// Process creation failed.
+ PROCESS_CREATION_ERROR = 5;
+ /// A Runner failed to start.
+ RUNNER_FAILED = 6;
+ /// A Runner terminated while attempting to run a component.
+ RUNNER_TERMINATED = 7;
+ /// Attempted to use an unsupported feature.
+ UNSUPPORTED = 8;
+};
+
+/// An interface for controlling components.
+///
+/// Closing this interface implicitly kills the controlled component unless
+/// the `Detach` method has been called.
+///
+/// If the component exits, this interface will be closed.
+///
+/// Typically obtained via `Launcher.CreateComponent`.
+protocol ComponentController {
+ /// Terminates the component.
+ ///
+ /// This ComponentController connection is closed when the component has
+ /// terminated.
+ Kill();
+
+ /// Decouples the lifetime of the component from this controller.
+ ///
+ /// After calling `Detach`, the component will not be implicitly killed when
+ /// this interface is closed.
+ Detach();
+
+ // DEPRECATED: Use OnTerminated instead of Wait().
+ // 3: Wait()
+
+ /// Event that is triggered when the component is terminated.
+ ///
+ /// This event provides the return code of the process and reason for
+ /// its termination. The return_code is only valid if the termination
+ /// reason is EXITED. If the termination reason is not EXITED, the
+ /// return code is guaranteed not to be 0.
+ -> OnTerminated(int64 return_code, TerminationReason termination_reason);
+
+ /// Event that is triggered when the component's output directory is mounted.
+ ///
+ /// This event will not be triggered for every component, only those that
+ /// serve a directory over their `PA_DIRECTORY_REQUEST` handle.
+ -> OnDirectoryReady();
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sys/environment.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.sys/environment.fidl
new file mode 100644
index 0000000..bc22dce
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sys/environment.fidl
@@ -0,0 +1,77 @@
+// Copyright 2016 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.
+
+library fuchsia.sys;
+
+/// Maximum length for an environment label.
+const uint32 kLabelMaxLength = 32;
+
+struct EnvironmentOptions {
+ /// True if this environment should inherit services provided by the
+ /// parent environment.
+ bool inherit_parent_services;
+ /// True if components in this environment will share a runner provided
+ /// by the parent environment. If false, a new runner will be started
+ /// in this environment for components.
+ bool use_parent_runners;
+ /// True if this environment should be killed first in out of memory
+ /// situations by setting the `ZX_PROP_JOB_KILL_ON_OOM` property on this
+ /// environment's job.
+ bool kill_on_oom;
+ /// True if "persistent" storage requested by components in this environment should not actually
+ /// be persistent, and instead be deleted when this environment is killed.
+ bool delete_storage_on_death;
+};
+
+/// An interface for managing a set of applications.
+///
+/// Applications run inside environments, which provide ambient services and
+/// support for their lifecycle.
+[Discoverable]
+protocol Environment {
+ /// Creates a new environment nested inside this environment.
+ ///
+ /// When applications are created inside the nested environment using the
+ /// environment's `Launcher`, the environment requests the
+ /// environment services from `host_directory` before passing those services to
+ /// the newly created application in its `StartupInfo`.
+ ///
+ /// The `controller` can be used to control the lifecycle of the created
+ /// environment. Note that by default the environment will be killed
+ /// automatically when the `EnvironmentController`'s interface is closed. You
+ /// can use `EnvironmentController.Detach` to disable this behavior.
+ ///
+ /// `label` defines the new environment's label/name. It must be unique within
+ /// the parent environment (though not globally) and is used for isolating
+ /// separate environments. It can also be used for diagnostic purposes. The
+ /// label will be truncated if it is longer than `kLabelMaxLength`.
+ ///
+ /// `additional_services`, which may be empty, contains a list of services
+ /// that the environment provides, which are hosted by
+ /// `additional_services.host_directory`. If `options.inherit_parent_services`
+ /// is false, `host_directory` must provide a `Loader` service if it wishes to
+ /// allow new components to be loaded in the new environment.
+ ///
+ /// `options` provides additional options, see `EnvironmentOptions` for
+ /// details.
+ CreateNestedEnvironment(request<Environment> environment,
+ request<EnvironmentController> controller,
+ string label,
+ ServiceList? additional_services,
+ EnvironmentOptions options);
+
+ /// Gets the Launcher associated with this environment.
+ ///
+ /// Applications created using this application launcher will be given the
+ /// environment services provided by this environment's `host_directory`.
+ GetLauncher(request<Launcher> launcher);
+
+ /// Gets a superset of services provided by this environment's
+ /// `host_directory`.
+ GetServices(request<ServiceProvider> services);
+
+ /// Gets a superset of services provided by this environment's
+ /// `host_directory`.
+ GetDirectory(handle<channel> directory_request);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sys/environment_controller.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.sys/environment_controller.fidl
new file mode 100644
index 0000000..97fb3b9
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sys/environment_controller.fidl
@@ -0,0 +1,31 @@
+// Copyright 2016 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.
+
+library fuchsia.sys;
+
+/// An interface for controlling an environment.
+///
+/// Closing this interface implicitly kills the controlled environment unless
+/// the `Detach` method has been called.
+///
+/// If the environment is destroyed, this interface will be closed.
+///
+/// Typically obtained via `Environment.CreateNestedEnvironment`.
+protocol EnvironmentController {
+ /// Terminates the environment.
+ ///
+ /// When an `Environment` is terminated, all applications launched
+ /// in the environment (and in all transitively nested environments) are also
+ /// killed.
+ Kill() -> ();
+
+ /// Decouples the lifetime of the environment from this controller.
+ ///
+ /// After calling `Detach`, the environment will not be implicitly killed when
+ /// this interface is closed.
+ Detach();
+
+ /// Event that is triggered when the environment is created.
+ -> OnCreated();
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sys/flat_namespace.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.sys/flat_namespace.fidl
new file mode 100644
index 0000000..31582d8
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sys/flat_namespace.fidl
@@ -0,0 +1,15 @@
+// Copyright 2017 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.
+
+library fuchsia.sys;
+
+struct FlatNamespace {
+ /// The mount point for each of the directories below.
+ ///
+ /// For example, ["/pkg", "/svc"].
+ vector<string> paths;
+
+ /// The directories mounted at each path in the namespace.
+ vector<handle<channel>> directories;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sys/job_provider.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.sys/job_provider.fidl
new file mode 100644
index 0000000..77fd3f9
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sys/job_provider.fidl
@@ -0,0 +1,14 @@
+// Copyright 2018 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.
+
+library fuchsia.sys;
+
+/// An interface for providing a job handle. Instances of this interface are
+/// created in the context of an already-identified realm, so there is no need
+/// to explicitly identify the realm below.
+[Discoverable]
+protocol JobProvider {
+ /// Gets the root job associated with the realm.
+ GetJob() -> (handle<job> job);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sys/launcher.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.sys/launcher.fidl
new file mode 100644
index 0000000..4bb184f
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sys/launcher.fidl
@@ -0,0 +1,91 @@
+// Copyright 2016 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.
+
+library fuchsia.sys;
+
+/// An FDIO file descriptor.
+// TODO(abarth): Use the real FDIO declaration once FDIO converts to FIDL2.
+struct FileDescriptor {
+ /// The FDIO types of the handle (e.g., `FA_FDIO_REMOTE`).
+ int32 type0;
+ int32 type1;
+ int32 type2;
+
+ /// The handles for the file descriptor (e.g., a channel).
+ handle? handle0;
+ handle? handle1;
+ handle? handle2;
+};
+
+/// Information used to create an instance of a component and obtain
+/// services from it.
+struct LaunchInfo {
+ /// The location from which to retrieve this component.
+ ///
+ /// This field will probably be replaced with a stronger notion of identity,
+ /// such as an unforgeable token. This field is included in this iteration to
+ /// ease the transition from the previous component interfaces.
+ component_url url;
+
+ /// The arguments to be provided to the component.
+ vector<string:MAX>:MAX? arguments;
+
+ /// The file descriptor to use for stdout.
+ ///
+ /// If null, the component will use the default stdout for the environment.
+ FileDescriptor? out;
+
+ /// The file descriptor to use for stderr.
+ ///
+ /// If null, the component will use the default stderr for the environment.
+ FileDescriptor? err;
+
+ /// The interface request for a Directory that is passed through to the
+ /// component and arrives in the component as its `directory_request`
+ /// interface request.
+ handle<channel>? directory_request;
+
+ /// A custom namespace that can be appended to the namespace generated by
+ /// appmgr and provided to this component.
+ /// Adding a mount point at standard paths like 'pkg' or 'svc' will be ignored.
+ /// HACK(alhaad): Adding mount points for deprecated default directories like
+ /// '/data' will override the default.
+ FlatNamespace? flat_namespace;
+
+ /// A list of services to be added to this component's svc namespace. These
+ /// services are in addition to those coming from Environment.
+ ServiceList? additional_services;
+};
+
+struct ServiceList {
+ /// A list of services that can be requested from `provider`.
+ vector<string> names;
+
+ /// A service provider to get the services listed in `names` from.
+ ServiceProvider? provider;
+
+ /// A channel to the directory hosting the services in `names`.
+ // TODO(CP-124): Support `host_directory` for CreateComponent and deprecate
+ // `provider`.
+ handle<channel>? host_directory;
+};
+
+/// An interface for creating component instances.
+///
+/// Typically obtained via `Environment.GetLauncher`.
+[Discoverable]
+protocol Launcher {
+ /// Creates a new instance of the component described by `launch_info`.
+ ///
+ /// The component instance is created in the `Environment`
+ /// associated with this `Launcher`. When creating the component,
+ /// the environment requests the environment services for this component from
+ /// its `EnvironmentHost`.
+ ///
+ /// The `controller` can be used to control the lifecycle of the created
+ /// component instance. If an `ComponentController`'s interface is
+ /// requested, the component instance is killed when the interface is closed.
+ CreateComponent(LaunchInfo launch_info,
+ request<ComponentController>? controller);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sys/loader.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.sys/loader.fidl
new file mode 100644
index 0000000..beb5225
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sys/loader.fidl
@@ -0,0 +1,14 @@
+// Copyright 2016 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.
+
+library fuchsia.sys;
+
+/// An interface for loading from packages.
+[Discoverable]
+protocol Loader {
+ /// Load a package by url. The returned `package`'s `data` VMO handle will
+ /// not have `ZX_RIGHT_EXECUTE`, but the `directory` field, if present, will
+ /// have both the `READABLE` and `EXECUTABLE` rights.
+ LoadUrl(component_url url) -> (Package? package);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sys/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.sys/meta.json
new file mode 100644
index 0000000..054a57d
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sys/meta.json
@@ -0,0 +1,20 @@
+{
+ "deps": [
+ "fuchsia.mem"
+ ],
+ "name": "fuchsia.sys",
+ "root": "fidl/fuchsia.sys",
+ "sources": [
+ "fidl/fuchsia.sys/component_controller.fidl",
+ "fidl/fuchsia.sys/environment.fidl",
+ "fidl/fuchsia.sys/environment_controller.fidl",
+ "fidl/fuchsia.sys/flat_namespace.fidl",
+ "fidl/fuchsia.sys/job_provider.fidl",
+ "fidl/fuchsia.sys/launcher.fidl",
+ "fidl/fuchsia.sys/loader.fidl",
+ "fidl/fuchsia.sys/runner.fidl",
+ "fidl/fuchsia.sys/service_provider.fidl",
+ "fidl/fuchsia.sys/types.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sys/runner.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.sys/runner.fidl
new file mode 100644
index 0000000..fa4cc6a
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sys/runner.fidl
@@ -0,0 +1,77 @@
+// Copyright 2016 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.
+
+library fuchsia.sys;
+
+using fuchsia.mem;
+
+/// Information given to components at startup.
+///
+/// For ELF binaries, this information is provided in the initialization
+/// message given to `libc` by `fuchsia.process.Launcher`.
+struct StartupInfo {
+ /// The launch info for the component to start.
+ LaunchInfo launch_info;
+
+ /// The namespace in which to run the component.
+ FlatNamespace flat_namespace;
+
+ /// Key string value string map of the component's program metadata,
+ /// obtained from its component manifest.
+ vector<ProgramMetadata>? program_metadata;
+
+ // TODO(abarth): Add more fields to this struct relating to component and
+ // environment identity.
+};
+
+/// Program information about a component.
+struct ProgramMetadata {
+ /// Key for program metadata pair. E.g. "binary" for an ELF binary
+ /// component, or "data" for a flutter/dart component.
+ string key;
+
+ /// Value for program metadata pair. E.g. "bin/app" for a "binary" key, or
+ /// "data/foo" for a flutter/dart component.
+ string value;
+};
+
+/// A binary representation of a component.
+///
+/// Typically provided to `Runner.StartComponent` when starting a component.
+struct Package {
+ /// A read-only binary representation of the component. For example, if the
+ /// component is intended to run in the Dart virtual machine, this data
+ /// might contain a dartx package.
+ fuchsia.mem.Buffer? data;
+
+ /// A directory containing the contents of the package. For example, if the
+ /// component is stored in pkgfs, this directory will be the pkgfs
+ /// directory containing the package.
+ handle<channel>? directory;
+
+ /// Resolved URL of the component. This is the url specified in
+ /// `startup_info` after following redirects and resolving relative paths.
+ component_url resolved_url;
+};
+
+/// An interface for running components.
+///
+/// Typically exposed by components that provide execution environments for
+/// particular classes of programs. For example, the Dart virtual machine
+/// exposes this interface to run Dart programs.
+[Discoverable]
+protocol Runner {
+ /// Execute the given component.
+ ///
+ /// Upon startup, the component is to be given the information in
+ /// `startup_info`, but the mechanism by which the component receives that
+ /// information is up to the component runner.
+ ///
+ /// The `controller` interface request typically originates from the
+ /// `Launcher.CreateComponent` message that caused this component to be
+ /// started.
+ StartComponent(Package package,
+ StartupInfo startup_info,
+ request<ComponentController>? controller);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sys/service_provider.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.sys/service_provider.fidl
new file mode 100644
index 0000000..018c1bc
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sys/service_provider.fidl
@@ -0,0 +1,20 @@
+// Copyright 2014 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.
+
+library fuchsia.sys;
+
+/// An interface through which a client may request services from a host.
+/// Instances of this interface are created within the context of an
+/// already-identified client and host pair, so there is no need to explicitly
+/// identify the client or host in the methods below.
+///
+/// This interface is deprecated. Services should be published as directory
+/// entries instead, just like files.
+// TODO(ZX-1358): Point to the FIDL interface for file I/O once RIO is migrated.
+protocol ServiceProvider {
+ /// Asks the host to provide the service identified by `service_name` through
+ /// the `channel` endpoint supplied by the caller. If the host is not willing
+ /// or able to provide the requested service, it should close the `channel`.
+ ConnectToService(string service_name, handle<channel> channel);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sys/types.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.sys/types.fidl
new file mode 100644
index 0000000..776fc51
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sys/types.fidl
@@ -0,0 +1,11 @@
+// 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.
+
+library fuchsia.sys;
+
+/// A URL used to retrieve, launch, and load a component from a specified network
+/// location, or to identify a component when connecting to it.
+using component_url = string:MAX_URL_LENGTH;
+
+const uint16 MAX_URL_LENGTH = 2083;
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sysinfo/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.sysinfo/BUILD.gn
new file mode 100644
index 0000000..b9c3278
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sysinfo/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.sysinfo") {
+ library_name = "sysinfo"
+ namespace = "fuchsia"
+ public_deps = [
+ ]
+ sources = [
+ "sysinfo.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.sysinfo",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sysinfo/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.sysinfo/meta.json
new file mode 100644
index 0000000..5ca44e2
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sysinfo/meta.json
@@ -0,0 +1,9 @@
+{
+ "deps": [],
+ "name": "fuchsia.sysinfo",
+ "root": "fidl/fuchsia.sysinfo",
+ "sources": [
+ "fidl/fuchsia.sysinfo/sysinfo.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sysinfo/sysinfo.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.sysinfo/sysinfo.fidl
new file mode 100644
index 0000000..26c1307
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sysinfo/sysinfo.fidl
@@ -0,0 +1,42 @@
+// Copyright 2018 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.
+
+library fuchsia.sysinfo;
+
+using zx;
+
+const uint8 BOARD_NAME_LEN = 32;
+const uint8 BOOTLOADER_VENDOR_LEN = 32;
+
+enum InterruptControllerType {
+ UNKNOWN = 0;
+ APIC = 1;
+ GIC_V2 = 2;
+ GIC_V3 = 3;
+};
+
+struct InterruptControllerInfo {
+ InterruptControllerType type;
+};
+
+[Discoverable, Layout = "Simple"]
+protocol SysInfo {
+ /// Return the hypervisor resource (with only ZX_RIGHT_TRANSFER).
+ GetHypervisorResource() -> (zx.status status, handle<resource>? resource);
+
+ /// Return the board name for the platform we are running on.
+ GetBoardName() -> (zx.status status, string:BOARD_NAME_LEN? name);
+
+ /// Return the board revision for the board we are running on.
+ // TODO (nealo): Remove Transitional qualifier after all board bootloaders
+ // provide board serial number, mac address and revision.
+ [Transitional = "Adding Board Revision"]
+ GetBoardRevision() -> (zx.status status, uint32 revision);
+
+ /// Return the bootloader vendor for the platform we are running on.
+ GetBootloaderVendor() -> (zx.status status, string:BOOTLOADER_VENDOR_LEN? vendor);
+
+ /// Return interrupt controller information.
+ GetInterruptControllerInfo() -> (zx.status status, InterruptControllerInfo? info);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/BUILD.gn
new file mode 100644
index 0000000..9508b07
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/BUILD.gn
@@ -0,0 +1,36 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.sysmem") {
+ library_name = "sysmem"
+ namespace = "fuchsia"
+ public_deps = [
+ ]
+ sources = [
+ "allocator.fidl",
+ "collection.fidl",
+ "collections_deprecated.fidl",
+ "constraints.fidl",
+ "driver_connector.fidl",
+ "format_modifier.fidl",
+ "formats_deprecated.fidl",
+ "heap.fidl",
+ "image_formats.fidl",
+ "image_formats_deprecated.fidl",
+ "secure_mem.fidl",
+ "usages.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.sysmem",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/allocator.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/allocator.fidl
new file mode 100644
index 0000000..cfdba74
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/allocator.fidl
@@ -0,0 +1,114 @@
+// Copyright 2018 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.
+
+library fuchsia.sysmem;
+
+using zx;
+
+/// Allocates system memory buffers.
+///
+// Needs Layout = "Simple" because used with "FIDL Simple C Bindings".
+[Discoverable, Layout = "Simple"]
+protocol Allocator {
+ /// Allocates a BufferCollection on behalf of a single client (aka initiator)
+ /// who is also the only participant (from the point of view of sysmem).
+ ///
+ /// This call exists mainly for temp/testing purposes. This call skips the
+ /// BufferCollectionToken stage, so there's no way to allow another
+ /// participant to specify its constraints.
+ ///
+ /// Real clients are encouraged to use AllocateSharedCollection() instead,
+ /// and to let relevant participants directly convey their own constraints to
+ /// sysmem.
+ ///
+ /// `constraints` indicates constraints on the buffer collection, such as how
+ /// many buffers to allocate, buffer size constraints, etc.
+ ///
+ /// `collection` is the server end of the BufferCollection FIDL channel. The
+ /// client can call SetConstraints() and then WaitForBuffersAllocated() on
+ /// the client end of this channel to specify constraints and then determine
+ /// success/failure and get the BufferCollectionInfo_2 for the
+ /// BufferCollection. The client should also keep the client end of
+ /// this channel open while using the BufferCollection, and should notice
+ /// when this channel closes and stop using the BufferCollection ASAP.
+ AllocateNonSharedCollection(request<BufferCollection> collection);
+
+ /// Creates a logical BufferCollectionToken which can be shared among
+ /// participants (using BufferCollectionToken.Duplicate()), and then
+ /// converted into a BufferCollection using BindSharedCollection().
+ ///
+ /// Success/failure to populate the BufferCollection with buffers is
+ /// determined via the BufferCollection interface.
+ AllocateSharedCollection(request<BufferCollectionToken> token_request);
+
+ /// Convert a BufferCollectionToken into a connection to the logical
+ /// BufferCollection. The BufferCollection hasn't yet been populated with
+ /// buffers - the participant must first also send SetConstraints() via the
+ /// client end of buffer_collection.
+ ///
+ /// All BufferCollectionToken(s) duplicated from a logical
+ /// BufferCollectionToken created via AllocateSharedCollection() must be
+ /// turned in via BindSharedCollection() before the logical BufferCollection
+ /// will be populated with buffers.
+ ///
+ /// `token` the client endpoint of a channel whose server end was sent to
+ /// sysmem using AllocateSharedCollection or whose server end was sent to
+ /// sysmem using BufferCollectionToken.Duplicate(). The token is being
+ /// "exchanged" for a channel to the logical BufferCollection.
+ ///
+ /// `buffer_collection` the server end of a BufferCollection channel. The
+ /// sender retains the client end as usual. The BufferCollection channel
+ /// is a single participant's connection to the logical BufferCollection.
+ /// There typically will be other participants with their own
+ /// BufferCollection channel to the logical BufferCollection.
+ BindSharedCollection(BufferCollectionToken token,
+ request<BufferCollection> buffer_collection_request);
+
+ /// Validate that a BufferCollectionToken is known to the sysmem server.
+ ///
+ /// This can be used in cases where BindSharedCollection() won't be called
+ /// until after BufferCollectionToken.Duplicate() +
+ /// BufferCollectionToken.Sync(), when the client code wants to know earlier
+ /// whether an incoming token is valid (so far).
+ ///
+ /// Calling BufferCollectionToken.Sync() on a token that isn't known to
+ /// sysmem risks the Sync() hanging forever.
+ ///
+ /// Given that an incoming token can become invalid at any time if any
+ /// participant drops their BufferCollectionToken(s) or BufferCollection(s),
+ /// authors of client code are encouraged to consider not calling
+ /// ValidateBufferCollectionToken() and instead dealing with async failure
+ /// of the BufferCollection.Sync() after all the
+ /// BufferCollectionToken.Duplicate() and BindSharedCollection() (before
+ /// sending any duplicate tokens to other processes).
+ ///
+ /// Regardless of the result of this call, this call has no effect on the
+ /// token with the referenced koid.
+ ///
+ /// A true result from this call doesn't guarantee that the token remains
+ /// valid for any duration afterwards.
+ ///
+ /// Client code will zx_object_get_info() on the client's token handle,
+ /// passing ZX_INFO_HANDLE_BASIC and getting back the related_koid
+ /// which then gets passed to ValidateBufferCollectionToken().
+ ///
+ /// If ValidateBufferCollectionToken() returns true, the token was known at
+ /// the time the sysmem server processed the call, but may no longer be
+ /// valid/known by the time the client code receives the response.
+ ///
+ /// If ValidateBufferCollectionToken() returns false, the token wasn't known
+ /// at the time the sysmem server processed the call, but the token may
+ /// become known by the time the client code receives the response. However
+ /// client code is not required to mitigate the possibility that the token
+ /// may become known late, since the source of the token should have synced
+ /// the token to sysmem before sending the token to the client code.
+ ///
+ /// If calling ValidateBufferCollectionToken() fails in some way, there will
+ /// be a zx_status_t from the FIDL layer.
+ ///
+ /// `token_server_koid` the koid of the server end of a channel that might
+ /// be a BufferCollectionToken channel. This can be obtained from
+ /// zx_object_get_info() ZX_INFO_HANDLE_BASIC related_koid.
+ ValidateBufferCollectionToken(zx.koid token_server_koid) -> (bool is_known);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/collection.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/collection.fidl
new file mode 100644
index 0000000..6096818
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/collection.fidl
@@ -0,0 +1,363 @@
+// Copyright 2018 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.
+
+library fuchsia.sysmem;
+
+using zx;
+
+/// A BufferCollectionToken is not a BufferCollection, but rather a way to
+/// identify a potential shared BufferCollection prior to the BufferCollection
+/// being allocated.
+///
+/// We use a channel for the BufferCollectionToken instead of a single eventpair
+/// (pair) because this way we can detect error conditions like a participant
+/// dying mid-create.
+[Discoverable, Layout = "Simple"]
+protocol BufferCollectionToken {
+ /// The initiator or a participant can send Duplicate() as part of creating
+ /// another participant-side handle to the same logical
+ /// BufferCollectionToken.
+ ///
+ /// This method is used to hand the logical token to all participants so all
+ /// participants can provide constraints to sysmem for the overall
+ /// BufferCollection to achieve the goal of allocating buffers compatible
+ /// with all participants.
+ ///
+ /// The Duplicate() message is intentionally available only on
+ /// BufferCollectionToken not BufferCollection.
+ ///
+ /// The token is separate from BufferCollection so that participants contact
+ /// sysmem directly, so that participants are only trusting their environment
+ /// for who sysmem is (fake token mitigation), not an initiator. Only after
+ /// successful BindSharedCollection does a participant know that the token
+ /// was a real sysmem token. In contrast, if we had Duplicate() directly on
+ /// BufferCollection, an initiator could attempt to serve the
+ /// BufferCollection channel itself, which would allow for some problematic
+ /// possibilities.
+ ///
+ /// All the BufferCollectionToken channels of a logical token must be turned
+ /// in via BindSharedCollection() for a BufferCollection to be successfully
+ /// created. Else the BufferCollection channel will close.
+ ///
+ /// When a client calls BindSharedCollection() to turn in a
+ /// BufferCollectionToken, the server will process all Duplicate() messages
+ /// before closing down the BufferCollectionToken. This allows the client
+ /// to Duplicate() and immediately turn in the BufferCollectionToken using
+ /// BindSharedCollection, then later transfer the client end of token_request
+ /// to another participant - the server will notice the existence of the
+ /// token_request before considering this BufferCollectionToken fully closed.
+ ///
+ /// `rights_attenuation_mask` rights bits that are zero in this mask will be
+ /// absent in the buffer VMO rights obtainable via the client end of
+ /// token_request. This allows an initiator or intermediary participant
+ /// to attenuate the rights available to a participant. This may not be the
+ /// only mechanism that attenuates rights on the VMO handles obtainable via
+ /// the client end of token_request. This does not allow a participant
+ /// to gain rights that the participant doesn't already have. The value
+ /// ZX_RIGHT_SAME_RIGHTS can be used to specify that no attenuation should
+ /// be applied.
+ ///
+ /// `token_request` is the server end of a BufferCollectionToken channel.
+ /// The client end of this channel acts as another handle to the same logical
+ /// BufferCollectionToken. Typically the sender of Duplicate() will transfer
+ /// the client end corresponding to collection_request to a/another
+ /// participant running in a separate process, but it's also fine for the
+ /// additional logical participant to be in the same process.
+ ///
+ /// After sending one or more Duplicate() messages, and before sending the
+ /// created tokens to other participants (or to other Allocator channels),
+ /// the client should send a Sync() and wait for its response. The Sync()
+ /// call can be made on the token, or on the BufferCollection obtained by
+ /// passing this token to BindSharedCollection(). Either will ensure that
+ /// the server knows about the tokens created via Duplicate() before the
+ /// other participant sends the token to the server via separate Allocator
+ /// channel. If a client is using FIDL C generated code and doesn't want to
+ /// block waiting for a response message, the other option is to notice
+ /// arrival of the BufferCollectionEvents::OnBufferCollectionCreated() event
+ /// after turning in this token for a BufferCollection.
+ //
+ // TODO(dustingreen): Consider other mechanisms to ensure the token created
+ // here is recognized by the server.
+ Duplicate(uint32 rights_attenuation_mask,
+ request<BufferCollectionToken> token_request);
+
+ /// Ensure that previous Duplicate() messages have been received server side,
+ /// so that it's safe to send the client end of token_request to another
+ /// participant knowing the server will recognize the token when it's sent
+ /// into BindSharedCollection by the other participant.
+ ///
+ /// Other options include waiting for each Duplicate() to complete
+ /// individually (using separate call to BufferCollectionToken.Sync() after
+ /// each), or calling Sync() on BufferCollection after this token has
+ /// been turned in via BindSharedCollection(), or noticing arrival of
+ /// BufferCollectionEvents::OnDuplicatedTokensKnownByServer().
+ ///
+ /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
+ /// valid sysmem token risks the Sync() hanging forever. See
+ /// ValidateBufferCollectionToken() for one way to mitigate the possiblity
+ /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
+ ///
+ /// Another way to mitigate is to avoid calling Sync() on the token, and
+ /// instead later deal with potential failure of BufferCollection.Sync() if
+ /// the original token was invalid. This option can be preferable from a
+ /// performance point of view, but requires client code to delay sending
+ /// tokens duplicated from this token until after client code has converted
+ /// this token to a BufferCollection and received successful response from
+ /// BufferCollection.Sync() (or received OnDuplicatedTokensKnownByServer()).
+ ///
+ /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
+ /// When BufferCollection.Sync() isn't feasible, the caller must already
+ /// know that this token is/was valid, or BufferCollectionToken.Sync() may
+ /// hang forever. See ValidateBufferCollectionToken() to check token
+ /// validity first if the token isn't already known to be (is/was) valid.
+ Sync() -> ();
+
+ /// Normally a participant will convert the token into a BufferCollection
+ /// view, but a particpant is also free to Close() the token (and then close
+ /// the channel immediately or shortly later in response to server closing
+ /// its end), which avoids causing LogicalBufferCollection failure.
+ /// Normally an unexpected token channel close will cause
+ /// LogicalBufferCollection failure.
+ Close();
+};
+
+/// BufferCollection is a connection directly from a participant to sysmem re.
+/// a logical BufferCollection; typically the logical BufferCollection is shared
+/// with other participants. In other words, an instance of the BufferCollection
+/// interface is a view of a "LogicalBufferCollection".
+///
+/// This connection exists to facilitate async indication of when the logical
+/// BufferCollection has been populated with buffers.
+///
+/// Also, the channel's closure by the server is an indication to the client
+/// that the client should close all VMO handles that were obtained from the
+/// BufferCollection ASAP.
+///
+/// Also, this interface may in future allow specifying constraints in other
+/// ways, and may allow for back-and-forth negotiation of constraints to some
+/// degree.
+///
+/// This interface may in future allow for more than 64 VMO handles per
+/// BufferCollection, but currently the limit is 64.
+///
+/// This interface may in future allow for allocating/deallocating single
+/// buffers.
+///
+/// Some initiators may wait a short duration until all old logical
+/// BufferCollection VMO handles have closed (or until the short duration times
+/// out) before allocating a new BufferCollection, to help control physical
+/// memory fragmentation and avoid overlap of buffer allocation lifetimes for
+/// the old and new collections. Collections can be large enough that it's worth
+/// avoiding allocation overlap (in time).
+[Discoverable, Layout = "Simple"]
+protocol BufferCollection {
+ /// At least for now, the only way to get events from a BufferCollection is
+ /// to set a reverse BufferCollectionEvents channel. This can be sent up to
+ /// once at any point during BufferCollection channel lifetime. All events
+ /// are one-shot events, and will be sent immediately via `events` if the
+ /// one-shot event's condition has already become true (once true will stay
+ /// true; only goes from false to true once).
+ ///
+ /// `events` is the client end of a BufferCollectionEvents which will be sent
+ /// one-way messages indicating events relevant to this BufferCollection
+ /// channel (some may be specific to this BufferCollection channel and some
+ /// may be relevant to the overall logical BufferCollection).
+ SetEventSink(BufferCollectionEvents events);
+
+ /// See comments on BufferCollectionToken::Sync().
+ Sync() -> ();
+
+ /// Provide BufferCollectionConstraints to the logical BufferCollection.
+ ///
+ /// Participants with read but not write can only call SetConstraints() once.
+ ///
+ /// Participants with write can call SetConstraints() more than once. The
+ /// initial buffer allocation will use the constraints in the first call to
+ /// SetConstraints(). Among other things, this allows a decoder to attempt
+ /// to allocate a new buffer that's larger to hold an output frame that's
+ /// larger.
+ ///
+ /// Sometimes the initiator is a participant only in the sense of wanting to
+ /// keep an eye on success/failure to populate with buffers, and zx.status on
+ /// failure. In that case, `has_constraints` can be false, and `constraints`
+ /// will be ignored.
+ ///
+ /// VMO handles will not be provided to the client that sends null
+ /// constraints - that can be intentional for an initiator that doesn't need
+ /// VMO handles. Not having VMO handles doesn't prevent the initator from
+ /// adjusting which portion of a buffer is considered valid and similar, but
+ /// the initiator can't hold a VMO handle open to prevent the logical
+ /// BufferCollection from cleaning up if the logical BufferCollection needs
+ /// to go away regardless of the initiator's degree of involvement for
+ /// whatever reason.
+ ///
+ /// For population of buffers to be attempted, all holders of a
+ /// BufferCollection client channel need to call SetConstraints() before
+ /// sysmem will attempt to allocate buffers.
+ ///
+ /// `has_constraints` if false, the constraints are effectively null, and
+ /// `constraints` are ignored. The sender of null constraints won't get any
+ /// VMO handles in BufferCollectionInfo, but can still find out how many
+ /// buffers were allocated and can still refer to buffers by their
+ /// buffer_index.
+ ///
+ /// `constraints` are constraints on the buffer collection.
+ SetConstraints(bool has_constraints,
+ BufferCollectionConstraints constraints);
+
+ /// This request completes when buffers have been allocated, responds with
+ /// some failure detail if allocation has been attempted but failed.
+ ///
+ /// The following must occur before buffers will be allocated:
+ /// * All BufferCollectionToken(s) of the logical BufferCollectionToken
+ /// must be turned in via BindSharedCollection().
+ /// * All BufferCollection(s) of the logical BufferCollection must have had
+ /// SetConstraints() sent to them.
+ ///
+ /// A caller using C generated FIDL code who wishes not to block a thread in
+ /// a zx_channel_call() for a potentially fairly long duration on this
+ /// message/response can use SetEventSink() and
+ /// BufferCollectionEvents.OnBuffersPopulated() instead.
+ ///
+ /// This method is still legal to call despite use of OnBuffersPopulated(),
+ /// but in that case the additional BufferCollectionInfo returned here will
+ /// include handles that are redundant with other handles in the
+ /// BufferCollectionInfo delivered via OnBuffersPopulated() (separate handle
+ /// but same underlying VMO objects), so most clients that bother calling
+ /// SetEventSink() will prefer to receive BufferCollectionInfo via
+ /// OnBuffersPopulated(). This method is mostly here for clients that don't
+ /// call SetEventSink().
+ ///
+ /// Returns `ZX_OK` if successful.
+ /// Returns `ZX_ERR_NO_MEMORY` if the request is valid but cannot be
+ /// fulfilled due to resource exhaustion.
+ /// Returns `ZX_ERR_ACCESS_DENIED` if the caller is not permitted to
+ /// obtain the buffers it requested.
+ /// Returns `ZX_ERR_INVALID_ARGS` if the request is malformed.
+ /// Returns `ZX_ERR_NOT_SUPPORTED` if request is valid but cannot be
+ /// satisfied, perhaps due to hardware limitations.
+ ///
+ /// `buffer_collection_info` has the VMO handles and other related info.
+ WaitForBuffersAllocated()
+ -> (zx.status status, BufferCollectionInfo_2 buffer_collection_info);
+
+ /// This returns the same result code as WaitForBuffersAllocated if the
+ /// buffer collection has been allocated or failed, or `ZX_ERR_UNAVAILABLE`
+ /// if WaitForBuffersAllocated would block.
+ CheckBuffersAllocated() -> (zx.status status);
+
+ /// The CloseBuffer() doesn't immediately force all VMO handles to that
+ /// buffer to close, but it does close any handle held by sysmem, and does
+ /// notify all participants of the desire to close the buffer at which point
+ /// each participant that's listening may close their handle to the buffer.
+ ///
+ /// Only a particpant with write can do this. Coordination among multiple
+ /// participants with write is outside of the scope of this interface.
+ ///
+ /// `buffer_index` indicates which buffer to close. If the buffer is already
+ /// closed this has no effect (idempotent).
+ CloseSingleBuffer(uint64 buffer_index);
+
+ /// This allocates a new buffer that is consistent with the most recent call
+ /// to SetConstraints(), if possible. If not possible, this indicates the
+ /// failure via OnNewBufferAllocated().
+ ///
+ /// Only a participant with write can do this. Coordination among multiple
+ /// participants with write is outside the scope of this interface.
+ ///
+ /// The participant is (intentionally) never informed of other participant's
+ /// constraints.
+ AllocateSingleBuffer(uint64 buffer_index);
+
+ /// Completes when AllocateBuffer is done. Callers who wish to avoid
+ /// blocking a thread while waiting can use OnAllocateSingleBufferDone()
+ /// instead.
+ WaitForSingleBufferAllocated(uint64 buffer_index)
+ -> (zx.status status, SingleBufferInfo buffer_info);
+
+ /// A participant can use this message to have sysmem verify that this
+ /// buffer_index exists. This message is intentionally ignored by the
+ /// server if the buffer_index _does_ exist. In that case, the client will
+ /// see OnAllocateSingleBufferDone() soon with status == `ZX_OK` (if the
+ /// client hasn't already seen that message). If on the other hand the
+ /// buffer_index does not exist, this message causes the server to send
+ /// OnAllocateSingleBufferDone() with status == `ZX_ERR_NOT_FOUND`. A
+ /// particpant will typically use this when the participant receives a new
+ /// buffer_index that the participant doesn't yet know about, to ensure that
+ /// the participant won't be waiting forever for the
+ /// OnAllocateSingleBufferDone() message regarding this buffer_index.
+ CheckSingleBufferAllocated(uint64 buffer_index);
+
+ /// The server handles unexpected failure of a BufferCollection by failing
+ /// the whole LogicalBufferCollection. Partly this is to expedite closing
+ /// VMO handles. If a participant would like to cleanly close a
+ /// BufferCollection view without causing LogicalBufferCollection failure,
+ /// the participant can send Close() before closing the client end of the
+ /// BufferCollection channel. If this is the last BufferCollection view, the
+ /// LogicalBufferCollection will still go away.
+ Close();
+};
+
+/// This interface intentionally doesn't include any event for
+/// OnOldBufferClosed(), because such an event could arrive at a participant too
+/// soon to be useful. Instead, such an indication should be made in-band within
+/// FIDL interfaces that deliver packets to downstream participants.
+[Discoverable, Layout = "Simple"]
+protocol BufferCollectionEvents {
+ /// See comments on BufferCollectionToken::Sync().
+ ///
+ /// This message only indicates that the server has reached the point where
+ /// it knows about previously created tokens Duplicate()ed from the token
+ /// used to create this BufferCollection.
+ OnDuplicatedTokensKnownByServer();
+
+ /// This event inidicates that buffer allocation is over, whether succesful
+ /// or failed.
+ ///
+ /// This event will eventually be sent by the server (unless the
+ /// BufferCollection channel closes first).
+ ///
+ /// `status`:
+ /// `ZX_OK` if successful.
+ /// `ZX_ERR_NO_MEMORY` if the request is valid but cannot be fulfilled due to
+ /// resource exhaustion.
+ /// `ZX_ERR_ACCESS_DENIED` if the caller is not permitted to obtain the
+ /// buffers it requested.
+ /// `ZX_ERR_INVALID_ARGS` if the request is malformed.
+ /// `ZX_ERR_NOT_SUPPORTED` if request is valid but cannot be satisfied,
+ /// perhaps due to hardware limitations.
+ ///
+ /// `buffer_collection_info` The buffer information, including VMO handles.
+ /// If `status` is not `ZX_OK`, `buffer_collection_info` is default
+ /// initialized and contains no meaningful information.
+ OnBuffersAllocated(zx.status status,
+ BufferCollectionInfo_2 buffer_collection_info);
+
+ /// A participant can learn when a new buffer is allocated via this event.
+ /// The only participant that will see a failing status is the participant
+ /// that attempted the single buffer allocation. Other participants will
+ /// only see successful single buffer allocations.
+ ///
+ /// `status`:
+ ///
+ /// `ZX_OK` if successful. This can be seen by any participant (whether
+ /// sender of AllocateSingleBuffer() or not.)
+ ///
+ /// `ZX_ERR_NOT_FOUND` if the buffer_index sent via
+ /// CheckSingleBufferAllocated() isn't known to the server. This can be seen
+ /// by any participant (whether sender of AllocateSingleBuffer() or not.)
+ ///
+ /// These error codes are only ever seen by the sender of
+ /// AllocateSingleBuffer():
+ ///
+ /// `ZX_ERR_NO_MEMORY` if the request is valid but cannot be fulfilled due to
+ /// resource exhaustion.
+ /// `ZX_ERR_ACCESS_DENIED` if the caller is not permitted to obtain the
+ /// buffers it requested.
+ /// `ZX_ERR_INVALID_ARGS` if the request is malformed.
+ /// `ZX_ERR_NOT_SUPPORTED` if request is valid but cannot be satisfied,
+ /// perhaps due to hardware limitations.
+ OnAllocateSingleBufferDone(zx.status status,
+ SingleBufferInfo buffer_info);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/collections_deprecated.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/collections_deprecated.fidl
new file mode 100644
index 0000000..ca7a7d1
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/collections_deprecated.fidl
@@ -0,0 +1,31 @@
+// Copyright 2018 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.
+
+library fuchsia.sysmem;
+
+/// Information about a buffer collection and its buffers.
+// TODO(ZX-2260): change struct to table
+struct BufferCollectionInfo {
+ /// The number of buffers in the collection.
+ uint32 buffer_count;
+
+ /// Describes how the contents of buffers are represented.
+ /// All buffers within the collection have the same format.
+ BufferFormat format;
+
+ /// VMO handles for each buffer in the collection.
+ /// The VMOs are only present when the buffers are backed by VMOs.
+ ///
+ /// If present, all the VMOs after `buffer_count` are invalid handles.
+ /// All buffer VMO handles have identical size and access rights.
+ /// The VMO access rights are determined based on the usages which the
+ /// client specified when allocating the buffer collection. For example,
+ /// a client which expressed a read-only usage will receive VMOs without
+ /// write rights.
+ array<handle<vmo>?>:64 vmos;
+
+ /// The size of each VMO provided.
+ /// This property is only present when the buffers are backed by VMOs.
+ uint64 vmo_size = 0;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/constraints.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/constraints.fidl
new file mode 100644
index 0000000..85bdb0a
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/constraints.fidl
@@ -0,0 +1,419 @@
+// Copyright 2018 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.
+
+library fuchsia.sysmem;
+
+// TODO(dustingreen): FIDL C generated code doesn't implement field defaults, so
+// either move to FIDL C++ generated code (for this reason among several others;
+// preferred), or make 0 values be aliases for the intended default value. For
+// now, the field defaults don't take effect and the field ends up having value
+// 0 if not explicitly initialized, despite having a default value in the FIDL.
+
+/// Constraints on BufferCollection parameters. These constraints can be
+/// specified per-participant. The sysmem service implements aggregation of
+/// constraints from multiple participants.
+struct BufferCollectionConstraints {
+ /// The usage is only meant as a hint to help sysmem choose a more optimal
+ /// PixelFormat or similar when multiple compatible options exist.
+ ///
+ /// When aggregating BufferCollectionConstraints, these values bitwise-OR.
+ ///
+ /// At least one usage bit must be specified unless the whole
+ /// BufferCollectionConstraints is logically null due to !has_constraints.
+ BufferUsage usage;
+
+ /// Per-participant minimum number of buffers that are needed for camping
+ /// purposes. A participant should specify a number for min_buffer_count
+ /// that's >= the maximum number of buffers that the participant may
+ /// concurrently camp on for any non-transient period of time.
+ ///
+ /// For example, a video decoder would specify (at least) the maximum number
+ /// of reference frames + 1 frame currently being decoded into.
+ ///
+ /// A participant must not camp on more buffers than specified here (except
+ /// very transiently) else processing may get stuck.
+ ///
+ /// When aggregating BufferCollectionConstraints, these values add.
+ ///
+ /// In testing scenarios, camping on more buffers than this for any
+ /// significant duration may (ideally will) be flagged as a failure. In
+ /// testing scenarios, the participant may not be provided with more buffers
+ /// than this concurrently.
+ uint32 min_buffer_count_for_camping;
+
+ /// Per-participant minimum number of buffers that are needed for slack
+ /// reasons, for better overlap of processing / better performance.
+ ///
+ /// When aggregating BufferCollectionConstraints, these values add.
+ ///
+ /// A participant should typically specify 0 or 1 here - typically 0 is
+ /// appropriate if min_buffer_count_for_camping is already enough to keep
+ /// the participant busy 100% of the time when the participant is slightly
+ /// behind, while 1 can be appropriate if 1 more buffer than strictly needed
+ /// for min-camping reasons gives enough slack to stay busy 100% of the time
+ /// (when slightly behind, vs. lower % without the extra buffer).
+ ///
+ /// In testing scenarios, this field may be forced to 0, and all
+ /// participants are expected to continue to work without getting stuck. If
+ /// a buffer is needed for forward progress reasons, that buffer should be
+ /// accounted for in min_buffer_count_for_camping.
+ uint32 min_buffer_count_for_dedicated_slack;
+
+ /// Similar to min_buffer_count_for_dedicated_slack, except when aggregating
+ /// these values max (instead of add). The value here is not shared with
+ /// any participant's min_buffer_count_for_dedicated_slack.
+ ///
+ /// A participant can specify > 0 here if a participant would like to ensure
+ /// there's some slack overall, but doesn't need that slack to be dedicated.
+ ///
+ /// The choice whether to use min_buffer_count_for_dedicated_slack or
+ /// min_buffer_count_for_shared_slack (or both) will typically be about the
+ /// degree to which the extra slack improves performance.
+ ///
+ /// In testing scenarios, this field may be forced to 0, and all
+ /// participants are expected to continue to work without getting stuck. If
+ /// a buffer is needed for forward progress reasons, that buffer should be
+ /// accounted for in min_buffer_count_for_camping.
+ uint32 min_buffer_count_for_shared_slack;
+
+ /// A particularly-picky participant may unfortunately need to demand a tight
+ /// range of buffer_count, or even a specific buffer_count. This field
+ /// should remain 0 unless a participant really must set this field to
+ /// constrain the overall BufferCollectionInfo_2.buffer_count. Any such
+ /// participant should still fill out the min_buffer_count_for_* fields
+ /// above.
+ uint32 min_buffer_count;
+ /// 0 is treated as 0xFFFFFFFF.
+ uint32 max_buffer_count;
+
+ /// Constraints on BufferCollectionSettings.buffer_settings.
+ ///
+ /// A participant that intends to specify image_format_constraints_count > 1
+ /// will typically specify the minimum buffer size implicitly via
+ /// image_format_constraints, and possibly specify only the max buffer size
+ /// via buffer_memory_constraints.
+ bool has_buffer_memory_constraints;
+ BufferMemoryConstraints buffer_memory_constraints;
+
+ /// Optional constraints on the image format parameters of an image stored
+ /// in a buffer of the BufferCollection. This includes pixel format and
+ /// image layout. These constraints are per-pixel-format, so more than one
+ /// is permitted.
+ ///
+ /// When aggregating, only pixel formats that are specified by all
+ /// particpants with non-zero image_format_constraints_count (and non-Null)
+ /// BufferCollectionConstraints) are retained.
+ uint32 image_format_constraints_count;
+ array<ImageFormatConstraints>:32 image_format_constraints;
+};
+
+struct VmoBuffer {
+ /// The same VMO can be used by more than one CodecBuffer (only of the same
+ /// buffer_lifetime_ordinal), but each vmo_handle must be a separate handle.
+ ///
+ /// The vmo field can be 0 if this is a VmoBuffer in BufferCollectionInfo_2
+ /// that's at or beyond BufferCollectionInfo_2.buffer_count.
+ handle<vmo>? vmo;
+
+ /// Offset within the VMO of the first usable byte. Must be < the VMO's size
+ /// in bytes, and leave sufficient room for BufferMemorySettings.size_bytes
+ /// before the end of the VMO.
+ uint64 vmo_usable_start;
+};
+
+/// Information about a buffer collection and its buffers.
+// TODO(ZX-2260): change struct to table
+struct BufferCollectionInfo_2 {
+ /// If this is the initial buffer collection allocation, this is the total
+ /// number of buffers. If this is a single buffer allocation, this is zero,
+ /// and the rest of the fields only apply to the single buffer.
+ uint32 buffer_count;
+
+ /// These settings apply to all the buffers in the inital buffer allocation.
+ SingleBufferSettings settings;
+
+ /// VMO handles (and vmo_usable_start offset) for each buffer in the
+ /// collection.
+ ///
+ /// If present, all the VMOs at or after index `buffer_count` are invalid (0)
+ /// handles.
+ ///
+ /// All buffer VMO handles have identical size and access rights. The size
+ /// is in settings.buffer_settings.size_bytes.
+ ///
+ /// The VMO access rights are determined based on the usages which the
+ /// client specified when allocating the buffer collection. For example,
+ /// a client which expressed a read-only usage will receive VMOs without
+ /// write rights. In addition, the rights can be attenuated by the parameter
+ /// to BufferCollectionToken.Duplicate() calls.
+ array<VmoBuffer>:64 buffers;
+};
+
+struct SingleBufferInfo {
+ SingleBufferSettings settings;
+ VmoBuffer buffer;
+};
+
+/// After the initial buffer allocation, it's allowed to close old buffers and
+/// allocate new buffers. When a new buffer is allocated its settings can differ
+/// from the rest of the buffers in the collection, and the single buffer's
+/// settings are delivered via OnSingleBufferAllocated() using this struct:
+struct SingleBufferSettings {
+ BufferMemorySettings buffer_settings;
+
+ /// Buffers holding data that is not uncompressed image data will not have
+ /// this field set. Buffers holding data that is uncompressed image data
+ /// _may_ have this field set.
+ ///
+ /// At least for now, changing the PixelFormat requires re-allocating
+ /// buffers.
+ bool has_image_format_constraints;
+ ImageFormatConstraints image_format_constraints;
+};
+
+/// Known heap types.
+/// Device specific types should have bit 60 set. Top order bit is reserved
+/// and should not be set.
+enum HeapType : uint64 {
+ SYSTEM_RAM = 0x0000000000000000;
+
+ /// Heap used for amlogic protected memory.
+ AMLOGIC_SECURE = 0x1000000000010000;
+
+ /// Heap used for amlogic protected memory between decrypt and video decode.
+ AMLOGIC_SECURE_VDEC = 0x1000000000010001;
+
+ /// Heap used by goldfish vulkan for device-local memory.
+ GOLDFISH_DEVICE_LOCAL = 0x1000000000020000;
+};
+
+struct BufferMemoryConstraints {
+ uint32 min_size_bytes = 0;
+ /// 0 is treated as 0xFFFFFFFF.
+ uint32 max_size_bytes = 0xFFFFFFFF;
+
+ bool physically_contiguous_required = false;
+
+ /// If true, at least one participant requires secure memory.
+ ///
+ /// When aggregating BufferCollectionConstraints, these values boolean-OR.
+ bool secure_required = false;
+
+ /// By default, participants must ensure the CPU can read or write data to
+ /// the buffer without cache operations. If they support using the RAM
+ /// domain, data must be available in RAM (with CPU cache state such that
+ /// the RAM data won't get corrupted by a dirty CPU cache line writing
+ /// incorrect data to RAM), and a consumer reading using the CPU must
+ /// invalidate CPU cache before reading (the producer doesn't guarantee
+ /// zero stale "clean" cache lines)
+ bool ram_domain_supported = false;
+ bool cpu_domain_supported = true;
+ bool inaccessible_domain_supported = false;
+
+ /// Optional heap constraints. Participants that don't care which heap
+ /// memory is allocated on should leave this field 0.
+ uint32 heap_permitted_count;
+ array<HeapType>:32 heap_permitted;
+};
+
+/// Inaccessible is only for cases where there is no CPU-based access to the
+/// buffers. A secure_required buffer can still have CoherencyDomain Cpu or
+/// Ram even if the secure_required buffer can only be accessed by the CPU when
+/// the CPU is running in secure mode (or similar). In contrast, device-local
+/// memory that isn't reachable from the CPU is CoherencyDomain Inaccessible,
+/// even if it's possible to cause a device (physical or virtual) to copy the
+/// data from the Inaccessible buffers to buffers that are visible to the CPU.
+enum CoherencyDomain {
+ CPU = 0;
+ RAM = 1;
+ INACCESSIBLE = 2;
+};
+
+struct BufferMemorySettings {
+ uint32 size_bytes;
+ bool is_physically_contiguous;
+ bool is_secure;
+ CoherencyDomain coherency_domain;
+ /// The specific heap from which buffers are allocated.
+ /// See above in this file for heap identifier values.
+ HeapType heap;
+};
+
+/// Describes constraints on layout of image data in buffers.
+// TODO(ZX-2260): change struct to table
+struct ImageFormatConstraints {
+ /// The PixelFormat for which the following constraints apply. A
+ /// participant may have more than one PixelFormat that's supported, in
+ /// which case that participant can use a list of ImageFormatConstraints
+ /// with an entry per PixelFormat. It's not uncommon for the other fields
+ /// of ImageFormatConstraints to vary by PixelFormat - for example for a
+ /// linear format to support smaller max size than a tiled format.
+ PixelFormat pixel_format;
+
+ /// Empty is an error. Redundant entries are an error. Arbitrary ordering
+ /// is not an error.
+ uint32 color_spaces_count;
+ array<ColorSpace>:32 color_space;
+
+ /// Minimum permitted width in pixels.
+ ///
+ /// For example a video decoder participant may set this field to the
+ /// minimum coded_width that might potentially be specified by a stream. In
+ /// contrast, required_min_coded_width would be set to the current
+ /// coded_width specified by the stream. While min_coded_width aggregates
+ /// by taking the max, required_min_coded_width aggregates by taking the
+ /// min.
+ ///
+ /// See also required_min_coded_width.
+ uint32 min_coded_width;
+ /// Maximum width in pixels. For example Scenic may set this field
+ /// (directly or via sub-participants) to the maximum width that can be
+ /// composited.
+ /// 0 is treated as 0xFFFFFFFF.
+ uint32 max_coded_width;
+
+ /// Minimum height in pixels. For example a video decoder participant may
+ /// set this field to the coded_height specified by a stream.
+ uint32 min_coded_height;
+ /// Maximum height in pixels. For example Scenic may set this field
+ /// (directly or via sub-participants) to the maximum height that can be
+ /// composited.
+ /// 0 is treated as 0xFFFFFFFF.
+ uint32 max_coded_height;
+
+ /// Must be >= the value implied by min_coded_width for plane 0.
+ uint32 min_bytes_per_row;
+ /// Must be >= the value implied by max_coded_width for plane 0.
+ /// 0 is treated as 0xFFFFFFFF.
+ uint32 max_bytes_per_row;
+
+ /// The max image area in pixels is limited indirectly via
+ /// BufferSettings.size_bytes, and can also be enforced directly via this
+ /// field.
+ /// 0 is treated as 0xFFFFFFFF.
+ uint32 max_coded_width_times_coded_height = 0xFFFFFFFF;
+
+ /// Number of layers within a multi-layered image.
+ /// 0 is treated as 1.
+ uint32 layers = 1;
+
+ /// coded_width % width_divisor must be 0.
+ /// 0 is treated as 1.
+ uint32 coded_width_divisor = 1;
+
+ /// coded_height % height_divisor must be 0.
+ /// 0 is treated as 1.
+ uint32 coded_height_divisor = 1;
+
+ /// bytes_per_row % bytes_per_row_divisor must be 0.
+ /// 0 is treated as 1.
+ uint32 bytes_per_row_divisor = 1;
+
+ /// vmo_usable_start % start_offset_divisor must be 0.
+ /// 0 is treated as 1.
+ uint32 start_offset_divisor = 1;
+
+ /// display_width % display_width_divisor must be 0.
+ /// 0 is treated as 1.
+ uint32 display_width_divisor = 1;
+
+ /// display_height % display_height_divisor must be 0.
+ /// 0 is treated as 1.
+ uint32 display_height_divisor = 1;
+
+ /// required_ dimension bounds.
+ ///
+ /// In contrast to the corresponding fields without "required_" at the
+ /// start, these fields (when set to non-zero values) express a requirement
+ /// that the resulting aggregated non-required_ fields specify a space that
+ /// fully contain the space expressed by each participant's required_
+ /// fields.
+ ///
+ /// For example, a producer video decoder is perfectly happy for the
+ /// consumer to be willing to accept anything, and the video decoder doesn't
+ /// really want to constrain the potential space of dimensions that might be
+ /// seen in a stream and may be acceptable to the consumer, but the video
+ /// decoder needs to ensure that the resulting dimension ranges contain
+ /// at least the current dimensions decoded from the stream.
+ ///
+ /// Similarly, an initiator with a particular dynamic-dimension scenario in
+ /// mind may wish to require up front that participants agree to handle at
+ /// least the range of dimensions expected by the initiator in that
+ /// scenario (else fail earlier rather than later, maybe trying again with
+ /// smaller required_ space).
+ ///
+ /// It's much more common for a producer or initiator to set these fields
+ /// than for a consumer to set these fields.
+ ///
+ /// While the non-required_ fields aggregate by taking the intersection, the
+ /// required_ fields aggregate by taking the union.
+ ///
+ /// If set, the required_max_coded_width and required_max_coded_height will
+ /// cause the allocated buffers to be large enough to hold an image that is
+ /// required_max_coded_width * required_max_coded_height.
+ ///
+ /// TODO(dustingreen): Make it easier to allocate buffers of minimal size
+ /// that can (optionally) also handle 90 degree rotated version of the max
+ /// dimensions / alternate required bounds for another main aspect ratio.
+ /// 0 is treated as 0xFFFFFFFF.
+ uint32 required_min_coded_width;
+ uint32 required_max_coded_width;
+ /// 0 is treated as 0xFFFFFFFF.
+ uint32 required_min_coded_height;
+ uint32 required_max_coded_height;
+ /// 0 is treated as 0xFFFFFFFF.
+ uint32 required_min_bytes_per_row;
+ uint32 required_max_bytes_per_row;
+};
+
+/// Describes how an image is represented.
+// TODO(ZX-2260): change struct to table
+struct ImageFormat_2 {
+ /// Pixel format.
+ PixelFormat pixel_format;
+
+ /// Row width in pixels that exist in the buffer. Must be >= display_width.
+ /// Can be < the width implied by stride_bytes.
+ uint32 coded_width;
+
+ /// Number of rows. Must be >= display_height.
+ uint32 coded_height;
+
+ // Stride in bytes of plane 0. Planes beyond plane 0 (if any, depending on
+ // pixel_format) have a known fixed relationship with plane 0's stride.
+ uint32 bytes_per_row;
+
+ /// Row width in pixels that are to be displayed. This can be <=
+ /// coded_width. Any cropping occurs on the right of the image (not left).
+ uint32 display_width;
+
+ /// Number of rows to be displayed. This can be <= coded_height, with any
+ /// cropping on the bottom (not top).
+ uint32 display_height;
+
+ /// Number of layers within a multi-layered image.
+ uint32 layers = 1;
+
+ /// Color space.
+ ColorSpace color_space;
+
+ /// The pixel_aspect_ratio_width : pixel_aspect_ratio_height is the
+ /// pixel aspect ratio (AKA sample aspect ratio aka SAR) for the luma
+ /// (AKA Y) samples. A pixel_aspect_ratio of 1:1 mean square pixels. A
+ /// pixel_aspect_ratio of 2:1 would mean pixels that are displayed twice
+ /// as wide as they are tall. Codec implementation should ensure these
+ /// two values are relatively prime by reducing the fraction (dividing
+ /// both by GCF) if necessary.
+ ///
+ /// When has_pixel_aspect_ratio == false, pixel_aspect_ratio_width and
+ /// pixel_aspect_ratio_height will both be 1, but in that case the
+ /// pixel_aspect_ratio_width : pixel_aspect_ratio_height of 1:1 is just
+ /// a very weak suggestion re. reasonable-ish handling, not in any way
+ /// authoritative. In this case (or in any case really) the receiver of
+ /// this message may have other OOB means to determine the actual
+ /// pixel_aspect_ratio.
+ bool has_pixel_aspect_ratio = false;
+ uint32 pixel_aspect_ratio_width = 1;
+ uint32 pixel_aspect_ratio_height = 1;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/driver_connector.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/driver_connector.fidl
new file mode 100644
index 0000000..b4cf7e6
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/driver_connector.fidl
@@ -0,0 +1,32 @@
+// Copyright 2018 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.
+
+library fuchsia.sysmem;
+
+/// Once a channel with this interface is established to a driver (typically in
+/// advance), this interface allows asynchronously sending the server end of an
+/// Allocator channel which will be served by the driver.
+///
+/// For now, the only FIDL interface directly served via normal devhost FIDL
+/// dispatching code by the sysmem driver is this interface. Other sysmem
+/// interfaces are served by separate dispatching code primarily because we want
+/// to be able to establish channels async by sending the server channel toward
+/// the driver without needing a round-trip open and without managing the channel
+/// as a file descriptor.
+///
+/// A secondary current reason tracked by ZX-3091 is that the current devhost
+/// dispatching code doesn't permit async processing of requests, which we want
+/// for proper functionining of at least the BufferCollection interface since
+/// that interface has requests that don't complete until the devhost has
+/// constraints from other participants.
+//
+// Needs Layout = "Simple" because used with "FIDL Simple C Bindings".
+[Discoverable, Layout = "Simple"]
+protocol DriverConnector {
+ /// This one-way message sends in the server end of an Allocator channel.
+ ///
+ /// `allocator_request` will be served by the sysmem driver (or the channel
+ /// will close).
+ Connect(request<Allocator> allocator_request);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/format_modifier.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/format_modifier.fidl
new file mode 100644
index 0000000..ee28fad
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/format_modifier.fidl
@@ -0,0 +1,58 @@
+// Copyright 2018 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.
+
+library fuchsia.sysmem;
+
+struct FormatModifier {
+ /// The upper 8 bits are a vendor code as allocated in FormatModifierVendor
+ /// enum. The lower 56 bits are vendor-defined.
+ ///
+ /// This field and the values that go in this field are defined this way for
+ /// compatibility reasons.
+ uint64 value;
+};
+
+const uint64 FORMAT_MODIFIER_NONE = 0x0000000000000000;
+
+const uint64 FORMAT_MODIFIER_VENDOR_NONE = 0x0000000000000000;
+const uint64 FORMAT_MODIFIER_VENDOR_INTEL = 0x0100000000000000;
+const uint64 FORMAT_MODIFIER_VENDOR_AMD = 0x0200000000000000;
+const uint64 FORMAT_MODIFIER_VENDOR_NVIDIA = 0x0300000000000000;
+const uint64 FORMAT_MODIFIER_VENDOR_SAMSUNG = 0x0400000000000000;
+const uint64 FORMAT_MODIFIER_VENDOR_QCOM = 0x0500000000000000;
+const uint64 FORMAT_MODIFIER_VENDOR_VIVANTE = 0x0600000000000000;
+const uint64 FORMAT_MODIFIER_VENDOR_BROADCOM = 0x0700000000000000;
+const uint64 FORMAT_MODIFIER_VENDOR_ARM = 0x0800000000000000;
+
+const uint64 FORMAT_MODIFIER_VALUE_RESERVED = 0x00FFFFFFFFFFFFFF;
+
+const uint64 FORMAT_MODIFIER_INVALID = FORMAT_MODIFIER_VALUE_RESERVED;
+
+const uint64 FORMAT_MODIFIER_LINEAR = 0x0000000000000000;
+
+//
+// Fill in (compatible) values below as needed.
+//
+
+// Intel format modifier values
+const uint64 FORMAT_MODIFIER_INTEL_I915_X_TILED = 0x0100000000000001;
+const uint64 FORMAT_MODIFIER_INTEL_I915_Y_TILED = 0x0100000000000002;
+const uint64 FORMAT_MODIFIER_INTEL_I915_YF_TILED = 0x0100000000000003;
+
+// AMD format modifier values
+
+// NVIDIA format modifier values
+
+// SAMSUNG format modifier values
+
+// QCOM format modifier values
+
+// VIVANTE format modifier values
+
+// BROADCOM format modifier values
+
+// ARM format modifier values
+const uint64 FORMAT_MODIFIER_ARM_AFBC_16x16 = 0x0800000000000001;
+const uint64 FORMAT_MODIFIER_ARM_AFBC_32x8 = 0x0800000000000002;
+
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/formats_deprecated.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/formats_deprecated.fidl
new file mode 100644
index 0000000..78217b7
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/formats_deprecated.fidl
@@ -0,0 +1,15 @@
+// Copyright 2018 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.
+
+library fuchsia.sysmem;
+
+/// Describes how the contents of buffers are represented.
+/// Buffers of each type are described by their own tables.
+struct BufferFormat {
+ /// Since this struct used to be a single member union, we kept the tag
+ /// to avoid any wire format changes. The tag must be set to `0`,
+ /// no other value is correct.
+ uint32 tag = 0;
+ ImageFormat image;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/heap.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/heap.fidl
new file mode 100644
index 0000000..e2f5fce
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/heap.fidl
@@ -0,0 +1,54 @@
+// 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.
+
+library fuchsia.sysmem;
+
+using zx;
+
+/// Manages resources on a specific sysmem heap.
+///
+/// Needs Layout = "Simple" because used with "FIDL Simple C Bindings".
+[Layout = "Simple"]
+protocol Heap {
+ /// Request a new memory allocation of `size` on heap.
+ /// For heaps which don't permit CPU access to the buffer data, this
+ /// will create a VMO with an official size, but which never has any
+ /// physical pages. For such heaps, the VMO is effectively used as
+ /// an opaque buffer identifier.
+ ///
+ /// Heaps should defer allocation of any associated resources until
+ /// CreateResource(), because the caller of AllocateVmo() may simply
+ /// delete the returned VMO with no further notification to the heap.
+ /// In contrast, after CreateResource(), the caller guarantees that
+ /// DestroyResource() or heap channel closure will occur.
+ ///
+ /// The caller guarantees that CreateResource() will be called prior
+ /// to the returned VMO or any associated child VMO being used.
+ AllocateVmo(uint64 size) -> (zx.status s, handle<vmo>? vmo);
+
+ /// Create resources and associate heap-specific resources with the
+ /// passed-in VMO. Resources can be hardware specific and their
+ /// lifetime don't have to be tied to `vmo`. `vmo` must be a VMO
+ /// (or a direct or indirect child of a VMO) acquired through a call
+ /// to AllocateVmo method above. If the passed-in vmo is a child VMO,
+ /// its size must match the size of the parent VMO created by
+ /// AllocateVmo(). For heaps that permit CPU access, the passed-in
+ /// VMO must not have a copy-on-write relationship with the parent
+ /// VMO, but rather a pass-through relationship. Successful return
+ /// status indicate that Heap has established a mapping between
+ /// VMO and hardware specific resources.
+ ///
+ /// The returned id must be passed to DestroyResource() later when
+ /// resources associated with VMO are no longer needed, unless the
+ /// heap channel closes first.
+ ///
+ /// The heap must not own/keep a handle to VMO, or any derived child
+ /// VMO, or any VMAR mapping to VMO, as any of those would keep VMO
+ /// alive beyond all sysmem participant usages of the vmo; instead
+ /// the heap can get the vmo's koid for the heap's mapping.
+ CreateResource(handle<vmo> vmo) -> (zx.status s, uint64 id);
+
+ /// Destroy previously created resources.
+ DestroyResource(uint64 id) -> ();
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/image_formats.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/image_formats.fidl
new file mode 100644
index 0000000..32bd58a
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/image_formats.fidl
@@ -0,0 +1,146 @@
+// Copyright 2018 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.
+
+library fuchsia.sysmem;
+
+/// Describes how the pixels within an image are represented.
+/// Simple formats need only a type.
+/// Parametric pixel formats may require additional properties.
+// TODO(ZX-2260): change struct to table
+struct PixelFormat {
+ PixelFormatType type;
+ /// This bool effectively makes format_modifier optional, to satisfy
+ /// 'Layout = "Simple"', to satisify "FIDL Simple C Bindings".
+ bool has_format_modifier;
+ FormatModifier format_modifier;
+};
+
+// TODO(ZX-2270): add more formats.
+/// The ordering of the channels in the format name reflects how
+/// the actual layout of the channel.
+///
+/// Each of these values is opinionated re. the color spaces that can be
+/// contained within (in contrast with Vulkan).
+//
+// TODO(dustingreen): Add more comment text re. pixel data layout for each of
+// these.
+enum PixelFormatType {
+ INVALID = 0;
+
+ /// RGB only, 8 bits per each of R/G/B/A sample
+ /// Compatible with VK_FORMAT_R8G8B8A8_UNORM.
+ /// Compatible with ZX_PIXEL_FORMAT_ABGR_8888 and ZX_PIXEL_FORMAT_BGR_x8888.
+ R8G8B8A8 = 1;
+
+ /// 32bpp BGRA, 1 plane. RGB only, 8 bits per each of B/G/R/A sample.
+ /// Compatible with VK_FORMAT_B8G8R8A8_UNORM.
+ /// Compatible with ZX_PIXEL_FORMAT_RGB_x888 and ZX_PIXEL_FORMAT_ARGB_8888.
+ BGRA32 = 101; // For UVC compliance.
+
+ /// YUV only, 8 bits per Y sample
+ /// Compatible with VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM.
+ I420 = 102; // For UVC compliance.
+
+ /// YUV only, 8 bits per Y sample
+ /// Not compatible with any vulkan format.
+ M420 = 103; // For UVC compliance.
+
+ /// YUV only, 8 bits per Y sample
+ /// Compatible with VK_FORMAT_G8_B8R8_2PLANE_420_UNORM.
+ /// Compatible with ZX_PIXEL_FORMAT_NV12.
+ NV12 = 104; // For UVC compliance.
+
+ /// YUV only, 8 bits per Y sample
+ /// Compatible with VK_FORMAT_G8B8G8R8_422_UNORM.
+ YUY2 = 105; // For UVC compliance.
+
+ // TODO(garratt): Please elaborate in a comment here re. what/where the spec
+ // for this is (including any variants that are specified / permitted /
+ // indicated in-band / prohibited).
+ MJPEG = 106; // For UVC compliance.
+
+ /// YUV only, 8 bits per Y sample
+ /// Compatible with VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM with B and R swizzled.
+ YV12 = 107;
+
+ /// 24bpp BGR, 1 plane. RGB only, 8 bits per each of B/G/R sample
+ /// Compatible with VK_FORMAT_B8G8R8_UNORM.
+ /// Compatible with ZX_PIXEL_FORMAT_RGB_888.
+ BGR24 = 108;
+
+ /// 16bpp RGB, 1 plane. 5 bits R, 6 bits G, 5 bits B
+ /// Compatible with VK_FORMAT_R5G6B5_UNORM_PACK16.
+ /// Compatible with ZX_PIXEL_FORMAT_RGB_565.
+ RGB565 = 109;
+
+ /// 8bpp RGB, 1 plane. 3 bits R, 3 bits G, 2 bits B
+ /// Not compatible with any vulkan format.
+ /// Compatible with ZX_PIXEL_FORMAT_RGB_332.
+ RGB332 = 110;
+
+ /// 8bpp RGB, 1 plane. 2 bits R, 2 bits G, 2 bits B
+ /// Not compatible with any vulkan format.
+ /// Compatible with ZX_PIXEL_FORMAT_RGB_2220.
+ RGB2220 = 111;
+
+ /// 8bpp, Luminance-only.
+ /// Compatible with VK_FORMAT_R8_UNORM.
+ /// Compatible with ZX_PIXEL_FORMAT_GRAY_8 and ZX_PIXEL_FORMAT_MONO_8.
+ L8 = 112;
+};
+
+/// Describes how the pixels within an image are meant to be presented.
+/// Simple color spaces need only a type.
+/// Parametric color spaces may require additional properties.
+// TODO(ZX-2260): change struct to table
+struct ColorSpace {
+ ColorSpaceType type;
+};
+
+/// This list has a separate entry for each variant of a color space standard.
+///
+/// For this reason, should we ever add support for the RGB variant of 709, for
+/// example, we'd add a separate entry to this list for that variant. Similarly
+/// for the RGB variants of 2020 or 2100. Similarly for the YcCbcCrc variant of
+/// 2020. Similarly for the ICtCp variant of 2100.
+///
+/// A given ColorSpaceType may permit usage with a PixelFormatType(s) that
+/// provides a bits-per-sample that's compatible with the ColorSpaceType's
+/// official spec. Not all spec-valid combinations are necessarily supported.
+/// See ImageFormatIsSupportedColorSpaceForPixelFormat() for the best-case degree
+/// of support, but a "true" from that function doesn't guarantee that any given
+/// combination of participants will all support the desired combination of
+/// ColorSpaceType and PixelFormatType.
+///
+/// The sysmem service helps find a mutually supported combination and allocate
+/// suitable buffers.
+///
+/// A ColorSpaceType's spec is not implicitly extended to support
+/// outside-the-standard bits-per-sample (R, G, B, or Y sample). For example,
+/// for 2020 and 2100, 8 bits-per-Y-sample is not supported (by sysmem), because
+/// 8 bits-per-Y-sample is not in the spec for 2020 or 2100. A sysmem
+/// participant that attempts to advertise support for a PixelFormat + ColorSpace
+/// that's non-standard will cause sysmem to reject the combo and fail to
+/// allocate (intentionally, to strongly discourage specifying
+/// insufficiently-defined combos).
+enum ColorSpaceType {
+ /// Not a valid color space type.
+ INVALID = 0;
+ /// sRGB
+ SRGB = 1;
+ /// 601 NTSC ("525 line") YCbCr primaries, narrow
+ REC601_NTSC = 2;
+ /// 601 NTSC ("525 line") YCbCr primaries, wide
+ REC601_NTSC_FULL_RANGE = 3;
+ /// 601 PAL ("625 line") YCbCr primaries, narrow
+ REC601_PAL = 4;
+ /// 601 PAL ("625 line") YCbCr primaries, wide
+ REC601_PAL_FULL_RANGE = 5;
+ /// 709 YCbCr (not RGB)
+ REC709 = 6;
+ /// 2020 YCbCr (not RGB, not YcCbcCrc)
+ REC2020 = 7;
+ /// 2100 YCbCr (not RGB, not ICtCp)
+ REC2100 = 8;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/image_formats_deprecated.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/image_formats_deprecated.fidl
new file mode 100644
index 0000000..7770361
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/image_formats_deprecated.fidl
@@ -0,0 +1,58 @@
+// Copyright 2018 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.
+
+library fuchsia.sysmem;
+
+/// Describes how an image is represented.
+// TODO(ZX-2260): change struct to table
+struct ImageFormat {
+ /// Row width in pixels.
+ uint32 width;
+
+ /// Number of rows.
+ uint32 height;
+
+ /// Number of layers within a multi-layered image.
+ /// Defaults to 1 if not specified.
+ uint32 layers = 1;
+
+ /// Pixel format.
+ PixelFormat pixel_format;
+
+ /// Color space.
+ ColorSpace color_space;
+
+ array<ImagePlane>:4 planes;
+};
+
+struct ImagePlane {
+ /// Byte offset of the start of the plane from the beginning of the image.
+ uint32 byte_offset;
+
+ /// Stride in bytes per row.
+ /// Only meaningful for linear buffer formats.
+ uint32 bytes_per_row;
+};
+
+/// Describes constraints for allocating images of some desired form.
+// TODO(ZX-2260): change struct to table
+struct ImageSpec {
+ /// Minimum width in pixels.
+ uint32 min_width;
+
+ /// Minimum height in pixels.
+ uint32 min_height;
+
+ /// Number of layers within a multi-layered image.
+ /// Defaults to 1 if not specified.
+ uint32 layers = 1;
+
+ /// Pixel format.
+ PixelFormat pixel_format;
+
+ /// Color space.
+ ColorSpace color_space;
+
+ // TODO(ZX-2270): Add tiling formats.
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/meta.json
new file mode 100644
index 0000000..d421099
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/meta.json
@@ -0,0 +1,20 @@
+{
+ "deps": [],
+ "name": "fuchsia.sysmem",
+ "root": "fidl/fuchsia.sysmem",
+ "sources": [
+ "fidl/fuchsia.sysmem/allocator.fidl",
+ "fidl/fuchsia.sysmem/collection.fidl",
+ "fidl/fuchsia.sysmem/collections_deprecated.fidl",
+ "fidl/fuchsia.sysmem/constraints.fidl",
+ "fidl/fuchsia.sysmem/driver_connector.fidl",
+ "fidl/fuchsia.sysmem/format_modifier.fidl",
+ "fidl/fuchsia.sysmem/formats_deprecated.fidl",
+ "fidl/fuchsia.sysmem/heap.fidl",
+ "fidl/fuchsia.sysmem/image_formats.fidl",
+ "fidl/fuchsia.sysmem/image_formats_deprecated.fidl",
+ "fidl/fuchsia.sysmem/secure_mem.fidl",
+ "fidl/fuchsia.sysmem/usages.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/secure_mem.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/secure_mem.fidl
new file mode 100644
index 0000000..9ddd556
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/secure_mem.fidl
@@ -0,0 +1,109 @@
+// 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.
+
+library fuchsia.sysmem;
+
+using zx;
+
+/// SecureMem
+///
+/// The client is sysmem. The server is securemem driver.
+///
+/// TEE - Trusted Execution Environment.
+///
+/// REE - Rich Execution Environment.
+///
+/// Enables sysmem to call the securemem driver to get any secure heaps
+/// configured via the TEE (or via the securemem driver), and set any physical
+/// secure heaps configured via sysmem.
+///
+/// Presently, dynamically-allocated secure heaps are configured via sysmem, as
+/// it starts quite early during boot and can successfully reserve contiguous
+/// physical memory. Presently, fixed-location secure heaps are configured via
+/// TEE, as the plumbing goes from the bootloader to the TEE. However, this
+/// protocol intentionally doesn't care which heaps are dynamically-allocated
+/// and which are fixed-location.
+protocol SecureMem {
+ /// Gets the physical address and length of any secure heap whose physical
+ /// range is configured via the TEE.
+ ///
+ /// Presently, these will be fixed physical addresses and lengths, with the
+ /// location plumbed via the TEE.
+ ///
+ /// This is preferred over RegisterHeap() when there isn't any special
+ /// heap-specific per-VMO setup or teardown required.
+ ///
+ /// The physical range must be secured/protected by the TEE before the
+ /// securemem driver responds to this request with success.
+ ///
+ /// Sysmem should only call this once. Returning zero heaps is not a
+ /// failure.
+ ///
+ /// Errors:
+ /// * ZX_ERR_BAD_STATE - called more than once.
+ /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
+ /// with TEE which doesn't generate zx_status_t errors).
+ /// * other errors are possible, such as from communication failures or
+ /// server propagation of zx_status_t failures
+ GetPhysicalSecureHeaps() -> (PhysicalSecureHeaps heaps) error zx.status;
+
+ /// This request from sysmem to the securemem driver lets the TEE know the
+ /// physical memory address and length of any secure heap whose location is
+ /// configured/established via sysmem.
+ ///
+ /// Only sysmem can call this because only sysmem is handed the client end
+ /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
+ /// securemem driver is the server end of this protocol.
+ ///
+ /// Presently, these physical ranges will be dynamically-allocated by sysmem
+ /// early during boot.
+ ///
+ /// The heap ID is included in case that's relevant to the securemem driver,
+ /// for more informative log messages, and for consistency with
+ /// GetPhysicalSecureHeaps().
+ ///
+ /// The securemem driver must configure all the provided ranges as secure
+ /// with the TEE before responding to this message with success.
+ ///
+ /// For heaps configured via sysmem, both the HeapType and heap location are
+ /// configured via sysmem, and ZX_ERR_INVALID_ARGS will be the result if the
+ /// securemem driver determines that the number of heaps or HeapType(s) are
+ /// not what's supported by the securemem driver. Typically these aspects
+ /// are essentially fixed for a given device, so this error would typically
+ /// imply a configuration or plumbing problem.
+ ///
+ /// Sysmem should only call this once.
+ ///
+ /// Errors:
+ /// * ZX_ERR_BAD_STATE - called more than once
+ /// * ZX_ERR_INVALID_ARGS - unexpected heap count or unexpected heap
+ /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
+ /// with TEE which doesn't generate zx_status_t errors).
+ /// * other errors are possible, such as from communication failures or
+ /// server propagation of zx_status_t failures
+ SetPhysicalSecureHeaps(PhysicalSecureHeaps heaps) -> () error zx.status;
+};
+
+struct PhysicalSecureHeap {
+ /// This must be a HeapType that is secure/protected.
+ HeapType heap;
+ /// Must be at least PAGE_SIZE aligned.
+ uint64 physical_address;
+ /// Must be at least PAGE_SIZE aligned.
+ uint64 size_bytes;
+};
+
+// Sysmem uses layout=Simple, which requires picking a specific array size.
+// Each heap consumes ~24 bytes on the stack, so we limit to a number that
+// exceeds the needs of any current use case (1 heap in each direction so far),
+// without over-using stack space (24 bytes * 32 == 768 bytes).
+const uint32 MAX_HEAPS_COUNT = 32;
+
+// In this struct we use array instead of vector because layout=Simple.
+struct PhysicalSecureHeaps {
+ /// Must be <= MAX_HEAPS_COUNT.
+ uint32 heaps_count;
+ /// Only the first heaps_count are meaningful. The rest are ignored.
+ array<PhysicalSecureHeap>:MAX_HEAPS_COUNT heaps;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/usages.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/usages.fidl
new file mode 100644
index 0000000..2d948fb
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.sysmem/usages.fidl
@@ -0,0 +1,69 @@
+// Copyright 2018 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.
+
+library fuchsia.sysmem;
+
+// Describes how a client will access the contents of a buffer.
+// TODO(ZX-2260): change struct to table
+struct BufferUsage {
+ uint32 none;
+ uint32 cpu;
+ uint32 vulkan;
+ uint32 display;
+ uint32 video;
+};
+
+// Flag for "none" usage.
+//
+// This bit indicates that there is no direct usage from the participant, and
+// that the participant hasn't forgotten to set usage.
+const uint32 noneUsage = 1;
+
+// Flags for "cpu" usage.
+// The "often" variants prefer cacheable memory.
+const uint32 cpuUsageRead = 1;
+const uint32 cpuUsageReadOften = 2;
+const uint32 cpuUsageWrite = 4;
+const uint32 cpuUsageWriteOften = 8;
+
+// Flags for "vulkan" usage.
+// Based on https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VkImageUsageFlagBits.html
+const uint32 vulkanUsageTransferSrc = 0x0001;
+const uint32 vulkanUsageTransferDst = 0x0002;
+const uint32 vulkanUsageSampled = 0x0004;
+const uint32 vulkanUsageStorage = 0x0008;
+const uint32 vulkanUsageColorAttachment = 0x0010;
+const uint32 vulkanUsageStencilAttachment = 0x0020;
+const uint32 vulkanUsageTransientAttachment = 0x0040;
+const uint32 vulkanUsageInputAttachment = 0x0080;
+
+// Flags for "display" usage.
+const uint32 displayUsageLayer = 1;
+const uint32 displayUsageCursor = 2;
+
+// Flags for "video" usage.
+// TODO(ZX-2259): Add more specific HwDecoder flags if needed.
+const uint32 videoUsageHwDecoder = 1;
+const uint32 videoUsageHwEncoder = 2;
+// TODO(34192): This bit is redundant with secure_required and supported heaps. This bit will
+// not be carried forward.
+const uint32 videoUsageHwProtected = 4;
+const uint32 videoUsageCapture = 8;
+// videoUsageDecryptorOutput is for the output of a decryptor; such buffers will contain decrypted
+// encoded access units. The decryptor output may be in secure memory (controlled separately via
+// secure_required).
+//
+// TODO(34192): Overhaul usage so we can add usage categories without breaking client struct init
+// code repeatedly. For now, this value is in the "video" category but to some degree isn't really
+// video; this usage can be used for the output of any secure decryptor. Also, other usages should
+// include input vs. output as those are separate buffer collections and are really separate usages.
+//
+// We have this as a separate usage because each participant that needs VMO handles needs to specify
+// a usage that isn't nonUsage, and the decryptor output participant shouldn't be specifying
+// videoUsageHwDecoder because the decryptor isn't the decoder.
+const uint32 videoUsageDecryptorOutput = 16;
+// This usage is for a HW video decoder's internal buffers that aren't shared with other
+// particpants. These are allocated via sysmem becuase sysmem pre-reserves contiguous SYSTEM_RAM
+// as appropriate, and is the only way to allocate secure memory.
+const uint32 videoUsageHwDecoderInternal = 32;
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.tracing.provider/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.tracing.provider/BUILD.gn
new file mode 100644
index 0000000..e13989b
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.tracing.provider/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.tracing.provider") {
+ library_name = "provider"
+ namespace = "fuchsia.tracing"
+ public_deps = [
+ ]
+ sources = [
+ "provider.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.tracing.provider",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.tracing.provider/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.tracing.provider/meta.json
new file mode 100644
index 0000000..bbdb955
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.tracing.provider/meta.json
@@ -0,0 +1,9 @@
+{
+ "deps": [],
+ "name": "fuchsia.tracing.provider",
+ "root": "fidl/fuchsia.tracing.provider",
+ "sources": [
+ "fidl/fuchsia.tracing.provider/provider.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.tracing.provider/provider.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.tracing.provider/provider.fidl
new file mode 100644
index 0000000..8f6fa92
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.tracing.provider/provider.fidl
@@ -0,0 +1,173 @@
+// Copyright 2016 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.
+
+library fuchsia.tracing.provider;
+
+using zx;
+
+/// The maximum length of a provider's name.
+const uint32 MAX_PROVIDER_NAME_LENGTH = 100;
+
+/// The maximum number of categories supported.
+const uint32 MAX_NUM_CATEGORIES = 100;
+
+/// The maximum length of a category name.
+const uint32 MAX_CATEGORY_NAME_LENGTH = 100;
+
+/// The provider interface which applications must implement and register
+/// with the `TraceRegistry` to participate in tracing.
+///
+/// See //zircon/system/ulib/trace-provider/ for a C++ implementation of
+/// this interface which can easily be configured by an application.
+protocol Provider {
+ /// Initialize tracing and prepare for writing trace records for events in
+ /// the specified `categories` into `buffer` using `fifo` for signaling.
+ /// Tracing hasn't started yet, a `Start()` call is still required.
+ ///
+ ///
+ /// At most one trace can be active at a time. Subsequent `Initialize()`
+ /// requests received prior to a `Terminate()` call must be ignored.
+ Initialize(ProviderConfig config);
+
+ /// Begin tracing.
+ ///
+ /// If tracing has already started the provider must ignore the request.
+ ///
+ /// There is no result. The provider must send a `TRACE_PROVIDER_STARTED`
+ /// packet on `fifo` to indicate success/failure of starting.
+ Start(StartOptions options);
+
+ /// Stop tracing.
+ ///
+ /// If tracing has already stopped the provider must ignore the request.
+ ///
+ /// Once the provider has finished writing any final events to the trace
+ /// buffer, it must send a `TRACE_PROVIDER_STOPPED` packet on `fifo`.
+ /// Note that multiple `Start,Stop` requests can be received between
+ /// `Initialize,Terminate`.
+ Stop();
+
+ /// Terminate tracing.
+ ///
+ /// Tracing is stopped first if not already stopped.
+ /// After tracing has fully terminated the provider must close both
+ /// `buffer` and `fifo` to indicate to the trace manager that tracing is
+ /// finished.
+ Terminate();
+};
+
+/// The service which trace providers use to register themselves with
+/// the tracing system.
+/// Note that one property of this interface is that once registration is made
+/// the provider can drop this connection.
+[Discoverable, Layout = "Simple"]
+protocol Registry {
+ /// Registers the trace provider.
+ /// Note: Registration is asynchronous, it's only at some point after this
+ /// returns that the provider is actually registered.
+ /// To unregister, simply close the Provider pipe.
+ /// `pid` is the process id of the provider, `name` is the name of the
+ /// provider. Both of these are used in logging and diagnostic messages.
+ RegisterProvider(Provider provider, zx.koid pid, string:MAX_PROVIDER_NAME_LENGTH name);
+
+ /// Registers the trace provider synchronously. The call doesn't return
+ /// until the provider is registered.
+ /// On return `s` is `ZX_OK` if registration was successful.
+ /// `started` is true if tracing has already started, which is a hint to
+ /// the provider to wait for the Start() message before continuing if it
+ /// wishes to not drop trace records before Start() is received.
+ /// To unregister, simply close the Provider pipe.
+ /// `pid` is the process id of the provider, `name` is the name of the
+ /// provider. Both of these are used in logging and diagnostic messages.
+ RegisterProviderSynchronously(Provider provider, zx.koid pid, string:MAX_PROVIDER_NAME_LENGTH name) -> (zx.status s, bool started);
+};
+
+/// The trace buffering mode.
+enum BufferingMode : uint8 {
+ /// In oneshot mode there is only one buffer that is not reused. When the
+ /// buffer fills the provider just keeps dropping records, keeping a count,
+ /// and then when tracing stops the header is updated to record final
+ /// state.
+ ONESHOT = 1;
+
+ /// In circular mode, the buffer is continually written to until tracing
+ /// stops. When the buffer fills older records are discarded as needed.
+ CIRCULAR = 2;
+
+ /// In streaming mode, the buffer is effectively split into two pieces.
+ /// When one half of the buffer fills the provider notifies the trace
+ /// manager via the provided fifo, and then starts filling the other half
+ /// of the buffer. When the buffer is saved, the manager responds via the
+ /// provided fifo. If trace manager hasn't saved the buffer in time, and
+ /// the other buffer fills, then the provider is required to drop records
+ /// until space becomes available.
+ STREAMING = 3;
+};
+
+/// Trace provider configuration.
+// The configuration of a provider is split out into a struct so that we can
+// add configuration data without changing the method signature. Structs still
+// introduce ABI compatibility issues, this will be switched to a table when
+// tables are ready for use in zircon.
+struct ProviderConfig {
+ /// `buffering_mode` specifies what happens when the buffer fills.
+ BufferingMode buffering_mode;
+
+ /// The buffer to write trace records into.
+ handle<vmo> buffer;
+
+ /// When the trace provider observes `ZX_FIFO_PEER_CLOSED` on `fifo`, it
+ /// must assume the trace manager has terminated abnormally (since `Stop`
+ /// was not received as usual) and stop tracing automatically, discarding
+ /// any in-flight trace data.
+ handle<fifo> fifo;
+
+ /// What trace categories to collect data for.
+ vector<string:MAX_CATEGORY_NAME_LENGTH>:MAX_NUM_CATEGORIES categories;
+};
+
+/// Choices for clearing/retaining trace buffer contents at Start.
+/// A brief summary of buffer contents:
+/// The trace buffer is divided into two main pieces: durable and non-durable.
+/// The durable portion contains things like the string and thread data for
+/// their respective references (trace_encoded_string_ref_t and
+/// trace_encoded_thread_ref_t). The non-durable portion contains the rest of
+/// the trace data like events); this is the portion that, for example, is
+/// discarded in circular buffering mode when the (non-durable) buffer fills.
+enum BufferDisposition : uint8 {
+ /// Clear the entire buffer, including durable buffer contents.
+ /// N.B. If this is done mid-session, then string and thread references
+ /// from prior to this point will become invalid - the underlying data
+ /// will be gone. To prevent this save buffer contents before clearing.
+ ///
+ /// This is typically used when buffer contents were saved after the
+ /// preceding Stop.
+ CLEAR_ENTIRE = 1;
+
+ /// Clear the non-durable portion of the buffer, retaining the durable
+ /// portion.
+ ///
+ /// This is typically used when buffer contents were not saved after the
+ /// preceding Stop and the current contents are to be discarded.
+ CLEAR_NONDURABLE = 2;
+
+ /// Retain buffer contents. New trace data is added where the previous
+ /// trace run left off.
+ ///
+ /// This is typically used when buffer contents were not saved after the
+ /// preceding Stop and the current contents are to be retained.
+ RETAIN = 3;
+};
+
+/// Additional options to control tracing at start.
+struct StartOptions {
+ /// Whether and how to clear the buffer when starting data collection.
+ /// This allows, for example, multiple Start/Stop trace runs to be
+ /// collected in the same buffer.
+ BufferDisposition buffer_disposition;
+
+ /// The trace categories to add to the initial set provided in
+ /// `ProviderConfig`.
+ vector<string:MAX_CATEGORY_NAME_LENGTH>:MAX_NUM_CATEGORIES additional_categories;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.activity.control/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.ui.activity.control/BUILD.gn
new file mode 100644
index 0000000..fcefb34
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.activity.control/BUILD.gn
@@ -0,0 +1,26 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.ui.activity.control") {
+ library_name = "control"
+ namespace = "fuchsia.ui.activity"
+ public_deps = [
+ "../fuchsia.ui.activity",
+ ]
+ sources = [
+ "control.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.ui.activity.control",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.activity.control/control.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.activity.control/control.fidl
new file mode 100644
index 0000000..50b2805
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.activity.control/control.fidl
@@ -0,0 +1,29 @@
+// 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.
+
+library fuchsia.ui.activity.control;
+
+using fuchsia.ui.activity;
+
+/// The Control protocol can be used to override the activity state of the
+/// Activity Service (fuchsia.ui.activity).
+///
+/// State provided through this interface takes precedence over state which
+/// is determined based on activity sent through the Tracker API.
+///
+/// Once a state has been assigned through this protocol, the Activity
+/// Service will no longer determine state based on input to the
+/// fuchsia.ui.activity.Tracker protocol, and instead will only report state
+/// transitions occuring through the Control protocol.
+// TODO(38334): Remove this transitional interface.
+[Discoverable]
+protocol Control {
+ /// Sets the Activity Service's state to `state`.
+ /// All listeners registered through the Provider protocol will immediately
+ /// be notified of the new state.
+ ///
+ /// Typically, state transitions should occur minutes apart (e.g.
+ /// transition from ACTIVE to IDLE after 15 minutes of inactivity).
+ SetState(fuchsia.ui.activity.State state);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.activity.control/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.ui.activity.control/meta.json
new file mode 100644
index 0000000..1b75882
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.activity.control/meta.json
@@ -0,0 +1,11 @@
+{
+ "deps": [
+ "fuchsia.ui.activity"
+ ],
+ "name": "fuchsia.ui.activity.control",
+ "root": "fidl/fuchsia.ui.activity.control",
+ "sources": [
+ "fidl/fuchsia.ui.activity.control/control.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.activity/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.ui.activity/BUILD.gn
new file mode 100644
index 0000000..dace99c
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.activity/BUILD.gn
@@ -0,0 +1,28 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.ui.activity") {
+ library_name = "activity"
+ namespace = "fuchsia.ui"
+ public_deps = [
+ ]
+ sources = [
+ "activity.fidl",
+ "provider.fidl",
+ "state.fidl",
+ "tracker.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.ui.activity",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.activity/activity.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.activity/activity.fidl
new file mode 100644
index 0000000..118bb49
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.activity/activity.fidl
@@ -0,0 +1,25 @@
+// 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.
+
+library fuchsia.ui.activity;
+
+/// DiscreteActivity is an activity which occurs at a point in time.
+flexible union DiscreteActivity {
+ /// Activities that require no special handling.
+ 1: GenericActivity generic;
+};
+
+/// OngoingActivity is an activity which has a definite start and end time.
+flexible union OngoingActivity {
+ /// Activities that require no special handling.
+ 1: GenericActivity generic;
+};
+
+/// GenericActivity is a user or system activity of unspecified type, e.g.
+/// a keyboard press or an alarm going off.
+table GenericActivity {
+ /// Brief human-readable label for the activity, for logging/debugging.
+ /// e.g. "cursor", "key", "video"
+ 1: string label;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.activity/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.ui.activity/meta.json
new file mode 100644
index 0000000..0951d48
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.activity/meta.json
@@ -0,0 +1,12 @@
+{
+ "deps": [],
+ "name": "fuchsia.ui.activity",
+ "root": "fidl/fuchsia.ui.activity",
+ "sources": [
+ "fidl/fuchsia.ui.activity/activity.fidl",
+ "fidl/fuchsia.ui.activity/provider.fidl",
+ "fidl/fuchsia.ui.activity/state.fidl",
+ "fidl/fuchsia.ui.activity/tracker.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.activity/provider.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.activity/provider.fidl
new file mode 100644
index 0000000..4f75587
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.activity/provider.fidl
@@ -0,0 +1,28 @@
+// 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.
+
+library fuchsia.ui.activity;
+
+using zx;
+
+/// The Provider protocol offers a subscription interface through
+/// which clients can watch for changes in the system's activity state.
+[Discoverable]
+protocol Provider {
+ /// Subscribe to changes in the system's state.
+ /// The server will always invoke listener.OnStateChanged at least once with
+ /// the initial state, and after that invoke listener.OnStateChanged
+ /// whenever the system's state changes.
+ WatchState(Listener listener);
+};
+
+/// The Listener protocol subscribes to changes in the system's activity
+/// state. Clients which care about the activity state of the system are
+/// expected to implement this protocol and subscribe via Provider.WatchState.
+protocol Listener {
+ /// Callback that is invoked whenever the system state changes.
+ /// The Listener is expected to acknowledge each call explicitly and will
+ /// not receive new state until this acknowledgement is done.
+ OnStateChanged(State state, zx.time transition_time) -> ();
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.activity/state.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.activity/state.fidl
new file mode 100644
index 0000000..7cec1bf
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.activity/state.fidl
@@ -0,0 +1,22 @@
+// 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.
+
+library fuchsia.ui.activity;
+
+/// State is an enumeration of the activity states the system may be in.
+enum State {
+ UNKNOWN = 0;
+ /// IDLE implies that the system is not currently being used by a user.
+ /// In other words, the system is not ACTIVE.
+ IDLE = 1;
+ /// ACTIVE implies that a user has recently or is currently using the
+ /// system.
+ ///
+ /// Activity can be signalled by discrete interactions (cursor, keyboard,
+ /// touchscreen), or by ongoing activities (video playback).
+ ///
+ /// The specific meaning of "recently" is an implementation
+ /// detail of the Activity Service, but a typical value is 15 minutes.
+ ACTIVE = 2;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.activity/tracker.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.activity/tracker.fidl
new file mode 100644
index 0000000..6c51295
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.activity/tracker.fidl
@@ -0,0 +1,30 @@
+// 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.
+
+library fuchsia.ui.activity;
+
+using zx;
+
+using OngoingActivityId = uint32;
+
+/// The Tracker protocol collects evidence of user activity and uses this
+/// evidence to set the system's activity state.
+[Discoverable]
+protocol Tracker {
+ /// Reports a discrete activity such as a keystroke.
+ /// `event_time` is in nanoseconds in the `CLOCK_MONOTONIC` time base.
+ ReportDiscreteActivity(DiscreteActivity activity, zx.time event_time) -> ();
+
+ /// Reports the start of an ongoing activity such as media playback.
+ /// `activity_id` is a unique identifier which is expected to be later
+ /// passed to EndOngoingActivity.
+ /// `start_time` is in nanoseconds in the `CLOCK_MONOTONIC` time base.
+ StartOngoingActivity(OngoingActivityId activity_id, OngoingActivity activity,
+ zx.time start_time) -> ();
+
+ /// Reports the end of an ongoing activity such as media playback.
+ /// `activity_id` is the nonce which was passed into StartOngoingActivity.
+ /// `end_time` is in nanoseconds in the `CLOCK_MONOTONIC` time base.
+ EndOngoingActivity(OngoingActivityId activity_id, zx.time end_time) -> ();
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.app/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.ui.app/BUILD.gn
new file mode 100644
index 0000000..eacc6a8
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.app/BUILD.gn
@@ -0,0 +1,30 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.ui.app") {
+ library_name = "app"
+ namespace = "fuchsia.ui"
+ public_deps = [
+ "../fuchsia.intl",
+ "../fuchsia.sys",
+ "../fuchsia.ui.views",
+ ]
+ sources = [
+ "view.fidl",
+ "view_config.fidl",
+ "view_provider.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.ui.app",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.app/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.ui.app/meta.json
new file mode 100644
index 0000000..d8d0146
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.app/meta.json
@@ -0,0 +1,15 @@
+{
+ "deps": [
+ "fuchsia.intl",
+ "fuchsia.sys",
+ "fuchsia.ui.views"
+ ],
+ "name": "fuchsia.ui.app",
+ "root": "fidl/fuchsia.ui.app",
+ "sources": [
+ "fidl/fuchsia.ui.app/view.fidl",
+ "fidl/fuchsia.ui.app/view_config.fidl",
+ "fidl/fuchsia.ui.app/view_provider.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.app/view.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.app/view.fidl
new file mode 100644
index 0000000..3666df4
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.app/view.fidl
@@ -0,0 +1,61 @@
+// 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.
+
+library fuchsia.ui.app;
+
+/// A View is an interface that a component implements to offer a Scenic
+/// view to its clients. A Scenic view is container of Scenic graph nodes,
+/// which, when rendered, might display a graphical user interface, such
+/// as a module, shell, or on-screen keyboard.
+///
+/// A client of the `View` interface will:
+///
+/// 1. Launch (or bind to) the component that provides the interface.
+/// 2. Connect to the component's `View` interface.
+/// 3. Call `SetConfig()` at least once to configure the view's presentation
+/// parameters.
+/// 4. Call `AttachView()` to ask the `View` to attach its graphical
+/// content to the Scenic scene graph using the provided `view_token`.
+/// 5. Optionally, while the View is attached, call `SetConfig()` again to
+/// modify any presentation parameters as needed.
+///
+/// When the client no longer needs the View, it should disconnect from
+/// the interface and terminate (or unbind) from the component.
+///
+/// NOTE: Unlike with `ViewProvider`, the client owns the `View` instance and
+/// must retain it for the lifetime of the UI that it displays. If the `View`
+/// instance is destroyed, the connection will be dropped.
+///
+/// On the implementation side, a component that exposes the
+/// `View` interface has the following responsibilities:
+///
+/// * Initialize and attach the View's content to the Scenic scene graph
+/// using the `fuchsia.ui.view.CreateViewCmd` and passing the provided
+/// `view_token`.
+/// * Adjust the appearance and/or contents of the view's content whenever
+/// its `ViewConfig` changes.
+/// * Provide graphical content for the view and handle user interface
+/// events such as touches, key presses, and `fuchsia.ui.view.ViewProperty`
+/// changes using other Scenic interfaces such as `fuchsia.ui.Scenic`
+/// and `fuchsia.ui.SessionListener`.
+///
+/// TODO(SCN-1198): Migrate all implementations of `ViewProvider` to use `View`.
+[Discoverable]
+protocol View {
+ /// Updates the View's configuration.
+ ///
+ /// To prevent triggering UI changes shortly after a client starts up, the
+ /// View's client should set the configuration prior to calling
+ /// `AttachView()` unless the default is adequate.
+ ///
+ /// May be called again at any time to modify the view's configuration.
+ SetConfig(ViewConfig config);
+
+ /// Attaches the View to Scenic's scene graph. Must only be called once per
+ /// `View` lifetime.
+ ///
+ /// The View's implementation should pass the `view_token` to Scenic
+ /// using a `fuchsia.ui.view.CreateViewCmd`.
+ Attach(handle<eventpair> view_token);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.app/view_config.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.app/view_config.fidl
new file mode 100644
index 0000000..243d744
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.app/view_config.fidl
@@ -0,0 +1,15 @@
+// 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.
+
+library fuchsia.ui.app;
+
+using fuchsia.intl;
+
+/// Collection of properties that provide affect the rendering of a view's
+/// contents. This might include internationalization settings, font scaling,
+/// night mode, high contrast mode, etc.
+struct ViewConfig {
+ fuchsia.intl.Profile intl_profile;
+ // Add others as needed.
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.app/view_provider.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.app/view_provider.fidl
new file mode 100644
index 0000000..45adf4e
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.app/view_provider.fidl
@@ -0,0 +1,61 @@
+// Copyright 2018 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.
+
+library fuchsia.ui.app;
+
+using fuchsia.sys;
+using fuchsia.ui.views;
+
+/// ViewProvider is the standard mechanism for two modules to each obtain half
+/// of a shared eventpair token. The shared token is a capability allowing the
+/// modules to ask Scenic to create a ViewHolder/View pair. The resulting
+/// View and ViewHolder are linked together until either one is destroyed.
+///
+/// Modules are free to use any other mechanism to agree upon the shared
+/// eventpair token, and use this to create the linked ViewHolder/View.
+/// ViewProvider is given for the convenience of clients that don't require
+/// a more complex implementation.
+[Discoverable]
+protocol ViewProvider {
+ /// Creates a new View under the control of the ViewProvider.
+ ///
+ /// `token` is one half of the shared eventpair which will bind the new View
+ /// to its associated ViewHolder. The ViewProvider will use `token` to
+ /// create its internal View representation. The caller is expected to use
+ /// its half to create corresponding ViewHolder object.
+ ///
+ /// `incoming_services` allows clients to request services from the
+ /// ViewProvider implementation. `outgoing_services` allows clients to
+ /// provide services of their own to the ViewProvider implementation.
+ ///
+ /// Clients can embed a ViewHolder (and by proxy the paired View) into their
+ /// scene graph by using `Node.AddChild()`. The ViewHolder cannot itself
+ /// have any children. A ViewProvider implementation can nest scene objects
+ /// within its View by using `View.AddChild()`. The View itself
+ /// cannot be a child of anything.
+ ///
+ /// Modules can use these mechanisms to establish a distributed,
+ /// inter-process scene graph.
+ CreateView(handle<eventpair> token,
+ request<fuchsia.sys.ServiceProvider>? incoming_services,
+ fuchsia.sys.ServiceProvider? outgoing_services);
+
+ /// Creates a new View under the control of the ViewProvider.
+ ///
+ /// `token` is one half of the shared eventpair which will bind the new View
+ /// to its associated ViewHolder. The ViewProvider will use `token` to
+ /// create its internal View representation. The caller is expected to use
+ /// its half to create corresponding ViewHolder object.
+ ///
+ /// `view_ref_control` and `view_ref` are two typed handles to each half of the
+ /// same event pair. The `view_ref` can be cloned before passing it to this method,
+ /// which will allow clients to track the view (e.g., in a focus chain update).
+ ///
+ /// `view_ref_control` must not have the ZX_RIGHT_DUPLICATE set, or view creation
+ /// will fail.
+ [Transitional]
+ CreateViewWithViewRef(handle<eventpair> token,
+ fuchsia.ui.views.ViewRefControl view_ref_control,
+ fuchsia.ui.views.ViewRef view_ref);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.brightness/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.ui.brightness/BUILD.gn
new file mode 100644
index 0000000..7c71260
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.brightness/BUILD.gn
@@ -0,0 +1,26 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.ui.brightness") {
+ library_name = "brightness"
+ namespace = "fuchsia.ui"
+ public_deps = [
+ ]
+ sources = [
+ "brightness.fidl",
+ "color_adjustment.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.ui.brightness",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.brightness/brightness.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.brightness/brightness.fidl
new file mode 100644
index 0000000..ca9e829
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.brightness/brightness.fidl
@@ -0,0 +1,61 @@
+// 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.
+
+library fuchsia.ui.brightness;
+
+/// A normalized relative brightness adjustment in the range
+/// 0.0 (off/minimum) to 1.0 (maximum).
+using brightness = float32;
+
+/// Control provides an interface to manage the brightness component.
+[Discoverable]
+protocol Control {
+ /// Turns the auto-brightness mode on.
+ /// SetManualBrightness will turn it off.
+ SetAutoBrightness();
+
+ /// Requests the current auto-brightness mode.
+ /// This call implements the Hanging Get protocol.
+ WatchAutoBrightness() -> (bool enabled);
+
+ /// Turns auto-brightness mode off.
+ /// Used by e.g. Settings to set manual brightness using a slider
+ /// Value is in the range 0.0 to 1.0 representing min to max and
+ /// will be clamped if out of range.
+ SetManualBrightness(brightness value);
+
+ /// Gets the current brightness in the range 0.0 to 1.0.
+ /// This result is valid for both manual and auto-brightness modes
+ /// and is typically used to show the current brightness on a slider.
+ /// This call implements the Hanging Get protocol.
+ WatchCurrentBrightness() -> (brightness value);
+
+ /// Sets the brightness adjustment.
+ /// This will change the brightness curve by the factor of the adjustment.
+ /// The adjustment is in the range of -1.0 to 1.0.
+ SetAutoBrightnessAdjustment(float32 adjustment);
+
+ /// Gets the current auto brightness adjustment.
+ /// This call implements the Hanging Get protocol.
+ WatchAutoBrightnessAdjustment() -> (float32 adjustment);
+
+ /// Sets the brightness curve as a set of points.
+ /// This will override the built-in brightness curve.
+ /// The default brightness curve will be used if the table is empty.
+ /// The connection will be closed if table errors are detected.
+ SetBrightnessTable(BrightnessTable table);
+};
+
+/// A tuple representing a point on the auto-brightness curve
+/// Ambient_lux and nits must be positive values.
+struct BrightnessPoint {
+ float32 ambient_lux;
+ float32 display_nits;
+};
+
+/// A set of points defining the auto-brightness curve.
+/// The ambient_lux values must be monotonically increasing.
+struct BrightnessTable {
+ vector<BrightnessPoint>:50 points;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.brightness/color_adjustment.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.brightness/color_adjustment.fidl
new file mode 100644
index 0000000..5ccb0bf
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.brightness/color_adjustment.fidl
@@ -0,0 +1,22 @@
+// 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.
+
+library fuchsia.ui.brightness;
+
+/// Handler implemented by the owner of the presentation.
+/// The UI component that controls brightness and screen tint uses this protocol to request changes
+/// to the screen's color adjustment matrix.
+[Discoverable]
+protocol ColorAdjustmentHandler {
+ /// Called when the color adjustment has changed.
+ SetColorAdjustment(ColorAdjustmentTable color_adjustment);
+};
+
+/// The table for screen color tint adjustments.
+table ColorAdjustmentTable {
+ /// 3x3 Matrix in row-major form which will be used by root presenter
+ /// to apply color adjustment.
+ /// This field may be omitted to disable color adjustment.
+ 1: array<float32>:9 matrix;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.brightness/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.ui.brightness/meta.json
new file mode 100644
index 0000000..bbcc238
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.brightness/meta.json
@@ -0,0 +1,10 @@
+{
+ "deps": [],
+ "name": "fuchsia.ui.brightness",
+ "root": "fidl/fuchsia.ui.brightness",
+ "sources": [
+ "fidl/fuchsia.ui.brightness/brightness.fidl",
+ "fidl/fuchsia.ui.brightness/color_adjustment.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/BUILD.gn
new file mode 100644
index 0000000..4dfc639
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/BUILD.gn
@@ -0,0 +1,38 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.ui.gfx") {
+ library_name = "gfx"
+ namespace = "fuchsia.ui"
+ public_deps = [
+ "../fuchsia.images",
+ "../fuchsia.mem",
+ "../fuchsia.ui.views",
+ ]
+ sources = [
+ "commands.fidl",
+ "display_info.fidl",
+ "events.fidl",
+ "hit.fidl",
+ "nodes.fidl",
+ "pose_buffer_provider.fidl",
+ "renderer.fidl",
+ "resources.fidl",
+ "shapes.fidl",
+ "tokens.fidl",
+ "types.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.ui.gfx",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/commands.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/commands.fidl
new file mode 100644
index 0000000..0055102
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/commands.fidl
@@ -0,0 +1,855 @@
+// Copyright 2017 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.
+
+library fuchsia.ui.gfx;
+
+using fuchsia.mem;
+
+/// Commands that are used to modify the state of a `Session`.
+union Command {
+ 1: CreateResourceCmd create_resource;
+ 2: ReleaseResourceCmd release_resource;
+ 3: ExportResourceCmdDeprecated export_resource;
+ 4: ImportResourceCmdDeprecated import_resource;
+
+ /// Tagging commands.
+ 5: SetTagCmd set_tag;
+
+ /// Grouping commands.
+ 6: DetachCmd detach;
+
+ /// Spatial commands.
+ 7: SetTranslationCmd set_translation;
+ 8: SetScaleCmd set_scale;
+ 9: SetRotationCmd set_rotation;
+ 10: SetAnchorCmd set_anchor;
+ 11: SetSizeCmd set_size;
+ 12: SetOpacityCmd set_opacity;
+
+ 13: SendSizeChangeHintCmdHACK send_size_change_hint_hack;
+
+ /// Node-specific commands.
+ 14: AddChildCmd add_child; // TODO: Should we require a DetachCmd before
+ /// re-parenting?
+ 15: AddPartCmd add_part;
+ 16: DetachChildrenCmd detach_children;
+ 17: SetShapeCmd set_shape;
+ 18: SetMaterialCmd set_material;
+ 19: SetClipCmd set_clip;
+ 20: SetHitTestBehaviorCmd set_hit_test_behavior;
+ 21: SetViewPropertiesCmd set_view_properties;
+ 22: TakeSnapshotCmdDEPRECATED take_snapshot_cmd;
+
+ /// Camera and lighting commands.
+ 23: SetCameraCmd set_camera;
+ 24: SetCameraTransformCmd set_camera_transform;
+ 25: SetCameraProjectionCmd set_camera_projection;
+ 26: SetStereoCameraProjectionCmd set_stereo_camera_projection;
+ 27: SetCameraPoseBufferCmd set_camera_pose_buffer;
+ 28: SetLightColorCmd set_light_color;
+ 29: SetLightDirectionCmd set_light_direction;
+ 30: AddLightCmd add_light;
+ 31: DetachLightCmd detach_light;
+ 32: DetachLightsCmd detach_lights;
+
+ 33: SetTextureCmd set_texture;
+ 34: SetColorCmd set_color;
+
+ /// Mesh commands.
+ 35: BindMeshBuffersCmd bind_mesh_buffers;
+
+ /// Layer and renderer commands.
+ 36: AddLayerCmd add_layer;
+ 37: RemoveLayerCmd remove_layer;
+ 38: RemoveAllLayersCmd remove_all_layers;
+ 39: SetLayerStackCmd set_layer_stack;
+ 40: SetRendererCmd set_renderer;
+ 41: SetRendererParamCmd set_renderer_param;
+
+ /// Events.
+ 42: SetEventMaskCmd set_event_mask;
+
+ /// Diagnostic commands.
+ 43: SetLabelCmd set_label;
+
+ /// Debugging commands.
+ 44: SetDisableClippingCmd set_disable_clipping;
+
+ // TODO(SCN-1026): Remove this.
+ 45: SetImportFocusCmdDEPRECATED set_import_focus;
+
+ // TODO(SCN-1225): Move these where they belong. They're added to the end of
+ // the struct temporarily until we transition to xunions.
+ 46: SetClipPlanesCmd set_clip_planes;
+ 47: SetPointLightPositionCmd set_point_light_position;
+ 48: SetPointLightFalloffCmd set_point_light_falloff;
+ 49: SceneAddAmbientLightCmd scene__add_ambient_light;
+ 50: SceneAddDirectionalLightCmd scene__add_directional_light;
+ 51: SceneAddPointLightCmd scene__add_point_light;
+
+ 52: SetDisplayColorConversionCmdHACK set_display_color_conversion;
+
+ 53: SetDisplayRotationCmdHACK set_display_rotation;
+
+ 54: SetEnableDebugViewBoundsCmd set_enable_view_debug_bounds;
+ 55: SetViewHolderBoundsColorCmd set_view_holder_bounds_color;
+
+ 56: SetCameraClipSpaceTransformCmd set_camera_clip_space_transform;
+};
+
+/// Instructs the compositor to create the specified `Resource`, and to register
+/// it in a table so that it can be referenced by subsequent commands.
+struct CreateResourceCmd {
+ /// An ID that is currently not used within the session.
+ uint32 id;
+ ResourceArgs resource;
+};
+
+/// Releases the client's reference to the resource; it is then illegal to use
+/// the ID in subsequent Commands. Other references to the resource may exist,
+/// so releasing the resource does not result in its immediate destruction; it is
+/// only destroyed once the last reference is released. For example, the
+/// resource may be required to render an in-progress frame, or it may be
+/// referred to by another resource). However, the ID will be immediately
+/// unregistered, and may be reused to create a new resource.
+struct ReleaseResourceCmd {
+ /// ID of the resource to be dereferenced.
+ uint32 id;
+};
+
+/// Create an external reference to the specified resource, which can then be
+/// imported into another Session by passing a handle to `token`'s peer to
+/// ImportResourceCmd; see that comment for more details.
+///
+/// The importing client is typically in a different process than the exporter.
+/// No specific mechanism is provided for transferring a token from an exporter
+/// to an importer; collaborators may choose any out-of-band API they wish to do
+/// so.
+struct ExportResourceCmdDeprecated {
+ uint32 id;
+ handle<eventpair> token;
+};
+
+/// Import a resource that was exported via ExportResourceCmd(). `token` is
+/// a handle to the eventpair peer that was used to export the resource, and
+/// `spec` describes the type of the imported resource, and the commands which
+/// can legally be applied to it. Afterward, `id` can be used to refer to the
+/// resource in an Command, similarly (but not identically: see below) to a
+/// resource that was created in the session. For example, you can add children
+/// to an imported EntityNode via AddChildCmd.
+///
+/// However, note that the importer does not gain full access to the imported
+/// resource, but rather to an attenuated subset of its capabilities. For
+/// example, you cannot use a DetachCmd to detach an imported EntityNode from
+/// its parent.
+///
+/// Unlike ExportResourceCmd, there is no configurable timeout. There is an
+/// expectation that the exported resource will become available in a short
+/// amount of time. TODO: this needs elaboration... e.g. we might notify via the
+/// SessionListener when we know that the link will never be made (e.g. if the
+/// peer of the import token is destroyed).
+///
+// TODO: describe how the imported resource behaves if the exported resource
+// isn't yet available, or becomes unavailable (e.g. an imported Material might
+// act as a plain white texture).
+struct ImportResourceCmdDeprecated {
+ uint32 id;
+ handle<eventpair> token;
+ ImportSpec spec;
+};
+
+/// Sets/clears a node's tag value.
+///
+/// A session can apply a tag value to any node to which it has access, including
+/// imported nodes. These tags are private to the session and cannot be read
+/// or modified by other sessions. When multiple sessions import the same node,
+/// each session will only observe its own tag values.
+///
+/// Hit test results for a session only include nodes which the session has
+/// tagged with a non-zero value. Therefore a session can use tag values to
+/// associate nodes with their functional purpose when picked.
+///
+/// Constraints:
+/// - `node_id` refs a `Node`.
+/// - `tag_value` is the tag value to assign, or 0 to remove the tag.
+struct SetTagCmd {
+ uint32 node_id;
+ uint32 tag_value;
+};
+
+/// Detaches a parentable object from its parent (e.g. a node from a parent node,
+/// or a layer from a layer stack). It is illegal to apply this command to a
+/// non-parentable object. No-op if the target object currently has no parent.
+///
+/// Constraints:
+/// - `id` refs a parentable object
+///
+/// Discussion:
+/// For nodes, this command will detach a node from its parent, regardless of
+/// whether it is a part or a child of its parent.
+struct DetachCmd {
+ uint32 id;
+};
+
+/// Sets a Resource's (typically a Node's) translation.
+///
+/// Constraints:
+/// - `id` refs a Resource with the has_transform characteristic.
+struct SetTranslationCmd {
+ uint32 id;
+ Vector3Value value;
+};
+
+/// Sets a Resource's (typically a Node's) scale.
+///
+/// Constraints:
+/// - `id` refs a Resource with the has_transform characteristic.
+struct SetScaleCmd {
+ uint32 id;
+ Vector3Value value;
+};
+
+/// Sets a Resource's (typically a Node's) rotation.
+///
+/// Constraints:
+/// - `id` refs a Resource with the has_transform characteristic.
+struct SetRotationCmd {
+ uint32 id;
+ QuaternionValue value;
+};
+
+/// Sets a Resource's (typically a Node's) anchor point.
+///
+/// Constraints:
+/// - `id` refs a Resource with the has_transform characteristic.
+struct SetAnchorCmd {
+ uint32 id;
+ Vector3Value value;
+};
+
+/// Sets an object's size.
+///
+/// Constraints:
+/// - `id` refs a resizeable object.
+/// - some objects that support this command may have additional constraints
+/// (e.g. in some cases `depth` must be zero).
+struct SetSizeCmd {
+ uint32 id;
+ Vector2Value value;
+};
+
+/// Sets a node's opacity.
+///
+/// Constraints:
+/// - `node_id` refs a `Node` with the has_opacity characteristic.
+/// - `opacity` is in the range [0, 1].
+struct SetOpacityCmd {
+ uint32 node_id;
+ float32 opacity;
+};
+
+/// Sends a hint about a pending size change to the given node and all nodes
+/// below. This is generally sent before an animation.
+///
+/// `width_change_factor` and `height_change_factor` is how much bigger or smaller
+/// the item is expected to be in the near future. This one number encapsulate
+/// both changes in scale, as well as changes to layout width and height.
+struct SendSizeChangeHintCmdHACK {
+ uint32 node_id;
+ float32 width_change_factor;
+ float32 height_change_factor;
+};
+
+/// Add a node as a child to another node.
+///
+/// Constraints:
+/// - `id` refs a Node with the has_children characteristic.
+/// - `child_id` refs any Node.
+///
+/// Discussion:
+/// The child node is first removed from its existing parent, as if DetachCmd
+/// was applied first.
+struct AddChildCmd {
+ uint32 node_id;
+ uint32 child_id;
+};
+
+/// Add a node as a part of another node. The implications of being a part
+/// rather than a child differ based on the type of the part. However, one
+/// implication is constant: removing all of a node's children (e.g. via
+/// DetachChildrenCmd) does not affect its parts. This is similar to the
+/// "shadow DOM" in a web browser: the controls of a <video> element are
+/// implemented as using the shadow DOM, and do no show up amongst the children
+/// of that element.
+///
+/// Constraints:
+/// - `id` refs a Node with the has_parts characteristic.
+/// - `part_id` refs any Node.
+///
+/// Discussion:
+/// The part node is first removed from its existing parent, as if DetachCmd
+/// was applied first.
+struct AddPartCmd {
+ uint32 node_id;
+ uint32 part_id;
+};
+
+/// Detaches all of a node's children (but not its parts).
+struct DetachChildrenCmd {
+ uint32 node_id;
+};
+
+// TODO: add "Shape/Material Compatibility section"
+/// Sets/clears a node's shape.
+///
+/// Constraints:
+/// - `node_id` refs a `Node` with the has_shape characteristic.
+/// - `shape_id` refs a `Shape`, or nothing.
+/// - if this command causes the target to have both a `Shape` and a `Material`,
+/// then these must be compatible with each other (see README.md regarding
+/// "Shape/Material Compatibility").
+///
+/// Discussion:
+/// In order to be painted, a node requires both a `Shape` and a `Material`.
+/// Without a material, a node can still participate in hit-testing and clipping.
+/// Without a shape, a node cannot do any of the above.
+struct SetShapeCmd {
+ uint32 node_id;
+ uint32 shape_id;
+};
+
+// TODO: add "Shape/Material Compatibility section"
+/// Sets/clears a node's material.
+///
+/// Constraints:
+/// - `node_id` refs a `Node` with the has_material characteristic.
+/// - `material_id` refs a `Material`, or nothing.
+/// - if this command causes the target to have both a `Shape` and a `Material`,
+/// then these must be compatible with each other (see README.md regarding
+/// "Shape/Material Compatibility").
+///
+/// Discussion:
+/// In order to be painted, a node requires both a `Shape` and a `Material`.
+/// Without a material, a node can still participate in hit-testing and clipping.
+/// Without a shape, a node cannot do any of the above.
+struct SetMaterialCmd {
+ uint32 node_id;
+ uint32 material_id;
+};
+
+/// Sets/clears a node's clip. DEPRECATED: use SetClipPlanesCmd.
+///
+/// Constraints:
+/// - `node_id` refs a `Node` with the has_clip characteristic.
+/// - `clip_id` a `Node` with the is_clip characteristic, or nothing. If the
+/// referenced node is not rooted, then it will have no effect (since its
+/// full world-transform cannot be determined).
+/// - `clip_to_self` If false, children are only clipped to the region specified
+/// by `clip_id`. If true, children are additionally clipped to the node's
+/// shape (as determined by its ShapeNode parts).
+///
+/// Discussion:
+/// If a node has a clip, it will be applied to both the parts and the children
+/// of the node. Under some circumstances (TBD), a clip will not be applicable
+/// to a node; in such cases it will be as though no clip has been specified for
+/// the node.
+// TODO: elaborate on the circumstances under which a clip is inapplicable.
+// For example, consider a 3D space that looks through a portal into a 2D space
+// that uses a clip for a circular reveal. It would not be meaningful to clip
+// objects on the outside (i.e. in the 3D space).
+struct SetClipCmd {
+ uint32 node_id;
+ uint32 clip_id;
+ bool clip_to_self;
+};
+
+/// Sets a node's hit test behavior.
+///
+/// Discussion:
+/// By default, hit testing is performed on the node's content, its parts,
+/// and its children.
+struct SetHitTestBehaviorCmd {
+ uint32 node_id;
+ HitTestBehavior hit_test_behavior;
+};
+
+/// Sets the properties for a ViewHolder's attached View.
+///
+/// Constraints:
+/// - `view_holder_id` refs a `ViewHolder`.
+struct SetViewPropertiesCmd {
+ uint32 view_holder_id;
+ ViewProperties properties;
+};
+
+protocol SnapshotCallbackDEPRECATED {
+ OnData(fuchsia.mem.Buffer data);
+};
+
+struct TakeSnapshotCmdDEPRECATED {
+ uint32 node_id;
+ SnapshotCallbackDEPRECATED callback;
+};
+
+/// Sets a renderer's camera.
+///
+/// Constraints:
+/// - `renderer_id` refs a `Renderer`.
+/// - `camera_id` refs a `Camera`, or stops rendering by passing zero.
+/// - `matrix` is a value or variable of type kMatrix4x4.
+struct SetCameraCmd {
+ uint32 renderer_id;
+ uint32 camera_id;
+};
+
+/// Sets a camera's view matrix.
+/// This operation can be applied to both Cameras and StereoCameras.
+///
+/// Constraints:
+/// - `camera_id` refs a `Camera`.
+/// - `eye_position` is the position of the eye.
+/// - `eye_look_at` is the point is the scene the that eye is pointed at.
+/// - `eye_up` defines the camera's "up" vector.
+struct SetCameraTransformCmd {
+ uint32 camera_id;
+ Vector3Value eye_position;
+ Vector3Value eye_look_at;
+ Vector3Value eye_up;
+};
+
+/// Sets a camera's projection matrix.
+/// This operation cannot be applied to a StereoCamera.
+///
+/// Constraints:
+/// - `camera_id` refs a `Camera` that is not a `StereoCamera`.
+/// - `fovy` is the Y-axis field of view, in radians.
+///
+/// NOTE: A default orthographic projection is specified by setting `fovy` to
+/// zero. In this case, the camera transform is ignored.
+struct SetCameraProjectionCmd {
+ uint32 camera_id;
+ FloatValue fovy; // Y-axis field of view, in radians.
+};
+
+/// Sets a StereoCamera's projection matrices.
+/// This operation can only be applied to a StereoCamera.
+///
+/// Constraints:
+/// - `camera_id` refs a `StereoCamera`.
+/// - `left_projection` is the projection matrix for the left eye.
+/// - `right_projection` is the projection matrix for the right eye.
+///
+/// These projection matrices may also contain a transform in camera space for
+/// their eye if needed.
+struct SetStereoCameraProjectionCmd {
+ uint32 camera_id;
+ Matrix4Value left_projection;
+ Matrix4Value right_projection;
+};
+
+/// Sets a camera's 2D clip-space transform.
+///
+/// Constraints:
+/// - `camera_id` refs a `Camera`.
+/// - `translation` is the desired translation, in Vulkan NDC.
+/// - `scale` is the scale factor to apply on the x/y plane before translation.
+struct SetCameraClipSpaceTransformCmd {
+ uint32 camera_id;
+ vec2 translation;
+ float32 scale;
+};
+
+/// Sets the "pose buffer" for the camera identified by `camera_id`.
+/// This operation can be applied to both Cameras and StereoCameras.
+///
+/// This will override any position and rotation set for the camera and will
+/// make it take its position and rotation from the pose buffer each frame
+/// based on the presentation time for that frame.
+///
+/// A pose buffer represents a ring buffer of poses for a fixed number of time
+/// points in the future. Each entry in the buffer identified by `buffer_id` is
+/// a quaternion and a position layed out as follows:
+///
+/// struct Pose {
+/// // Quaternion
+/// float32 a;
+/// float32 b;
+/// float32 c;
+/// float32 d;
+///
+/// // Position
+/// float32 x;
+/// float32 y;
+/// float32 z;
+///
+/// // Reserved/Padding
+/// byte[4] reserved;
+/// }
+///
+/// The buffer can be thought of as a packed array of `num_entries` Pose structs
+/// and is required to be at least num_entries * sizeof(Pose) bytes.
+///
+/// The quaternions and positions are specified in the space of the camera's
+/// parent node.
+///
+/// `base_time` is a base time point expressed in nanoseconds in the
+/// `CLOCK_MONOTONIC` timebase and `time_interval` is the time in nanoseconds
+/// between entries in the buffer. `base_time` must be in the past.
+///
+/// For a given point in time `t` expressed in nanoseconds in the
+/// `CLOCK_MONOTONIC` timebase the index of the corresponding pose in
+/// the pose buffer can be computed as follows:
+///
+/// index(t) = ((t - base_time) / time_interval) % num_entries
+///
+/// poses[index(t)] is valid for t over the time interval (t - time_interval, t]
+/// and should be expected to updated continuously without synchronization
+/// for the duration of that interval. If a single pose value is needed for
+/// multiple non-atomic operations a value should be latched and stored outside
+/// the pose buffer.
+///
+/// Because the poses are not protected by any synchronization primitives it is
+/// possible that when a pose is latched it will be only partially updated, and
+/// the pose being read will contain some components from the pose before it is
+/// updated and some components from the updated pose. The safety of using these
+/// "torn" poses relies on two things:
+///
+/// 1) Sequential poses written to poses[index(t)] are very similar to each
+/// other numerically, so that if some components are taken from the first and
+/// some are taken from another the result is numerically similar to both
+///
+/// 2) The space of positions and quaternions is locally flat at the scale of
+/// changes between sequential updates, which guarantees that two poses which
+/// are numerically similar also represent semantically similar poses (i.e.
+/// there are no discontinuities which will cause a small numerical change in
+/// the position or quaterninon to cause a large change in the encoded pose)
+/// For positions this is guaranteed because Scenic uses a Euclidean 3-space
+/// which is globally flat and for quaternions this is guaranteed because
+/// quaternions encode rotation as points on a unit 4-sphere, and spheres are
+/// locally flat. For more details on the encoding of rotations in quaterions
+/// see https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation
+///
+/// This commanderation is intended for late latching camera pose to support
+/// low-latency motion-tracked rendering.
+struct SetCameraPoseBufferCmd {
+ uint32 camera_id;
+ uint32 buffer_id;
+ uint32 num_entries;
+ int64 base_time;
+ uint64 time_interval;
+};
+
+/// Sets the color of the Light identified by `light_id`.
+struct SetLightColorCmd {
+ uint32 light_id;
+ ColorRgbValue color;
+};
+
+/// Sets the direction of the DirectionalLight identified by `light_id`.
+struct SetLightDirectionCmd {
+ uint32 light_id;
+ Vector3Value direction;
+};
+
+/// DEPRECATED
+/// Adds the light specified by `light_id` specified by `light_id` to the scene
+/// identified by `scene_id`.
+struct AddLightCmd {
+ uint32 scene_id;
+ uint32 light_id;
+};
+
+/// Detach the light specified by `light_id` from the scene that it is attached
+/// to, if any.
+struct DetachLightCmd {
+ uint32 light_id;
+};
+
+/// Detach all lights from the scene specified by `scene_id`.
+struct DetachLightsCmd {
+ uint32 scene_id;
+};
+
+/// Sets/clears a material's texture.
+///
+/// Constraints:
+/// - `material_id` refs a `Material`.
+/// - `texture_id` refs a `Image`, `ImagePipe`, or nothing.
+///
+/// If no texture is provided (i.e. `texture_id` is zero), a solid color is used.
+/// If a texture is provided, then the value sampled from the texture is
+/// multiplied by the color.
+struct SetTextureCmd {
+ uint32 material_id;
+ uint32 texture_id; // Refers to an Image resource. May be zero (no texture).
+};
+
+/// Sets a material's color.
+///
+/// Constraints:
+/// - `material_id` refs a `Material`.
+///
+/// If a texture is set on the material, then the value sampled from the texture
+/// is multiplied by the color.
+struct SetColorCmd {
+ uint32 material_id;
+ ColorRgbaValue color;
+};
+
+/// Set a mesh's indices and vertices.
+///
+/// `mesh_id` refs the Mesh to be updated.
+/// `index_buffer_id` refs a Buffer that contains the mesh indices.
+/// `index_format` defines how the index buffer data is to be interpreted.
+/// `index_offset` number of bytes from the start of the index Buffer.
+/// `index_count` number of indices.
+/// `vertex_buffer_id` refs a Buffer that contains the mesh vertices.
+/// `vertex_format` defines how the vertex buffer data is to be interpreted.
+/// `vertex_offset` number of bytes from the start of the vertex Buffer.
+/// `vertex_count` number of vertices.
+/// `bounding_box` must contain all vertices within the specified range.
+///
+/// The MeshVertexFormat defines which per-vertex attributes are provided by the
+/// mesh, and the size of each attribute (and therefore the size of each vertex).
+/// The attributes are ordered within the vertex in the same order that they
+/// appear within the MeshVertexFormat struct. For example, if the values are
+/// kVector3, kNone and kVector2, then:
+/// - each vertex has a position and UV-coordinates, but no surface normal.
+/// - the 3D position occupies bytes 0-11 (3 dimensions * 4 bytes per float32).
+/// - the UV coords occupy bytes 12-19, since no surface normal is provided.
+enum MeshIndexFormat {
+ // TODO(SCN-275): only kUint32 is currently supported.
+ kUint16 = 1;
+ kUint32 = 2;
+};
+
+struct MeshVertexFormat {
+ /// kVector2 or kVector3.
+ ValueType position_type;
+ /// kVector2 or kVector3 (must match position_type), or kNone.
+ ValueType normal_type;
+ /// kVector2 or kNone.
+ ValueType tex_coord_type;
+};
+
+struct BindMeshBuffersCmd {
+ uint32 mesh_id;
+ uint32 index_buffer_id;
+ MeshIndexFormat index_format;
+ uint64 index_offset;
+ uint32 index_count;
+ uint32 vertex_buffer_id;
+ MeshVertexFormat vertex_format;
+ uint64 vertex_offset;
+ uint32 vertex_count;
+ BoundingBox bounding_box;
+};
+
+/// Add a layer to a layer stack.
+/// Constraints:
+/// - `layer_stack_id` refs a `LayerStack`.
+/// - `layer_id` refs a `Layer`.
+/// - The layer must not already belong to a different stack; it must first be
+/// detached.
+struct AddLayerCmd {
+ uint32 layer_stack_id;
+ uint32 layer_id;
+};
+
+/// Remove a layer from a layer stack.
+/// Constraints:
+/// - `layer_stack_id` refs a `LayerStack`.
+/// - `layer_id` refs a `Layer`.
+/// - The layer must belong to this stack.
+struct RemoveLayerCmd {
+ uint32 layer_stack_id;
+ uint32 layer_id;
+};
+
+/// Remove all layers from a layer stack.
+/// Constraints
+/// - `layer_stack_id` refs a `LayerStack`.
+struct RemoveAllLayersCmd {
+ uint32 layer_stack_id;
+};
+
+/// Set a compositor's layer stack, replacing the current stack (if any).
+/// Constraints:
+/// - `compositor_id` refs a `DisplayCompositor` or `ImagePipeCompositor`.
+/// - `layer_stack_id` refs a `LayerStack`.
+struct SetLayerStackCmd {
+ uint32 compositor_id;
+ uint32 layer_stack_id;
+};
+
+/// Set a layer's renderer, replacing the current renderer (if any).
+/// Constraints:
+/// - `layer_id` refs a `Layer`.
+/// - `renderer_id` refs a `Renderer`.
+struct SetRendererCmd {
+ uint32 layer_id;
+ uint32 renderer_id;
+};
+
+/// Sets a parameter that affects how a renderer renders a scene.
+///
+/// `renderer_id` refs the Renderer that is being modified.
+/// `param` describes the parameter that should be set, and to what.
+struct SetRendererParamCmd {
+ uint32 renderer_id;
+ RendererParam param;
+};
+
+/// Sets which events a resource should deliver to the session listener.
+/// This command replaces any prior event mask for the resource.
+///
+/// The initial event mask for a resource is zero, meaning no events are
+/// reported.
+///
+/// Constraints:
+/// - `resource_id` is a valid resource id
+/// - `event_mask` is zero or a combination of `k*EventMask` bits OR'ed together.
+struct SetEventMaskCmd {
+ uint32 id;
+ uint32 event_mask;
+};
+
+/// Maximum length for a resource label.
+const uint32 kLabelMaxLength = 32;
+
+/// Sets/clears a label to help developers identify the purpose of the resource
+/// when using diagnostic tools.
+///
+/// The label serves no functional purpose in the scene graph. It exists only
+/// to help developers understand its structure. The scene manager may truncate
+/// or discard labels at will.
+///
+/// Constraints:
+/// - The label's maximum length is `kLabelMaxLength` characters.
+/// - Setting the label to an empty string clears it.
+struct SetLabelCmd {
+ uint32 id;
+ string label;
+};
+
+/// Set whether clipping should be disabled for the specified renderer. For a
+/// newly-created renderer, clipping will NOT be disabled (i.e. it will be
+/// enabled).
+///
+/// NOTE: this disables visual clipping only; objects are still clipped for the
+/// purposes of hit-testing.
+///
+/// `renderer_id` refs the target renderer.
+/// `disable_clipping` specifies whether the clipping should be disabled.
+struct SetDisableClippingCmd {
+ uint32 renderer_id;
+ bool disable_clipping;
+};
+
+// TODO(SCN-1026): Remove this.
+struct SetImportFocusCmdDEPRECATED {
+};
+
+/// Sets the list of clip planes that apply to a Node and all of its children. Replaces
+/// the list set by any previous SetClipPlanesCmd.
+///
+/// - `node_id` refs a `Node` with the has_clip characteristic.
+/// - `clip_planes` is the new list of oriented clip planes.
+struct SetClipPlanesCmd {
+ uint32 node_id;
+ vector<Plane3> clip_planes;
+};
+
+/// Sets the position of the PointLight identified by `light_id`.
+struct SetPointLightPositionCmd {
+ uint32 light_id;
+ Vector3Value position;
+};
+
+/// Sets the falloff factor of the PointLight identified by `light_id`.
+/// A value of 1.0 corresponds to the physically-based "inverse-square law"
+/// (see Wikipedia). Other values can be used for artistic effect, e.g. a
+/// value of 0.0 means that the radiance of a surface is not dependant on
+/// its distance from the light.
+///
+// TODO(SCN-528): need to formalize the units of light intensity and distance used
+// to compute fall-off. Currently the unit is pips; consequently a falloff of 1.0
+// causes light to attenuate far too rapidly. Meters would be more appropriate.
+struct SetPointLightFalloffCmd {
+ uint32 light_id;
+ FloatValue falloff;
+};
+
+/// Adds the light specified by `light_id` specified by `light_id` to the scene
+/// identified by `scene_id`.
+struct SceneAddAmbientLightCmd {
+ uint32 scene_id;
+ uint32 light_id;
+};
+
+/// Adds the light specified by `light_id` specified by `light_id` to the scene
+/// identified by `scene_id`.
+struct SceneAddDirectionalLightCmd {
+ uint32 scene_id;
+ uint32 light_id;
+};
+
+/// Adds the light specified by `light_id` specified by `light_id` to the scene
+/// identified by `scene_id`.
+struct SceneAddPointLightCmd {
+ uint32 scene_id;
+ uint32 light_id;
+};
+
+/// Set the color conversion applied to the compositor's display.
+/// The conversion is applied to to each pixel according to the formula:
+///
+/// (matrix * (pixel + preoffsets)) + postoffsets
+///
+/// where pixel is a column vector consisting of the pixel's 3 components.
+///
+/// `matrix` is passed in row-major order. Clients will be responsible
+/// for passing default values, when needed.
+/// Default values are not currently supported in fidl.
+/// Default Values:
+/// preoffsets = [0 0 0]
+/// matrix = [1 0 0 0 1 0 0 0 1]
+/// postoffsets = [0 0 0]
+struct SetDisplayColorConversionCmdHACK {
+ uint32 compositor_id;
+ array<float32>:3 preoffsets;
+ array<float32>:9 matrix;
+ array<float32>:3 postoffsets;
+};
+
+/// Depending on the device, the display might be rotated
+/// with respect to what the lower level device controller
+/// considers the physical orientation of pixels. The
+/// compositors and layers must be in alignment with the
+/// underlying physical orientation which means that for
+/// certain operations like screenshotting, they cannot
+/// provide results with the accurate orientation unless
+/// they have information about how the higher-level display
+/// is orienting the screen. The only legal values for the
+/// rotation are 0, 90, 180, and 270, which are each
+/// applied counterclockwise.
+struct SetDisplayRotationCmdHACK {
+ uint32 compositor_id;
+ uint32 rotation_degrees;
+};
+
+// Enable (or disable) debug wireframe rendering for the specified
+// view and its immediately embedded views (i.e. any view whose
+// nearest ancestor view is this one).
+struct SetEnableDebugViewBoundsCmd {
+ uint32 view_id;
+ bool enable;
+};
+
+// This command determines the color to be set on a view holders
+// debug wireframe bounding box.
+struct SetViewHolderBoundsColorCmd {
+ uint32 view_holder_id;
+ ColorRgbValue color;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/display_info.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/display_info.fidl
new file mode 100644
index 0000000..d1e8a3b
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/display_info.fidl
@@ -0,0 +1,12 @@
+// Copyright 2017 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.
+
+library fuchsia.ui.gfx;
+
+/// Provides information about a display.
+struct DisplayInfo {
+ /// The size of the display, in physical pixels.
+ uint32 width_in_px;
+ uint32 height_in_px;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/events.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/events.fidl
new file mode 100644
index 0000000..c863e6f
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/events.fidl
@@ -0,0 +1,136 @@
+// Copyright 2017 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.
+
+library fuchsia.ui.gfx;
+
+/// Reports metrics information.
+/// This event type is only reported for node resources.
+const uint32 kMetricsEventMask = 1;
+const uint32 kSizeChangeHintEventMask = 2;
+
+/// These are all of the types of events which can be reported by a `Session`.
+/// Use `SetEventMaskCmd` to enable event delivery for a resource.
+union Event {
+ /// Events which are controlled by a mask.
+ 1: MetricsEvent metrics;
+
+ 2: SizeChangeHintEvent size_change_hint;
+
+ /// Events which are always delivered, regardless of mask.
+ 3: ImportUnboundEvent import_unbound;
+ 4: ViewConnectedEvent view_connected;
+ 5: ViewDisconnectedEvent view_disconnected;
+ 6: ViewHolderDisconnectedEvent view_holder_disconnected;
+ 7: ViewAttachedToSceneEvent view_attached_to_scene;
+ 8: ViewDetachedFromSceneEvent view_detached_from_scene;
+ 9: ViewPropertiesChangedEvent view_properties_changed;
+ 10: ViewStateChangedEvent view_state_changed;
+ 11: ViewHolderConnectedEvent view_holder_connected;
+};
+
+/// Provides rendering target metrics information about the specified node.
+///
+/// This event is delivered when the following conditions are true:
+/// - The node is a descendant of a `Scene`.
+/// - The node has `kMetricsEventMask` set to an enabled state.
+/// - The node's metrics have changed since they were last delivered, or since
+/// `kMetricsEventMask` transitioned from a disabled state to an enabled state.
+///
+/// Subscribe to this event to receive information about the scale factors you
+/// should apply when generating textures for your nodes.
+struct MetricsEvent {
+ uint32 node_id;
+ Metrics metrics;
+};
+
+/// Delivered in response to a size change hint from a parent node
+/// (SendSizeChangeHintCmd).
+///
+/// This event is delivered when the following conditions are true:
+/// - The node has `kSizeChangeEventMask` set to an enabled state.
+/// - A parent node has sent a SendSizeChangeHintCmd.
+///
+/// Subscribe to this event to receive information about how large textures you
+/// will need in the near future for your nodes. The canonical use case is to
+/// pre-allocate memory to avoid repeated re-allocations.
+struct SizeChangeHintEvent {
+ uint32 node_id;
+ float32 width_change_factor;
+ float32 height_change_factor;
+};
+
+/// Delivered when the imported resource with the given ID is no longer bound to
+/// its host resource, or if the imported resource can not be bound because
+/// the host resource is not available.
+struct ImportUnboundEvent {
+ uint32 resource_id;
+};
+
+/// Delivered to a ViewHolder's Session when its peer View is connected.
+struct ViewConnectedEvent {
+ uint32 view_holder_id;
+};
+
+/// Delivered to a ViewHolder's Session when its peer View is disconnected or
+/// destroyed.
+///
+/// If the View is destroyed before the connection is established, then this
+/// event will be delivered immediately when the ViewHolder attempts to connect.
+struct ViewDisconnectedEvent {
+ uint32 view_holder_id;
+};
+
+/// Delivered to a View's Session when its peer ViewHolder is disconnected or
+/// destroyed.
+///
+/// If the ViewHolder is destroyed before the connection is established, then
+/// this event will be delivered immediately when the View attempts to connect.
+struct ViewHolderDisconnectedEvent {
+ uint32 view_id;
+};
+
+/// Delivered to a View's Session when its peer ViewHolder is connected.
+///
+/// If the ViewHolder is destroyed before the connection is established, then
+/// this event will not be delivered.
+struct ViewHolderConnectedEvent {
+ uint32 view_id;
+};
+
+/// Delivered to a View's Session when the parent ViewHolder for the given View
+/// becomes a part of a Scene.
+///
+/// A ViewHolder is considered to be part of a Scene if there is an unbroken
+/// chain of parent-child relationships between the Scene node and the
+/// ViewHolder node.
+struct ViewAttachedToSceneEvent {
+ uint32 view_id;
+ ViewProperties properties;
+};
+
+/// Delivered to a View's Session when the parent ViewHolder for the given View
+/// is no longer part of a scene.
+///
+/// This can happen if the ViewHolder is detached directly from the scene, or
+/// if one of its parent nodes is.
+///
+/// A ViewHolder is considered to be part of a Scene if there is an unbroken
+/// chain of parent-child relationships between the Scene node and the
+/// ViewHolder node.
+struct ViewDetachedFromSceneEvent {
+ uint32 view_id;
+};
+
+/// Delivered when the parent ViewHolder for the given View makes a change to
+/// the View's properties.
+struct ViewPropertiesChangedEvent {
+ uint32 view_id;
+ ViewProperties properties;
+};
+
+/// Delivered to a ViewHolder's Session when its peer View's state has changed.
+struct ViewStateChangedEvent {
+ uint32 view_holder_id;
+ ViewState state;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/hit.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/hit.fidl
new file mode 100644
index 0000000..988438f
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/hit.fidl
@@ -0,0 +1,36 @@
+// Copyright 2017 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.
+
+library fuchsia.ui.gfx;
+
+/// Describes where a hit occurred within the content of a node tagged
+/// by this session.
+///
+/// To compute the point of intersection within the node's local coordinate
+/// system, perform the following calculation using the ray which was
+/// originally passed to `Session.HitTest()`.
+///
+/// hit_point = ray.origin + (hit.distance * ray.direction)
+/// local_point = hit.inverse_transform * hit_point
+struct Hit {
+ /// The node's tag value.
+ uint32 tag_value;
+
+ /// The origin of the ray that was used for the hit test, in the hit
+ /// node's coordinate system.
+ vec4 ray_origin;
+
+ /// The direction of the ray that was used for the hit test, in the hit
+ /// node's coordinate system.
+ vec4 ray_direction;
+
+ /// The inverse transformation matrix which maps the coordinate system of
+ /// the node at which the hit test was initiated into the local coordinate
+ /// system of the node which was hit.
+ mat4 inverse_transform;
+
+ /// The distance from the ray's origin to the closest point of intersection
+ /// in multiples of the ray's direction vector.
+ float32 distance;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/meta.json
new file mode 100644
index 0000000..6b487f7
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/meta.json
@@ -0,0 +1,23 @@
+{
+ "deps": [
+ "fuchsia.images",
+ "fuchsia.ui.views",
+ "fuchsia.mem"
+ ],
+ "name": "fuchsia.ui.gfx",
+ "root": "fidl/fuchsia.ui.gfx",
+ "sources": [
+ "fidl/fuchsia.ui.gfx/commands.fidl",
+ "fidl/fuchsia.ui.gfx/display_info.fidl",
+ "fidl/fuchsia.ui.gfx/events.fidl",
+ "fidl/fuchsia.ui.gfx/hit.fidl",
+ "fidl/fuchsia.ui.gfx/nodes.fidl",
+ "fidl/fuchsia.ui.gfx/pose_buffer_provider.fidl",
+ "fidl/fuchsia.ui.gfx/renderer.fidl",
+ "fidl/fuchsia.ui.gfx/resources.fidl",
+ "fidl/fuchsia.ui.gfx/shapes.fidl",
+ "fidl/fuchsia.ui.gfx/tokens.fidl",
+ "fidl/fuchsia.ui.gfx/types.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/nodes.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/nodes.fidl
new file mode 100644
index 0000000..a4b2158
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/nodes.fidl
@@ -0,0 +1,65 @@
+// Copyright 2017 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.
+
+library fuchsia.ui.gfx;
+
+// These are the types of nodes that can be created within a Scenic `Session`.
+//
+// All nodes have an associated transform, which distinguishes them from mere
+// resources. Nodes may also have one or more node Characteristics:
+//
+// These are characteristics that each type of `Node` either has or doesn't.
+// These constrain operations that reference nodes; violations will cause the
+// `Session` connection to be closed. For example, `NodeAddChildOp` must target
+// a node with the "has_children" characteristic. These characteristics are not
+// explicitly reflected in the Session API; instead, they must be enforced by
+// implementations of the API.
+// - has_children: The node can contain other nodes as children.
+// - has_parent: The node can be a child of another node. If this is false,
+// the node can only be a direct descendant of its containing scene.
+// - has_parts: The node can contain other nodes as parts. All parts must be
+// from the same session as their parent.
+// - has_clip: The node can contain a clip node as a child.
+// - is_clip: The node can clip other nodes.
+// - has_shape: The node can contain ShapeNodes as children.
+// - has_material: The node can have a Material resource applied to it.
+
+/// Characteristics:
+/// - has_parent
+/// - has_shape
+/// - has_material
+struct ShapeNodeArgs {
+ // TODO(SCN-694): Clean up dummy args.
+ uint32 unused = 0;
+};
+
+/// Characteristics:
+/// - has_parent
+/// - is_clip
+/// - has_parts
+struct ClipNodeArgs {
+ // TODO(SCN-694): Clean up dummy args.
+ uint32 unused = 0;
+};
+
+/// Characteristics:
+/// - has_transform
+/// - has_parent
+/// - has_children
+/// - has_parts
+/// - has_opacity
+struct OpacityNodeArgsHACK {
+ uint32 unused = 0;
+};
+
+/// Characteristics:
+/// - has_transform
+/// - has_children
+/// - has_parent
+/// - has_parts
+/// - has_clip
+struct EntityNodeArgs {
+ // TODO(SCN-694): Clean up dummy args.
+ uint32 unused = 0;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/pose_buffer_provider.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/pose_buffer_provider.fidl
new file mode 100644
index 0000000..cccaef6
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/pose_buffer_provider.fidl
@@ -0,0 +1,14 @@
+// Copyright 2018 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.
+
+library fuchsia.ui.gfx;
+
+/// A minimal fidl interface to allow sourcing the contents of a PoseBuffer from another service.
+[Discoverable]
+protocol PoseBufferProvider {
+ /// Sets the PoseBuffer and the parameters PoseBufferProvider will use to fill that PoseBuffer.
+ /// Setting this when it is already set will replace the previously set parameters with the new
+ /// parameters, which will release the provider's reference to the buffer.
+ SetPoseBuffer(handle<vmo> buffer, uint32 num_entries, int64 base_time, uint64 time_interval);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/renderer.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/renderer.fidl
new file mode 100644
index 0000000..547ef02
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/renderer.fidl
@@ -0,0 +1,37 @@
+// Copyright 2017 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.
+
+library fuchsia.ui.gfx;
+
+/// These are all of the types of parameters that can be set to configure a
+/// `Renderer`.
+union RendererParam {
+ 1: ShadowTechnique shadow_technique;
+
+ [Deprecated]
+ 2: RenderFrequency reserved; // No longer supported.
+
+ 3: bool enable_debugging;
+};
+
+/// Represents the shadow algorithm that the `Renderer` should use when lighting
+/// the scene.
+enum ShadowTechnique {
+ /// No shadows.
+ UNSHADOWED = 0;
+ /// Default. Screen-space, depth-buffer based shadows; SSDO-ish.
+ SCREEN_SPACE = 1;
+ /// Basic shadow map.
+ SHADOW_MAP = 2;
+ /// Moment shadow map (see http:///momentsingraphics.de).
+ MOMENT_SHADOW_MAP = 3;
+ /// Stencil shadow volume.
+ STENCIL_SHADOW_VOLUME = 4;
+};
+
+[Deprecated]
+enum RenderFrequency {
+ WHEN_REQUESTED = 0;
+ CONTINUOUSLY = 1;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/resources.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/resources.fidl
new file mode 100644
index 0000000..a58845a
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/resources.fidl
@@ -0,0 +1,322 @@
+// Copyright 2017 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.
+
+library fuchsia.ui.gfx;
+
+using fuchsia.images;
+using fuchsia.ui.views;
+
+/// These are all of the types of resources that can be created within a
+/// `Session`. Add new fields only to the bottom of the list.
+union ResourceArgs {
+ // Memory resources.
+ 1: MemoryArgs memory;
+ 2: ImageArgs image;
+ 3: ImagePipeArgs image_pipe;
+ 4: BufferArgs buffer;
+
+ // Views.
+ 5: ViewArgs view;
+ 6: ViewHolderArgs view_holder;
+
+ // Shapes (see shapes.fidl).
+ 7: RectangleArgs rectangle;
+ 8: RoundedRectangleArgs rounded_rectangle;
+ 9: CircleArgs circle;
+ 10: MeshArgs mesh;
+
+ // Nodes (see nodes.fidl).
+ 11: ShapeNodeArgs shape_node;
+ 12: ClipNodeArgs clip_node;
+ 13: EntityNodeArgs entity_node;
+ 14: OpacityNodeArgsHACK opacity_node;
+
+ // Materials.
+ 15: MaterialArgs material;
+
+ // Layers.
+ 16: CompositorArgs compositor;
+ 17: DisplayCompositorArgs display_compositor;
+ 18: ImagePipeCompositorArgs image_pipe_compositor;
+ 19: LayerStackArgs layer_stack;
+ 20: LayerArgs layer;
+
+ // Scene representation and display.
+ 21: SceneArgs scene;
+ 22: CameraArgs camera;
+ 23: StereoCameraArgs stereo_camera;
+ 24: RendererArgs renderer;
+
+ // Lighting.
+ 25: AmbientLightArgs ambient_light;
+ 26: DirectionalLightArgs directional_light;
+
+ // A value that can be used in place of a constant value.
+ 27: VariableArgs variable;
+
+ // TODO(SCN-1225): Move these where they belong. They're added to the end
+ // of the struct temporarily until we transition to xunions.
+ 28: PointLightArgs point_light;
+ 29: reserved;
+ 30: reserved;
+ 31: ViewArgs3 view3;
+ 32: ImagePipe2Args image_pipe2;
+};
+
+struct ImagePipeArgs {
+ request<fuchsia.images.ImagePipe> image_pipe_request;
+};
+
+/// `ImagePipe2` is a `Resource` that can be used as a `Texture` for a `Material`.
+struct ImagePipe2Args {
+ request<fuchsia.images.ImagePipe2> image_pipe_request;
+};
+
+/// `Memory` is a `Resource` that wraps a client-provided Zircon vmo to register
+/// it with Scenic.
+// TODO: specify resizing behavior. Who can resize? Client/Scenic/both/none?
+struct MemoryArgs {
+ // The VMO which backs this memory.
+ handle<vmo> vmo;
+
+ // The amount of memory from `vmo` that should be utilized.
+ uint64 allocation_size;
+
+ // The type of memory stored in the VMO, namely whether it's GPU memory or
+ // host memory.
+ fuchsia.images.MemoryType memory_type;
+};
+
+/// An image mapped to a range of a `Memory` resource.
+// TODO: more precise and extensive docs.
+struct ImageArgs {
+ fuchsia.images.ImageInfo info;
+
+ uint32 memory_id; // id of a `Memory` resource
+ uint32 memory_offset; // byte offset of image within `Memory` resource
+};
+
+/// A buffer mapped to a range of `Memory`.
+struct BufferArgs {
+ uint32 memory_id; // id of a `Memory` resource
+ uint32 memory_offset; // byte offset of buffer within `Memory` resource
+ uint32 num_bytes;
+};
+
+/// Represents the root of a subgraph within a larger scene graph. Nodes can be
+/// attached to the `View` as children, and these Nodes will have the `View`s'
+/// coordinate transform applied to their own, in addition to being clipped to
+/// the `View`s' bounding box.
+/// See `ViewProperties`.
+///
+/// Each `View` is linked to a paired `ViewHolder` via a shared token pair.
+///
+/// Usually the `View` and its associated `ViewHolder` exist in separate
+/// processes. By combining them, the UI for an entire system can be built
+/// using content contributed from many different processes.
+struct ViewArgs {
+ fuchsia.ui.views.ViewToken token;
+ string? debug_name;
+};
+
+/// Represents the root of a subgraph within a larger scene graph. Nodes can be
+/// attached to the `View` as children, and these Nodes will have the `View`s'
+/// coordinate transform applied to their own, in addition to being clipped to
+/// the `View`s' bounding box.
+/// See `ViewProperties`.
+///
+/// Each `View` is linked to a paired `ViewHolder` via a shared token pair.
+///
+/// Usually the `View` and its associated `ViewHolder` exist in separate
+/// processes. By combining them, the UI for an entire system can be built
+/// using content contributed from many different processes.
+///
+/// Clients self-identify their `View` with a `ViewRef`, which is a stable
+/// identifier that may be cloned and passed to other components in a
+/// feed-forward style. It is accompanied by a `ViewRefControl`, which Scenic
+/// uses to signal `View` destruction across the system; the `ViewRefControl`
+/// must be unique - do not clone it.
+struct ViewArgs3 {
+ fuchsia.ui.views.ViewToken token;
+ /// `control_ref.reference` must have full rights (i.e., with signaling).
+ fuchsia.ui.views.ViewRefControl control_ref;
+ /// `view_ref.reference` must have basic rights (i.e., no signaling).
+ fuchsia.ui.views.ViewRef view_ref;
+ string? debug_name;
+};
+
+/// Represents an attachment point for a subgraph within a larger scene graph.
+/// The `ViewHolder` can be attached to a Node as a child, and the contents of
+/// the linked `View` will become a child of the Node as well.
+///
+/// Each `ViewHolder` is linked to a paired `View` via a shared token pair.
+///
+/// Usually the `ViewHolder` and its associated `View` exist in separate
+/// processes. By combining them, the UI for an entire system can be built
+/// using content contributed from many different processes.
+struct ViewHolderArgs {
+ fuchsia.ui.views.ViewHolderToken token;
+ string? debug_name;
+};
+
+/// A Compositor draws its `LayerStack` into a framebuffer provided by its
+/// attached `Display`, if any. If no display is attached, nothing is rendered.
+// TODO(fxb/23686): there is currently no way to create/attach a display.
+struct CompositorArgs {
+ // TODO(SCN-694): Clean up dummy args.
+ uint32 dummy = 0;
+};
+
+/// A DisplayCompositor draws its attached `LayerStack` into an image that is
+/// presented on a display.
+struct DisplayCompositorArgs {
+ // TODO(SCN-694): Clean up dummy args.
+ uint32 dummy = 0;
+};
+
+/// An ImagePipeCompositor draws its attached `LayerStack` into an image that is
+/// presented on an image-pipe.
+struct ImagePipeCompositorArgs {
+ fuchsia.images.ImagePipe target;
+};
+
+/// A LayerStack is a stack of layers that are attached to a Compositor, which
+/// draws them in order of increasing Z-order (or rather, presents the illusion
+/// of drawing them in that order: it may apply any optimizations that don't
+/// affect the output).
+///
+/// Supported commands:
+/// - AddLayer
+struct LayerStackArgs {
+ // TODO(SCN-694): Clean up dummy args.
+ uint32 dummy = 0;
+};
+
+/// A Layer is a 2-dimensional image that is drawn by a Compositor. The
+/// contents of each Layer in a Layerstack are independent of each other.
+/// A layer is not drawn unless it has a camera, texture, or color.
+///
+/// Supported commands:
+/// - Detach
+/// - SetCamera
+/// - SetColor
+/// - SetTexture
+/// - SetSize (depth must be zero)
+/// - SetSize
+/// - SetTranslation (z component determines the relative Z-ordering of layers)
+/// - SetRotation (must rotate around Z-axis)
+/// - SetScale
+struct LayerArgs {
+ // TODO(SCN-694): Clean up dummy args.
+ uint32 dummy = 0;
+};
+
+/// A Scene is the root of a scene-graph, and defines the rendering environment
+/// (lighting, etc.) for the tree of nodes beneath it.
+///
+/// Supported commands:
+/// - Add/RemoveLight
+/// - AddChild
+struct SceneArgs {
+ // TODO(SCN-694): Clean up dummy args.
+ uint32 dummy = 0;
+};
+
+/// A Camera is used to render a Scene from a particular viewpoint. This is
+/// achieved by setting a Renderer to use the camera.
+///
+/// The following commands may be applied to a Camera:
+/// - SetCameraTransform
+/// - SetCameraProjection
+/// - SetCameraPoseBuffer
+struct CameraArgs {
+ // The scene that the camera is viewing.
+ uint32 scene_id;
+};
+
+/// A StereoCamera is a Camera that renders the scene in side-by-side stereo.
+///
+/// Any command which can be applied to a Camera can also be applied to a
+/// StereoCamera.
+/// Additional supported commands:
+/// - SetStereoCameraProjection
+struct StereoCameraArgs {
+ // The scene that the camera is viewing.
+ uint32 scene_id;
+};
+
+/// A Renderer renders a Scene via a Camera.
+///
+/// Supported commands:
+/// - SetCamera
+/// - SetRendererParam
+struct RendererArgs {
+ // TODO(SCN-694): Clean up dummy args.
+ uint32 dummy = 0;
+};
+
+/// An AmbientLight is a Light that is is assumed to be everywhere in the scene,
+/// in all directions.
+///
+/// Supported commands:
+/// - SetLightColor
+struct AmbientLightArgs {
+ // TODO(SCN-694): Clean up dummy args.
+ uint32 dummy = 0;
+};
+
+/// A DirectionalLight is a Light that is emitted from a point at infinity.
+///
+/// Although the light is directional, the light has some amount of angular
+/// dispersion (i.e., the light is not fully columnated). For simplicity, we
+/// assume the dispersion of the light source is symmetric about the light's
+/// primary direction.
+///
+/// Supported commands:
+/// - SetLightColor
+/// - SetLightDirection
+struct DirectionalLightArgs {
+ // TODO(SCN-694): Clean up dummy args.
+ uint32 dummy = 0;
+};
+
+/// A PointLight is a Light that emits light in all directions. By default, the
+/// intensity of the light falls off according to the physically based
+/// "inverse-square law" (see Wikipedia), although it can be adjusted to other
+/// values for artistic effect.
+///
+/// Supported commands:
+/// - SetLightColor
+/// - SetPointLightPosition
+/// - SetPointLightFalloff
+struct PointLightArgs {
+ // TODO(SCN-694): Clean up dummy args.
+ uint32 dummy = 0;
+};
+
+/// Simple texture-mapped material.
+///
+/// Supported commands:
+/// - SetTextureCmd: sets the texture, or it can be left as zero (no texture).
+/// The texture can be an Image or ImagePipe.
+/// - SetColorCmd: sets the color.
+struct MaterialArgs {
+ // TODO(SCN-694): Clean up dummy args.
+ uint32 dummy = 0;
+};
+
+/// Describes a typed, client-modifiable value.
+struct VariableArgs {
+ ValueType type;
+ Value initial_value; // Must match type. Must not be a variable_id.
+};
+
+/// Describes an exported resource that is to be imported by an
+/// ImportResourceCmd.
+///
+/// NOTE: Currently just an enum of importable resource types, but may later be
+/// expanded to express concepts like "meshes with a particular vertex format".
+enum ImportSpec {
+ NODE = 0;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/shapes.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/shapes.fidl
new file mode 100644
index 0000000..e861c7e
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/shapes.fidl
@@ -0,0 +1,39 @@
+// Copyright 2017 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.
+
+library fuchsia.ui.gfx;
+
+// The shapes defined in this file can be used to define the rendered shape of
+// an `ObjectNode`, and to define the clip region of a `ClipNode`.
+
+/// Rectangle centered at (0,0).
+struct RectangleArgs {
+ Value width; // float32
+ Value height; // float32
+};
+
+/// RoundedRectangle centered at (0,0). Legal parameter values must satisfy the
+/// constraint that the flat sides of the rectangle have non-negative length.
+/// In other words, the following constraints must hold:
+/// - top_left_radius + top_right_radius <= width
+/// - bottom_left_radius + bottom_right_radius <= width
+/// - top_left_radius + bottom_left_radius <= height
+/// - top_right_radius + bottom_right_radius <= height
+struct RoundedRectangleArgs {
+ Value width; // float32
+ Value height; // float32
+ Value top_left_radius; // float32
+ Value top_right_radius; // float32
+ Value bottom_right_radius; // float32
+ Value bottom_left_radius; // float32
+};
+
+struct CircleArgs {
+ Value radius; // float32
+};
+
+/// A Mesh cannot be rendered until it has been bound to vertex/index buffers;
+/// see BindMeshBuffersCmd.
+struct MeshArgs {
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/tokens.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/tokens.fidl
new file mode 100644
index 0000000..a89be75
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/tokens.fidl
@@ -0,0 +1,36 @@
+// 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.
+
+library fuchsia.ui.gfx;
+
+/// Token that uniquely identifies an attachment point for a subgraph in the
+/// global scene graph. Each `ImportToken` has exactly one corresponding
+/// `ExportToken`.
+///
+/// A Scenic client can reference contents from another client by creating a
+/// typed resource using this token. The other client must also create a
+/// correspondingly typed resource using the corresponding `ExportToken`.
+///
+/// The exact nature of the inter-client reference depends on the specific
+/// resources created from the tokens. For example, creating a `ViewHolder`
+/// resource from this token allows a client to embed another client's `View`.
+struct ImportToken {
+ handle<eventpair> value;
+};
+
+/// Token that uniquely identifies a root point for a subgraph in the global
+/// scene graph. Each `ExportToken` has exactly one corresponding `ImportToken`.
+///
+/// A Scenic client can have its contents referenced from another client by
+/// creating a typed resource using this token. The other client must also
+/// create a correspondingly typed resource using the corresponding
+/// `ImportToken`.
+///
+/// The exact nature of the inter-client reference depends on the specific
+/// resources created from the tokens. For example, creating a `View`
+/// resource from this token allows everything attached to the `View` to be
+/// embedded in another clients `ViewHolder`.
+struct ExportToken {
+ handle<eventpair> value;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/types.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/types.fidl
new file mode 100644
index 0000000..dfbdf45
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.gfx/types.fidl
@@ -0,0 +1,245 @@
+// Copyright 2017 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.
+
+library fuchsia.ui.gfx;
+
+struct vec2 {
+ float32 x;
+ float32 y;
+};
+
+struct vec3 {
+ float32 x;
+ float32 y;
+ float32 z;
+};
+
+struct vec4 {
+ float32 x;
+ float32 y;
+ float32 z;
+ float32 w;
+};
+
+struct mat4 {
+ /// Column major order.
+ array<float32>:16 matrix;
+};
+
+/// sRGB color space and nonlinear transfer function.
+// TODO(SCN-238): use float32s instead of uint8.
+struct ColorRgba {
+ uint8 red;
+ uint8 green;
+ uint8 blue;
+ uint8 alpha;
+};
+
+struct ColorRgb {
+ float32 red;
+ float32 green;
+ float32 blue;
+};
+
+struct Quaternion {
+ float32 x;
+ float32 y;
+ float32 z;
+ float32 w;
+};
+
+/// Oriented plane described by a normal vector and a distance
+/// from the origin along that vector.
+struct Plane3 {
+ vec3 dir;
+ float32 dist;
+};
+
+struct FactoredTransform {
+ vec3 translation;
+ vec3 scale;
+ /// Point around which rotation and scaling occur.
+ vec3 anchor;
+ Quaternion rotation;
+};
+
+union Value {
+ 1: float32 vector1;
+ 2: vec2 vector2;
+ 3: vec3 vector3;
+ 4: vec4 vector4;
+ 5: mat4 matrix4x4;
+ 6: ColorRgba color_rgba;
+ 7: ColorRgb color_rgb;
+ /// Degrees of counter-clockwise rotation in the XY plane.
+ 8: float32 degrees;
+ 9: Quaternion quaternion;
+ 10: FactoredTransform transform;
+ /// ID of a value-producing resource (an animation or an expression).
+ /// The type of this value matches the type produced by the named resource.
+ 11: uint32 variable_id;
+};
+
+/// A value that is specified explicitly by `value` if `variable_id` is zero,
+/// or is the value produced by the resource identified by `variable_id`, e.g.
+/// an animation or expression. In the latter case, the value produced by the
+/// resource must be a float32, and `value` is ignored.
+struct FloatValue {
+ float32 value;
+ uint32 variable_id;
+};
+
+/// A value that is specified explicitly by `value` if `variable_id` is zero,
+/// or is the value produced by the resource identified by `variable_id`, e.g.
+/// an animation or expression. In the latter case, the value produced by the
+/// resource must be a vec2, and `value` is ignored.
+struct Vector2Value {
+ vec2 value;
+ uint32 variable_id;
+};
+
+/// A value that is specified explicitly by `value` if `variable_id` is zero,
+/// or is the value produced by the resource identified by `variable_id`, e.g.
+/// an animation or expression. In the latter case, the value produced by the
+/// resource must be a vec3, and `value` is ignored.
+struct Vector3Value {
+ vec3 value;
+ uint32 variable_id;
+};
+
+/// A value that is specified explicitly by `value` if `variable_id` is zero,
+/// or is the value produced by the resource identified by `variable_id`, e.g.
+/// an animation or expression. In the latter case, the value produced by the
+/// resource must be a vec4, and `value` is ignored.
+struct Vector4Value {
+ vec4 value;
+ uint32 variable_id;
+};
+
+/// A value that is specified explicitly by `value` if `variable_id` is zero,
+/// or is the value produced by the resource identified by `variable_id`, e.g.
+/// an animation or expression. In the latter case, the value produced by the
+/// resource must be a vec4, and `value` is ignored.
+struct Matrix4Value {
+ mat4 value;
+ uint32 variable_id;
+};
+
+/// A value that is specified explicitly by `value` if `variable_id` is zero,
+/// or is the value produced by the resource identified by `variable_id`, e.g.
+/// an animation or expression. In the latter case, the value produced by the
+/// resource must be a ColorRgb, and `value` is ignored.
+struct ColorRgbValue {
+ ColorRgb value;
+ uint32 variable_id;
+};
+
+/// A value that is specified explicitly by `value` if `variable_id` is zero,
+/// or is the value produced by the resource identified by `variable_id`, e.g.
+/// an animation or expression. In the latter case, the value produced by the
+/// resource must be a ColorRgba, and `value` is ignored.
+struct ColorRgbaValue {
+ ColorRgba value;
+ uint32 variable_id;
+};
+
+/// A value that is specified explicitly by `value` if `variable_id` is zero,
+/// or is the value produced by the resource identified by `variable_id`, e.g.
+/// an animation or expression. In the latter case, the value produced by the
+/// resource must be a Quaternion, and `value` is ignored.
+struct QuaternionValue {
+ Quaternion value;
+ uint32 variable_id;
+};
+
+enum ValueType {
+ kNone = 0;
+ kVector1 = 1;
+ kVector2 = 2;
+ kVector3 = 3;
+ kVector4 = 4;
+ kMatrix4 = 5;
+ kColorRgb = 6;
+ kColorRgba = 7;
+ kQuaternion = 8;
+ kFactoredTransform = 9;
+};
+
+/// Describes how nodes interact with hit testings.
+enum HitTestBehavior {
+ /// Apply hit testing to the node's content, its parts, and its children.
+ kDefault = 0;
+
+ /// Suppress hit testing of the node and everything it contains.
+ kSuppress = 1;
+};
+
+/// Rendering target metrics associated with a node.
+/// See also `MetricsEvent`.
+struct Metrics {
+ /// The ratio between the size of one logical pixel within the node's local
+ /// coordinate system and the size of one physical pixel of the rendering
+ /// target.
+ ///
+ /// This scale factors change in relation to the resolution of the rendering
+ /// target and the scale transformations applied by containing nodes.
+ /// They are always strictly positive and non-zero.
+ ///
+ /// For example, suppose the rendering target is a high resolution display
+ /// with a device pixel ratio of 2.0 meaning that each logical pixel
+ /// within the model corresponds to two physical pixels of the display.
+ /// Assuming no scale transformations affect the node, then its metrics event
+ /// will report a scale factor of 2.0.
+ ///
+ /// Building on this example, if instead the node's parent applies a
+ /// scale transformation of 0.25 to the node, then the node's metrics event
+ /// will report a scale factor of 0.5 indicating that the node should render
+ /// its content at a reduced resolution and level of detail since a smaller
+ /// area of physical pixels (half the size in each dimension) will be rendered.
+ float32 scale_x;
+ float32 scale_y;
+ float32 scale_z;
+};
+
+/// Represents an axis-aligned bounding box. If any of the dimensions has a
+/// negative extent (e.g. max.x < min.x) then the bounding box is treated as
+/// empty.
+struct BoundingBox {
+ vec3 min;
+ vec3 max;
+};
+
+/// Represents the properties for a View.
+struct ViewProperties {
+ /// The View's bounding box extents can be defined as:
+ /// { bounding_box.min + inset_from_min, bounding_box.max - inset_from_max }
+ /// Content contained within the View is clipped to this bounding box.
+ ///
+ // TODO(SCN-819): should we just have a vec3 extent instead of a bounding box
+ // with a potentially non-zero min?
+ BoundingBox bounding_box;
+
+ /// `insets_from_min` and `insets_from_max` specify the distances between the
+ /// view's bounding box and that of its parent.
+ vec3 inset_from_min;
+ vec3 inset_from_max;
+
+ /// Whether the View can receive a focus event; default is true. When
+ /// false, and this View is eligible to receive a focus event, no
+ /// focus/unfocus event is actually sent to any View.
+ bool focus_change = true;
+
+ /// Whether the View allows geometrically underlying Views to receive input;
+ /// default is true. When false, Scenic does not send input events to
+ /// underlying Views.
+ // TODO(SCN-1513): not implemented yet.
+ bool downward_input = true;
+};
+
+/// Represents the state of a View in Scenic.
+struct ViewState {
+ /// Whether the View is rendering. Default is false. Delivered to the View's
+ /// corresponding ViewHolder after the View's first frame render request.
+ bool is_rendering;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/BUILD.gn
new file mode 100644
index 0000000..cd06ab2
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/BUILD.gn
@@ -0,0 +1,37 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.ui.input") {
+ library_name = "input"
+ namespace = "fuchsia.ui"
+ public_deps = [
+ "../fuchsia.ui.input2",
+ "../fuchsia.ui.input3",
+ "../fuchsia.ui.views",
+ ]
+ sources = [
+ "commands.fidl",
+ "ime_service.fidl",
+ "input_device_registry.fidl",
+ "input_event_constants.fidl",
+ "input_events.fidl",
+ "input_reports.fidl",
+ "pointer_capture.fidl",
+ "text_editing.fidl",
+ "text_input.fidl",
+ "usages.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.ui.input",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/commands.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/commands.fidl
new file mode 100644
index 0000000..6bff402
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/commands.fidl
@@ -0,0 +1,48 @@
+// Copyright 2018 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.
+
+library fuchsia.ui.input;
+
+union Command {
+ /// Commands for conveying input events to a `Session`.
+ /// Structs defined in input_events.fidl.
+ 1: SendKeyboardInputCmd send_keyboard_input;
+ 2: SendPointerInputCmd send_pointer_input;
+
+ /// Command to enable/disable delivery of hard keyboard events.
+ 3: SetHardKeyboardDeliveryCmd set_hard_keyboard_delivery;
+
+ /// Command to enable/disable parallel delivery of input events.
+ 4: SetParallelDispatchCmd set_parallel_dispatch;
+};
+
+struct SendKeyboardInputCmd {
+ uint32 compositor_id;
+ KeyboardEvent keyboard_event; // Defined in input_events.fidl
+};
+
+struct SendPointerInputCmd {
+ uint32 compositor_id;
+ PointerEvent pointer_event; // Defined in input_events.fidl
+};
+
+/// Typically, clients should receive text inputs from an IME.
+///
+/// For cases where no IME mediation is desired (such as a game application),
+/// this command requests Scenic to deliver hard keyboard events to the client.
+///
+/// By default, Scenic will *not* deliver hard keyboard events to a client.
+struct SetHardKeyboardDeliveryCmd {
+ bool delivery_request;
+};
+
+/// Typically, clients that participate in the hit test should receive input
+/// events in parallel. This behavior is required for gesture disambiguation.
+///
+/// This command, typically set by the root presenter, allows disabling parallel
+/// dispatch; it is part of the input v2 transition work.
+// TODO(SCN-1047): Remove after gesture disambiguation is implemented.
+struct SetParallelDispatchCmd {
+ bool parallel_dispatch;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/ime_service.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/ime_service.fidl
new file mode 100644
index 0000000..85196d7
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/ime_service.fidl
@@ -0,0 +1,37 @@
+// Copyright 2017 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.
+
+library fuchsia.ui.input;
+
+using fuchsia.ui.input2;
+using fuchsia.ui.input3;
+
+/// The service provided by an IME
+[Discoverable]
+protocol ImeService {
+ GetInputMethodEditor(KeyboardType keyboard_type,
+ InputMethodAction action,
+ TextInputState initial_state,
+ InputMethodEditorClient client,
+ request<InputMethodEditor> editor);
+ ShowKeyboard();
+ HideKeyboard();
+ // DEPRECATED: Will be replaced with DispatchKey3
+ InjectInput(InputEvent event);
+
+ // DEPRECATED: Will be replaced with DispatchKey3
+ DispatchKey(fuchsia.ui.input2.KeyEvent event) -> (bool handled);
+
+ // Notify IME Service of a keyboard event. Will be migrated into
+ // fuchsia.ui.input after fuchsia.ui.input cleanup.
+ [Transitional]
+ DispatchKey3(fuchsia.ui.input3.KeyEvent event) -> (bool handled);
+};
+
+/// Onscreen keyboard containers connect to this to know when a keyboard
+/// should be shown or hidden.
+[Discoverable]
+protocol ImeVisibilityService {
+ -> OnKeyboardVisibilityChanged(bool visible);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/input_device_registry.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/input_device_registry.fidl
new file mode 100644
index 0000000..fab3dbf
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/input_device_registry.fidl
@@ -0,0 +1,20 @@
+// Copyright 2017 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.
+
+library fuchsia.ui.input;
+
+/// Service to receive input events.
+///
+/// Input devices can describe their capabilities using `DeviceDescriptor`
+/// and register themselves with the `InputDeviceRegistry`.
+[Discoverable]
+protocol InputDeviceRegistry {
+ /// Register a device with the capabilities described by `DeviceDescriptor`
+ RegisterDevice(DeviceDescriptor descriptor, request<InputDevice> input_device);
+};
+
+protocol InputDevice {
+ /// Dispatch an `InputReport` from the device `token`
+ DispatchReport(InputReport report);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/input_event_constants.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/input_event_constants.fidl
new file mode 100644
index 0000000..7e592c8
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/input_event_constants.fidl
@@ -0,0 +1,32 @@
+// Copyright 2014 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.
+
+library fuchsia.ui.input;
+
+/// Keyboard modifiers
+const uint32 kModifierNone = 0;
+const uint32 kModifierCapsLock = 1;
+const uint32 kModifierLeftShift = 2;
+const uint32 kModifierRightShift = 4;
+const uint32 kModifierShift = 6; // (kModifierLeftShift | kModifierRightShift);
+const uint32 kModifierLeftControl = 8;
+const uint32 kModifierRightControl = 16;
+const uint32 kModifierControl = 24; // (kModifierLeftControl | kModifierRightControl);
+const uint32 kModifierLeftAlt = 32;
+const uint32 kModifierRightAlt = 64;
+const uint32 kModifierAlt = 96; // (kModifierLeftAlt | kModifierRightAlt);
+const uint32 kModifierLeftSuper = 128;
+const uint32 kModifierRightSuper = 256;
+const uint32 kModifierSuper = 384; // (kModifierLeftSuper | kModifierRightSuper);
+
+/// Mouse buttons
+const uint32 kMousePrimaryButton = 1;
+const uint32 kMouseSecondaryButton = 2;
+const uint32 kMouseTertiaryButton = 4;
+
+/// Stylus buttons
+const uint32 kStylusPrimaryButton = 1;
+const uint32 kStylusSecondaryButton = 2;
+
+// end-no-format
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/input_events.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/input_events.fidl
new file mode 100644
index 0000000..4081a75
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/input_events.fidl
@@ -0,0 +1,167 @@
+// Copyright 2014 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.
+
+library fuchsia.ui.input;
+
+enum KeyboardEventPhase {
+ /// When key is pressed down.
+ PRESSED = 0;
+ /// When key is released.
+ RELEASED = 1;
+ /// This key `PRESSED` is not directed to this input client anymore.
+ CANCELLED = 2;
+ /// Whether this is an automatically generated key repeat
+ REPEAT = 3;
+};
+
+/// `KeyboardEvent` represents event generated by a user's interaction with a
+/// keyboard.
+///
+/// Those events are triggered by distinct pressed state changes of the keys.
+///
+/// The state transitions should be as follows:
+/// PRESSED -> (REPEAT ->) RELEASED
+/// or
+/// PRESSED -> (REPEAT ->) CANCELLED
+///
+/// The input system will repeat those events automatically when a code_point is
+/// available.
+///
+/// DEPRECATED: Will be removed in favor of `fuchsia.ui.input.KeyEvent`.
+struct KeyboardEvent {
+ /// Time the event was delivered. The time is in nanoseconds and corresponds
+ /// to the uptime of the machine.
+ uint64 event_time;
+
+ uint32 device_id;
+
+ KeyboardEventPhase phase;
+
+ /// Keyboard HID Usage
+ /// See https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf
+ uint32 hid_usage;
+
+ /// The unicode code point represented by this key event, if any.
+ /// Dead keys are represented as Unicode combining characters.
+ ///
+ /// If there is no unicode code point, this value is zero.
+ uint32 code_point;
+
+ /// Key modifiers as defined by the different kModifier constants such as
+ /// `kModifierCapsLock` currently pressed
+ uint32 modifiers;
+};
+
+enum PointerEventType {
+ /// A touch-based pointer device.
+ TOUCH = 0;
+
+ /// A pointer device with a stylus.
+ STYLUS = 1;
+
+ /// A pointer device with a stylus that has been inverted.
+ INVERTED_STYLUS = 2;
+
+ /// A pointer device without a stylus.
+ MOUSE = 3;
+};
+
+enum PointerEventPhase {
+ /// The device has started tracking the pointer.
+ ///
+ /// For example, the pointer might be hovering above the device, having not yet
+ /// made contact with the surface of the device.
+ ADD = 0;
+
+ /// The pointer has moved with respect to the device while not in contact with
+ /// the device.
+ HOVER = 1;
+
+ /// The pointer has made contact with the device.
+ ///
+ /// For `MOUSE` devices, this is triggered when the primary button is pressed
+ /// down to emulate a touch on the screen.
+ DOWN = 2;
+
+ /// The pointer has moved with respect to the device while in contact with the
+ /// device.
+ MOVE = 3;
+
+ /// The pointer has stopped making contact with the device.
+ ///
+ /// For `MOUSE` devices, this is triggered when the primary button is
+ /// released.
+ UP = 4;
+
+ /// The device is no longer tracking the pointer.
+ ///
+ /// For example, the pointer might have drifted out of the device's hover
+ /// detection range or might have been disconnected from the system entirely.
+ REMOVE = 5;
+
+ /// The input from the pointer is no longer directed towards this receiver.
+ CANCEL = 6;
+
+ // TODO: add phases to indicate button press / release
+};
+
+/// Pointers represent raw data about the user's interaction with the screen.
+///
+/// The state transitions should be as follows:
+/// ADD (-> HOVER) -> DOWN -> MOVE -> UP (-> HOVER) -> REMOVE
+///
+/// At any point after the initial ADD, a transition to CANCEL is also possible.
+struct PointerEvent {
+ /// Time the event was delivered. The time is in nanoseconds and corresponds
+ /// to the uptime of the machine.
+ uint64 event_time;
+
+ uint32 device_id;
+
+ uint32 pointer_id;
+
+ PointerEventType type;
+
+ PointerEventPhase phase;
+
+ /// `x` and `y` are in the coordinate system of the View.
+ float32 x;
+ float32 y;
+
+ // TODO(jpoichet) float32 vx;
+ // TODO(jpoichet) float32 vy;
+
+ float32 radius_major = 0.0; // DO NOT USE
+ float32 radius_minor = 0.0; // DO NOT USE
+ // TODO(jpoichet) float32 orientation;
+ // TODO(jpoichet) float32 tilt;
+ // TODO(jpoichet) float32 altitude;
+ // TODO(jpichet) float32 amplitude;
+
+ /// Currently pressed buttons as defined the kButton constants such as
+ /// `kMousePrimaryButton`
+ uint32 buttons;
+};
+
+struct FocusEvent {
+ /// Time the event was delivered. The time is in nanoseconds and corresponds
+ /// to the uptime of the machine.
+ uint64 event_time;
+
+ /// Whether the view has gained input focused or not.
+ bool focused;
+};
+
+table MediaButtonsEvent {
+ 1: int8 volume;
+ 2: bool mic_mute;
+ 3: bool pause;
+};
+
+/// This union does not include MediaButtonsEvent because it's processed differently.
+union InputEvent {
+ 1: PointerEvent pointer;
+ 2: KeyboardEvent keyboard;
+ 3: FocusEvent focus;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/input_reports.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/input_reports.fidl
new file mode 100644
index 0000000..3f0d199
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/input_reports.fidl
@@ -0,0 +1,266 @@
+// Copyright 2017 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.
+
+library fuchsia.ui.input;
+
+// Descriptors are used to describe the capabilities of an input device.
+//
+// Devices can have multiple descriptors of multiple kinds, for example:
+// `KeyboardDescriptor`, `MouseDescriptor`, `StylusDescriptor`,
+// `TouchscreenDescriptor` and `SensorDescriptor`
+//
+// An input device will generate `InputReport` corresponding to the
+// capabilities of that device listed in its descriptor.
+// For instance a input device with a `KeyboardDescriptor` will generate
+// `KeyboardReport` when a key is pressed on the keyboard.
+
+// Describe a `Range` of values
+struct Range {
+ int32 min;
+ int32 max;
+};
+
+struct RangeF {
+ float32 min;
+ float32 max;
+};
+
+enum AxisScale {
+ LINEAR = 0;
+ LOGARITHMIC = 1;
+};
+
+// An `Axis` is defined as a `range` and `resolution`.
+struct Axis {
+ Range range;
+ int32 resolution = 1;
+ AxisScale scale = AxisScale.LINEAR;
+};
+
+struct AxisF {
+ RangeF range;
+ float32 resolution = 1.0;
+ AxisScale scale = AxisScale.LINEAR;
+};
+
+// `MediaButtonsDescriptor` describes the media buttons.
+struct MediaButtonsDescriptor {
+ // A bitmask that represents the list of media buttons available.
+ // The mask bit values are located in usages.fidl.
+ uint32 buttons;
+};
+
+// Keyboards
+
+// `KeyboardDescriptor` describes the capabilities of a keyboard.
+struct KeyboardDescriptor {
+ // The list of HID keyboard usages that this keyboard can generate.
+ vector<uint32> keys;
+};
+
+// `KeyboardReport` lists the keys currently pressed down.
+struct KeyboardReport {
+ // `pressed_keys` is the list of HID usage that are currently pressed down on
+ // the keyboard.
+ vector<uint32> pressed_keys;
+};
+
+// Mouse
+
+// `MouseDescriptor` describes the capabilities of a mouse.
+struct MouseDescriptor {
+ // The range of relative X and Y movement which can be described by a mouse
+ // report.
+ Axis rel_x;
+ Axis rel_y;
+
+ // The range of relative vertical and horizontal scroll which can be
+ // described by a mouse report.
+ Axis? vscroll;
+ Axis? hscroll;
+
+ // The list of HID mouse usages that this mouse can generate.
+ uint32 buttons;
+};
+
+// `MouseReport` gives the relative mouvement of the mouse and currently
+// pressed buttons.
+struct MouseReport {
+ // Relative X and Y positional displacement.
+ int32 rel_x;
+ int32 rel_y;
+
+ // Relative horizontal and vertical scrolling displacement.
+ int32 rel_hscroll;
+ int32 rel_vscroll;
+
+ // buttons currently down
+ uint32 pressed_buttons;
+};
+
+// Stylus
+
+// `Stylus` describes the capabilities of a stylus.
+struct StylusDescriptor {
+ // Ranges for the `x` and `y` axis of the stylus.
+ Axis x;
+ Axis y;
+
+ // Range for the pressure of the tip
+ Axis? pressure;
+
+ bool is_invertible = false;
+
+ // The list of HID button usages that this stylus can generate.
+ uint32 buttons;
+};
+
+// `StylusReport` describes the current state of the stylus.
+struct StylusReport {
+ // Current position of the stylus within the range described in
+ // `StylusDescriptor`
+ int32 x;
+ int32 y;
+
+ // Pressure applied on the stylus tip
+ uint32 pressure;
+
+ // Whether the stylus has made contact with the surface.
+ bool is_in_contact;
+
+ // Whether the stylus is within range. If `is_in_contact` is false, then the stylus
+ // is hovering.
+ bool in_range;
+
+ // Whether the stylus is thought to be inverted.
+ bool is_inverted;
+
+ // List of buttons currently pressed down.
+ uint32 pressed_buttons;
+};
+
+// Touchscreen
+
+// `TouchscreenDescriptor` describes the capabilities of a touchscreen.
+struct TouchscreenDescriptor {
+ // Ranges of the `x` and `y` axis.
+ Axis x;
+ Axis y;
+ uint32 max_finger_id;
+};
+
+// `Touch` describes one touch on a touchscreen, which should correspond to
+// one finger.
+struct Touch {
+ // Identifier for a finger that is down.
+ // Note: `finger_id` might not be sequential and will range from 0 to
+ // `max_finger_id`
+ uint32 finger_id;
+
+ // Location within the axis defined in `TouchscreenDescriptor`
+ int32 x;
+ int32 y;
+
+ // Area pressed.
+ uint32 width;
+ uint32 height;
+};
+
+// `TouchscreenReport` describes the current touches recorded by the touchscreen
+// and holds a `Touch` per finger down.
+struct TouchscreenReport {
+ vector<Touch> touches;
+};
+
+// Motion Sensors
+
+// Descriptive categories for sensor devices.
+// We assume that each (SensorType,SensorLocation) pair is unique to the system.
+
+enum SensorType {
+ ACCELEROMETER = 0;
+ GYROSCOPE = 1;
+ MAGNETOMETER = 2;
+ LIGHTMETER = 3;
+};
+
+enum SensorLocation {
+ UNKNOWN = 0;
+ BASE = 1;
+ LID = 2;
+};
+
+// `SensorDescriptor` describes the capabilities of a sensor device. It does
+// not capture properties that can be changed after initialization, such as the
+// current sampling frequency.
+struct SensorDescriptor {
+ SensorType type;
+ SensorLocation loc;
+
+ // Min and max sampling frequencies for a sensor.
+ uint32 min_sampling_freq;
+ uint32 max_sampling_freq;
+ // Max number of sensor events that could be in hardware FIFO.
+ uint32 fifo_max_event_count;
+
+ // Physical range of a specific sensor.
+ // Accelerometer ranges are given in Gs.
+ // Gyroscope ranges are given in deg/s.
+ // Magnetometer ranges are given in multiples of 1/16 uT.
+ // Light meter ranges can be given in Lux or units not specified.
+ int32 phys_min;
+ int32 phys_max;
+};
+
+// `SensorReport` describes the sensor event delivered from the event stream.
+union SensorReport {
+ 1: array<int16>:3 vector;
+ 2: uint16 scalar;
+};
+
+/// `MediaButtonsReport` describes the media buttons event delivered from the event stream.
+/// Each bool in the report represents a single button where true means the button
+/// is being pressed. A single report should be sent on every state change.
+struct MediaButtonsReport {
+ bool volume_up;
+ bool volume_down;
+ bool mic_mute;
+ bool reset;
+ bool pause;
+};
+
+// Device and Report
+
+struct DeviceInfo {
+ uint32 vendor_id;
+ uint32 product_id;
+ uint32 version;
+ string name;
+};
+
+// `DeviceDescriptor` describes one input device.
+struct DeviceDescriptor {
+ DeviceInfo? device_info;
+ KeyboardDescriptor? keyboard;
+ MediaButtonsDescriptor? media_buttons;
+ MouseDescriptor? mouse;
+ StylusDescriptor? stylus;
+ TouchscreenDescriptor? touchscreen;
+ SensorDescriptor? sensor;
+};
+
+// `InputReport` is an input `report` triggered by an input device.
+struct InputReport {
+ // `event_time` is in nanoseconds when the event was recorded.
+ uint64 event_time;
+
+ KeyboardReport? keyboard;
+ MediaButtonsReport? media_buttons;
+ MouseReport? mouse;
+ StylusReport? stylus;
+ TouchscreenReport? touchscreen;
+ SensorReport? sensor;
+
+ uint64 trace_id = 0; // Unique ID to connect trace async begin/end events.
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/meta.json
new file mode 100644
index 0000000..bca6f83
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/meta.json
@@ -0,0 +1,22 @@
+{
+ "deps": [
+ "fuchsia.ui.input2",
+ "fuchsia.ui.input3",
+ "fuchsia.ui.views"
+ ],
+ "name": "fuchsia.ui.input",
+ "root": "fidl/fuchsia.ui.input",
+ "sources": [
+ "fidl/fuchsia.ui.input/commands.fidl",
+ "fidl/fuchsia.ui.input/ime_service.fidl",
+ "fidl/fuchsia.ui.input/input_device_registry.fidl",
+ "fidl/fuchsia.ui.input/input_event_constants.fidl",
+ "fidl/fuchsia.ui.input/input_events.fidl",
+ "fidl/fuchsia.ui.input/input_reports.fidl",
+ "fidl/fuchsia.ui.input/pointer_capture.fidl",
+ "fidl/fuchsia.ui.input/text_editing.fidl",
+ "fidl/fuchsia.ui.input/text_input.fidl",
+ "fidl/fuchsia.ui.input/usages.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/pointer_capture.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/pointer_capture.fidl
new file mode 100644
index 0000000..6762cd3
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/pointer_capture.fidl
@@ -0,0 +1,21 @@
+// 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.
+
+library fuchsia.ui.input;
+
+using fuchsia.ui.views;
+
+/// A method of obtaining global pointer events, regardless of view focus.
+protocol PointerCaptureListener {
+ OnPointerEvent(PointerEvent event) -> ();
+};
+
+/// Injects a listener protocol, along with a ViewRef that defines the coordinate space of the
+/// captured pointer events.
+[Discoverable]
+protocol PointerCaptureListenerRegistry {
+ /// This protocol will be subsumed by gesture disambiguation.
+ [Transitional]
+ RegisterListener(PointerCaptureListener listener, fuchsia.ui.views.ViewRef view_ref) -> (bool success);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/text_editing.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/text_editing.fidl
new file mode 100644
index 0000000..86b9107
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/text_editing.fidl
@@ -0,0 +1,70 @@
+// Copyright 2017 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.
+
+library fuchsia.ui.input;
+
+/// Whether a TextPosition is visually upstream or downstream of its offset.
+///
+/// For example, when a text position exists at a line break, a single offset has
+/// two visual positions, one prior to the line break (at the end of the first
+/// line) and one after the line break (at the start of the second line). A text
+/// affinity disambiguates between those cases. (Something similar happens with
+/// between runs of bidirectional text.)
+enum TextAffinity {
+ /// The position has affinity for the upstream side of the text position.
+ ///
+ /// For example, if the offset of the text position is a line break, the
+ /// position represents the end of the first line.
+ UPSTREAM = 0;
+
+ /// The position has affinity for the downstream side of the text position.
+ ///
+ /// For example, if the offset of the text position is a line break, the
+ /// position represents the start of the second line.
+ DOWNSTREAM = 1;
+};
+
+/// A range of characters in a string of text. Although strings in FIDL's wire
+/// format are UTF-8 encoded, these indices are measured in UTF-16 code units
+/// for legacy reasons. These text input APIs will eventually be replaced by
+/// fuchsia.ui.text, which uses code points instead.
+struct TextRange {
+ /// The index of the first UTF-16 code unit in the range.
+ ///
+ /// If `start` and `end` are both -1, the text range is empty.
+ int64 start = -1;
+
+ /// The next index after the last UTF-16 code unit in this range.
+ ///
+ /// If `start` and `end` are both -1, the text range is empty.
+ int64 end = -1;
+};
+
+/// A range of text that represents a selection. Although strings in FIDL's wire
+/// format are UTF-8 encoded, these indices are measured in UTF-16 code units
+/// for legacy reasons. These text input APIs will eventually be replaced by
+/// fuchsia.ui.text, which uses code points instead.
+///
+/// Text selection is always directional. Direction should be determined by
+/// comparing base and extent.
+struct TextSelection {
+ /// The offset at which the selection originates, as measured in UTF-16 code units.
+ ///
+ /// Might be larger than, smaller than, or equal to extent.
+ int64 base;
+
+ /// The offset at which the selection terminates, as measured in UTF-16 code units.
+ ///
+ /// When the user uses the arrow keys to adjust the selection, this is the
+ /// value that changes. Similarly, if the current theme paints a caret on one
+ /// side of the selection, this is the location at which to paint the caret.
+ ///
+ /// Might be larger than, smaller than, or equal to base.
+ int64 extent;
+
+ /// If the text range is collapsed and has more than one visual location
+ /// (e.g., occurs at a line break), which of the two locations to use when
+ /// painting the caret.
+ TextAffinity affinity;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/text_input.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/text_input.fidl
new file mode 100644
index 0000000..f6d854e
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/text_input.fidl
@@ -0,0 +1,56 @@
+// Copyright 2017 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.
+
+library fuchsia.ui.input;
+
+enum KeyboardType {
+ TEXT = 0;
+ NUMBER = 1;
+ PHONE = 2;
+ DATETIME = 3;
+};
+
+enum InputMethodAction {
+ UNSPECIFIED = 0;
+ NONE = 1;
+ GO = 2;
+ SEARCH = 3;
+ SEND = 4;
+ NEXT = 5;
+ DONE = 6;
+ PREVIOUS = 7;
+};
+
+/// The current text, selection, and composing state for editing a run of text.
+struct TextInputState {
+ /// Current state revision to avoid race conditions.
+ uint32 revision;
+
+ /// The current text being edited.
+ string text;
+
+ /// The range of text that is currently selected.
+ TextSelection selection;
+
+ /// The range of text that is still being composed.
+ TextRange composing;
+};
+
+/// A interface for interacting with a text input control.
+protocol InputMethodEditor {
+ SetKeyboardType(KeyboardType keyboard_type);
+ SetState(TextInputState state);
+ InjectInput(InputEvent event);
+
+ // TODO(TEXT-19): remove these in a later change, after PlatformView has been
+ // switched over to open/close on the input_connection_ instead.
+ Show();
+ Hide();
+};
+
+/// An interface to receive information from `TextInputService`.
+protocol InputMethodEditorClient {
+ DidUpdateState(TextInputState state, InputEvent? event);
+ OnAction(InputMethodAction action);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/usages.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/usages.fidl
new file mode 100644
index 0000000..59ee251
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input/usages.fidl
@@ -0,0 +1,20 @@
+// Copyright 2017 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.
+
+library fuchsia.ui.input;
+
+/// Common mouse buttons report constants
+const uint32 kMouseButtonPrimary = 1;
+const uint32 kMouseButtonSecondary = 2;
+const uint32 kMouseButtonTertiary = 4;
+
+/// Common stylus buttons report constants
+const uint32 kStylusBarrel = 1;
+
+/// Used as mask bits (2^N) against ButtonDescriptor.buttons.
+const uint32 kVolumeUp = 1;
+const uint32 kVolumeDown = 2;
+const uint32 kMicMute = 4;
+const uint32 kReset = 8;
+const uint32 kPause = 16;
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.input2/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input2/BUILD.gn
new file mode 100644
index 0000000..ecc7813
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input2/BUILD.gn
@@ -0,0 +1,31 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.ui.input2") {
+ library_name = "input2"
+ namespace = "fuchsia.ui"
+ public_deps = [
+ "../fuchsia.ui.views",
+ ]
+ sources = [
+ "events.fidl",
+ "keyboard.fidl",
+ "keys.fidl",
+ "layout.fidl",
+ "modifiers.fidl",
+ "semantic_keys.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.ui.input2",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.input2/events.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input2/events.fidl
new file mode 100644
index 0000000..ffe1e03
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input2/events.fidl
@@ -0,0 +1,86 @@
+// 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.
+
+library fuchsia.ui.input2;
+
+/// Phase of the keyboard key input.
+enum KeyEventPhase {
+ /// Key is pressed down.
+ PRESSED = 0;
+
+ /// Key is released.
+ RELEASED = 1;
+};
+
+/// Semantic for a physical key typed by the user.
+/// For letter or symbolic keys, is a string representation of the key typed.
+/// For non-symbolic keys, is a SemanticKeyAction value corresponding to the key pressed.
+///
+/// Examples:
+/// Key.A:
+/// "a" or "A" in US key layout, depending on CapsLock and Shift
+/// Key.SPACE:
+/// " "
+/// Key.TAB:
+/// SemanticKeyAction.TAB
+/// Key.GRAVE_ACCENT:
+/// "`" or "]" or "<", depending on key layout
+flexible union SemanticKey {
+ /// For symbolic keys: string representing character typed.
+ 1: string:16 symbol;
+
+ /// For non-symbolic keys: meaning of the key pressed.
+ 2: SemanticKeyAction action;
+};
+
+/// Direct key mapping from hardware code (USB HID).
+///
+/// Example:
+/// Key.Q for USB HID page 0x0007 usage 0x0014
+using PhysicalKey = Key;
+
+/// Keyboard event is generated to reflect key input.
+table KeyEvent {
+ /// The key that was pressed or released, taking the keyboard layout into account.
+ ///
+ /// Use this value for the following purposes:
+ /// - interpreting keyboard shortcuts such as CTRL+C
+ ///
+ /// The input system derives this value from `physical_key` by consulting the
+ /// physical key map of the `KeyboardLayout` that was active for the keyboard when
+ /// when the key was pressed. Note that the same value will be reported when
+ /// the key is released even if the keyboard layout changes in the interim between press
+ /// and release.
+ 1: Key key;
+
+ /// Phase of input.
+ 2: KeyEventPhase phase;
+
+ /// Modifier keys being held.
+ 3: Modifiers modifiers;
+
+ /// The semantic meaning of the key that was pressed or released, taking the keyboard
+ /// layout and modifiers into account.
+ ///
+ /// Use this value for the following purposes:
+ /// - typing text when implementing an input method editor (IME) or when IME services
+ /// are not available (this won’t work for languages that require composition)
+ ///
+ /// The input system derives this value from the combination of `physical_key` and
+ /// `modifiers` by consulting the key symbol map of `KeyboardLayout` that was active
+ /// for the keyboard when the key was pressed. Note that the same value will be reported
+ /// when the key is released even if the keyboard layout or modifiers change in the
+ /// interim between press and release.
+ 4: SemanticKey semantic_key;
+
+ /// Identifies the physical key, ignoring modifiers and layout.
+ ///
+ /// Use this value for the following purposes:
+ /// - applying keyboard layout translations
+ /// - synthesizing input events into virtual machines, since VMs will do own layout mapping
+ ///
+ /// The input system derives this value from the data reported by the keyboard itself
+ /// without taking into account the keyboard’s current `KeyboardLayout` or modifiers.
+ 5: PhysicalKey physical_key;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.input2/keyboard.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input2/keyboard.fidl
new file mode 100644
index 0000000..2242315
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input2/keyboard.fidl
@@ -0,0 +1,31 @@
+// 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.
+
+library fuchsia.ui.input2;
+
+using fuchsia.ui.views;
+
+/// Components may request this service from their namespace to
+/// be notified of physical key events.
+[Discoverable]
+protocol Keyboard {
+ /// Set key event listener for the specified View.
+ SetListener(fuchsia.ui.views.ViewRef view_ref, KeyListener listener) -> ();
+};
+
+/// Client should implement this protocol to get notified of key events.
+/// Returning HANDLED will stop event propagation to other clients.
+/// This notification is triggered on the following conditions:
+/// 1. Component is focused (ViewRef is on FocusChain)
+/// 2. Parent Views get the event first, child views last
+/// 3. Client returning HANDLED stops the propagation to subsequent clients
+protocol KeyListener {
+ OnKeyEvent(KeyEvent event) -> (Status result);
+};
+
+/// Return type for clients key events listener.
+enum Status {
+ HANDLED = 1;
+ NOT_HANDLED = 2;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.input2/keys.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input2/keys.fidl
new file mode 100644
index 0000000..863cb35
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input2/keys.fidl
@@ -0,0 +1,796 @@
+// 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.
+
+library fuchsia.ui.input2;
+
+/// A Fuchsia key represents a control that can be pressed or released
+/// such as a button on a keyboard.
+///
+/// Where applicable, the definition of each key is derived from one of the
+/// following sources albeit with a Fuchsia-specific numeric value:
+/// - USB HID usage codes for usage page 0x0007 (Keyboard/Keypad)
+/// - USB HID usage codes for usage page 0x000c (Consumer)
+/// - Common but non-standard keys (vendor defined)
+///
+/// The example key mappings included in this documentation assume a
+/// US English keyboard layout. Actual behavior varies by layout.
+enum Key : uint32 {
+ // Keyboard keys
+ // Reserved range: 0x00000001 - 0x000001ff
+
+ /// Keyboard a and A
+ /// Corresponds to USB HID page 0x0007 usage 0x0004
+ A = 0x00000001;
+
+ /// Keyboard b and B
+ /// Corresponds to USB HID page 0x0007 usage 0x0005
+ B = 0x00000002;
+
+ /// Keyboard c and C
+ /// Corresponds to USB HID page 0x0007 usage 0x0006
+ C = 0x00000003;
+
+ /// Keyboard d and D
+ /// Corresponds to USB HID page 0x0007 usage 0x0007
+ D = 0x00000004;
+
+ /// Keyboard e and E
+ /// Corresponds to USB HID page 0x0007 usage 0x0008
+ E = 0x00000005;
+
+ /// Keyboard f and F
+ /// Corresponds to USB HID page 0x0007 usage 0x0009
+ F = 0x00000006;
+
+ /// Keyboard g and G
+ /// Corresponds to USB HID page 0x0007 usage 0x000a
+ G = 0x00000007;
+
+ /// Keyboard h and H
+ /// Corresponds to USB HID page 0x0007 usage 0x000b
+ H = 0x00000008;
+
+ /// Keyboard i and I
+ /// Corresponds to USB HID page 0x0007 usage 0x000c
+ I = 0x00000009;
+
+ /// Keyboard j and J
+ /// Corresponds to USB HID page 0x0007 usage 0x000d
+ J = 0x0000000a;
+
+ /// Keyboard k and K
+ /// Corresponds to USB HID page 0x0007 usage 0x000e
+ K = 0x0000000b;
+
+ /// Keyboard l and L
+ /// Corresponds to USB HID page 0x0007 usage 0x000f
+ L = 0x0000000c;
+
+ /// Keyboard m and M
+ /// Corresponds to USB HID page 0x0007 usage 0x0010
+ M = 0x0000000d;
+
+ /// Keyboard n and N
+ /// Corresponds to USB HID page 0x0007 usage 0x0011
+ N = 0x0000000e;
+
+ /// Keyboard o and O
+ /// Corresponds to USB HID page 0x0007 usage 0x0012
+ O = 0x0000000f;
+
+ /// Keyboard p and P
+ /// Corresponds to USB HID page 0x0007 usage 0x0013
+ P = 0x00000010;
+
+ /// Keyboard q and Q
+ /// Corresponds to USB HID page 0x0007 usage 0x0014
+ Q = 0x00000011;
+
+ /// Keyboard r and R
+ /// Corresponds to USB HID page 0x0007 usage 0x0015
+ R = 0x00000012;
+
+ /// Keyboard s and S
+ /// Corresponds to USB HID page 0x0007 usage 0x0016
+ S = 0x00000013;
+
+ /// Keyboard t and T
+ /// Corresponds to USB HID page 0x0007 usage 0x0017
+ T = 0x00000014;
+
+ /// Keyboard u and U
+ /// Corresponds to USB HID page 0x0007 usage 0x0018
+ U = 0x00000015;
+
+ /// Keyboard v and V
+ /// Corresponds to USB HID page 0x0007 usage 0x0019
+ V = 0x00000016;
+
+ /// Keyboard w and W
+ /// Corresponds to USB HID page 0x0007 usage 0x001a
+ W = 0x00000017;
+
+ /// Keyboard x and X
+ /// Corresponds to USB HID page 0x0007 usage 0x001b
+ X = 0x00000018;
+
+ /// Keyboard y and Y
+ /// Corresponds to USB HID page 0x0007 usage 0x001c
+ Y = 0x00000019;
+
+ /// Keyboard z and Z
+ /// Corresponds to USB HID page 0x0007 usage 0x001d
+ Z = 0x0000001a;
+
+ /// Keyboard 1 and !
+ /// Corresponds to USB HID page 0x0007 usage 0x001e
+ KEY_1 = 0x0000001b;
+
+ /// Keyboard 2 and @
+ /// Corresponds to USB HID page 0x0007 usage 0x001f
+ KEY_2 = 0x0000001c;
+
+ /// Keyboard 3 and #
+ /// Corresponds to USB HID page 0x0007 usage 0x0020
+ KEY_3 = 0x0000001d;
+
+ /// Keyboard 4 and $
+ /// Corresponds to USB HID page 0x0007 usage 0x0021
+ KEY_4 = 0x0000001e;
+
+ /// Keyboard 5 and %
+ /// Corresponds to USB HID page 0x0007 usage 0x0022
+ KEY_5 = 0x0000001f;
+
+ /// Keyboard 6 and ^
+ /// Corresponds to USB HID page 0x0007 usage 0x0023
+ KEY_6 = 0x00000020;
+
+ /// Keyboard 7 and &
+ /// Corresponds to USB HID page 0x0007 usage 0x0024
+ KEY_7 = 0x00000021;
+
+ /// Keyboard 8 and *
+ /// Corresponds to USB HID page 0x0007 usage 0x0025
+ KEY_8 = 0x00000022;
+
+ /// Keyboard 9 and (
+ /// Corresponds to USB HID page 0x0007 usage 0x0026
+ KEY_9 = 0x00000023;
+
+ /// Keyboard 0 and )
+ /// Corresponds to USB HID page 0x0007 usage 0x0027
+ KEY_0 = 0x00000024;
+
+ /// Keyboard Enter (Return)
+ /// Corresponds to USB HID page 0x0007 usage 0x0028
+ ENTER = 0x00000025;
+
+ /// Keyboard Escape
+ /// Corresponds to USB HID page 0x0007 usage 0x0029
+ ESCAPE = 0x00000026;
+
+ /// Keyboard Backspace (Backward Delete)
+ /// Corresponds to USB HID page 0x0007 usage 0x002a
+ BACKSPACE = 0x00000027;
+
+ /// Keyboard Tab
+ /// Corresponds to USB HID page 0x0007 usage 0x002b
+ TAB = 0x00000028;
+
+ /// Keyboard Spacebar
+ /// Corresponds to USB HID page 0x0007 usage 0x002c
+ SPACE = 0x00000029;
+
+ /// Keyboard - and (underscore)
+ /// Corresponds to USB HID page 0x0007 usage 0x002d
+ MINUS = 0x0000002a;
+
+ /// Keyboard = and +
+ /// Corresponds to USB HID page 0x0007 usage 0x002e
+ EQUALS = 0x0000002b;
+
+ /// Keyboard [ and {
+ /// Corresponds to USB HID page 0x0007 usage 0x002f
+ LEFT_BRACE = 0x0000002c;
+
+ /// Keyboard ] and }
+ /// Corresponds to USB HID page 0x0007 usage 0x0030
+ RIGHT_BRACE = 0x0000002d;
+
+ /// Keyboard \ and |
+ /// Corresponds to USB HID page 0x0007 usage 0x0031
+ BACKSLASH = 0x0000002e;
+
+ /// Keyboard Non-US # and ~
+ /// Corresponds to USB HID page 0x0007 usage 0x0032
+ NON_US_HASH = 0x0000002f;
+
+ /// Keyboard ; and :
+ /// Corresponds to USB HID page 0x0007 usage 0x0033
+ SEMICOLON = 0x00000030;
+
+ /// Keyboard ' and "
+ /// Corresponds to USB HID page 0x0007 usage 0x0034
+ APOSTROPHE = 0x00000031;
+
+ /// Keyboard Grave Accent and Tilde
+ /// Corresponds to USB HID page 0x0007 usage 0x0035
+ GRAVE_ACCENT = 0x00000032;
+
+ /// Keyboard , and <
+ /// Corresponds to USB HID page 0x0007 usage 0x0036
+ COMMA = 0x00000033;
+
+ /// Keyboard . and >
+ /// Corresponds to USB HID page 0x0007 usage 0x0037
+ DOT = 0x00000034;
+
+ /// Keyboard / and ?
+ /// Corresponds to USB HID page 0x0007 usage 0x0038
+ SLASH = 0x00000035;
+
+ /// Keyboard Caps Lock
+ /// Corresponds to USB HID page 0x0007 usage 0x0039
+ CAPS_LOCK = 0x00000036;
+
+ /// Keyboard F1
+ /// Corresponds to USB HID page 0x0007 usage 0x003a
+ F1 = 0x00000037;
+
+ /// Keyboard F2
+ /// Corresponds to USB HID page 0x0007 usage 0x003b
+ F2 = 0x00000038;
+
+ /// Keyboard F3
+ /// Corresponds to USB HID page 0x0007 usage 0x003c
+ F3 = 0x00000039;
+
+ /// Keyboard F4
+ /// Corresponds to USB HID page 0x0007 usage 0x003d
+ F4 = 0x0000003a;
+
+ /// Keyboard F5
+ /// Corresponds to USB HID page 0x0007 usage 0x003e
+ F5 = 0x0000003b;
+
+ /// Keyboard F6
+ /// Corresponds to USB HID page 0x0007 usage 0x003f
+ F6 = 0x0000003c;
+
+ /// Keyboard F7
+ /// Corresponds to USB HID page 0x0007 usage 0x0040
+ F7 = 0x0000003d;
+
+ /// Keyboard F8
+ /// Corresponds to USB HID page 0x0007 usage 0x0041
+ F8 = 0x0000003e;
+
+ /// Keyboard F9
+ /// Corresponds to USB HID page 0x0007 usage 0x0042
+ F9 = 0x0000003f;
+
+ /// Keyboard F10
+ /// Corresponds to USB HID page 0x0007 usage 0x0043
+ F10 = 0x00000040;
+
+ /// Keyboard F11
+ /// Corresponds to USB HID page 0x0007 usage 0x0044
+ F11 = 0x00000041;
+
+ /// Keyboard F12
+ /// Corresponds to USB HID page 0x0007 usage 0x0045
+ F12 = 0x00000042;
+
+ /// Keyboard Print Screen
+ /// Corresponds to USB HID page 0x0007 usage 0x0046
+ PRINT_SCREEN = 0x00000043;
+
+ /// Keyboard Scroll Lock
+ /// Corresponds to USB HID page 0x0007 usage 0x0047
+ SCROLL_LOCK = 0x00000044;
+
+ /// Keyboard Pause
+ /// Corresponds to USB HID page 0x0007 usage 0x0048
+ PAUSE = 0x00000045;
+
+ /// Keyboard Insert
+ /// Corresponds to USB HID page 0x0007 usage 0x0049
+ INSERT = 0x00000046;
+
+ /// Keyboard Home
+ /// Corresponds to USB HID page 0x0007 usage 0x004a
+ HOME = 0x00000047;
+
+ /// Keyboard Page Up
+ /// Corresponds to USB HID page 0x0007 usage 0x004b
+ PAGE_UP = 0x00000048;
+
+ /// Keyboard Forward Delete
+ /// Corresponds to USB HID page 0x0007 usage 0x004c
+ DELETE = 0x00000049;
+
+ /// Keyboard End
+ /// Corresponds to USB HID page 0x0007 usage 0x004d
+ END = 0x0000004a;
+
+ /// Keyboard Page Down
+ /// Corresponds to USB HID page 0x0007 usage 0x004e
+ PAGE_DOWN = 0x0000004b;
+
+ /// Keyboard Right Arrow
+ /// Corresponds to USB HID page 0x0007 usage 0x004f
+ RIGHT = 0x0000004c;
+
+ /// Keyboard Left Arrow
+ /// Corresponds to USB HID page 0x0007 usage 0x0050
+ LEFT = 0x0000004d;
+
+ /// Keyboard Down Arrow
+ /// Corresponds to USB HID page 0x0007 usage 0x0051
+ DOWN = 0x0000004e;
+
+ /// Keyboard Up Arrow
+ /// Corresponds to USB HID page 0x0007 usage 0x0052
+ UP = 0x0000004f;
+
+ /// Keyboard Non-US \ and |
+ /// Corresponds to USB HID page 0x0007 usage 0x0064
+ NON_US_BACKSLASH = 0x00000050;
+
+ /// Keyboard Left Control
+ /// Corresponds to USB HID page 0x0007 usage 0x00e0
+ LEFT_CTRL = 0x00000051;
+
+ /// Keyboard Left Shift
+ /// Corresponds to USB HID page 0x0007 usage 0x00e1
+ LEFT_SHIFT = 0x00000052;
+
+ /// Keyboard Left Alt
+ /// Corresponds to USB HID page 0x0007 usage 0x00e2
+ LEFT_ALT = 0x00000053;
+
+ /// Keyboard Left GUI (Meta, Windows)
+ /// Corresponds to USB HID page 0x0007 usage 0x00e3
+ LEFT_META = 0x00000054;
+
+ /// Keyboard Right Control
+ /// Corresponds to USB HID page 0x0007 usage 0x00e4
+ RIGHT_CTRL = 0x00000055;
+
+ /// Keyboard Right Shift
+ /// Corresponds to USB HID page 0x0007 usage 0x00e5
+ RIGHT_SHIFT = 0x00000056;
+
+ /// Keyboard Right Alt
+ /// Corresponds to USB HID page 0x0007 usage 0x00e6
+ RIGHT_ALT = 0x00000057;
+
+ /// Keyboard Right GUI (Meta, Windows)
+ /// Corresponds to USB HID page 0x0007 usage 0x00e7
+ RIGHT_META = 0x00000058;
+
+ /// Keyboard Menu
+ /// Corresponds to USB HID page 0x0007 usage 0x0076
+ MENU = 0x00000059;
+
+ // Keypad keys
+ // Reserved range: 0x00000200 - 0x000002ff
+
+ /// Keypad Num Lock and Clear
+ /// Corresponds to USB HID page 0x0007 usage 0x0053
+ NUM_LOCK = 0x00000200;
+
+ /// Keypad /
+ /// Corresponds to USB HID page 0x0007 usage 0x0054
+ KEYPAD_SLASH = 0x00000201;
+
+ /// Keypad *
+ /// Corresponds to USB HID page 0x0007 usage 0x0055
+ KEYPAD_ASTERISK = 0x00000202;
+
+ /// Keypad -
+ /// Corresponds to USB HID page 0x0007 usage 0x0056
+ KEYPAD_MINUS = 0x00000203;
+
+ /// Keypad +
+ /// Corresponds to USB HID page 0x0007 usage 0x0057
+ KEYPAD_PLUS = 0x00000204;
+
+ /// Keypad ENTER
+ /// Corresponds to USB HID page 0x0007 usage 0x0058
+ KEYPAD_ENTER = 0x00000205;
+
+ /// Keypad 1 and End
+ /// Corresponds to USB HID page 0x0007 usage 0x0059
+ KEYPAD_1 = 0x00000206;
+
+ /// Keypad 2 and Down Arrow
+ /// Corresponds to USB HID page 0x0007 usage 0x005a
+ KEYPAD_2 = 0x00000207;
+
+ /// Keypad 3 and Page Down
+ /// Corresponds to USB HID page 0x0007 usage 0x005b
+ KEYPAD_3 = 0x00000208;
+
+ /// Keypad 4 and Left Arrow
+ /// Corresponds to USB HID page 0x0007 usage 0x005c
+ KEYPAD_4 = 0x00000209;
+
+ /// Keypad 5
+ /// Corresponds to USB HID page 0x0007 usage 0x005d
+ KEYPAD_5 = 0x0000020A;
+
+ /// Keypad 6 and Right Arrow
+ /// Corresponds to USB HID page 0x0007 usage 0x005e
+ KEYPAD_6 = 0x0000020B;
+
+ /// Keypad 7 and Home
+ /// Corresponds to USB HID page 0x0007 usage 0x005f
+ KEYPAD_7 = 0x0000020C;
+
+ /// Keypad 8 and Up Arrow
+ /// Corresponds to USB HID page 0x0007 usage 0x0060
+ KEYPAD_8 = 0x0000020D;
+
+ /// Keypad 9 and Page Up
+ /// Corresponds to USB HID page 0x0007 usage 0x0061
+ KEYPAD_9 = 0x0000020E;
+
+ /// Keypad 0 and Insert
+ /// Corresponds to USB HID page 0x0007 usage 0x0062
+ KEYPAD_0 = 0x0000020F;
+
+ /// Keypad . and Delete
+ /// Corresponds to USB HID page 0x0007 usage 0x0063
+ KEYPAD_DOT = 0x00000210;
+
+ // Keypad =
+ // Corresponds to USB HID page 0x0007 usage 0x0067
+ KEYPAD_EQUALS = 0x00000211;
+
+ // Media keys
+ // Reserved range: 0x00000300 - 0x000004ff
+
+ // Mute
+ // Corresponds to USB HID page 0x000c usage 0x00e2
+ MEDIA_MUTE = 0x00000300;
+
+ // Volume Increment
+ // Corresponds to USB HID page 0x000c usage 0x00e9
+ MEDIA_VOLUME_INCREMENT = 0x00000301;
+
+ // Volume Decrement
+ // Corresponds to USB HID page 0x000c usage 0x00ea
+ MEDIA_VOLUME_DECREMENT = 0x00000302;
+
+ // Next available range: 0x00000500
+
+ // TODO: Define additional USB HID keys as needed.
+ //
+ // Keyboard Application
+ // Corresponds to USB HID page 0x0007 usage 0x0065
+ //
+ // Keyboard Power (Not a physical key)
+ // Corresponds to USB HID page 0x0007 usage 0x0066
+ // Note: Reserved for typical keyboard status or keyboard errors.
+ // Sent as a member of the keyboard array.
+ //
+ // Keyboard F13
+ // Corresponds to USB HID page 0x0007 usage 0x0068
+ //
+ // Keyboard F14
+ // Corresponds to USB HID page 0x0007 usage 0x0069
+ //
+ // Keyboard F15
+ // Corresponds to USB HID page 0x0007 usage 0x006a
+ //
+ // Keyboard F16
+ // Corresponds to USB HID page 0x0007 usage 0x006b
+ //
+ // Keyboard F17
+ // Corresponds to USB HID page 0x0007 usage 0x006c
+ //
+ // Keyboard F18
+ // Corresponds to USB HID page 0x0007 usage 0x006d
+ //
+ // Keyboard F19
+ // Corresponds to USB HID page 0x0007 usage 0x006e
+ //
+ // Keyboard F20
+ // Corresponds to USB HID page 0x0007 usage 0x006f
+ //
+ // Keyboard F21
+ // Corresponds to USB HID page 0x0007 usage 0x0070
+ //
+ // Keyboard F22
+ // Corresponds to USB HID page 0x0007 usage 0x0071
+ //
+ // Keyboard F23
+ // Corresponds to USB HID page 0x0007 usage 0x0072
+ //
+ // Keyboard F24
+ // Corresponds to USB HID page 0x0007 usage 0x0073
+ //
+ // Keyboard Execute
+ // Corresponds to USB HID page 0x0007 usage 0x0074
+ //
+ // Keyboard Help
+ // Corresponds to USB HID page 0x0007 usage 0x0075
+ //
+ // Keyboard Select
+ // Corresponds to USB HID page 0x0007 usage 0x0077
+ //
+ // Keyboard Stop
+ // Corresponds to USB HID page 0x0007 usage 0x0078
+ //
+ // Keyboard Again
+ // Corresponds to USB HID page 0x0007 usage 0x0079
+ //
+ // Keyboard Undo
+ // Corresponds to USB HID page 0x0007 usage 0x007a
+ //
+ // Keyboard Cut
+ // Corresponds to USB HID page 0x0007 usage 0x007b
+ //
+ // Keyboard Copy
+ // Corresponds to USB HID page 0x0007 usage 0x007c
+ //
+ // Keyboard Paste
+ // Corresponds to USB HID page 0x0007 usage 0x007d
+ //
+ // Keyboard Find
+ // Corresponds to USB HID page 0x0007 usage 0x007e
+ //
+ // Keyboard Volume Down
+ // Corresponds to USB HID page 0x0007 usage 0x0081
+ //
+ // Keyboard Volume Up
+ // Corresponds to USB HID page 0x0007 usage 0x0080
+ //
+ // Keyboard Locking Caps Lock
+ // Corresponds to USB HID page 0x0007 usage 0x0082
+ //
+ // Keyboard Locking Num Lock
+ // Corresponds to USB HID page 0x0007 usage 0x0083
+ //
+ // Keyboard Locking Scroll Lock
+ // Corresponds to USB HID page 0x0007 usage 0x0084
+ //
+ // Keypad Comma
+ // Corresponds to USB HID page 0x0007 usage 0x0085
+ //
+ // Keypad Equal Sign
+ // Corresponds to USB HID page 0x0007 usage 0x0086
+ //
+ // Keyboard International1
+ // Corresponds to USB HID page 0x0007 usage 0x0087
+ //
+ // Keyboard International2
+ // Corresponds to USB HID page 0x0007 usage 0x0088
+ //
+ // Keyboard International3
+ // Corresponds to USB HID page 0x0007 usage 0x0089
+ //
+ // Keyboard International4
+ // Corresponds to USB HID page 0x0007 usage 0x008a
+ //
+ // Keyboard International5
+ // Corresponds to USB HID page 0x0007 usage 0x008b
+ //
+ // Keyboard International6
+ // Corresponds to USB HID page 0x0007 usage 0x008c
+ //
+ // Keyboard International7
+ // Corresponds to USB HID page 0x0007 usage 0x008d
+ //
+ // Keyboard International8
+ // Corresponds to USB HID page 0x0007 usage 0x008e
+ //
+ // Keyboard International9
+ // Corresponds to USB HID page 0x0007 usage 0x008f
+ //
+ // Keyboard LANG1
+ // Corresponds to USB HID page 0x0007 usage 0x0090
+ //
+ // Keyboard LANG2
+ // Corresponds to USB HID page 0x0007 usage 0x0091
+ //
+ // Keyboard LANG3
+ // Corresponds to USB HID page 0x0007 usage 0x0092
+ //
+ // Keyboard LANG4
+ // Corresponds to USB HID page 0x0007 usage 0x0093
+ //
+ // Keyboard LANG5
+ // Corresponds to USB HID page 0x0007 usage 0x0094
+ //
+ // Keyboard LANG6
+ // Corresponds to USB HID page 0x0007 usage 0x0095
+ //
+ // Keyboard LANG7
+ // Corresponds to USB HID page 0x0007 usage 0x0096
+ //
+ // Keyboard LANG8
+ // Corresponds to USB HID page 0x0007 usage 0x0097
+ //
+ // Keyboard LANG9
+ // Corresponds to USB HID page 0x0007 usage 0x0098
+ //
+ // Keyboard Alternate Erase
+ // Corresponds to USB HID page 0x0007 usage 0x0099
+ //
+ // Keyboard SysReq/Attention
+ // Corresponds to USB HID page 0x0007 usage 0x009a
+ //
+ // Keyboard Cancel
+ // Corresponds to USB HID page 0x0007 usage 0x009b
+ //
+ // Keyboard Clear
+ // Corresponds to USB HID page 0x0007 usage 0x009c
+ //
+ // Keyboard Prior
+ // Corresponds to USB HID page 0x0007 usage 0x009d
+ //
+ // Keyboard Return
+ // Corresponds to USB HID page 0x0007 usage 0x009e
+ //
+ // Keyboard Separator
+ // Corresponds to USB HID page 0x0007 usage 0x009f
+ //
+ // Keyboard Out
+ // Corresponds to USB HID page 0x0007 usage 0x00a0
+ //
+ // Keyboard Oper
+ // Corresponds to USB HID page 0x0007 usage 0x00a1
+ //
+ // Keyboard Clear/Again
+ // Corresponds to USB HID page 0x0007 usage 0x00a2
+ //
+ // Keyboard CrSel/Props
+ // Corresponds to USB HID page 0x0007 usage 0x00a3
+ //
+ // Keyboard ExSel
+ // Corresponds to USB HID page 0x0007 usage 0x00a4
+ //
+ // Note: USB HID usage page 0x0007 reserves codes 0x00a5 - 0x00af
+ //
+ // Keypad 00
+ // Corresponds to USB HID page 0x0007 usage 0x00b0
+ //
+ // Keypad 000
+ // Corresponds to USB HID page 0x0007 usage 0x00b1
+ //
+ // Thousands Separator
+ // Corresponds to USB HID page 0x0007 usage 0x00b2
+ //
+ // Decimal Separator
+ // Corresponds to USB HID page 0x0007 usage 0x00b3
+ //
+ // Currency Unit
+ // Corresponds to USB HID page 0x0007 usage 0x00b4
+ //
+ // Currency Sub-unit
+ // Corresponds to USB HID page 0x0007 usage 0x00b5
+ //
+ // Keypad (
+ // Corresponds to USB HID page 0x0007 usage 0x00b6
+ //
+ // Keypad )
+ // Corresponds to USB HID page 0x0007 usage 0x00b7
+ //
+ // Keypad {
+ // Corresponds to USB HID page 0x0007 usage 0x00b8
+ //
+ // Keypad }
+ // Corresponds to USB HID page 0x0007 usage 0x00b9
+ //
+ // Keypad Tab
+ // Corresponds to USB HID page 0x0007 usage 0x00ba
+ //
+ // Keypad Backspace
+ // Corresponds to USB HID page 0x0007 usage 0x00bb
+ //
+ // Keypad A
+ // Corresponds to USB HID page 0x0007 usage 0x00bc
+ //
+ // Keypad B
+ // Corresponds to USB HID page 0x0007 usage 0x00bd
+ //
+ // Keypad C
+ // Corresponds to USB HID page 0x0007 usage 0x00be
+ //
+ // Keypad D
+ // Corresponds to USB HID page 0x0007 usage 0x00bf
+ //
+ // Keypad E
+ // Corresponds to USB HID page 0x0007 usage 0x00c0
+ //
+ // Keypad F
+ // Corresponds to USB HID page 0x0007 usage 0x00c1
+ //
+ // Keypad XOR
+ // Corresponds to USB HID page 0x0007 usage 0x00c2
+ //
+ // Keypad ^
+ // Corresponds to USB HID page 0x0007 usage 0x00c3
+ //
+ // Keypad %
+ // Corresponds to USB HID page 0x0007 usage 0x00c4
+ //
+ // Keypad <
+ // Corresponds to USB HID page 0x0007 usage 0x00c5
+ //
+ // Keypad >
+ // Corresponds to USB HID page 0x0007 usage 0x00c6
+ //
+ // Keypad &
+ // Corresponds to USB HID page 0x0007 usage 0x00c7
+ //
+ // Keypad &&
+ // Corresponds to USB HID page 0x0007 usage 0x00c8
+ //
+ // Keypad |
+ // Corresponds to USB HID page 0x0007 usage 0x00c9
+ //
+ // Keypad ||
+ // Corresponds to USB HID page 0x0007 usage 0x00ca
+ //
+ // Keypad :
+ // Corresponds to USB HID page 0x0007 usage 0x00cb
+ //
+ // Keypad #
+ // Corresponds to USB HID page 0x0007 usage 0x00cc
+ //
+ // Keypad Space
+ // Corresponds to USB HID page 0x0007 usage 0x00cd
+ //
+ // Keypad @
+ // Corresponds to USB HID page 0x0007 usage 0x00ce
+ //
+ // Keypad !
+ // Corresponds to USB HID page 0x0007 usage 0x00cf
+ //
+ // Keypad Memory Store
+ // Corresponds to USB HID page 0x0007 usage 0x00d0
+ //
+ // Keypad Memory Recall
+ // Corresponds to USB HID page 0x0007 usage 0x00d1
+ //
+ // Keypad Memory Clear
+ // Corresponds to USB HID page 0x0007 usage 0x00d2
+ //
+ // Keypad Memory Add
+ // Corresponds to USB HID page 0x0007 usage 0x00d3
+ //
+ // Keypad Memory Subtract
+ // Corresponds to USB HID page 0x0007 usage 0x00d4
+ //
+ // Keypad Memory Multiply
+ // Corresponds to USB HID page 0x0007 usage 0x00d5
+ //
+ // Keypad Memory Divide
+ // Corresponds to USB HID page 0x0007 usage 0x00d6
+ //
+ // Keypad +/-
+ // Corresponds to USB HID page 0x0007 usage 0x00d7
+ //
+ // Keypad Clear
+ // Corresponds to USB HID page 0x0007 usage 0x00d8
+ //
+ // Keypad Clear Entry
+ // Corresponds to USB HID page 0x0007 usage 0x00d9
+ //
+ // Keypad Binary
+ // Corresponds to USB HID page 0x0007 usage 0x00da
+ //
+ // Keypad Octal
+ // Corresponds to USB HID page 0x0007 usage 0x00db
+ //
+ // Keypad Decimal
+ // Corresponds to USB HID page 0x0007 usage 0x00dc
+ //
+ // Keypad Hexadecimal
+ // Corresponds to USB HID page 0x0007 usage 0x00dd
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.input2/layout.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input2/layout.fidl
new file mode 100644
index 0000000..5fc474e
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input2/layout.fidl
@@ -0,0 +1,103 @@
+// 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.
+
+library fuchsia.ui.input2;
+
+const uint64 MAX_ENTRIES_PER_MAP = 1024;
+const uint64 MAX_MAPS_PER_LAYOUT = 64;
+
+/// Input method editors should implement this protocol to populate
+/// `KeyEvent.symbol` field based on current key layout.
+[Discoverable]
+protocol KeyboardLayoutState {
+ /// Get current key layout. Returns immediately on first call;
+ /// subsequent calls return when the value changes.
+ Watch() -> (KeyboardLayout layout);
+};
+
+/// Collection of key maps.
+///
+/// A physical key is first converted to key using `key_map`.
+/// The key is then used to populate `symbol` using `symbol_map`.
+/// Maps in `KeySymbolMap` should be searched for the key mapping in the order
+/// they are included.
+/// First key mapping found in an applicable map should be used.
+/// Only maps with matching modifiers should be used.
+/// See `KeySymbolMap` for modifiers matching criteria and examples.
+table KeyboardLayout {
+ 1: PhysicalKeyMap key_map;
+
+ 2: vector<SemanticKeyMap>:MAX_MAPS_PER_LAYOUT semantic_key_map;
+};
+
+/// Key map describes a conversion of a physical key to a key.
+/// Physical keys not included here are translated directly into keys.
+table PhysicalKeyMap {
+ /// Collection of keys that should be explicitly mapped.
+ 1: vector<PhysicalKeyMapEntry>:MAX_ENTRIES_PER_MAP entries;
+};
+
+/// A mapping of a physical key to a key.
+struct PhysicalKeyMapEntry {
+ /// Physical key that's being mapped.
+ PhysicalKey physical_key;
+
+ /// A key to which the physical key is mapped to.
+ Key key;
+};
+
+/// Key map describes a conversion of a key to symbol representation.
+///
+/// The map should be validated using key event modifier states.
+/// Map is applied if every modifier in the 'modifiers' list is active,
+/// and all other active modifiers are members of the 'optional_modifiers' list.
+/// If a modifier is enabled and not listed in neither `modifiers` nor
+/// `optional_modifiers`, the map should be ignored.
+///
+/// Example:
+/// Keyboard has NumLock and CapsLock enabled, and user presses Shift + Key.A
+///
+/// Map1:
+/// modifiers: "CapsLock"
+/// optional_modifiers: "NumLock"
+/// Map2:
+/// modifiers: "Shift",
+/// optional_modifiers: "NumLock", "CapsLock", "ScrollLock"
+/// Map3:
+/// modifiers: None
+/// optional_modifiers: "Shift", "CapsLock"
+///
+/// Map1 should be ignored, since "Shift" is pressed but is not included in
+/// `modifiers` or `optional_modifiers`.
+///
+/// Map2 should be searched, since required "Shift" is enabled, and all other
+/// enabled modifiers are included in `optional_modifiers`.
+///
+/// Map3 should be ignored, since "NumLock" is enabled but not included in
+/// `modifiers` or `optional_modifiers`.
+table SemanticKeyMap {
+ /// Combination of modifiers required for this map to be applied.
+ /// E.g. if CAPS_LOCK bit is set for this map, the map will be
+ /// applied if the Caps Lock state is ON.
+ /// Otherwise this map will be ignored if Caps Lock is off.
+ 1: Modifiers modifiers;
+
+ /// Combination of modifiers that may be enabled for this map to be applied.
+ /// E.g. if CAPS_LOCK bit is set for this map, the map will be
+ /// applied if Caps Lock state is ON.
+ /// Also it may be applied if Caps Lock is off.
+ 2: Modifiers optional_modifiers;
+
+ /// Collection of key to semantic meaning mappings.
+ 3: vector<SemanticKeyMapEntry>:MAX_ENTRIES_PER_MAP entries;
+};
+
+/// A mapping of a key to the semantic meaning.
+struct SemanticKeyMapEntry {
+ /// Key that's being mapped.
+ Key key;
+
+ /// Semantic key corresponding to the key.
+ SemanticKey semantic_key;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.input2/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input2/meta.json
new file mode 100644
index 0000000..7894d00
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input2/meta.json
@@ -0,0 +1,16 @@
+{
+ "deps": [
+ "fuchsia.ui.views"
+ ],
+ "name": "fuchsia.ui.input2",
+ "root": "fidl/fuchsia.ui.input2",
+ "sources": [
+ "fidl/fuchsia.ui.input2/events.fidl",
+ "fidl/fuchsia.ui.input2/keyboard.fidl",
+ "fidl/fuchsia.ui.input2/keys.fidl",
+ "fidl/fuchsia.ui.input2/layout.fidl",
+ "fidl/fuchsia.ui.input2/modifiers.fidl",
+ "fidl/fuchsia.ui.input2/semantic_keys.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.input2/modifiers.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input2/modifiers.fidl
new file mode 100644
index 0000000..e8db292
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input2/modifiers.fidl
@@ -0,0 +1,47 @@
+// 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.
+
+library fuchsia.ui.input2;
+
+/// Modifiers are special keys that modify the purpose or the function
+/// of other keys when used in combination with them.
+bits Modifiers : uint32 {
+ /// Applies when either the `LEFT_SHIFT` or `RIGHT_SHIFT` modifier is pressed.
+ SHIFT = 0x00000001;
+ /// Applies when the `LEFT_SHIFT` modifier is pressed.
+ LEFT_SHIFT = 0x00000002;
+ /// Applies when the `RIGHT_SHIFT` modifier is pressed.
+ RIGHT_SHIFT = 0x00000004;
+
+ /// Applies when either the `LEFT_CONTROL` or `RIGHT_CONTROL` modifier is pressed.
+ CONTROL = 0x00000008;
+ /// Applies when the `LEFT_CONTROL` modifier is pressed.
+ LEFT_CONTROL = 0x00000010;
+ /// Applies when the `RIGHT_CONTROL` modifier is pressed.
+ RIGHT_CONTROL = 0x00000020;
+
+ /// Applies when either the `LEFT_ALT` or `RIGHT_ALT` modifier is pressed.
+ ALT = 0x00000040;
+ /// Applies when the `LEFT_ALT` modifier is pressed.
+ LEFT_ALT = 0x00000080;
+ /// Applies when the `RIGHT_ALT` modifier is pressed.
+ RIGHT_ALT = 0x00000100;
+
+ /// Applies when either the `LEFT_META` or `RIGHT_META` modifier is pressed.
+ META = 0x00000200;
+ /// Applies when the `LEFT_META` modifier is pressed.
+ LEFT_META = 0x00000400;
+ /// Applies when the `RIGHT_META` modifier is pressed.
+ RIGHT_META = 0x00000800;
+
+ /// Applies when the `CAPS_LOCK` modifier is locked.
+ CAPS_LOCK = 0x00001000;
+ /// Applies when the `NUM_LOCK` modifier is locked.
+ NUM_LOCK = 0x00002000;
+ /// Applies when the `SCROLL_LOCK` modifier is locked.
+ SCROLL_LOCK = 0x00004000;
+
+ // TODO: Define additional modifiers as needed.
+ // ALT_GRAPH, FUNCTION, FUNCTION_LOCK, SYMBOL, SYMBOL_LOCK
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.input2/semantic_keys.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input2/semantic_keys.fidl
new file mode 100644
index 0000000..0bb3d31
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input2/semantic_keys.fidl
@@ -0,0 +1,168 @@
+// 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.
+
+library fuchsia.ui.input2;
+
+/// Semantic Key represents the meaning of a non-symbolic key on a keyboard.
+///
+/// Definition of each key is derived from W3C named values of a key attribute:
+/// https://www.w3.org/TR/uievents-key/#named-key-attribute-values
+enum SemanticKeyAction : uint32 {
+ // Modifier keys
+ // Reserved range: 0x00000001 - 0x00000020
+
+ /// The Alt (Alternative) key.
+ /// This key enables the alternate modifier function for interpreting
+ /// concurrent or subsequent keyboard input.
+ /// This key value is also used for the Apple Option key.
+ ALT = 0x00000001;
+
+ /// The Alternate Graphics (AltGr or AltGraph) key.
+ /// This key is used enable the ISO Level 3 shift modifier (the standard
+ /// Shift key is the level 2 modifier). See [ISO9995-1].
+ ALT_GRAPH = 0x00000002;
+
+ /// The Caps Lock (Capital) key.
+ /// Toggle capital character lock function for interpreting subsequent
+ /// keyboard input event.
+ CAPS_LOCK = 0x00000003;
+
+ /// The Control or Ctrl key, to enable control modifier function for
+ /// interpreting concurrent or subsequent keyboard input.
+ CONTROL = 0x00000004;
+
+ /// The Meta key, to enable meta modifier function for interpreting
+ /// concurrent or subsequent keyboard input.
+ /// This key value is used for the Windows Logo key and the Apple Command
+ /// or ⌘ key.
+ META = 0x00000005;
+
+ /// The NumLock or Number Lock key, to toggle numpad mode function for
+ /// interpreting subsequent keyboard input.
+ NUM_LOCK = 0x00000006;
+
+ /// "ScrollLock" The Scroll Lock key, to toggle between scrolling and cursor
+ /// movement modes.
+ SCROLL_LOCK = 0x00000007;
+
+ /// The Shift key, to enable shift modifier function for interpreting
+ /// concurrent or subsequent keyboard input.
+ SHIFT = 0x00000008;
+
+ // Navigation keys
+ // Reserved range: 0x00000021 - 0x00000030
+
+ /// The down arrow key, to navigate or traverse downward.
+ ARROW_DOWN = 0x00000021;
+
+ /// The left arrow key, to navigate or traverse leftward.
+ ARROW_LEFT = 0x00000022;
+
+ /// The right arrow key, to navigate or traverse rightward.
+ ARROW_RIGHT = 0x00000023;
+
+ /// The up arrow key, to navigate or traverse upward.
+ ARROW_UP = 0x00000024;
+
+ /// The End key, used with keyboard entry to go to the end of content.
+ END = 0x00000025;
+
+ /// The Home key, used with keyboard entry, to go to start of content.
+ /// For the mobile phone Home key (which goes to the phone’s main screen),
+ /// use "GO_HOME".
+ HOME = 0x00000026;
+
+ // The Page Down key, to scroll down or display next page of content.
+ PAGE_DOWN = 0x00000027;
+
+ // The Page Up key, to scroll up or display previous page of content.
+ PAGE_UP = 0x00000028;
+
+ // Whitespace keys
+ // Reserved range: 0x00000031 - 0x00000040
+
+ /// The Enter or ↵ key, to activate current selection or accept current input.
+ /// This key value is also used for the Return (Macintosh numpad) key.
+ ENTER = 0x00000031;
+
+ /// The Horizontal Tabulation Tab key.
+ TAB = 0x00000032;
+
+ // Editing keys
+ // Reserved range: 0x00000041 - 0x00000060
+
+ /// The Backspace key. This key value is also used for the key labeled Delete
+ /// on MacOS keyboards.
+ BACKSPACE = 0x00000041;
+
+ /// The Delete (Del) Key.
+ /// This key value is also used for the key labeled Delete on MacOS keyboards
+ /// when modified by the Fn key.
+ DELETE = 0x00000042;
+
+ /// The Insert (Ins) key, to toggle between text modes for insertion or
+ /// overtyping.
+ INSERT = 0x00000043;
+
+ // General-purpose function keys
+ // Reserved range: 0x00000061 - 0x00000080
+
+ // The F1 key, a general purpose function key, as index 1.
+ F1 = 0x00000061;
+
+ // The F2 key, a general purpose function key, as index 2.
+ F2 = 0x00000062;
+
+ // The F3 key, a general purpose function key, as index 3.
+ F3 = 0x00000063;
+
+ // The F4 key, a general purpose function key, as index 4.
+ F4 = 0x00000064;
+
+ // The F5 key, a general purpose function key, as index 5.
+ F5 = 0x00000065;
+
+ // The F6 key, a general purpose function key, as index 6.
+ F6 = 0x00000066;
+
+ // The F7 key, a general purpose function key, as index 7.
+ F7 = 0x00000067;
+
+ // The F8 key, a general purpose function key, as index 8.
+ F8 = 0x00000068;
+
+ // The F9 key, a general purpose function key, as index 9.
+ F9 = 0x00000069;
+
+ // The F10 key, a general purpose function key, as index 10.
+ F10 = 0x0000006A;
+
+ // The F11 key, a general purpose function key, as index 11.
+ F11 = 0x0000006B;
+
+ // The F12 key, a general purpose function key, as index 12.
+ F12 = 0x0000006C;
+
+ // UI Keys
+ // Reserved range: 0x00000081 - 0x000000B0
+
+ /// Show the application’s context menu.
+ /// This key is commonly found between the right Meta key and the right
+ /// Control key.
+ CONTEXT_MENU = 0x00000081;
+
+ /// The Esc key. This key was originally used to initiate an escape sequence,
+ /// but is now more generally used to exit or "escape" the current context,
+ /// such as closing a dialog or exiting full screen mode.
+ ESCAPE = 0x00000082;
+
+ // Mobile Phone Keys
+ // Reserved range: 0x000000B1 - 0x000000D0
+
+ /// The Back key.
+ GO_BACK = 0x000000B1;
+
+ /// The Home key, which goes to the phone’s main screen.
+ GO_HOME = 0x000000B2;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.input3/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input3/BUILD.gn
new file mode 100644
index 0000000..db7537f
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input3/BUILD.gn
@@ -0,0 +1,30 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.ui.input3") {
+ library_name = "input3"
+ namespace = "fuchsia.ui"
+ public_deps = [
+ "../fuchsia.input",
+ "../fuchsia.ui.views",
+ ]
+ sources = [
+ "events.fidl",
+ "keyboard.fidl",
+ "modifiers.fidl",
+ "pointer.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.ui.input3",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.input3/events.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input3/events.fidl
new file mode 100644
index 0000000..d290805
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input3/events.fidl
@@ -0,0 +1,55 @@
+// Copyright 2020 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.
+
+library fuchsia.ui.input3;
+
+using fuchsia.input;
+using zx;
+
+/// Type of the keyboard key input event.
+enum KeyEventType {
+ /// Key is pressed down.
+ PRESSED = 1;
+
+ /// Key is released.
+ RELEASED = 2;
+
+ /// Key was pressed while the client wasn't able to receive it, e.g new device connected
+ /// with a key held down or before system was started.
+ /// Client should not handle this as a key press.
+ SYNC = 3;
+
+ /// Key was released while the client wasn't able to receive it, e.g device was disconnected
+ /// or focus lost.
+ /// Client should not handle this as a key release.
+ CANCEL = 4;
+};
+
+/// Keyboard event is generated to reflect key input.
+table KeyEvent {
+ /// Time in nanoseconds when the event was recorded, in the `CLOCK_MONOTONIC` time base.
+ 1: zx.time timestamp;
+
+ /// Type of event.
+ 2: KeyEventType type;
+
+ /// Identifies the key ignoring modifiers, layout, prior key events, etc.
+ 3: fuchsia.input.Key key;
+
+ /// Modifiers in effect at the time of the event.
+ /// Example:
+ /// CapsLock is off, user presses CapsLock, then A, then releases both.
+ /// Event sequence is as follows:
+ /// 1. type: Pressed, key: CapsLock, modifiers: None
+ /// 2. type: Pressed, key: A, modifiers: CapsLock
+ /// 3. type: Released, key: CapsLock, modifiers: CapsLock
+ /// 4. type: Released, key: A, modifiers: CapsLock
+ ///
+ /// CapsLock is on, user presses CapsLock, then A, then releases both.
+ /// 1. type: Pressed, key: CapsLock, modifiers: CapsLock
+ /// 2. type: Pressed, key: A, modifiers: None
+ /// 3. type: Released, key: CapsLock, modifiers: None
+ /// 4. type: Released, key: A, modifiers: None
+ 4: Modifiers modifiers;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.input3/keyboard.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input3/keyboard.fidl
new file mode 100644
index 0000000..1b7b985
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input3/keyboard.fidl
@@ -0,0 +1,40 @@
+// Copyright 2020 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.
+
+library fuchsia.ui.input3;
+
+using fuchsia.ui.views;
+
+/// Components may request this service from their namespace to be notified of
+/// physical key events.
+[Discoverable]
+protocol Keyboard {
+ /// Add a key event listener for the specified View.
+ /// If multiple listeners are added, each will receive key events independently and
+ /// should respond with a `Status`.
+ AddListener(fuchsia.ui.views.ViewRef view_ref, KeyboardListener listener) -> ();
+};
+
+/// Client should implement this protocol to get notified of key events.
+protocol KeyboardListener {
+ /// Called when a key event takes place, such as key press or release.
+ /// Protocol implementers must respond to acknowledge the event by returning Status
+ /// in a timely manner, i.e. not introducing significant delays to the
+ /// input pipeline (typically 10s of milliseconds).
+ /// Returning `NOT_HANDLED` means the event will propagate to another client or listener.
+ /// Clients that do not acknowledge their events will eventually be disconnected.
+ /// Notification is only dispatched when the View is focused (ViewRef is on FocusChain).
+ /// Parent Views receive the notification first, child Views last.
+ /// Returning `HANDLED` will stop event propagation to other clients and listeners.
+ OnKeyEvent(KeyEvent event) -> (KeyEventStatus status);
+};
+
+/// Return type for clients key events listener.
+enum KeyEventStatus {
+ /// The key event was handled and its further propagation should be stopped.
+ HANDLED = 1;
+
+ /// The key event wasn't handled and should be delivered to other clients or listeners.
+ NOT_HANDLED = 2;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.input3/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input3/meta.json
new file mode 100644
index 0000000..029c88c
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input3/meta.json
@@ -0,0 +1,15 @@
+{
+ "deps": [
+ "fuchsia.input",
+ "fuchsia.ui.views"
+ ],
+ "name": "fuchsia.ui.input3",
+ "root": "fidl/fuchsia.ui.input3",
+ "sources": [
+ "fidl/fuchsia.ui.input3/events.fidl",
+ "fidl/fuchsia.ui.input3/keyboard.fidl",
+ "fidl/fuchsia.ui.input3/modifiers.fidl",
+ "fidl/fuchsia.ui.input3/pointer.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.input3/modifiers.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input3/modifiers.fidl
new file mode 100644
index 0000000..2ecff8f
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input3/modifiers.fidl
@@ -0,0 +1,20 @@
+// Copyright 2020 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.
+
+library fuchsia.ui.input3;
+
+/// Modifiers are special keys that modify the purpose or the function
+/// of other keys when used in combination with them.
+bits Modifiers : uint64 {
+ /// Applies when the `CAPS_LOCK` modifier is locked.
+ CAPS_LOCK = 0x00000001;
+ /// Applies when the `NUM_LOCK` modifier is locked.
+ NUM_LOCK = 0x00000002;
+ /// Applies when the `SCROLL_LOCK` modifier is locked.
+ SCROLL_LOCK = 0x00000004;
+
+ // TODO: Define additional modifiers as needed.
+ // SHIFT, CONTROL, ALT, META
+ // ALT_GRAPH, FUNCTION, FUNCTION_LOCK, SYMBOL, SYMBOL_LOCK
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.input3/pointer.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input3/pointer.fidl
new file mode 100644
index 0000000..af3a311
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.input3/pointer.fidl
@@ -0,0 +1,29 @@
+// Copyright 2020 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.
+
+library fuchsia.ui.input3;
+
+/// A characterization of a device that issues pointer event streams.
+enum PointerDeviceType {
+ /// A device intended for manipulation by direct contact over its surface.
+ TOUCH = 1;
+};
+
+/// The possible states of a pointer event stream's state machine.
+///
+/// A typical pointer will move through this state machine:
+/// ADD - CHANGE* - REMOVE
+enum PointerEventPhase {
+ /// The device has started tracking the pointer.
+ ADD = 1;
+
+ /// The device has reported an update to the pointer state.
+ CHANGE = 2;
+
+ /// The device has stopped tracking the pointer.
+ REMOVE = 3;
+
+ /// The event stream is no longer available.
+ CANCEL = 4;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.lifecycle/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.ui.lifecycle/BUILD.gn
new file mode 100644
index 0000000..1fd3b59
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.lifecycle/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.ui.lifecycle") {
+ library_name = "lifecycle"
+ namespace = "fuchsia.ui"
+ public_deps = [
+ ]
+ sources = [
+ "lifecycle_controller.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.ui.lifecycle",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.lifecycle/lifecycle_controller.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.lifecycle/lifecycle_controller.fidl
new file mode 100644
index 0000000..a7705ab
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.lifecycle/lifecycle_controller.fidl
@@ -0,0 +1,18 @@
+// 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.
+
+library fuchsia.ui.lifecycle;
+
+/// An interface implemented by system UI components that wish to terminate gracefully.
+[Discoverable]
+protocol LifecycleController {
+ /// The controller of this component has requested that this component terminate gracefully.
+ /// If the component does not terminate itself in a timely manner, the client may forcibly
+ /// terminate the component.
+ ///
+ /// The connection to the controller will be broken shortly before the target terminates;
+ /// clients should listen for channel closure to learn the approximate moment that the target
+ /// terminates.
+ Terminate();
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.lifecycle/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.ui.lifecycle/meta.json
new file mode 100644
index 0000000..741e443
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.lifecycle/meta.json
@@ -0,0 +1,9 @@
+{
+ "deps": [],
+ "name": "fuchsia.ui.lifecycle",
+ "root": "fidl/fuchsia.ui.lifecycle",
+ "sources": [
+ "fidl/fuchsia.ui.lifecycle/lifecycle_controller.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.policy/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.ui.policy/BUILD.gn
new file mode 100644
index 0000000..cc8e2e6
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.policy/BUILD.gn
@@ -0,0 +1,30 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.ui.policy") {
+ library_name = "policy"
+ namespace = "fuchsia.ui"
+ public_deps = [
+ "../fuchsia.ui.input",
+ "../fuchsia.ui.views",
+ ]
+ sources = [
+ "device_listener.fidl",
+ "display_usage.fidl",
+ "presentation.fidl",
+ "presenter.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.ui.policy",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.policy/device_listener.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.policy/device_listener.fidl
new file mode 100644
index 0000000..a7d7086
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.policy/device_listener.fidl
@@ -0,0 +1,22 @@
+// 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.
+
+library fuchsia.ui.policy;
+
+using fuchsia.ui.input;
+
+/// Service for exposing state and events of devices, such as media buttons.
+[Discoverable]
+protocol DeviceListenerRegistry {
+ /// Registers a listener to receive media button related events, such as
+ /// changes from volume buttons and mute switches.
+ RegisterMediaButtonsListener(MediaButtonsListener listener);
+};
+
+/// A listener for media buttons events. `DeviceListenerRegistry.RegisterMediaButtonsListener`
+/// will consume this listener interface and call `OnMediaButtonsEvent` when the
+/// registered media buttons event occurs.
+protocol MediaButtonsListener {
+ OnMediaButtonsEvent(fuchsia.ui.input.MediaButtonsEvent event);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.policy/display_usage.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.policy/display_usage.fidl
new file mode 100644
index 0000000..cf0d60e
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.policy/display_usage.fidl
@@ -0,0 +1,20 @@
+// Copyright 2018 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.
+
+library fuchsia.ui.policy;
+
+/// Describes the intended usage of the display.
+enum DisplayUsage {
+ kUnknown = 0;
+ /// Display is held in one or both hands.
+ kHandheld = 1;
+ /// Display is used well within arm's reach.
+ kClose = 2;
+ /// Display is used at arm's reach.
+ kNear = 3;
+ /// Display is used beyond arm's reach.
+ kMidrange = 4;
+ /// Display is used well beyond arm's reach.
+ kFar = 5;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.policy/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.ui.policy/meta.json
new file mode 100644
index 0000000..deb9c3a
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.policy/meta.json
@@ -0,0 +1,15 @@
+{
+ "deps": [
+ "fuchsia.ui.input",
+ "fuchsia.ui.views"
+ ],
+ "name": "fuchsia.ui.policy",
+ "root": "fidl/fuchsia.ui.policy",
+ "sources": [
+ "fidl/fuchsia.ui.policy/device_listener.fidl",
+ "fidl/fuchsia.ui.policy/display_usage.fidl",
+ "fidl/fuchsia.ui.policy/presentation.fidl",
+ "fidl/fuchsia.ui.policy/presenter.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.policy/presentation.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.policy/presentation.fidl
new file mode 100644
index 0000000..a9acba3
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.policy/presentation.fidl
@@ -0,0 +1,23 @@
+// Copyright 2017 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.
+
+library fuchsia.ui.policy;
+
+using fuchsia.ui.input;
+
+/// `Presentation.CapturePointerEvent` will consume this listener interface and
+/// call `OnEvent` when a pointer event occurs.
+protocol PointerCaptureListenerHACK {
+ OnPointerEvent(fuchsia.ui.input.PointerEvent event);
+};
+
+/// Allows clients of Presenter.Present() to control a presentation.
+/// Experimental.
+[Discoverable]
+protocol Presentation {
+ /// This call exists so that base shell can capture pointer events.
+ // TODO: Figure out the feasibility of this feature and the best place to put
+ // it. This call will be replaced by gesture disambiguation system in future.
+ CapturePointerEventsHACK(PointerCaptureListenerHACK listener);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.policy/presenter.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.policy/presenter.fidl
new file mode 100644
index 0000000..ae35f71
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.policy/presenter.fidl
@@ -0,0 +1,25 @@
+// Copyright 2016 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.
+
+library fuchsia.ui.policy;
+
+using fuchsia.ui.views;
+
+/// The Presenter service provides a way for applications to ask that a view be
+/// added to a view tree, leaving any window management concerns up to the
+/// discretion of the presenter implementation.
+[Discoverable]
+protocol Presenter {
+ /// Request that the View's contents be displayed on the screen as a `Presentation`.
+ /// Each call to `PresentView` creates a new `Presentation`. Having more than one simultaneous
+ /// `Presentation` (i.e. calling `PresentView` more than once) is deprecated, and will
+ /// print a warning. In the future, this will result in an error and the channel being closed.
+ PresentView(fuchsia.ui.views.ViewHolderToken view_holder_token, request<Presentation>? presentation_request);
+
+ /// Request that the View's contents be displayed on the screen as a `Presentation`.
+ /// Destroys any existing presentations and replaces them with the new one.
+ /// This is true whether the existing view was created by a call to
+ /// PresentOrReplaceView or to PresentView.
+ PresentOrReplaceView(fuchsia.ui.views.ViewHolderToken view_holder_token, request<Presentation>? presentation_request);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.scenic/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.ui.scenic/BUILD.gn
new file mode 100644
index 0000000..96c662f
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.scenic/BUILD.gn
@@ -0,0 +1,35 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.ui.scenic") {
+ library_name = "scenic"
+ namespace = "fuchsia.ui"
+ public_deps = [
+ "../fuchsia.images",
+ "../fuchsia.mem",
+ "../fuchsia.scenic.scheduling",
+ "../fuchsia.ui.gfx",
+ "../fuchsia.ui.input",
+ "../fuchsia.ui.views",
+ ]
+ sources = [
+ "commands.fidl",
+ "events.fidl",
+ "scenic.fidl",
+ "session.fidl",
+ "snapshot.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.ui.scenic",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.scenic/commands.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.scenic/commands.fidl
new file mode 100644
index 0000000..f98f9a3
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.scenic/commands.fidl
@@ -0,0 +1,16 @@
+// Copyright 2018 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.
+
+library fuchsia.ui.scenic;
+
+using fuchsia.ui.gfx;
+using fuchsia.ui.input;
+using fuchsia.ui.views;
+
+union Command {
+ 1: fuchsia.ui.gfx.Command gfx;
+ 2: reserved;
+ 3: fuchsia.ui.views.Command views;
+ 4: fuchsia.ui.input.Command input;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.scenic/events.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.scenic/events.fidl
new file mode 100644
index 0000000..5b13ea9
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.scenic/events.fidl
@@ -0,0 +1,14 @@
+// Copyright 2018 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.
+
+library fuchsia.ui.scenic;
+
+using fuchsia.ui.input;
+using fuchsia.ui.gfx;
+
+union Event {
+ 1: fuchsia.ui.gfx.Event gfx;
+ 2: fuchsia.ui.input.InputEvent input;
+ 3: Command unhandled;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.scenic/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.ui.scenic/meta.json
new file mode 100644
index 0000000..9950ba8
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.scenic/meta.json
@@ -0,0 +1,20 @@
+{
+ "deps": [
+ "fuchsia.images",
+ "fuchsia.scenic.scheduling",
+ "fuchsia.ui.gfx",
+ "fuchsia.ui.input",
+ "fuchsia.ui.views",
+ "fuchsia.mem"
+ ],
+ "name": "fuchsia.ui.scenic",
+ "root": "fidl/fuchsia.ui.scenic",
+ "sources": [
+ "fidl/fuchsia.ui.scenic/commands.fidl",
+ "fidl/fuchsia.ui.scenic/events.fidl",
+ "fidl/fuchsia.ui.scenic/scenic.fidl",
+ "fidl/fuchsia.ui.scenic/session.fidl",
+ "fidl/fuchsia.ui.scenic/snapshot.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.scenic/scenic.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.scenic/scenic.fidl
new file mode 100644
index 0000000..7a5fd74
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.scenic/scenic.fidl
@@ -0,0 +1,51 @@
+// Copyright 2018 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.
+
+library fuchsia.ui.scenic;
+
+using fuchsia.images;
+using fuchsia.mem;
+using fuchsia.ui.gfx;
+using fuchsia.ui.views;
+
+/// Scenic.TakeScreenshot() returns a raw BGRA formatted image in
+/// sRGB color space and with a non-linear transfer function in this
+/// struct.
+struct ScreenshotData {
+ fuchsia.images.ImageInfo info;
+ fuchsia.mem.Buffer data;
+};
+
+[Discoverable]
+protocol Scenic {
+ /// Create a new Session, which is the primary way to interact with Scenic.
+ CreateSession(request<Session> session, SessionListener? listener);
+
+ /// Create a new Session, which is the primary way to interact with Scenic.
+ ///
+ /// In this variant, the caller may register a request for focus management.
+ /// The `view_focuser`'s client is coupled to the requested `session`, and
+ /// this coupling acts as a security boundary: the ViewRef used as the basis
+ /// for authority by `view_focuser` must come from `session`.
+ [Transitional]
+ CreateSession2(request<Session> session, SessionListener? listener,
+ request<fuchsia.ui.views.Focuser>? view_focuser);
+
+ /// Get information about the Scenic's primary display.
+ // TODO(SCN-453): in the future there will probably be a DisplayManager, and
+ // info about which displays to use will be provided to the Scenic.
+ GetDisplayInfo() -> (fuchsia.ui.gfx.DisplayInfo info);
+ /// Gets an event signaled with displayOwnedSignal or displayNotOwnedSignal
+ /// when display ownership changes.
+ GetDisplayOwnershipEvent() -> (handle<event> ownership_event);
+
+ /// Take a screenshot and return the data in `img_data`. `img_data` will
+ /// not contain BGRA data if `success` is false.
+ // TODO(SCN-678): The permissions here are too wide (anyone can take a
+ // screenshot), we should narrow them.
+ TakeScreenshot() -> (ScreenshotData img_data, bool success);
+};
+
+const uint32 displayOwnedSignal = 0x02000000;
+const uint32 displayNotOwnedSignal = 0x01000000;
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.scenic/session.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.scenic/session.fidl
new file mode 100644
index 0000000..4dd3a4d
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.scenic/session.fidl
@@ -0,0 +1,223 @@
+// Copyright 2018 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.
+
+library fuchsia.ui.scenic;
+
+using zx;
+using fuchsia.images;
+using fuchsia.scenic.scheduling;
+
+/// Arguments passed into Present2(). Note that every argument is mandatory.
+table Present2Args {
+ /// `requested_presentation_time` specifies the time on or after which the
+ /// client would like the enqueued operations to take visible effect
+ /// (light up pixels on the screen), expressed in nanoseconds in the
+ /// `CLOCK_MONOTONIC` timebase.
+ ///
+ /// Using a `requested_presentation_time` in the present or past (such as 0)
+ /// schedules enqueued operations to take visible effect as soon as
+ /// possible, during the next frame to be prepared. Requested presentation
+ /// times must be monotonically increasing.
+ ///
+ /// Using a `requested_presentation_time` in the future schedules the enqueued
+ /// operations to take visible effect as closely as possible to or after
+ /// the stated time, but no earlier.
+ ///
+ /// Each rendered frame has a target presentation time. This is when Scenic
+ /// aims to have the frame presented to the user. Before rendering a frame,
+ /// the scene manager applies all enqueued operations associated with all
+ /// prior calls to Present2 whose `requested_presentation_time` is on or
+ /// before the frame's target presentation time.
+ 1: zx.time requested_presentation_time;
+
+ /// Scenic will wait until all of a session's `acquire_fences` are ready
+ /// before it will execute the presented commands.
+ 2: vector<handle<event>> acquire_fences;
+
+ /// `release_fences` is the list of events that will be signalled by Scenic when
+ /// the following Present2 call's `acquire_fences` has been signalled, and
+ /// the updated session state has been fully committed: future frames will be
+ /// rendered using this state, and all frames generated using previous session
+ /// states have been fully-rendered and presented to the display.
+ 3: vector<handle<event>> release_fences;
+
+ /// `requested_prediction_span` is the amount of time into the future Scenic
+ /// will provide predictions for. A span of 0 is guaranteed to provide at
+ /// least one future time.
+ 4: zx.duration requested_prediction_span;
+};
+
+/// Client use Sessions to interact with a Scenic instance by enqueuing commands
+/// that create or modify resources.
+protocol Session {
+ Enqueue(vector<Command> cmds);
+
+ // TODO(jeffbrown): Defining presentation time in terms of `CLOCK_MONOTONIC`
+ // simplifies synchronization across subsystems but it might be too simple.
+ // We should consider using a synthetic timebase and describing its relation
+ // to other clocks separately. That would make it possible to present
+ // content (animations, media, and UI) in "slow mode" simply by varying the
+ // timing relation, assuming clients play along.
+ // TODO(SCN-400): document invariants that apply to `presentation_info`. Is it
+ // strong enough to guarantee that receiving the response means that all
+ // previously-enqueued Commands have been applied? Or does it need to be stronger,
+ // e.g. that all frames based on previous presentations are completely done,
+ // and subsequent frames will be rendered based on the most recent presented
+ // content?
+ /// Present all previously enqueued operations. In order to pipeline the
+ /// preparation of the resources required to render the scene, two lists of
+ /// fences (implemented as events) are passed.
+ ///
+ /// SCHEDULING PRESENTATION
+ ///
+ /// `presentation_time` specifies the time on or after which the
+ /// client would like the enqueued operations should take visible effect
+ /// (light up pixels on the screen), expressed in nanoseconds in the
+ /// `CLOCK_MONOTONIC` timebase. Desired presentation times must be
+ /// monotonically non-decreasing.
+ ///
+ /// Using a desired presentation time in the present or past (such as 0)
+ /// schedules enqueued operations to take visible effect as soon as possible
+ /// (during the next frame to be prepared).
+ ///
+ /// Using a desired presentation time in the future schedules the enqueued
+ /// operations to take visible effect as closely as possible to or after
+ /// the stated time (but no earlier).
+ ///
+ /// Each rendered frame has a target presentation time. Before rendering
+ /// a frame, the scene manager applies all enqueued operations associated
+ /// with all prior calls to `Present()` whose desired presentation time
+ /// is on or before the frame's target presentation time.
+ ///
+ /// The `Present()` method does not return until the scene manager begins
+ /// preparing the first frame which includes its presented content.
+ /// Upon return, the `PresentationInfo` provides timing information for the
+ /// frame which includes the presented content.
+ ///
+ /// To present new content on each successive frame, wait for `Present()`
+ /// to return before calling `Present()` again with content for the next
+ /// frame.
+ ///
+ /// It is also possible to enqueue and present successive frames of content
+ /// all at once with increasing desired presentation times, incrementing by
+ /// `PresentationInfo.presentation_interval` for each one.
+ ///
+ /// Animation updates are also coordinated in terms of presentation time.
+ ///
+ /// SYNCHRONIZATION
+ ///
+ /// `acquire_fences` are used by Scenic to wait until all of the session's
+ /// resources are ready to render (or to allow downstream components, such as
+ /// the Vulkan driver, to wait for these resources).
+ ///
+ /// For example, Fuchsia's Vulkan driver allows an zx::event to be obtained
+ /// from a VkSemaphore. This allows a Scenic client to submit a Vulkan command
+ /// buffer to generate images/meshes/etc., and instructing Vulkan to signal a
+ /// VkSemaphore when it is done. By inserting the zx::event corresponding to
+ /// this semaphore into `acquire_fences`, the client allows Scenic to submit work
+ /// to the Vulkan driver without waiting on the CPU for the event to be
+ /// signalled.
+ ///
+ /// `release_fences` is a list of events that will be signalled by Scenic when
+ /// the updated session state has been fully committed: future frames will be
+ /// rendered using this state, and all frames generated using previous session
+ /// states have been fully-rendered and presented to the display.
+ ///
+ /// Together, `acquire_fences` and `release_fences` are intended to allow clients
+ /// to implement strategies such as double-buffering. For example, a client
+ /// might do the following in the Scenic subsystem:
+ /// 1) create two Image with resource IDs #1 and #2.
+ /// 2) create two Materials with resource IDs #3 and #4, which respectively
+ /// use Images #1 and #2 as their texture.
+ /// 3) create a tree of Nodes and attach them to the scene.
+ /// 4) set one of the nodes above, say #5, to use Material #3.
+ /// 5) submit a Vulkan command-buffer which renders into Image #1, and
+ /// will signal a VkSemaphore.
+ /// 6) call Present() with one acquire-fence (obtained from the VkSemaphore
+ /// above) and one newly-created release-fence.
+ ///
+ /// After the steps above, Scenic will use the committed session state to render
+ /// frames whenever necessary. When the client wants to display something
+ /// different than Image #1, it would do something similar to steps 4) to 6):
+ /// 7) set Node #5 to use Material #4.
+ /// 8) submit a Vulkan command-buffer which renders into Image #1, and
+ /// will signal a VkSemaphore.
+ /// 9) call Present() with one acquire-fence (obtained from the VkSemaphore
+ /// above) and one newly-created release-fence.
+ ///
+ /// Finally, to continually draw new content, the client could repeat steps
+ /// 4) to 9), with one important difference: step 5) must wait on the event
+ /// signalled by step 9). Otherwise, it might render into Image #1 while that
+ /// image is still being used by Scenic to render a frame. Similarly, step 8)
+ /// must wait on the event signalled by step 6).
+ ///
+ /// The scenario described above uses one acquire-fence and one release-fence,
+ /// but it is easy to imagine cases that require more. For example, in addition
+ /// to using Vulkan to render into Images #1 and #2, the client might also
+ /// upload other resources to Vulkan on a different VkQueue, which would
+ /// would signal a separate semaphore, and therefore require an additional
+ /// acquire-fence.
+ ///
+ /// Note: `acquire_fences` and `release_fences` are only necessary to synchronize
+ /// access to memory (and other external resources). Any modification to
+ /// resources made via the Session API are automatically synchronized.
+ [Transitional]Present(uint64 presentation_time,
+ vector<handle<event>> acquire_fences, vector<handle<event>> release_fences)
+ -> (fuchsia.images.PresentationInfo presentation_info);
+
+ /// Present all previously enqueued operations. In order to pipeline the
+ /// preparation of the resources required to render the scene, two lists of
+ /// fences, implemented as events, are passed.
+ ///
+ /// When a client calls Present2, they receive an immediate callback
+ /// consisting of the same information they would get as if they had called
+ /// `RequestPresentationTimes` with the equivalent
+ /// `requested_prediction_span`. See its documentation below for more
+ /// information, as Present2's functionality is a superset of it.
+ ///
+ /// Then, when the commands flushed by Present2 make it to display, an
+ /// `OnFramePresented` event is fired. This event includes information
+ /// pertaining to all Present2s that had content that were part of that
+ /// frame.
+ ///
+ /// Clients may only use one of Present/Present2 per Session.
+ /// Switching between both is an error that will result in the Session being
+ /// closed.
+ ///
+ /// See `Present2Args` documentation above for more detailed information on
+ /// what arguments are passed in and their role.
+ Present2(Present2Args args)
+ -> (fuchsia.scenic.scheduling.FuturePresentationTimes request_presentation_times_info);
+
+ /// This event is fired whenever a set of one or more Present2s are
+ /// presented simultaenously, and are therefore no longer in flight.
+ -> OnFramePresented(fuchsia.scenic.scheduling.FramePresentedInfo frame_presented_info);
+
+ /// Returns information about future presentation times, and their
+ /// respective latch points. Clients can use the returned information to
+ /// make informed scheduling decisions: if a client wants their frame to be
+ /// displayed at a given `presentation_time`, they should aim to have all
+ /// `acquire_fences` fired before the associated `latch_point`.
+ ///
+ /// Scenic will attempt to return predictions that span a duration equal to
+ /// `requested_prediction_span`, up to a limit.
+ ///
+ /// A value of 0 is guaranteed to give at least one future presentation info.
+ RequestPresentationTimes(zx.duration requested_prediction_span)
+ -> (fuchsia.scenic.scheduling.FuturePresentationTimes request_presentation_times_info);
+
+ /// Set an optional debug name for the session. The debug name will be
+ /// output in things such as logging and trace events.
+ SetDebugName(string debug_name);
+};
+
+/// Listens for events which occur within the session.
+protocol SessionListener {
+ /// Called when an error has occurred and the session will be torn down.
+ OnScenicError(string error);
+
+ /// Called to deliver a batch of one or more events to the listener.
+ /// Use `SetEventMaskCmd` to enable event delivery for a resource.
+ OnScenicEvent(vector<Event> events);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.scenic/snapshot.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.scenic/snapshot.fidl
new file mode 100644
index 0000000..2a794be
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.scenic/snapshot.fidl
@@ -0,0 +1,11 @@
+// Copyright 2018 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.
+
+library fuchsia.ui.scenic;
+
+/// Defines an interface to take view snapshots.
+[Discoverable]
+protocol Snapshot {
+ // TODO(SCN-35081): Implement this interface for non-privileged clients.
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.types/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.ui.types/BUILD.gn
new file mode 100644
index 0000000..3973a22
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.types/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.ui.types") {
+ library_name = "types"
+ namespace = "fuchsia.ui"
+ public_deps = [
+ ]
+ sources = [
+ "types.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.ui.types",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.types/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.ui.types/meta.json
new file mode 100644
index 0000000..5be784c
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.types/meta.json
@@ -0,0 +1,9 @@
+{
+ "deps": [],
+ "name": "fuchsia.ui.types",
+ "root": "fidl/fuchsia.ui.types",
+ "sources": [
+ "fidl/fuchsia.ui.types/types.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.types/types.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.types/types.fidl
new file mode 100644
index 0000000..719df17
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.types/types.fidl
@@ -0,0 +1,23 @@
+// 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.
+
+library fuchsia.ui.types;
+
+/// Represents a color. Interfaces that use this struct should document whether
+/// or not the floats have been premultiplied by alpha. Range per channel is
+/// usually between 0.0 and 1.0.
+struct ColorRgba {
+ float32 red;
+ float32 green;
+ float32 blue;
+ float32 alpha;
+};
+
+/// Represents a color without alpha channel. Range per channel is usually
+/// between 0.0 and 1.0.
+struct ColorRgb {
+ float32 red;
+ float32 green;
+ float32 blue;
+};
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.views/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.ui.views/BUILD.gn
new file mode 100644
index 0000000..019e9df
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.views/BUILD.gn
@@ -0,0 +1,29 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.ui.views") {
+ library_name = "views"
+ namespace = "fuchsia.ui"
+ public_deps = [
+ ]
+ sources = [
+ "commands.fidl",
+ "focuser.fidl",
+ "view.fidl",
+ "view_ref.fidl",
+ "view_token.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.ui.views",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.views/commands.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.views/commands.fidl
new file mode 100644
index 0000000..4dda2bc
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.views/commands.fidl
@@ -0,0 +1,12 @@
+// Copyright 2018 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.
+
+library fuchsia.ui.views;
+
+/// DO NOT USE - Retained for ABI stability in fuchsia.ui.scenic.Command
+///
+/// DO NOT USE
+union Command {
+ 1: int32 empty;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.views/focuser.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.views/focuser.fidl
new file mode 100644
index 0000000..09c6695
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.views/focuser.fidl
@@ -0,0 +1,38 @@
+// 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.
+
+library fuchsia.ui.views;
+
+/// Problematic situations that occur on Focuser.RequestFocus.
+enum Error {
+ /// Value returned when RequestFocus is denied.
+ DENIED = 1;
+};
+
+/// A method of programmatically transferring view focus.
+///
+/// The protocol client has implicit access to a requestor ViewRef, which is
+/// used as the basis for request authority.
+protocol Focuser {
+ /// Asks the server to transfer focus to the view specified by `view_ref`,
+ /// with the authority of the requestor ViewRef. Such a request may be
+ /// honored or denied.
+ ///
+ /// If the request was honored, and it triggers a focus change, a FocusEvent
+ /// (with focused=true) is issued to the newly-focused view, and a
+ /// FocusEvent (with focused=false) is issued to the previous view.
+ ///
+ /// The result callback indicates that the request was received and honored.
+ /// It does not guarantee that the requested view actually received a
+ /// FocusEvent in time.
+ ///
+ /// The request may be denied for many reasons, for example:
+ /// - if `view_ref` is invalid
+ /// - if there is no view backed by `view_ref`
+ /// - if there is no requestor ViewRef accessible to Focuser
+ /// - if the requestor ViewRef lacks authority over `view_ref`'s view
+ /// - if `view_ref`'s view is not hittable or may not receive focus
+ /// etc. A denied request is indicated with a Error.
+ RequestFocus(ViewRef view_ref) -> () error Error;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.views/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.ui.views/meta.json
new file mode 100644
index 0000000..f91cd8d
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.views/meta.json
@@ -0,0 +1,13 @@
+{
+ "deps": [],
+ "name": "fuchsia.ui.views",
+ "root": "fidl/fuchsia.ui.views",
+ "sources": [
+ "fidl/fuchsia.ui.views/commands.fidl",
+ "fidl/fuchsia.ui.views/focuser.fidl",
+ "fidl/fuchsia.ui.views/view.fidl",
+ "fidl/fuchsia.ui.views/view_ref.fidl",
+ "fidl/fuchsia.ui.views/view_token.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.views/view.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.views/view.fidl
new file mode 100644
index 0000000..14ef4a9
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.views/view.fidl
@@ -0,0 +1,97 @@
+// 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.
+
+library fuchsia.ui.views;
+
+/// A View is an interface that a component implements to offer Scenic view(s)
+/// to its clients.
+///
+/// A Scenic view contains a tree of Scenic graph nodes which is used to render
+/// a graphical user interface, such as a module, shell, or on-screen keyboard.
+/// Other Scenic views can be embedded within this tree of nodes. This creates
+/// a scene graph describing the UI of the entire system, rooted at the
+/// top-most view. Different processes can contribute branches to the scene
+/// graph, and their content will be rendered together in a shared space.
+///
+/// # Offering a View
+///
+/// A component that wishes to offer a `View` can do so in one of two ways:
+///
+/// 1. Expose a `View` interface as a service. This is usually done by components
+/// that provide a single view, or have a clearly defined "main" view.
+/// In this case, the component may obtain relevant properties for configuring
+/// the view using services that may be available in its namespace, such as:
+/// - `fuchsia.intl.PropertyProvider`
+/// - `fuchsia.accessibility.PropertyProvider`
+///
+/// 2. Offer a domain-specific interface that provides `View`s using a
+/// `request<View>` parameter. In this case, the component may obtain relevant
+/// properties for configuring the view using services that may be provided by its
+/// client as part of the request.
+///
+/// For example, an encyclopedia component might offer a method to expose article views:
+///
+/// GetArticleView(string article_id,
+/// fuchsia.intl.PropertyProvider intl_properties,
+/// fuchsia.accessibility.PropertyProvider accessibility_properties,
+/// request<View> view_request);
+///
+/// This latter case is probably less common, as controlling domain-specific
+/// views tends to be the job of the component that creates them.
+///
+/// # Presenting a View
+///
+/// A client of the `View` interface will:
+///
+/// 1. Launch (or bind to) the component that provides the interface.
+/// 2. Connect to the component's `View` interface.
+/// 3. Call `Present()` to give the `View` an attachment point into the scene graph
+/// via the `view_token`. Subsequent calls to `Present()` will generate an error
+/// and cause the connection to be closed.
+///
+/// When the client no longer needs the View, it should disconnect from the
+/// interface.
+///
+/// NOTE: The client owns the `View` instance and must retain it for the
+/// lifetime of the UI that it displays. If the `View` instance is destroyed,
+/// the connection will be dropped and all UI content will be destroyed.
+///
+/// # Implementing a View
+///
+/// On the implementation side, a component that exposes the `View` interface
+/// has the following responsibilities:
+///
+/// * When `Present()` is called, create a root for the `View`'s content in the
+/// Scenic scene graph by passing the provided `view_token`.
+/// * Provide graphical content for the view and attach it to the root.
+/// * Adjust the appearance and/or contents of the view's content based on
+/// relevant internationalization and/or accessibility properties as described
+/// above.
+/// * Handle user interface events such as touches, key presses, and
+/// `fuchsia.ui.gfx.ViewProperty` changes using other Scenic interfaces such
+/// as `fuchsia.ui.Scenic` and `fuchsia.ui.SessionListener`.
+///
+/// See also: `fuchsia.intl.PropertyProvider`, `fuchsia.accessibility.PropertyProvider`.
+///
+/// TODO(SCN-1198): Migrate all implementations of `ViewProvider` to use `View`.
+[Discoverable]
+protocol View {
+
+ /// Provides the View with an attachment point to Scenic's scene graph.
+ ///
+ /// When `Present()` is called the View's implementation should create a
+ /// View resource within Scenic by providing it with the `view_token` (using
+ /// a `fuchsia.ui.gfx.CreateResourceCmd` and `fuchsia.ui.gfx.ViewArgs`).
+ ///
+ /// Then the implementation should attach its graphical content to the
+ /// newly-created View resource using a `fuchsia.ui.gfx.AddChildCmd`.
+ ///
+ /// If the implementation already owns a View resource (because `Present()`
+ /// had already been called before), then it should terminate the connection
+ /// with an error.
+ ///
+ /// TODO(SCN-1271): Allow re-parenting `View`s with a new `Present()` call.
+ [Transitional]
+ Present(ViewToken view_token);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.views/view_ref.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.views/view_ref.fidl
new file mode 100644
index 0000000..3d691bb
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.views/view_ref.fidl
@@ -0,0 +1,48 @@
+// Copyright 2020 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.
+
+library fuchsia.ui.views;
+
+/// A ViewRef is a handle to a kernel object which identifies a unique View
+/// across the system. Two ViewRefs to the same View have the same KOID.
+///
+/// Clients use a ViewRef to identify a View, to validate a View, and to
+/// receive a View invalidation signal.
+///
+/// As part of View creation, the client creates a linked
+/// ViewRef/ViewRefControl pair and hands the pair to Scenic (ViewRefControl is
+/// described below). The client must remove the ViewRef's signal
+/// capabilities; otherwise the View is not created.
+///
+/// The client may freely clone its ViewRef and share it, even before sending
+/// it to Scenic.
+///
+/// Example 1. Accessibility accepts a ViewRef from a client to group the
+/// semantic nodes, and semantic operations, associated with a client's View.
+/// It must validate a client's ViewRef with Scenic.
+///
+/// Example 2. We use ViewRefs to create a FocusChain, which identifies Views
+/// considered as "in-focus" down the View hierarchy. When a View is destroyed,
+/// Scenic signals to all FocusChain holders that the ViewRef is now invalid.
+struct ViewRef {
+ handle<eventpair> reference;
+};
+
+/// A ViewRefControl is the peer to a ViewRef. Their `reference`s are linked.
+///
+/// Like ViewRef, a ViewRefControl is a typed handle to an eventpair. Unlike
+/// ViewRef, a ViewRefControl's handle is unique. Scenic uses this property
+/// when it ties a ViewRefControl to a View, arranged to share fate. When a
+/// View is destroyed, the associated destruction of its ViewRefControl
+/// triggers an automatic `ZX_ERR_PEER_CLOSED` signal sent to all ViewRef
+/// holders; hence ViewRef holders may track View lifetime.
+///
+/// As part of View creation, the client creates a linked
+/// ViewRef/ViewRefControl pair and hands the pair to Scenic (ViewRef is
+/// described above). The client must not clone the ViewRefControl. It must
+/// not remove or modify the ViewRefControl's capabilities; otherwise the View
+/// is not created.
+struct ViewRefControl {
+ handle<eventpair> reference;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.ui.views/view_token.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.ui.views/view_token.fidl
new file mode 100644
index 0000000..bec47f1
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.ui.views/view_token.fidl
@@ -0,0 +1,27 @@
+// 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.
+
+library fuchsia.ui.views;
+
+/// Token that uniquely identifies an attachment point for a `View` in the
+/// global scene graph. Each `ViewHolderToken` has exactly one corresponding
+/// `ViewToken`.
+///
+/// A Scenic client can reference contents from another client by creating a
+/// `ViewHolder` resource using this token. The other client must also create
+/// a `View` resource using the corresponding `ViewToken`.
+struct ViewHolderToken {
+ handle<eventpair> value;
+};
+
+/// Token that uniquely identifies a `View`, which is the root point for a
+/// subgraph in the global scene graph. Each `ViewToken` has exactly one
+/// corresponding `ViewHolderToken`.
+///
+/// A Scenic client can have its contents referenced from another client by
+/// creating a `View` resource using this token. The other client must also
+/// create a `ViewHolder` resource using the corresponding `ViewHolderToken`.
+struct ViewToken {
+ handle<eventpair> value;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.update.channel/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.update.channel/BUILD.gn
new file mode 100644
index 0000000..9ca2bee
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.update.channel/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.update.channel") {
+ library_name = "channel"
+ namespace = "fuchsia.update"
+ public_deps = [
+ ]
+ sources = [
+ "channel.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.update.channel",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.update.channel/channel.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.update.channel/channel.fidl
new file mode 100644
index 0000000..f62b709
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.update.channel/channel.fidl
@@ -0,0 +1,14 @@
+// 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.
+
+library fuchsia.update.channel;
+
+/// Information about the state of the update system.
+[Discoverable]
+protocol Provider {
+ /// Retrieve the currently active update channel.
+ ///
+ /// - response `channel` the currently active update channel.
+ GetCurrent() -> (string:128 channel);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.update.channel/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.update.channel/meta.json
new file mode 100644
index 0000000..3c31c92
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.update.channel/meta.json
@@ -0,0 +1,9 @@
+{
+ "deps": [],
+ "name": "fuchsia.update.channel",
+ "root": "fidl/fuchsia.update.channel",
+ "sources": [
+ "fidl/fuchsia.update.channel/channel.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.update.channelcontrol/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.update.channelcontrol/BUILD.gn
new file mode 100644
index 0000000..53bbc15
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.update.channelcontrol/BUILD.gn
@@ -0,0 +1,26 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.update.channelcontrol") {
+ library_name = "channelcontrol"
+ namespace = "fuchsia.update"
+ public_deps = [
+ "../fuchsia.update.channel",
+ ]
+ sources = [
+ "channelcontrol.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.update.channelcontrol",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.update.channelcontrol/channelcontrol.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.update.channelcontrol/channelcontrol.fidl
new file mode 100644
index 0000000..29da1e1
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.update.channelcontrol/channelcontrol.fidl
@@ -0,0 +1,37 @@
+// 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.
+
+library fuchsia.update.channelcontrol;
+
+using fuchsia.update.channel;
+
+/// Control the target update channel, this is the channel we will use on the next update check.
+[Discoverable]
+protocol ChannelControl {
+ compose fuchsia.update.channel.Provider;
+
+ /// Set a new desired target channel. This tells the updater to attempt to
+ /// check for updates using a new channel. This is tentative, and won't be
+ /// persisted unless an update check on that channel is successful.
+ ///
+ /// A response is generated when the new target channel has been verified as
+ /// valid.
+ ///
+ /// + request `channel` the new target channel name (name used by the updater)
+ SetTarget(string:128 channel) -> ();
+
+ /// Get the current tentative target channel for updates.
+ /// This returns the channel that the update client is using to perform update
+ /// checks. It's always one of:
+ /// - the current channel
+ /// - the default channel
+ /// - a new target that's different, but hasn't been OTA'd from yet.
+ ///
+ /// - response `channel` the current target channel.
+ GetTarget() -> (string:128 channel);
+
+ /// Get the list of well-known target channels that can be passed to SetTarget().
+ /// There may be other, unlisted channels.
+ GetTargetList() -> (vector<string:128>:100 channels);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.update.channelcontrol/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.update.channelcontrol/meta.json
new file mode 100644
index 0000000..614b62f
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.update.channelcontrol/meta.json
@@ -0,0 +1,11 @@
+{
+ "deps": [
+ "fuchsia.update.channel"
+ ],
+ "name": "fuchsia.update.channelcontrol",
+ "root": "fidl/fuchsia.update.channelcontrol",
+ "sources": [
+ "fidl/fuchsia.update.channelcontrol/channelcontrol.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.update/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.update/BUILD.gn
new file mode 100644
index 0000000..35af0eb
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.update/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.update") {
+ library_name = "update"
+ namespace = "fuchsia"
+ public_deps = [
+ ]
+ sources = [
+ "update.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.update",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.update/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.update/meta.json
new file mode 100644
index 0000000..a80211f
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.update/meta.json
@@ -0,0 +1,9 @@
+{
+ "deps": [],
+ "name": "fuchsia.update",
+ "root": "fidl/fuchsia.update",
+ "sources": [
+ "fidl/fuchsia.update/update.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.update/update.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.update/update.fidl
new file mode 100644
index 0000000..d69f4b4
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.update/update.fidl
@@ -0,0 +1,257 @@
+// Copyright 2020 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.
+
+library fuchsia.update;
+
+/// The Manager protocol is used by a client that wishes to either check for an
+/// update, or follow the status of ongoing updates.
+///
+/// The Manager provides a mechanism for checking for updates via the
+/// [fuchisa.update2/Manager.CheckNow] message.
+[Discoverable]
+protocol Manager {
+ /// Immediately check for an update, and optionally track the state and
+ /// progress of that update check.
+ ///
+ /// + request `options`: Options for how this request should be performed.
+ /// E.g. What kind of entity initiated this request?
+ /// E.g. Is monitoring an existing update check that
+ /// is already in process an acceptable
+ /// alternative?
+ ///
+ /// + request `monitor`: An interface on which to receive the status events
+ /// for this update check. The monitor is only valid
+ /// for this single update check, after that it will
+ /// not receive any more notifications and will be
+ /// closed.
+ ///
+ /// * error If an update check cannot be started, an error will be returned.
+ /// The Monitor, if provided, will not receive any notifications.
+ CheckNow(CheckOptions options, Monitor? monitor)
+ -> () error CheckNotStartedReason;
+};
+
+/// These are configuration options for an update check.
+table CheckOptions {
+
+ /// Who or what initiated this update attempt. This is taken as input to
+ /// Policy, and may influence how the update check is performed.
+ ///
+ /// **This is a required field.**
+ 1: Initiator initiator;
+
+ /// If an update check is already in progress, it's acceptable to instead
+ /// attach a Monitor to that in-progress update instead of failing this
+ /// request to check for updates. This may convert situations that would
+ /// have resulted in the ALREADY_IN_PROGRESS to be treated as non-error
+ /// cases.
+ 2: bool allow_attaching_to_existing_update_check;
+};
+
+/// Who or what initiated the update check.
+enum Initiator {
+
+ /// The update check was initiated by an interactive user, or the user is
+ /// otherwise blocked and waiting for the result of this update check. This
+ /// SHOULD only be used when there is a UI element or flow that a user has
+ /// interacted with which has initiated this update check.
+ USER = 1;
+
+ /// The update check was initiated by a service, not a user-facing aspect
+ /// of the system.
+ SERVICE = 2;
+};
+
+/// This is a protocol that clients which wish to receive of updates for an
+/// individual update check should implement. This will not receive the events
+/// for more than one update check attempt.
+protocol Monitor {
+ /// This method is used to receive the current state as it changes. This
+ /// receive all state changes, skipping none. However, message delivery is
+ /// throttled by the rate at which the implementation acknowledges the
+ /// messages.
+ ///
+ /// The throttled delivery doesn't impact the underlying state of the
+ /// Manager. It does not wait for any acknowledgements before it moves on
+ /// to the next state in its state machine. The Manager will simply queue
+ /// up the states for the Monitor implementor to receive.
+ ///
+ /// During the installing_update state, the Manager implementation may, at
+ /// its discretion, collapse redundant information like the fraction
+ /// completed, in the event that the Monitor implementor is not
+ /// acknowledging the OnState() messages in a timely manner.
+ ///
+ /// 'state': The new state from the Manager.
+ ///
+ /// -> The implementor is ready to receive the next State from the Manager.
+ OnState(State state) -> ();
+};
+
+/// ```
+/// The set of states that a Monitor can receive as part of an update check are
+/// as follows. There are a number of terminal states for a single update
+/// check. They are the ones on the right-hand side of the diagram (and have no
+/// arrows leading out of them).
+///
+/// +----------------------+ +---------------------------------+
+/// | checking_for_updates |---->| error_checking_for_update |
+/// +----------------------+ +---------------------------------+
+/// |
+/// | +---------------------------------+
+/// +---------------->| no_update_available |
+/// | +---------------------------------+
+/// |
+/// | +---------------------------------+
+/// +---------------->| installation_deferred_by_policy |
+/// | +---------------------------------+
+/// v
+/// +----------------------+ +---------------------------------+
+/// | installing_update |---->| installation_error |
+/// +----------------------+ +---------------------------------+
+/// |
+/// | +---------------------------------+
+/// +---------------->| waiting_for_reboot |
+/// +---------------------------------+
+///
+/// ```
+union State {
+
+ /// The Manager is currently checking for an update.
+ ///
+ /// Next states:
+ /// * `installing_update` update is available and allowed by policy
+ /// * `error_checking_for_update` on error
+ /// * `update_deferred_by_policy` update is available but deferred by policy
+ 1: CheckingForUpdatesData checking_for_updates;
+
+ /// The Manager encountered an error while checking for the existence of a
+ /// a new update.
+ ///
+ /// **This is a terminal state**
+ ///
+ 2: ErrorCheckingForUpdateData error_checking_for_update;
+
+ /// There is not update available at this time.
+ ///
+ /// **This is a terminal state**
+ ///
+ 3: NoUpdateAvailableData no_update_available;
+
+ /// The Manager has found an available update but is not acting on it at
+ /// this time due to policy restrictions.
+ ///
+ /// **This is a terminal state**
+ ///
+ 4: InstallationDeferredData installation_deferred_by_policy;
+
+ /// The Manager is installing the available update.
+ ///
+ /// Next states:
+ /// * `waiting_for_reboot` on success
+ /// * `installation_error` on error
+ 5: InstallingData installing_update;
+
+ /// The update has been installed, and the device is waiting to be rebooted.
+ ///
+ /// Next states:
+ /// * (none, the device reboots)
+ ///
+ /// **This is a terminal state**
+ ///
+ 6: InstallingData waiting_for_reboot;
+
+ /// The Manager encountered an update in the installation of the update.
+ ///
+ /// **This is a terminal state**
+ ///
+ 7: InstallationErrorData installation_error;
+};
+
+/// This is the set of data associated with `checking_for_updates`.
+/// (currently none)
+table CheckingForUpdatesData {
+};
+
+/// This is the set of data associated with the `error_checking_for_update`
+/// state.
+/// (currently none)
+table ErrorCheckingForUpdateData {
+};
+
+/// This is the set of data associated with the `no_update_available` state.
+/// (currently none)
+table NoUpdateAvailableData {
+};
+
+/// This is the set of data associated with the
+/// `installation_deferred_by_policy` state.
+table InstallationDeferredData {
+ 1: UpdateInfo update;
+};
+
+/// This is the set of data associated with the states involved with installing
+/// an update:
+/// * `installing_update`
+/// * `waiting_for_reboot`
+table InstallingData {
+ 1: UpdateInfo update;
+ 2: InstallationProgress installation_progress;
+};
+
+/// This is the set of data associated with the `installation_error` state.
+/// (currently none)
+table InstallationErrorData {
+ 1: UpdateInfo update;
+ 2: InstallationProgress installation_progress;
+};
+
+/// This describes the update that is available to be installed.
+table UpdateInfo {
+ /// A string that describes the version that is available. This may be
+ /// either a semantic version (A.B.C.D) or an opaque hash. Clients MUST
+ /// not attempt to inspect this value, it is for display purposes only.
+ 1: string:MAX_VERSION_STRING_SIZE version_available;
+
+ /// The total number of bytes that may be downloaded to apply this update.
+ 2: uint64 download_size;
+};
+
+/// This is the maximum length of a version string that will be returned by the
+/// protocol
+const uint32 MAX_VERSION_STRING_SIZE = 128;
+
+/// This describes the progress installing the update that has been made so far.
+table InstallationProgress {
+ /// The fraction [0-1.0f] of the installation that has been completed.
+ 1: float32 fraction_completed;
+};
+
+/// This is the set of values that are returned by an request to immediately
+/// check for an update.
+enum CheckNotStartedReason {
+
+ /// There was an internal error in starting the update check. The client
+ /// is not expected to be able to do something meaningful about this error,
+ /// except to try again later (after an appropriate delay and back-off in
+ /// the event of multiple errors.
+ INTERNAL = 1;
+
+ /// If there are required options (or option values in conflict), provided
+ /// via the CheckOptions table to CheckNow, this error will be returned.
+ INVALID_OPTIONS = 2;
+
+ /// There was already another update check in progress when this request was
+ /// made. A new update check will not be started.
+ ALREADY_IN_PROGRESS = 3;
+
+ /// The update check was not started, because too many requests to check for
+ /// updates have been made by clients in a short period of time.
+ ///
+ /// **NOTE:** Clients MUST NOT attempt to cause background update checks to
+ /// happen at a more frequent rate than the fuchsia.update.Manager will do
+ /// them.
+ ///
+ /// If a client attempts to abuse this, it will be throttled.
+ THROTTLED = 4;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.url/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.url/BUILD.gn
new file mode 100644
index 0000000..03b0231
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.url/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.url") {
+ library_name = "url"
+ namespace = "fuchsia"
+ public_deps = [
+ ]
+ sources = [
+ "url.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.url",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.url/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.url/meta.json
new file mode 100644
index 0000000..82a4baa
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.url/meta.json
@@ -0,0 +1,9 @@
+{
+ "deps": [],
+ "name": "fuchsia.url",
+ "root": "fidl/fuchsia.url",
+ "sources": [
+ "fidl/fuchsia.url/url.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.url/url.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.url/url.fidl
new file mode 100644
index 0000000..cdbf7ea
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.url/url.fidl
@@ -0,0 +1,11 @@
+// Copyright 2020 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.
+
+library fuchsia.url;
+
+/// Some major applications limit URL length to 2083.
+const uint32 MAX_URL_LENGTH = 2083;
+
+/// A URL is used to reference a resource from a specified network location.
+using Url = string:MAX_URL_LENGTH;
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.weave/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.weave/BUILD.gn
new file mode 100644
index 0000000..cb40aff
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.weave/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.weave") {
+ library_name = "weave"
+ namespace = "fuchsia"
+ public_deps = [
+ ]
+ sources = [
+ "auth.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.weave",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.weave/auth.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.weave/auth.fidl
new file mode 100644
index 0000000..e37f56d
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.weave/auth.fidl
@@ -0,0 +1,38 @@
+// Copyright 2020 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.
+
+library fuchsia.weave;
+
+/// Error codes for WeaveKeyStore operations.
+enum ErrorCode {
+ /// Key/pairing code not found in storage.
+ FILE_NOT_FOUND = 1;
+ /// Error occurred during cryptographic operations.
+ CRYPTO_ERROR = 2;
+};
+
+/// This protocol is used for signing operations with the factory-provisioned
+/// Weave key.
+[Discoverable]
+protocol Signer {
+ /// Sign the provided |hash| with the factory provisioned key. On success
+ /// the result is returned in |signature|. The signature must be of a type
+ /// that is supported by Weave, and must take the standard form of an ASN.1
+ /// DER SEQUENCE. This operation must support SHA1 and SHA256 hash values.
+ ///
+ /// Currently, Weave only supports ECDSA signatures using the P224 curve,
+ /// however, to allow this protocol to support future changes to supported
+ /// Weave signatures the maximum size of the returned signature is set to
+ /// 139 bytes which is the largest amount of space needed to return an
+ /// encoded ECDSA P521 signature.
+ SignHash(bytes:32 hash) -> (bytes:139 signature) error ErrorCode;
+};
+
+/// This protocol is used to retrieve factory data that may be encrypted at
+/// rest.
+[Discoverable]
+protocol FactoryDataManager {
+ /// Return the device |pairing_code| on success.
+ GetPairingCode() -> (bytes:16 pairing_code) error ErrorCode;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.weave/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.weave/meta.json
new file mode 100644
index 0000000..b0897a5
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.weave/meta.json
@@ -0,0 +1,9 @@
+{
+ "deps": [],
+ "name": "fuchsia.weave",
+ "root": "fidl/fuchsia.weave",
+ "sources": [
+ "fidl/fuchsia.weave/auth.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.web/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.web/BUILD.gn
new file mode 100644
index 0000000..95d278f
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.web/BUILD.gn
@@ -0,0 +1,37 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.web") {
+ library_name = "web"
+ namespace = "fuchsia"
+ public_deps = [
+ "../fuchsia.io",
+ "../fuchsia.media.sessions2",
+ "../fuchsia.mem",
+ "../fuchsia.net.http",
+ "../fuchsia.ui.gfx",
+ "../fuchsia.ui.views",
+ ]
+ sources = [
+ "constants.fidl",
+ "context.fidl",
+ "cookie.fidl",
+ "debug.fidl",
+ "frame.fidl",
+ "navigation.fidl",
+ "url_request_rewrite_rules.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.web",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.web/constants.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.web/constants.fidl
new file mode 100644
index 0000000..7592c16
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.web/constants.fidl
@@ -0,0 +1,27 @@
+// 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.
+
+library fuchsia.web;
+
+// Most web browsers support up to 64 kiB maximum URL length.
+const int32 MAX_URL_LENGTH = 65536;
+using Url = string:MAX_URL_LENGTH;
+
+// There is no defined maximum length for schemes but this is a reasonable upper bound.
+const int32 MAX_URL_SCHEME_NAME_LENGTH = 255;
+using UrlSchemeName = string:MAX_URL_SCHEME_NAME_LENGTH;
+
+// RFC 1035 2.3.4 https://tools.ietf.org/html/rfc1035#section-2.3.4
+const int32 MAX_HOST_LENGTH = 255;
+using UrlHostName = string:MAX_HOST_LENGTH;
+
+// MAX_URL_SCHEME_NAME_LENGTH + 3 + MAX_HOST_LENGTH.
+const int32 MAX_SCHEME_AND_HOST_LENGTH = 513;
+using UrlSchemeAndHostName = string:MAX_SCHEME_AND_HOST_LENGTH;
+
+// Most servers support less than 16 kiB maximum header size. 4k max headers is a reasonable size.
+const int32 MAX_HEADERS_COUNT = 4096;
+
+// A maximum of 4k rules is enough for the current usage of these APIs.
+const int32 MAX_RULE_COUNT = 4096;
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.web/context.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.web/context.fidl
new file mode 100644
index 0000000..c85251b
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.web/context.fidl
@@ -0,0 +1,199 @@
+// 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.
+
+library fuchsia.web;
+
+using fuchsia.io;
+
+enum ContextError : int32 {
+ /// The remote debugging service was not opened.
+ REMOTE_DEBUGGING_PORT_NOT_OPENED = 1;
+};
+
+/// The top-level service interface which allows for the creation of Context resources.
+// TODO(fxb/29926): Remove ContextProvider in favor of launching Context instances directly.
+[Discoverable]
+protocol ContextProvider {
+ /// Creates a new browser [`fuchsia.web.Context`] whose state is wholly independent and
+ /// isolated from other Contexts.
+ ///
+ /// - `context`: An interface request which will receive a bound [`fuchsia.web.Context`]
+ /// service.
+ Create(CreateContextParams params, request<Context> context);
+};
+
+/// Defines a provider which hosts resources from a [`fuchsia.io.Directory`]. Content can `GET`
+/// resource files via the provider, but not enumerate directories. Resources can be accessed by
+/// their URLs: `fuchsia-dir://<provider-name>/<path/to/resource>`
+///
+/// By default the MIME types of files are determined automatically by "sniffing" the contents of
+/// the files. No content encoding will be declared, which browsers will interpret as meaning
+/// `"text/plain"`.
+///
+/// Content type and encoding metadata may optionally be specified explicitly by metadata files,
+/// which reside alongside the file. Metadata is expressed in JSON files, named after the files
+/// they describe with a `"._metadata"` suffix.
+///
+/// For example, the file `"index.html"` would have the a metadata file called
+/// `"index.html._metadata"`, with the following contents:
+/// ```
+/// {
+/// "charset": "utf-8",
+/// "mime": "text/html"
+/// }
+/// ```
+table ContentDirectoryProvider {
+ /// Name of the provider. Must be non-empty and composed solely of alphanumerics, dots, and
+ /// dashes.
+ 1: string:255 name;
+
+ /// Directory containing the files served by this provider.
+ 2: fuchsia.io.Directory directory;
+};
+
+/// Feature flags that allow augmenting Context behavior. Some features require additional services
+/// in the service directory provided during context initialization. See
+/// [`fuchsia.web.CreateContextParams/service_directory`].
+bits ContextFeatureFlags : uint64 {
+ /// Enables network access. Requires the following services:
+ /// - [`fuchsia.net.NameLookup`]
+ /// - [`fuchsia.netstack.Netstack`]
+ /// - [`fuchsia.posix.socket.Provider`]
+ NETWORK = 0x1;
+
+ /// Enables audio input and output. Requires [`fuchsia.media.Audio`] and
+ /// [`fuchsia.media.SessionAudioConsumerFactory`] service.
+ AUDIO = 0x2;
+
+ /// Enables GPU-accelerated rendering of the web content. Requires the following services:
+ /// - [`fuchsia.sysmem.Allocator`]
+ /// - [`fuchsia.vulkan.loader.Loader`]
+ VULKAN = 0x4;
+
+ /// Enables hardware video decoding. `VULKAN` must be enabled as well. Requires
+ /// [`fuchsia.mediacodec.CodecFactory`] service.
+ HARDWARE_VIDEO_DECODER = 0x8;
+
+ /// Disables all software video decoders. Videos will be rendered only if they can be decoded
+ /// in hardware using [`fuchsia.mediacodec.CodecFactory`].
+ /// Requires the [`HARDWARE_VIDEO_DECODER`] flag.
+ HARDWARE_VIDEO_DECODER_ONLY = 0x10;
+
+ /// Enables Widevine CDM modules for EME API. `VULKAN` feature must be enabled as well.
+ /// Requires [`fuchsia.media.drm.Widevine`] service.
+ WIDEVINE_CDM = 0x20;
+
+ /// Allows embedders to render web content without graphical output or Scenic.
+ /// Not compatible with the [`VULKAN`] flag.
+ HEADLESS = 0x40;
+
+ /// Report telemetry data to the [`fuchsia.legacymetrics.MetricsRecorder`].
+ LEGACYMETRICS = 0x80;
+};
+
+table CreateContextParams {
+ /// Service directory to be used by the context. The following services must be present in the
+ /// directory:
+ /// - [`fuchsia.accessibility.semantics.SemanticsManager`]
+ /// - [`fuchsia.device.NameProvider`]
+ /// - [`fuchsia.fonts.Provider`]
+ /// - [`fuchsia.intl.PropertyProvider`]
+ /// - [`fuchsia.logger.LogSink`]
+ /// - [`fuchsia.process.Launcher`]
+ ///
+ /// The following services must be present in order to present web content in a Scenic view
+ /// using [`fuchsia.web.Frame/CreateView`]:
+ /// - [`fuchsia.ui.input.ImeService`]
+ /// - [`fuchsia.ui.input.ImeVisibilityService`]
+ /// - [`fuchsia.ui.scenic.Scenic`]
+ 1: fuchsia.io.Directory service_directory;
+
+ /// Handle to the directory that will contain the [`fuchsia.web.Context`]'s persistent data. If
+ /// it is left unset, then the created [`fuchsia.web.Context`] will be stateless, with all of
+ /// its data discarded upon [`fuchsia.web.Context`] destruction.
+ ///
+ /// If set, `data_directory` must not be shared with any other [`fuchsia.web.Context`].
+ // TODO(fxb/29925): Provide an API to inform the caller when the `data_directory` can be safely
+ // removed.
+ 2: fuchsia.io.Directory data_directory;
+
+ /// Optional string describing the embedding product to append to the User-Agent string.
+ /// See the specification for the
+ /// [HTTP User-Agent header](https://tools.ietf.org/html/rfc7231#section-5.5.3).
+ /// Requires that `user_agent_version` is also specified.
+ 3: string:128 user_agent_product;
+
+ /// Optional version for the embedding product to append to the User-Agent string.
+ /// Requires that `user_agent_product` is also specified.
+ 4: string:128 user_agent_version;
+
+ /// Enables Frames to be created with remote debugging enabled using the DevTools protocol. If
+ /// `port` is 0, then an ephemeral port will be used, which can be queried via the
+ /// [`fuchsia.web.Context/GetRemoteDebuggingPort`] API.
+ 5: uint16 remote_debugging_port;
+
+ /// List of providers whose contents will be served by `fuchsia-dir://` URLs.
+ 6: vector<ContentDirectoryProvider>:100 content_directories;
+
+ /// Optional features that should be enabled for this context. Some features may also require
+ /// additional services in `service_directory`.
+ 7: ContextFeatureFlags features;
+
+ /// Enables PlayReady CDM for the Context using the specified string as a key system
+ /// string. The string should be a reverse domain name, as required by
+ /// [EME API](https://www.w3.org/TR/encrypted-media/#key-system). Requires
+ /// [`fuchsia.media.drm.PlayReady`] service.
+ 8: string:128 playready_key_system;
+
+ /// Treat given insecure origins as secure origins. For the definition of secure contexts, see
+ /// https://w3c.github.io/webappsec-secure-contexts/ and
+ /// https://www.w3.org/TR/powerful-features/#is-origin-trustworthy.
+ /// Example value: `{"http://a.com", "http://b.com"}`.
+ 9: vector<UrlSchemeAndHostName>:100 unsafely_treat_insecure_origins_as_secure;
+
+ /// Specifies a set of header names for which [Cross-Origin Resource Sharing
+ /// (CORS)](https://www.w3.org/TR/cors/) checks should not be enforced.
+ 10: vector<bytes:MAX>:MAX cors_exempt_headers;
+};
+
+/// Manages browsing state (e.g. LocalStorage, cookies, etc) associated with a set of
+/// [`fuchsia.web.Frame`].
+protocol Context {
+ /// Creates a new [`fuchsia.web.Frame`] under this [`fuchsia.web.Context`]. Destruction of a
+ /// [`fuchsia.web.Context`] triggers the destruction of all of its associated
+ /// [`fuchsia.web.Frame`]. [`fuchsia.web.Frame`] can be transferred to another component but
+ /// cannot be shared across multiple components.
+ ///
+ /// - `frame`: An interface request that will be bound to the created [`fuchsia.web.Frame`].
+ CreateFrame(request<Frame> frame);
+
+ /// Similar to [`fuchsia.web.Context/CreateFrame`], with extra parameters.
+ [Transitional]
+ CreateFrameWithParams(CreateFrameParams params, request<Frame> frame);
+
+ /// Used to observe cookies for sites hosted under this Context.
+ [Transitional]
+ GetCookieManager(request<CookieManager> manager);
+
+ /// Waits until debugging is available on one or more Frames, and returns the DevTools port
+ /// number. Multiple calls may be queued to received the port number.
+ ///
+ /// If an error occured, the [`fuchsia.web.ContextError`] will be set to this value:
+ /// - `REMOTE_DEBUGGING_PORT_NOT_OPENED`: `remote_debugging_port` was not set in
+ /// [`fuchsia.web.CreateContextParams`] or the remote debugging service failed to start.
+ GetRemoteDebuggingPort() -> (uint16 port) error ContextError;
+};
+
+table CreateFrameParams {
+ /// Set to true to enable remote debugging. The [`fuchsia.web.Frame`] will be closed with
+ /// `ERR_INVALID_ARGS` if `remote_debugging_port` was not set in
+ /// [`fuchsia.web.CreateContextParams`].
+ 1: bool enable_remote_debugging;
+
+ /// Set to give the Frame a name to help distinguish it in debug contexts , such as system log
+ /// output. For example, the name may be added to messages from web content when they are logged
+ /// to the system logger. The name does not affect user- or web-visible behavior.
+ /// Popup Frames created by the Frame will have a name derived from the parent Frame's name.
+ 2: string:MAX debug_name;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.web/cookie.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.web/cookie.fidl
new file mode 100644
index 0000000..63aae13
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.web/cookie.fidl
@@ -0,0 +1,54 @@
+// 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.
+
+library fuchsia.web;
+
+using CookieName = string;
+
+/// Provides methods for monitoring and accessing browser cookie state.
+protocol CookieManager {
+ /// Observe changes to all cookies named `name` that would be sent in a request to `url`.
+ ///
+ /// If neither `url` nor `name` are set then all cookies are observed. If only `url` is set
+ /// then all cookies for that URL are observed. If both are set then only cookies matching both
+ /// fields are observed.
+ ///
+ /// `changes` iterates over a stream of cookie changes. Additions or updates are expressed as
+ /// complete cookies, while deletions are expressed as cookies with no `value` set.
+ ObserveCookieChanges(
+ Url? url,
+ CookieName? name,
+ request<CookiesIterator> changes);
+
+ /// Returns a list of Cookies, optionally limited to those matching `url`, and optionally
+ /// `name`. `cookies` iterates over the matching cookies, including their `value`s.
+ GetCookieList(Url? url,
+ CookieName? name,
+ request<CookiesIterator> cookies);
+};
+
+/// Used to iterator over a set of cookies, or a stream of changes to cookies.
+protocol CookiesIterator {
+ /// Fetches the next batch of cookies, or of changes to cookies.
+ GetNext() -> (vector<Cookie> changed_cookies);
+};
+
+table CookieId {
+ /// The name of the cookie. An arbitrary string defined by the website.
+ 1: CookieName name;
+
+ /// Specifies the host that is allowed to receive the cookie.
+ 2: string domain;
+
+ /// Specifies the URL path prefix which is required to receive the cookie.
+ 3: string path;
+};
+
+table Cookie {
+ /// A table with fields to identify a cookie.
+ 1: CookieId id;
+
+ /// The cookie value.
+ 2: string value;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.web/debug.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.web/debug.fidl
new file mode 100644
index 0000000..cee9371
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.web/debug.fidl
@@ -0,0 +1,35 @@
+// 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.
+
+library fuchsia.web;
+
+/// The debug service which allows to enable the DevTools service on Contexts.
+[Discoverable]
+protocol Debug {
+ /// Enables the DevTools service on every subsequent Context creation and
+ /// and delivers subsequent DevTools events to the supplied `listener`.
+ /// The callback indicates when the WebEngine is in a debuggable state.
+ /// Events will be sent to every `listener` registered with this method.
+ EnableDevTools(DevToolsListener listener) -> ();
+};
+
+/// Interface used to observe DevTools service availability events.
+protocol DevToolsListener {
+ /// Called when the DevTools service is available on a new Context.
+ ///
+ /// `listener`: Channel over which DevTools events for the new Context will
+ /// be delivered. This channel will disconnect when the Context
+ /// is detroyed.
+ OnContextDevToolsAvailable(request<DevToolsPerContextListener> listener);
+};
+
+/// Interface supplied by the debugging component to observe the DevTools
+/// service opening event.
+protocol DevToolsPerContextListener {
+ /// Called when the DevTools service starts accepting TCP connections on
+ /// `port`. `port` will remain open until the Context is destroyed.
+ ///
+ /// `port`: The port used by the service.
+ OnHttpPortOpen(uint16 port);
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.web/frame.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.web/frame.fidl
new file mode 100644
index 0000000..f772548
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.web/frame.fidl
@@ -0,0 +1,350 @@
+// 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.
+
+library fuchsia.web;
+
+using fuchsia.media.sessions2;
+using fuchsia.mem;
+using fuchsia.ui.gfx;
+using fuchsia.ui.views;
+
+// TODO(fxb/29927): Consider using [`fuchsia.logger.LogLevelFilter`] if possible.
+enum ConsoleLogLevel : int32 {
+ /// No logging.
+ NONE = 100;
+
+ /// Outputs messages from `console.debug()` and above levels.
+ DEBUG = -1;
+
+ /// Outputs messages from `console.log()`, `console.info()` and above levels.
+ INFO = 0;
+
+ /// Outputs messages from `console.warn()` and `console.error()`.
+ WARN = 1;
+
+ /// Outputs messages from `console.error()`.
+ ERROR = 2;
+};
+
+/// Identifies the types of input events which may be handled by a View.
+bits InputTypes : uint64 {
+ /// Keyboard events.
+ KEY = 0x1;
+
+ /// Mouse button events, for any button.
+ MOUSE_CLICK = 0x2;
+
+ /// Mouse scroll wheel events.
+ MOUSE_WHEEL = 0x4;
+
+ /// Mouse movement events.
+ MOUSE_MOVE = 0x8;
+
+ /// Single tapping with one finger.
+ GESTURE_TAP = 0x10;
+
+ /// Pinching (for zooming).
+ GESTURE_PINCH = 0x20;
+
+ /// Dragging a finger (for scrolling).
+ GESTURE_DRAG = 0x40;
+
+ /// Matches all input types.
+ ALL = 0x8000000000000000;
+};
+
+/// Controls whether ConfigureInputTypes() should allow or deny processing of
+/// the specified [`fuchsia.web.InputTypes`].
+enum AllowInputState : int32 {
+ ALLOW = 1;
+ DENY = 2;
+};
+
+/// Represents the return status of a [`fuchsia.web.Frame`] method.
+enum FrameError : int32 {
+ /// An internal error occured.
+ INTERNAL_ERROR = 1;
+
+ /// The provided buffer is not UTF-8 encoded.
+ BUFFER_NOT_UTF8 = 2;
+
+ /// The Frame's URL does not match any of the origins provided by the caller.
+ INVALID_ORIGIN = 3;
+
+ /// The required `data` property is missing from a [`fuchsia.web.WebMessage`].
+ NO_DATA_IN_MESSAGE = 4;
+};
+
+/// Identifies a type of permission that may be granted to a web origin.
+enum PermissionType : uint16 {
+ /// Permission to access microphone(s).
+ MICROPHONE = 1;
+
+ /// Permission to access camera(s).
+ CAMERA = 2;
+
+ /// Permission to use device identifier(s) for EME.
+ PROTECTED_MEDIA_IDENTIFIER = 3;
+
+ /// Permission to use persistent storage.
+ PERSISTENT_STORAGE = 4;
+};
+
+/// Describes a web permission. In the future, it may be extended with
+/// type-specific fields.
+table PermissionDescriptor {
+ 1: PermissionType type;
+};
+
+/// A state for a web permission.
+enum PermissionState : uint8 {
+ /// Permission is denied.
+ DENIED = 1;
+
+ /// Permission is granted.
+ GRANTED = 2;
+};
+
+protocol Frame {
+ /// Creates a new view using the specified `view_token`. Caller should pass the other end of
+ /// the token to [`fuchsia.ui.gfx.ViewHolderArgs/token`] to attach the new view to a view tree.
+ ///
+ /// - `view_token`: Token for the new view.
+ CreateView(fuchsia.ui.views.ViewToken view_token);
+
+ /// Enables headless rendering of the Frame.
+ /// This is used when content depends on layout and/or animation events firing normally.
+ /// May only be used on a Context created with the `HEADLESS` feature flag.
+ [Transitional]
+ EnableHeadlessRendering();
+
+ /// Stops headless rendering of the Frame.
+ /// May only be used on a Context created with the `HEADLESS` feature flag.
+ [Transitional]
+ DisableHeadlessRendering();
+
+ /// Returns a [`fuchsia.media.sessions2.Player`] interface through which media (i.e.
+ /// video/audio) playback in the frame may be observed, and/or controlled. Only one
+ /// [`fuchsia.media.sessions2.Player`] may be active at a time, for each [`fuchsia.web.Frame`].
+ [Transitional]
+ GetMediaPlayer(request<fuchsia.media.sessions2.Player> player);
+
+ /// Returns an interface through which the [`fuchsia.web.Frame`] may be navigated to a desired
+ /// URL, reloaded, etc.
+ ///
+ /// - `controller`: An asynchronous interface request for the [`fuchsia.web.Frame`]'s
+ /// [`fuchsia.web.NavigationController`].
+ GetNavigationController(request<NavigationController> controller);
+
+ /// Executes a UTF-8 encoded `script` in the [`fuchsia.web.Frame`] if the
+ /// [`fuchsia.web.Frame`]'s URL has an origin which matches entries in `origins`.
+ ///
+ /// At least one `origins` entry must be specified. If a wildcard `"*"` is specified in
+ /// `origins`, then the script will be evaluated unconditionally.
+ ///
+ /// Returns the result of executing `script`, as a JSON-encoded string.
+ ///
+ /// Note that scripts share the same execution context as the document,
+ /// meaning that document may modify variables, classes, or objects set by
+ /// the script in arbitrary or unpredictable ways.
+ ///
+ /// If an error occured, the FrameError will be set to one of these values:
+ /// - `BUFFER_NOT_UTF8`: `script` is not UTF-8 encoded.
+ /// - `INVALID_ORIGIN`: The [`fuchsia.web.Frame`]'s current URL does not match any of the
+ /// values in `origins` or `origins` is an empty vector.
+ // TODO(crbug.com/900391): Investigate if we can run the scripts in isolated JS worlds.
+ ExecuteJavaScript(
+ vector<Url> origins,
+ fuchsia.mem.Buffer script)
+ -> (fuchsia.mem.Buffer result) error FrameError;
+
+ /// Variant of [`fuchsia.web.Frame/ExecuteJavaScript`] which executes the supplied script
+ /// without returning a result.
+ ExecuteJavaScriptNoResult(
+ vector<Url> origins,
+ fuchsia.mem.Buffer script)
+ -> () error FrameError;
+
+ /// Executes a UTF-8 encoded `script` for every subsequent page load where the
+ /// [`fuchsia.web.Frame`]'s URL has an origin reflected in `origins`. The script is executed
+ /// early, prior to the execution of the document's scripts.
+ ///
+ /// Scripts are identified by a client-managed identifier `id`. Any script previously injected
+ /// using the same `id` will be replaced.
+ ///
+ /// The order in which multiple bindings are executed is the same as the order in which the
+ /// bindings were added. If a script is added which clobbers an existing script of the same
+ /// `id`, the previous script's precedence in the injection order will be preserved.
+ ///
+ /// At least one `origins` entry must be specified. If a wildcard `"*"` is specified in
+ /// `origins`, then the script will be evaluated unconditionally.
+ ///
+ /// If an error occured, the [`fuchsia.web.FrameError`] will be set to one of these values:
+ /// - `BUFFER_NOT_UTF8`: `script` is not UTF-8 encoded.
+ /// - `INVALID_ORIGIN`: `origins` is an empty vector.
+ AddBeforeLoadJavaScript(
+ uint64 id,
+ vector<Url> origins,
+ fuchsia.mem.Buffer script)
+ -> () error FrameError;
+
+ /// Removes a previously added JavaScript snippet identified by `id`. This is a no-op if there
+ /// is no JavaScript snippet identified by `id`.
+ RemoveBeforeLoadJavaScript(uint64 id);
+
+ /// Posts a message to the frame's onMessage handler.
+ ///
+ /// `target_origin` restricts message delivery to the specified origin. If `target_origin` is
+ /// `"*"`, then the message will be sent to the document regardless of its origin.
+ /// See the
+ /// [https://html.spec.whatwg.org/multipage/web-messaging.html#posting-messages](HTML spec)
+ /// section 9.4.3 for more details on how the target origin policy is applied.
+ ///
+ /// If an error occured, the [`fuchsia.web.FrameError`] will be set to one of these values:
+ /// - `INTERNAL_ERROR`: The WebEngine failed to create a message pipe.
+ /// - `BUFFER_NOT_UTF8`: The script in `message`'s `data` property is not UTF-8 encoded.
+ /// - `INVALID_ORIGIN`: `origins` is an empty vector.
+ /// - `NO_DATA_IN_MESSAGE`: The `data` property is missing in `message`.
+ PostMessage(Url target_origin, WebMessage message)
+ -> () error FrameError;
+
+ /// Sets the listener for handling page navigation events.
+ ///
+ /// - `listener`: The observer to use. Unregisters any existing listener is null.
+ SetNavigationEventListener(NavigationEventListener? listener);
+
+ /// If set to a value other than [`fuchsia.web.ConsoleLogLevel/NONE`], allows web content to
+ /// log messages to the system logger using the console APIs (`debug()`, `log()`, `info()`,
+ /// `warn()` and `error()`).
+ /// The default value is [`fuchsia.web.ConsoleLogLevel/NONE`].
+ ///
+ /// As the system log may be persisted, it is recommended that
+ /// [`fuchsia.web.ConsoleLogLevel/NONE`] be used in Incognito and other private browsing modes.
+ ///
+ /// When logged to the system logger:
+ /// - `debug()`, `log()` and `info()` logs are logged with
+ /// [`fuchsia.logger.LogLevelFilter/INFO`] severity level.
+ /// - `warn()` logs are logged with [`fuchsia.logger.LogLevelFilter/WARNING`] severity level.
+ /// - `error()` logs are logged with [`fuchsia.logger.LogLevelFilter/ERROR`] severity level.
+ SetJavaScriptLogLevel(ConsoleLogLevel level);
+
+ [Transitional, Deprecated]
+ SetEnableInput(bool enable_input);
+
+ /// Enables or disables the processing of the specified `types` of user inputs.
+ /// `enable` specifies whether to enable or disable the specified `types`.
+ /// All input types are enabled by default.
+ [Transitional]
+ ConfigureInputTypes(InputTypes types, AllowInputState allow);
+
+ /// Sets the listener for handling popup frame opened by web content. If no listener is
+ /// present, then any new popup frame will be blocked.
+ ///
+ /// - `listener`: The listener to use. Unregisters any existing listener if null.
+ SetPopupFrameCreationListener(PopupFrameCreationListener? listener);
+
+ /// Supplies a set of [`fuchsia.web.UrlRequestRewriteRule`] to apply on every subsequent URL
+ /// request.
+ /// - `rules` are cumulative and applied in order.
+ /// - `rules` will be validated before being applied. If `rules` are invalid, the
+ /// [`fuchsia.web.Frame`] will be closed with `ERR_INVALID_ARGS`.
+ /// - [`fuchsia.web.Frame/SetUrlRequestRewriteRules`] must not be called again until its
+ /// acknowledgement callback has been processed. If this happens, the [`fuchsia.web.Frame`]
+ /// will be closed with `ERR_BAD_STATE`.
+ SetUrlRequestRewriteRules(vector<UrlRequestRewriteRule>:MAX_RULE_COUNT rules) -> ();
+
+ /// Sets `session_id` to pass to the [`fuchsia.media.AudioConsumer`] when playing audio. The
+ /// specified value is not applied retroactively to audio streams that were started before this
+ /// message is processed. If the caller needs to ensure the value is applied to all streams it
+ /// should call this method before [`fuchsia.web.Frame/GetNavigationController`].
+ [Transitional]
+ SetMediaSessionId(uint64 session_id);
+
+ /// Overrides the dimensions reported to web content. The devicePixelRatio reported to
+ /// web content will be adjusted in response to changes in the pixel size of the View,
+ /// rather than changing the size reported to the content. Call with null `web_dips` to
+ /// remove any prior forced content dimensions.
+ [Transitional]
+ ForceContentDimensions(fuchsia.ui.gfx.vec2? web_dips);
+
+ /// Sets the permission state for the specified `permission` and `web_origin`. By default, all
+ /// permissions are denied.
+ [Transitional]
+ SetPermissionState(PermissionDescriptor permission,
+ Url web_origin,
+ PermissionState state);
+
+ /// Sets whether to block all HTMLMediaElements in the frame from fetching and loading media
+ /// resources.
+ /// May be used, for example, to prevent loading media in frames that are not visible.
+ ///
+ /// While media loading is blocked, elements with `autoplay` set to `true` will not start
+ /// playback. The promises returned by calls to `play()` will remain unresolved until loading is
+ /// unblocked by a call to this method.
+ /// When media loading is unblocked, elements will begin fetching, resource, loading, and
+ /// playing as appropriate.
+ ///
+ /// Any elements that have begun fetching or loading media resources for the current source
+ /// before media loading was blocked will continue to fetch, load, and start playback as
+ /// appropriate. This includes calls to `play()` even after media loading is blocked.
+ [Transitional]
+ SetBlockMediaLoading(bool blocked);
+};
+
+table WebMessage {
+ /// The message payload, encoded as an UTF-8 string. This is a required property.
+ 1: fuchsia.mem.Buffer data;
+
+ /// Optional list of objects transferred into the [`fuchsia.web.MessagePort`] from the FIDL
+ /// client.
+ 2: vector<IncomingTransferable> incoming_transfer;
+
+ /// Optional list of objects transferred out of the [`fuchsia.web.MessagePort`] to the FIDL
+ /// client.
+ 3: vector<OutgoingTransferable> outgoing_transfer;
+};
+
+flexible union OutgoingTransferable {
+ 1: request<MessagePort> message_port;
+};
+
+flexible union IncomingTransferable {
+ 1: MessagePort message_port;
+};
+
+/// Represents one end of an HTML5 MessageChannel. Can be used to send and exchange Messages with
+/// the peered MessagePort in the Frame's script context. The port is destroyed when either end of
+/// the MessagePort channel is torn down.
+protocol MessagePort {
+ /// Sends a [`fuchsia.web.WebMessage`] to the peer. These are processed in order, one at a
+ /// time. It is not necessary for the caller to wait for the completion callback before calling
+ /// [`fuchsia.web.MessagePort/PostMessage`] again.
+ ///
+ /// If an error occured, the [`fuchsia.web.FrameError`] will be set to one of these value:
+ /// - `BUFFER_NOT_UTF8`: The script in `message`'s `data` property is not UTF-8 encoded.
+ /// - `NO_DATA_IN_MESSAGE`: The `data` property is missing in `message`.
+ PostMessage(WebMessage message) -> () error FrameError;
+
+ /// Asynchronously reads the next message from the channel. The client should invoke the
+ /// callback when it is ready to process another message. Unreceived messages are buffered
+ /// on the sender's side and bounded by its available resources.
+ ReceiveMessage() -> (WebMessage message);
+};
+
+/// Specifies additional information about a newly created popup frame.
+table PopupFrameCreationInfo {
+ /// The URL to which the popup frame was initially navigated.
+ 1: Url initial_url;
+
+ /// Set if the popup frame was created in response to UI interaction from the user (e.g. a
+ /// link was clicked).
+ 2: bool initiated_by_user;
+};
+
+protocol PopupFrameCreationListener {
+ /// Called when a [`fuchsia.web.Frame`] has created a new popup `frame`. Information about the
+ /// popup frame, and how it was created, is provided via `info`. Additional popup frames are
+ /// delivered after the the acknowledgement callback is invoked.
+ OnPopupFrameCreated(Frame frame, PopupFrameCreationInfo info) -> ();
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.web/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.web/meta.json
new file mode 100644
index 0000000..6baf704
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.web/meta.json
@@ -0,0 +1,22 @@
+{
+ "deps": [
+ "fuchsia.media.sessions2",
+ "fuchsia.net.http",
+ "fuchsia.ui.gfx",
+ "fuchsia.ui.views",
+ "fuchsia.io",
+ "fuchsia.mem"
+ ],
+ "name": "fuchsia.web",
+ "root": "fidl/fuchsia.web",
+ "sources": [
+ "fidl/fuchsia.web/constants.fidl",
+ "fidl/fuchsia.web/context.fidl",
+ "fidl/fuchsia.web/cookie.fidl",
+ "fidl/fuchsia.web/debug.fidl",
+ "fidl/fuchsia.web/frame.fidl",
+ "fidl/fuchsia.web/navigation.fidl",
+ "fidl/fuchsia.web/url_request_rewrite_rules.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.web/navigation.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.web/navigation.fidl
new file mode 100644
index 0000000..ab8b8da
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.web/navigation.fidl
@@ -0,0 +1,128 @@
+// 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.
+
+library fuchsia.web;
+
+using fuchsia.net.http;
+
+/// Interface supplied by the embedder for receiving notifications about navigation events in a
+/// [`fuchsia.web.Frame`].
+protocol NavigationEventListener {
+ /// Called when user-visible navigation state has changed since [`fuchsia.web.Frame`] creation
+ /// or the last acknowledgement callback, whichever occurred last. `change` will contain all
+ /// the differences in navigation state since the last acknowledgement. Any unchanged
+ /// properties will be left unset in `change`.
+ ///
+ /// Implementer must call the acknowledgement callback to receive new navigation events.
+ OnNavigationStateChanged(NavigationState change) -> ();
+};
+
+/// Represents the return status of a [`fuchsia.web.NavigationController`] method.
+enum NavigationControllerError : int32 {
+ /// The provided URL is invalid.
+ INVALID_URL = 1;
+
+ /// At least one of the provided headers was invalid.
+ INVALID_HEADER = 2;
+};
+
+/// Provides methods for controlling and querying the navigation state of a [`fuchsia.web.Frame`].
+protocol NavigationController {
+ /// Tells the [`fuchsia.web.Frame`] to navigate to a `url`.
+ ///
+ /// - `url`: The address to navigate to.
+ /// - `params`: Additional parameters that affect how the resource will be
+ /// loaded (e.g. cookies, HTTP headers, etc.)
+ ///
+ /// If an error occured, the [`fuchsia.web.NavigationControllerError`] will be set to one of
+ /// these values:
+ /// - `INVALID_URL`: The `url` parameter is invalid.
+ /// - `INVALID_HEADER`: At least one of the headers in [`fuchsia.web.LoadUrlParams/headers`]
+ /// is invalid.
+ LoadUrl(Url url, LoadUrlParams params)
+ -> () error NavigationControllerError;
+
+ /// Tells the [`fuchsia.web.Frame`] to navigate to the previous page in its history, if any.
+ GoBack();
+
+ /// Tells the [`fuchsia.web.Frame`] to navigate to the next page in its history, if any.
+ GoForward();
+
+ /// Tells the [`fuchsia.web.Frame`] to stop the current navigation if a navigation is ongoing.
+ Stop();
+
+ /// Tells the [`fuchsia.web.Frame`] to reload the current page.
+ Reload(ReloadType type);
+
+ /// Returns information for the currently visible content regardless of loading state, or an
+ /// empty entry if no content is being displayed.
+ GetVisibleEntry() -> (NavigationState entry);
+};
+
+/// Additional parameters for modifying the behavior of
+/// [`fuchsia.web.NavigationController/LoadUrl`].
+table LoadUrlParams {
+ /// Provides a hint to the browser UI about how [`fuchsia.web.NavigationController/LoadUrl`]
+ /// was triggered.
+ 1: LoadUrlReason type;
+
+ /// The URL that linked to the resource being requested.
+ 2: Url referrer_url;
+
+ /// Should be set to true to propagate user activation to the frame. User activation implies
+ /// that the user is interacting with the web frame. It enables some web features that are not
+ /// available otherwise. For example, autoplay will work only when this flag is set to true.
+ 3: bool was_user_activated;
+
+ /// Custom HTTP headers.
+ 4: vector<fuchsia.net.http.Header> headers;
+};
+
+/// Contains information about the [`fuchsia.web.Frame`]'s navigation state.
+table NavigationState {
+ /// The page's URL.
+ 1: Url url;
+
+ /// The user-visible page title.
+ 2: string title;
+
+ /// Indicates whether this was a navigation to an error page.
+ 3: PageType page_type;
+
+ /// Indicates if there is a following navigation.
+ 4: bool can_go_forward;
+
+ /// Indicates if there is a previous navigation.
+ 5: bool can_go_back;
+
+ /// Indicates that the main document's statically declared resources have been loaded.
+ 6: bool is_main_document_loaded;
+};
+
+/// Characterizes the type of reload.
+enum ReloadType : uint32 {
+ /// Reloads the current entry, bypassing the cache for the main resource.
+ PARTIAL_CACHE = 0;
+
+ /// Reloads the current entry, bypassing the cache entirely.
+ NO_CACHE = 1;
+};
+
+/// Characterizes the origin of a [`fuchsia.web.NavigationController/LoadUrl`] request.
+enum LoadUrlReason : uint32 {
+ /// Navigation was initiated by the user following a link.
+ LINK = 0;
+
+ /// Navigation was initiated by a user-provided URL.
+ TYPED = 1;
+};
+
+/// Characterizes the page type in a [`fuchsia.web.NavigationState`].
+enum PageType {
+ /// Regular web page.
+ NORMAL = 0;
+
+ /// Error page.
+ ERROR = 1;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.web/url_request_rewrite_rules.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.web/url_request_rewrite_rules.fidl
new file mode 100644
index 0000000..1032875
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.web/url_request_rewrite_rules.fidl
@@ -0,0 +1,95 @@
+// 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.
+
+library fuchsia.web;
+
+using fuchsia.net.http;
+
+table UrlRequestRewriteRule {
+ /// Set of hosts to apply the rules to. If not set, the rule will apply to every request,
+ /// independent of host.
+ 1: vector<UrlHostName>:MAX_RULE_COUNT hosts_filter;
+
+ /// Set of schemes to apply the rules to. If not set, the rule will apply to every request,
+ /// independent of scheme.
+ 2: vector<UrlSchemeName>:MAX_RULE_COUNT schemes_filter;
+
+ /// URL request rewrites to apply.
+ 3: vector<UrlRequestRewrite>:MAX_RULE_COUNT rewrites;
+
+ /// Specifies the action to take for requests matching the filter criteria.
+ /// Requests are allowed by default.
+ 4: UrlRequestAction action;
+};
+
+enum UrlRequestAction : int32 {
+ /// Allow the request to be processed.
+ ALLOW = 1;
+
+ /// Block the request.
+ DENY = 2;
+};
+
+flexible union UrlRequestRewrite {
+ /// Adds a set of headers to a URL request.
+ 1: UrlRequestRewriteAddHeaders add_headers;
+
+ /// Removes a header based on the presence of a pattern in the URL query.
+ 2: UrlRequestRewriteRemoveHeader remove_header;
+
+ /// Substitutes a pattern in the URL query.
+ 3: UrlRequestRewriteSubstituteQueryPattern substitute_query_pattern;
+
+ /// Replaces a URL if the original URL ends with a pattern.
+ 4: UrlRequestRewriteReplaceUrl replace_url;
+
+ /// Adds to the URL query.
+ 5: UrlRequestRewriteAddQuery add_query;
+};
+
+/// Adds `headers` to the URL request. If a header is already present in the original URL request,
+/// it will be overwritten.
+/// - `headers` must be set.
+/// - Each [`fuchsia.net.http.Header`] in `headers` must have a valid HTTP header name and value,
+/// per [RFC 7230 section 3.2](https://tools.ietf.org/html/rfc7230#section-3.2).
+table UrlRequestRewriteAddHeaders {
+ 1: vector<fuchsia.net.http.Header>:MAX_HEADERS_COUNT headers;
+};
+
+/// If `query_pattern` in the URL query, removes `header_name` from the list of headers. If
+/// `query_pattern` is not set, removes `header_name` from the list of headers unconditionally.
+/// - `header_name` must be set.
+/// - `header_name` must be a valid HTTP header name, per
+/// [RFC 7230 section 3.2](https://tools.ietf.org/html/rfc7230#section-3.2).
+table UrlRequestRewriteRemoveHeader {
+ 1: Url query_pattern;
+ 2: bytes:MAX_HEADERS_COUNT header_name;
+};
+
+/// If `pattern` is found in the URL request query, replaces it with `substitution`.
+/// - `pattern` and `substitution` must be set.
+/// - `substitution` must be a valid
+/// [URL-query string](https://url.spec.whatwg.org/#url-query-string).
+table UrlRequestRewriteSubstituteQueryPattern {
+ 1: Url pattern;
+ 2: Url substitution;
+};
+
+/// If the URL in the URL request ends with `url_ends_with`, rewrites the URL to `new_url`.
+/// - `url_ends_with` and `new_url` must be set.
+/// - `url_ends_with` must be a valid
+/// [path-relative-URL string](https://url.spec.whatwg.org/#path-relative-url-string).
+/// - `new_url` must be a [valid URL string](https://url.spec.whatwg.org/#valid-url-string).
+table UrlRequestRewriteReplaceUrl {
+ 1: Url url_ends_with;
+ 2: Url new_url;
+};
+
+/// Adds the specified `query` parameters to the query section of the URL, creating a query section
+/// if none exists.
+/// - `query` must be set.
+/// - `query` must be a valid [URL-query string](https://url.spec.whatwg.org/#url-query-string).
+table UrlRequestRewriteAddQuery {
+ 1: Url query;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.wlan.common/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.wlan.common/BUILD.gn
new file mode 100644
index 0000000..31a917d
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.wlan.common/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.wlan.common") {
+ library_name = "common"
+ namespace = "fuchsia.wlan"
+ public_deps = [
+ ]
+ sources = [
+ "wlan_common.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.wlan.common",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.wlan.common/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.wlan.common/meta.json
new file mode 100644
index 0000000..8fe4fd4
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.wlan.common/meta.json
@@ -0,0 +1,9 @@
+{
+ "deps": [],
+ "name": "fuchsia.wlan.common",
+ "root": "fidl/fuchsia.wlan.common",
+ "sources": [
+ "fidl/fuchsia.wlan.common/wlan_common.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.wlan.common/wlan_common.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.wlan.common/wlan_common.fidl
new file mode 100644
index 0000000..9067e5a
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.wlan.common/wlan_common.fidl
@@ -0,0 +1,73 @@
+// Copyright 2018 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.
+
+library fuchsia.wlan.common;
+
+enum RequestStatus {
+ ACKNOWLEDGED = 0;
+ REJECTED_NOT_SUPPORTED = 1;
+ REJECTED_INCOMPATIBLE_MODE = 2;
+ REJECTED_ALREADY_IN_USE = 3;
+ REJECTED_DUPLICATE_REQUEST = 4;
+};
+
+// LINT analyzer keyword intended for humans:
+// LINT.IfChange
+
+enum PHY {
+ /// IEEE 802.11b, used for DSSS, HR/DSSS, ERP-DSSS/CCK
+ HR = 1;
+ /// IEEE 802.11a/g, used for ERP-OFDM
+ ERP = 2;
+ /// IEEE 802.11n
+ HT = 3;
+ /// IEEE 802.11ac
+ VHT = 4;
+ /// IEEE 802.11ax
+ HEW = 5;
+};
+
+enum CBW { // Channel Bandwidth
+ CBW20 = 0;
+ CBW40 = 1;
+ //CBW40ABOVE = CBW40;
+ CBW40BELOW = 2;
+ CBW80 = 3;
+ CBW160 = 4;
+ CBW80P80 = 5;
+};
+
+struct WlanChan {
+ uint8 primary;
+ CBW cbw;
+ uint8 secondary80;
+};
+
+enum Band : uint8 {
+ WLAN_BAND_2GHZ = 0;
+ WLAN_BAND_5GHZ = 1;
+ WLAN_BAND_COUNT = 2;
+};
+
+// LINT.ThenChange(//zircon/system/banjo/ddk.protocol.wlan.info/info.banjo)
+
+enum ScanType {
+ ACTIVE = 1;
+ PASSIVE = 2;
+};
+
+enum DriverFeature {
+ SCAN_OFFLOAD = 0;
+ RATE_SELECTION = 1;
+ SYNTH = 2;
+ TX_STATUS_REPORT = 3;
+ DFS = 4;
+ PROBE_RESP_OFFLOAD = 5;
+ /// Temporary feature flag for incrementally transitioning drivers to use
+ /// SME channel on iface creation.
+ TEMP_DIRECT_SME_CHANNEL = 3141592;
+ /// Temporary feature flag for driver to indicate this iface a SoftMAC device.
+ /// TODO(41640): Remove this flag once FullMAC drivers no longer use SME.
+ TEMP_SOFTMAC = 2718281828;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.wlan.policy/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.wlan.policy/BUILD.gn
new file mode 100644
index 0000000..639996e
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.wlan.policy/BUILD.gn
@@ -0,0 +1,28 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.wlan.policy") {
+ library_name = "policy"
+ namespace = "fuchsia.wlan"
+ public_deps = [
+ "../fuchsia.wlan.common",
+ ]
+ sources = [
+ "access_point_provider.fidl",
+ "client_provider.fidl",
+ "types.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.wlan.policy",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.wlan.policy/access_point_provider.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.wlan.policy/access_point_provider.fidl
new file mode 100644
index 0000000..f03c273
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.wlan.policy/access_point_provider.fidl
@@ -0,0 +1,112 @@
+// 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.
+
+library fuchsia.wlan.policy;
+
+using fuchsia.wlan.common;
+
+/// The AccessPointProvider API provides a mechanism for access point
+/// control and is intended to be called by applications or entities representing
+/// the user (ex, Settings). This API is not intended to be called by other
+/// applications to change wlan state without explicit user control.
+///
+/// The second aim of this API design is to eliminate the "last-caller wins"
+/// paradigm by limiting the number of controlling applications. A single caller
+/// at a time is permitted to make API calls that impact wlan state.
+[Discoverable]
+protocol AccessPointProvider {
+ /// Control channel used by a single caller to trigger wlan access point (ap) mode
+ /// state changes. The caller also provides a channel to receive wlan ap updates.
+ /// Only one caller can have the control channel open at a time. Attempts to
+ /// register as a controller while there is an active control registration
+ /// will result in the new caller's provided channel being closed.
+ GetController(request<AccessPointController> requests, AccessPointStateUpdates updates);
+};
+
+/// The AccessPointListener API provides a mechanism for callers to receive state change
+/// updates about wlan access point operation.
+[Discoverable]
+protocol AccessPointListener {
+ /// Registration for callers to receive wlan access point (ap) mode state updates.
+ GetListener(AccessPointStateUpdates updates);
+};
+
+/// AccessPointControllers allow the caller to trigger wlan state changes. This
+/// includes whether the device will act as an access point and provide a wlan
+/// network for other co-located devices.
+protocol AccessPointController {
+ /// Enables wlan to initiate AccessPoint operation using the provided network
+ /// configuration, connectivity mode and band.
+ StartAccessPoint(NetworkConfig config, ConnectivityMode mode, OperatingBand band)
+ -> (fuchsia.wlan.common.RequestStatus status);
+
+ /// Deactivate AccessPoint operation for a specified network configuration.
+ StopAccessPoint(NetworkConfig config) -> (fuchsia.wlan.common.RequestStatus status);
+
+ /// Deactivates all AccessPoints currently operating on the device.
+ StopAllAccessPoints();
+};
+
+/// AccessPoint operation status changes along with associated connection status.
+protocol AccessPointStateUpdates {
+ /// Updates registered listeners with the current summary of wlan access point
+ /// operating states. This will be called when there are changes with active
+ /// access point networks - both the number of access points and their
+ /// individual activity. Registered listeners are responsible for deciding
+ /// what information has changed (this is dependent on when they last
+ /// acknowledged the update).
+ // NOLINTNEXTLINE vector-bounds-not-specified
+ OnAccessPointStateUpdate(vector<AccessPointState> access_points) -> ();
+};
+
+/// Information about the individual operating access points. This includes limited
+/// information about any connected clients.
+table AccessPointState {
+ /// Current access point operating state
+ 1: OperatingState state;
+
+ /// Requested operating connectivity mode
+ 2: ConnectivityMode mode;
+
+ /// Access point operating band.
+ 3: OperatingBand band;
+
+ /// Access point operating frequency (in MHz).
+ 4: uint32 frequency;
+
+ /// Information about connected clients
+ 5: ConnectedClientInformation clients;
+};
+
+/// Connectivity operating mode for the access point.
+enum ConnectivityMode {
+ /// Allows for connectivity between co-located devices. Local only access points do not
+ /// forward traffic to other network connections.
+ LOCAL_ONLY = 1;
+
+ /// Allows for full connectivity with traffic potentially being forwarded
+ /// to other network connections (ex., tethering mode).
+ UNRESTRICTED = 2;
+};
+
+/// Current detailed operating state for an access point.
+enum OperatingState {
+ /// Access point operation failed. Access points that enter the failed state will
+ /// have one update informing registered listeners of the failure and then an
+ /// additional update with the access point removed from the list.
+ FAILED = 1;
+
+ /// Access point operation is starting up.
+ STARTING = 2;
+
+ /// Access point operation is active.
+ ACTIVE = 3;
+};
+
+/// Connected client information. This is initially limited to the number of
+/// connected clients.
+table ConnectedClientInformation {
+ /// Number of connected clients
+ 1: uint8 count;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.wlan.policy/client_provider.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.wlan.policy/client_provider.fidl
new file mode 100644
index 0000000..027687a
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.wlan.policy/client_provider.fidl
@@ -0,0 +1,244 @@
+// 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.
+
+library fuchsia.wlan.policy;
+
+using fuchsia.wlan.common;
+using zx;
+
+/// The ClientProvider API provides a mechanism for wlan control and is intended
+/// to be called by applications or entities representing the user (ex, Settings).
+/// This API is not intended to be called by other applications to change wlan
+/// state without explicit user control.
+///
+/// The second aim of this API design is to eliminate the "last-caller wins"
+/// paradigm by limiting the number of controlling applications. A single caller
+/// at a time is permitted to make API calls that impact wlan state.
+[Discoverable]
+protocol ClientProvider {
+ /// Control channel used by a single caller to trigger wlan client mode state
+ /// changes. The caller also provides a channel to receive wlan updates.
+ /// Only one caller can have the control channel open at a time. Attempts to
+ /// register as a controller while there is an active control registration
+ /// will result in the new caller's provided channel being closed.
+ GetController(request<ClientController> requests, ClientStateUpdates updates);
+};
+
+/// The ClientListener API provides a mechanism for callers to receive state change
+/// updates about wlan operation.
+[Discoverable]
+protocol ClientListener {
+ /// Registration for callers to receive wlan client mode state updates.
+ GetListener(ClientStateUpdates updates);
+};
+
+/// ClientControllers allow the caller to trigger wlan state changes. This includes
+/// whether connections will be attempted, scan triggers and saved network
+/// configuration changes.
+///
+/// Individual calls provided by the API are triggered after registering with
+/// the wlan ClientProvider via the OpenControlChannel call.
+protocol ClientController {
+ /// Enables wlan to initiate connections to networks (either autoconnect to
+ /// saved networks or act on incoming calls triggering connections). Depending
+ /// on the underlying capabilities of the device, this call may impact other
+ /// device operation (for example, acting as an access point).
+ StartClientConnections() -> (fuchsia.wlan.common.RequestStatus status);
+
+ /// Disables connections to wlan networks and tears down any existing connections.
+ StopClientConnections() -> (fuchsia.wlan.common.RequestStatus status);
+
+ /// Triggers a network scan. Note, even in normal operation, some scan requests
+ /// may be rejected due to timing with connection establishment or other critical
+ /// connection maintenance. If the scan is cancelled or errors, the caller is
+ /// notified via a status update in the ScanResultIterator.
+ ScanForNetworks(request<ScanResultIterator> iterator);
+
+ /// Saves a network and any credential information needed to connect. Multiple
+ /// entries for the same NetworkIdentifier can exist if the credentials are
+ /// different. If a caller attempts to save a NetworkConfig with the same
+ /// NetworkIdentifier and same Credentials as a previously saved network
+ /// the method will effectively be a no-op.
+ SaveNetwork(NetworkConfig config) -> () error NetworkConfigChangeError;
+
+ /// Removes a saved network configuration, if one exists. This method will
+ /// automatically trigger a disconnection if the NetworkConfig was used to
+ /// establish the connection.
+ RemoveNetwork(NetworkConfig config) -> () error NetworkConfigChangeError;
+
+ /// Retrieve the currently saved networks using the provided iterator.
+ GetSavedNetworks(request<NetworkConfigIterator> iterator);
+
+ /// Request to attempt a connection to the specified network. The target of the
+ /// connect call must already be a saved network. This call is not a
+ /// blocking call for the duration of the connection attempt. If the call cannot
+ /// be immediately attempted, a failure status will be returned. If the connection
+ /// request will be attempted, an acknowledgment status will be returned. Updates
+ /// to the connection status are disseminated via the ClientStateUpdates protocol.
+ /// If the connect attempt fails, the service will fall back to default behavior
+ /// with scanning and connecting via network selection.
+ Connect(NetworkIdentifier id) -> (fuchsia.wlan.common.RequestStatus status);
+};
+
+/// Iterator used to send back scan results to the caller. The corresponding channel
+/// will be closed after the scan is complete and results are returned or fails due
+/// to an error.
+protocol ScanResultIterator {
+ /// Allows caller to request the next set of scan results. When all scan results
+ /// have been handled, GetNext will return an empty vector and the channel will
+ /// be closed. If an error is encountered during the scan, it will be returned
+ /// after all scan results have been retrieved.
+ GetNext() -> (vector<ScanResult> scan_results) error ScanErrorCode;
+};
+
+/// Wlan scan error codes.
+enum ScanErrorCode {
+ /// Unexpected scan error without a specific cause.
+ GENERAL_ERROR = 1;
+ /// Scan was cancelled and stopped. This can happen due to operating state changes,
+ /// higher priority operations or conflicting requests.
+ CANCELLED = 2;
+};
+
+
+/// Information from an observed wlan network. This includes the
+/// network name, security type, detected access point information and network
+/// compatibility information.
+table ScanResult {
+ /// Network properties used to distinguish between networks and to group
+ /// individual APs.
+ 1: NetworkIdentifier id;
+
+ /// Individual access points offering the specified network.
+ 2: vector<Bss> entries;
+
+ /// Indication if the detected network is supported by the implementation.
+ 3: Compatibility compatibility;
+};
+
+/// Information for a particular ScanResult entry.
+table Bss {
+ /// MAC address for the AP interface.
+ 1: array<uint8>:6 bssid;
+
+ /// Calculated received signal strength for the beacon/probe response.
+ 2: int8 rssi;
+
+ /// Operating frequency for this network (in MHz).
+ 3: uint32 frequency;
+
+ /// Realtime timestamp for this scan result entry.
+ 4: zx.time timestamp_nanos;
+};
+
+/// Iterator used by callers to retrieve saved network information.
+protocol NetworkConfigIterator {
+
+ /// Method allowing the next block of saved networks to be handled.
+ GetNext() -> (vector<NetworkConfig> configs);
+};
+
+/// Wlan status changes for client connections and the associated network state.
+/// These updates contain information about whether or not the device will attempt
+/// to connect to networks, saved network configuration change information,
+/// individual connection state information by NetworkIdentifier and connection
+/// attempt information. The connection and network related calls are based on
+/// NetworkIdentifier to allow multiple simultaneous connections on supporting
+/// devices.
+protocol ClientStateUpdates {
+
+ /// Updates registered listeners with the current summary of wlan client state.
+ /// This will be called when there is any change to the state and the
+ /// registered listeners are responsible for deciding what information has
+ /// changed (since this is dependent on when they last acknowledged the update).
+ OnClientStateUpdate(ClientStateSummary summary) -> ();
+};
+
+/// Information about the current client state for the device. This includes if the
+/// device will attempt to connect to access points (when applicable), any existing
+/// connections and active connection attempts and their outcomes.
+table ClientStateSummary {
+ /// State indicating whether wlan will attempt to connect to networks or not.
+ 1: WlanClientState state;
+
+ /// Active connections, connection attempts or failed connections.
+ 2: vector<NetworkState> networks;
+};
+
+/// Information about current network connections and attempts.
+table NetworkState {
+ /// Network id for the current connection (or attempt).
+ 1: NetworkIdentifier id;
+
+ /// Current state for the connection.
+ 2: ConnectionState state;
+
+ /// Extra information for debugging or Settings display
+ 3: DisconnectStatus status;
+};
+
+/// Wlan operating state for client connections
+enum WlanClientState {
+ CONNECTIONS_DISABLED = 1;
+ CONNECTIONS_ENABLED = 2;
+};
+
+/// High level compatibility for the scan result. Not all network security protocols
+/// are supported. New protocols may be detected before they are connectable
+/// and deprecated protocols may explicitly be unsupported due to security and
+/// privacy concerns.
+enum Compatibility {
+ /// Denotes that the network is supported and connections can be attempted (given
+ /// appropriate credentials when required).
+ SUPPORTED = 1;
+
+ /// The network uses a deprecated security protocol and is explicitly not supported.
+ DISALLOWED_INSECURE = 2;
+
+ /// The network uses a currently unsupported security protocol.
+ DISALLOWED_NOT_SUPPORTED = 3;
+};
+
+/// Potential error cases for saving and removing network configurations. This is
+/// intentionally sparse and will be expanded as use cases develop.
+enum NetworkConfigChangeError {
+ GENERAL_ERROR = 1;
+};
+
+/// Connection states used to update registered wlan observers.
+enum ConnectionState {
+ /// The connection attempt was terminated due to an error.
+ FAILED = 1;
+
+ /// The network is disconnected.
+ DISCONNECTED = 2;
+
+ /// The device is attempting a connection to a network.
+ CONNECTING = 3;
+
+ /// The connection is now established. Note: This does not make any guarantees
+ /// about higher level network reachability.
+ CONNECTED = 4;
+};
+
+/// Disconnect and connection attempt failure status codes
+enum DisconnectStatus {
+ /// The requested connection attempt failed due to timeout.
+ TIMED_OUT = 1;
+
+ /// The requested connection attempt failed due to suspected credential failure.
+ CREDENTIALS_FAILED = 2;
+
+ /// The existing connection was explicitly disconnected by an action of wlan
+ /// service on this device. This can be the result of wlan connections being
+ /// disabled, network configuration being removed or a connection attempt to a
+ /// different network (as examples).
+ CONNECTION_STOPPED = 3;
+
+ /// The existing connection failed unexpectedly in a way that is not an
+ /// explicitly triggered disconnect by the device (or user). Examples
+ /// of unexpected disconnections include: an underlying error (driver,
+ /// firmware, etc.), beacon loss, access point failure.
+ CONNECTION_FAILED = 4;
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.wlan.policy/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.wlan.policy/meta.json
new file mode 100644
index 0000000..1781b88
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.wlan.policy/meta.json
@@ -0,0 +1,13 @@
+{
+ "deps": [
+ "fuchsia.wlan.common"
+ ],
+ "name": "fuchsia.wlan.policy",
+ "root": "fidl/fuchsia.wlan.policy",
+ "sources": [
+ "fidl/fuchsia.wlan.policy/access_point_provider.fidl",
+ "fidl/fuchsia.wlan.policy/client_provider.fidl",
+ "fidl/fuchsia.wlan.policy/types.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.wlan.policy/types.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.wlan.policy/types.fidl
new file mode 100644
index 0000000..6f32c31
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.wlan.policy/types.fidl
@@ -0,0 +1,67 @@
+// 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.
+
+library fuchsia.wlan.policy;
+
+// Basic definitions for wlan APIs.
+
+/// High level protection type for the network. This does not convey all details needed
+/// for the mechanism of the connection, but is primarily used to map the target network
+/// to proper scan results.
+enum SecurityType {
+ NONE = 1;
+ WEP = 2;
+ WPA = 3;
+ WPA2 = 4;
+ WPA3 = 5;
+};
+
+/// Primary means of distinguishing between available networks - the combination of
+/// the (mostly) human recognizable name and the security type. The security type is used
+/// to distinguish between different network protection (or lack thereof) types.
+struct NetworkIdentifier {
+ /// Network name, often used by users to choose between networks in the UI.
+ bytes:32 ssid;
+
+ /// Protection type (or not) for the network.
+ SecurityType type;
+};
+
+/// Network information used to establish a connection.
+table NetworkConfig {
+ /// Identifier used to represent a specific network. No guarantee for uniqueness.
+ 1: NetworkIdentifier id;
+
+ /// Information needed to join a network.
+ 2: Credential credential;
+};
+
+/// Information used to verify access to a target network.
+flexible union Credential {
+ /// The network does not use credentials (open networks).
+ 1: Empty none;
+
+ /// Plaintext password (handled as binary data).
+ 2: bytes password;
+
+ /// Hash representation of the network passphrase (handled as binary data).
+ 3: bytes psk;
+};
+
+/// Operating band for wlan control request and status updates.
+enum OperatingBand {
+ /// Allows for band switching depending on device operating mode and environment.
+ ANY = 1;
+
+ /// Restricted to 2.4 GHz bands only.
+ ONLY_2_4GHZ = 2;
+
+ /// Restricted to 5 GHz bands only.
+ ONLY_5GHZ = 3;
+};
+
+/// Empty struct used in place of optional values.
+// TODO: FIDL-589
+struct Empty {
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.wlan.service/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.wlan.service/BUILD.gn
new file mode 100644
index 0000000..cf9bee9
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.wlan.service/BUILD.gn
@@ -0,0 +1,27 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.wlan.service") {
+ library_name = "service"
+ namespace = "fuchsia.wlan"
+ public_deps = [
+ "../fuchsia.wlan.common",
+ "../fuchsia.wlan.stats",
+ ]
+ sources = [
+ "wlan_service.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.wlan.service",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.wlan.service/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.wlan.service/meta.json
new file mode 100644
index 0000000..12dbf28
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.wlan.service/meta.json
@@ -0,0 +1,12 @@
+{
+ "deps": [
+ "fuchsia.wlan.common",
+ "fuchsia.wlan.stats"
+ ],
+ "name": "fuchsia.wlan.service",
+ "root": "fidl/fuchsia.wlan.service",
+ "sources": [
+ "fidl/fuchsia.wlan.service/wlan_service.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.wlan.service/wlan_service.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.wlan.service/wlan_service.fidl
new file mode 100644
index 0000000..89393d3
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.wlan.service/wlan_service.fidl
@@ -0,0 +1,90 @@
+// Copyright 2017 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.
+
+library fuchsia.wlan.service;
+
+using fuchsia.wlan.common;
+using fuchsia.wlan.stats;
+
+enum ErrCode {
+ OK = 0;
+ INTERNAL = 1;
+ NOT_FOUND = 2;
+ NOT_SUPPORTED = 3;
+ INVALID_ARGS = 4;
+};
+
+struct Error {
+ ErrCode code;
+ string description;
+};
+
+struct AP {
+ bytes bssid;
+ string ssid; // TODO(NET-698, NET-1474): Make this as vector<uint8:32>
+ int8 rssi_dbm;
+ bool is_secure;
+ bool is_compatible; // with respect to Fuchsia
+ fuchsia.wlan.common.WlanChan chan;
+};
+
+struct ScanRequest {
+ uint8 timeout; // seconds
+ // TODO: more parameters here
+};
+
+struct ScanResult {
+ Error error;
+ vector<AP>? aps;
+};
+
+struct ConnectConfig {
+ string ssid;
+ string passPhrase;
+ uint8 scanInterval; // seconds
+ string bssid;
+};
+
+enum State {
+ UNKNOWN = 0;
+ BSS = 1;
+ QUERYING = 2;
+ SCANNING = 3;
+ JOINING = 4;
+ AUTHENTICATING = 5;
+ ASSOCIATING = 6;
+ ASSOCIATED = 7;
+};
+
+struct WlanStatus {
+ Error error;
+ State state;
+ AP? current_ap;
+};
+
+struct BssConfig {
+ string ssid;
+ int32 beaconPeriod;
+ int32 dtimPeriod;
+ uint8 channel;
+};
+
+struct WlanStats {
+ Error error;
+ fuchsia.wlan.stats.IfaceStats stats;
+};
+
+/// Stub interface; eventually to be replaced by something based on the 802.11
+/// SME / MSGCF.
+[Discoverable]
+protocol Wlan {
+ Scan(ScanRequest req) -> (ScanResult result);
+ Connect(ConnectConfig req) -> (Error error);
+ Disconnect() -> (Error error);
+ Status() -> (WlanStatus status);
+ StartBss(BssConfig cfg) -> (Error error);
+ StopBss() -> (Error error);
+ Stats() -> (WlanStats stats);
+ ClearSavedNetworks() -> ();
+};
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.wlan.stats/BUILD.gn b/third_party/fuchsia-sdk/fidl/fuchsia.wlan.stats/BUILD.gn
new file mode 100644
index 0000000..3b54fc2
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.wlan.stats/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fidl_library.gni")
+
+fidl_library("fuchsia.wlan.stats") {
+ library_name = "stats"
+ namespace = "fuchsia.wlan"
+ public_deps = [
+ ]
+ sources = [
+ "wlan_stats.fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fuchsia.wlan.stats",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.wlan.stats/meta.json b/third_party/fuchsia-sdk/fidl/fuchsia.wlan.stats/meta.json
new file mode 100644
index 0000000..4842af1
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.wlan.stats/meta.json
@@ -0,0 +1,9 @@
+{
+ "deps": [],
+ "name": "fuchsia.wlan.stats",
+ "root": "fidl/fuchsia.wlan.stats",
+ "sources": [
+ "fidl/fuchsia.wlan.stats/wlan_stats.fidl"
+ ],
+ "type": "fidl_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/fidl/fuchsia.wlan.stats/wlan_stats.fidl b/third_party/fuchsia-sdk/fidl/fuchsia.wlan.stats/wlan_stats.fidl
new file mode 100644
index 0000000..e2a00b4
--- /dev/null
+++ b/third_party/fuchsia-sdk/fidl/fuchsia.wlan.stats/wlan_stats.fidl
@@ -0,0 +1,63 @@
+// Copyright 2018 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.
+
+library fuchsia.wlan.stats;
+
+struct Counter {
+ uint64 count;
+ string name;
+};
+
+struct PacketCounter {
+ Counter in;
+ Counter out;
+ Counter drop;
+ Counter in_bytes;
+ Counter out_bytes;
+ Counter drop_bytes;
+};
+
+// LINT.IfChange
+struct DispatcherStats {
+ PacketCounter any_packet;
+ PacketCounter mgmt_frame;
+ PacketCounter ctrl_frame;
+ PacketCounter data_frame;
+};
+
+const uint8 RSSI_BINS = 129;
+
+/// RssiStats count the occurrence of the RSSIs.
+/// RSSI value r's occurrence is counted in the bin[-r],
+/// where r is defined in [-128, 0] in dBm.
+struct RssiStats {
+ // TODO(alexandrew): Change this to array.
+ vector<uint64>:RSSI_BINS hist;
+};
+
+struct ClientMlmeStats {
+ PacketCounter svc_msg;
+ PacketCounter data_frame;
+ PacketCounter mgmt_frame;
+ PacketCounter tx_frame;
+ PacketCounter rx_frame;
+ RssiStats assoc_data_rssi;
+ RssiStats beacon_rssi;
+};
+
+struct ApMlmeStats {
+ PacketCounter not_used;
+};
+
+// LINT.ThenChange(//src/connectivity/wlan/lib/common/cpp/include/wlan/common/stats.h)
+
+union MlmeStats {
+ 1: ClientMlmeStats client_mlme_stats;
+ 2: ApMlmeStats ap_mlme_stats;
+};
+
+struct IfaceStats {
+ DispatcherStats dispatcher_stats;
+ MlmeStats? mlme_stats;
+};
diff --git a/third_party/fuchsia-sdk/meta/manifest.json b/third_party/fuchsia-sdk/meta/manifest.json
new file mode 100644
index 0000000..95f6e10
--- /dev/null
+++ b/third_party/fuchsia-sdk/meta/manifest.json
@@ -0,0 +1,841 @@
+{
+ "arch": {
+ "host": "x86_64-linux-gnu",
+ "target": [
+ "arm64",
+ "x64"
+ ]
+ },
+ "id": "0.20200420.1.1",
+ "parts": [
+ {
+ "meta": "bin/fconfig-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "bin/fcp-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "bin/fdevtools-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "bin/femu-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "bin/fpave-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "bin/fpublish-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "bin/fserve-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "bin/fserve-remote-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "bin/fssh-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "build/gn-build-files-meta.json",
+ "type": "documentation"
+ },
+ {
+ "meta": "build/gn-rules-meta.json",
+ "type": "documentation"
+ },
+ {
+ "meta": "docs/low_level.json",
+ "type": "documentation"
+ },
+ {
+ "meta": "docs/metadata_schemas.json",
+ "type": "documentation"
+ },
+ {
+ "meta": "docs/modular_config_schema.json",
+ "type": "documentation"
+ },
+ {
+ "meta": "docs/musl_license.json",
+ "type": "documentation"
+ },
+ {
+ "meta": "docs/open_source.json",
+ "type": "documentation"
+ },
+ {
+ "meta": "docs/vulkan_license.json",
+ "type": "documentation"
+ },
+ {
+ "meta": "fidl/fuchsia.accessibility.semantics/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.auth.oldtokens/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.auth/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.bluetooth.a2dp/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.bluetooth.control/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.bluetooth.gatt/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.bluetooth.le/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.bluetooth.sys/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.bluetooth/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.camera/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.camera2.hal/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.camera2/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.camera3/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.castauth/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.castconfig/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.castremotecontrol/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.castsetup/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.castsysteminfo/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.castwindow/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.cobalt/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.component.runner/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.component/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.data/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.deprecatedtimezone/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.developer.tiles/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.diagnostics/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.factory/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.feedback/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.fonts/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.hardware.ethernet/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.hardware.goldfish/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.hardware.light/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.hardware.power.statecontrol/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.hwinfo/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.images/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.input/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.inspect/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.intl/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.io/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.ldsvc/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.legacymetrics/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.location.namedplace/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.logger/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.math/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.media.audio/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.media.drm/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.media.playback/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.media.sessions2/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.media.sounds/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.media.target/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.media/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.mediacodec/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.mem/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.memorypressure/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.migration/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.modular.auth/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.modular.session/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.modular.testing/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.modular/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.net.dhcp/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.net.http/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.net.mdns/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.net.oldhttp/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.net/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.netstack/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.posix.socket/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.process/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.recovery.ui/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.recovery/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.scenic.scheduling/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.settings/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.sys.test/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.sys/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.sysinfo/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.sysmem/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.tracing.provider/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.ui.activity.control/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.ui.activity/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.ui.app/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.ui.brightness/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.ui.gfx/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.ui.input/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.ui.input2/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.ui.input3/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.ui.lifecycle/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.ui.policy/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.ui.scenic/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.ui.types/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.ui.views/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.update.channel/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.update.channelcontrol/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.update/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.url/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.weave/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.web/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.wlan.common/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.wlan.policy/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.wlan.service/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "fidl/fuchsia.wlan.stats/meta.json",
+ "type": "fidl_library"
+ },
+ {
+ "meta": "pkg/async-cpp/meta.json",
+ "type": "cc_source_library"
+ },
+ {
+ "meta": "pkg/async-default/meta.json",
+ "type": "cc_prebuilt_library"
+ },
+ {
+ "meta": "pkg/async-loop-cpp/meta.json",
+ "type": "cc_source_library"
+ },
+ {
+ "meta": "pkg/async-loop-default/meta.json",
+ "type": "cc_prebuilt_library"
+ },
+ {
+ "meta": "pkg/async-loop/meta.json",
+ "type": "cc_source_library"
+ },
+ {
+ "meta": "pkg/async-testing/meta.json",
+ "type": "cc_source_library"
+ },
+ {
+ "meta": "pkg/async/meta.json",
+ "type": "cc_source_library"
+ },
+ {
+ "meta": "pkg/fdio/meta.json",
+ "type": "cc_prebuilt_library"
+ },
+ {
+ "meta": "pkg/fidl-async/meta.json",
+ "type": "cc_source_library"
+ },
+ {
+ "meta": "pkg/fidl/meta.json",
+ "type": "cc_source_library"
+ },
+ {
+ "meta": "pkg/fidl_base/meta.json",
+ "type": "cc_source_library"
+ },
+ {
+ "meta": "pkg/fidl_cpp/meta.json",
+ "type": "cc_source_library"
+ },
+ {
+ "meta": "pkg/fidl_cpp_base/meta.json",
+ "type": "cc_source_library"
+ },
+ {
+ "meta": "pkg/fidl_cpp_sync/meta.json",
+ "type": "cc_source_library"
+ },
+ {
+ "meta": "pkg/fit/meta.json",
+ "type": "cc_source_library"
+ },
+ {
+ "meta": "pkg/images_cpp/meta.json",
+ "type": "cc_source_library"
+ },
+ {
+ "meta": "pkg/inspect/meta.json",
+ "type": "cc_source_library"
+ },
+ {
+ "meta": "pkg/inspect_service_cpp/meta.json",
+ "type": "cc_source_library"
+ },
+ {
+ "meta": "pkg/media_cpp/meta.json",
+ "type": "cc_source_library"
+ },
+ {
+ "meta": "pkg/media_cpp_no_converters/meta.json",
+ "type": "cc_source_library"
+ },
+ {
+ "meta": "pkg/memfs/meta.json",
+ "type": "cc_prebuilt_library"
+ },
+ {
+ "meta": "pkg/modular_cpp/meta.json",
+ "type": "cc_source_library"
+ },
+ {
+ "meta": "pkg/modular_testing_cpp/meta.json",
+ "type": "cc_source_library"
+ },
+ {
+ "meta": "pkg/scenic_cpp/meta.json",
+ "type": "cc_source_library"
+ },
+ {
+ "meta": "pkg/svc/meta.json",
+ "type": "cc_prebuilt_library"
+ },
+ {
+ "meta": "pkg/sync/meta.json",
+ "type": "cc_prebuilt_library"
+ },
+ {
+ "meta": "pkg/sys_cpp/meta.json",
+ "type": "cc_source_library"
+ },
+ {
+ "meta": "pkg/sys_cpp_testing/meta.json",
+ "type": "cc_source_library"
+ },
+ {
+ "meta": "pkg/sys_inspect_cpp/meta.json",
+ "type": "cc_source_library"
+ },
+ {
+ "meta": "pkg/sys_service_cpp/meta.json",
+ "type": "cc_source_library"
+ },
+ {
+ "meta": "pkg/syslog/meta.json",
+ "type": "cc_prebuilt_library"
+ },
+ {
+ "meta": "pkg/sysroot/meta.json",
+ "type": "sysroot"
+ },
+ {
+ "meta": "pkg/trace-engine/meta.json",
+ "type": "cc_prebuilt_library"
+ },
+ {
+ "meta": "pkg/trace-provider-so/meta.json",
+ "type": "cc_prebuilt_library"
+ },
+ {
+ "meta": "pkg/trace/meta.json",
+ "type": "cc_source_library"
+ },
+ {
+ "meta": "pkg/vfs_cpp/meta.json",
+ "type": "cc_source_library"
+ },
+ {
+ "meta": "pkg/vulkan/meta.json",
+ "type": "cc_prebuilt_library"
+ },
+ {
+ "meta": "pkg/vulkan_layers/meta.json",
+ "type": "loadable_module"
+ },
+ {
+ "meta": "pkg/zx/meta.json",
+ "type": "cc_source_library"
+ },
+ {
+ "meta": "readme-meta.json",
+ "type": "documentation"
+ },
+ {
+ "meta": "tools/arm64/bootserver-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/arm64/dev_finder-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/arm64/device-finder-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/arm64/far-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/arm64/fidl-format-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/arm64/fidlc-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/arm64/fidlgen-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/arm64/fvm-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/arm64/loglistener-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/arm64/merkleroot-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/arm64/minfs-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/arm64/pm-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/arm64/symbolize-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/arm64/zbi-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/bootserver-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/cmc-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/dart_kernel_compiler-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/dev_finder-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/device-finder-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/far-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/fidl-format-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/fidlc-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/fidlcat-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/fidlgen-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/fidlgen_dart-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/fvm-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/gen_snapshot-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/loglistener-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/merkleroot-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/minfs-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/pm-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/symbolize-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/x64/bootserver-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/x64/cmc-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/x64/dev_finder-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/x64/device-finder-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/x64/far-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/x64/fidl-format-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/x64/fidlc-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/x64/fidlcat-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/x64/fidlgen-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/x64/fvm-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/x64/loglistener-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/x64/merkleroot-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/x64/minfs-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/x64/pm-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/x64/symbolize-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/x64/zbi-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/x64/zxdb-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/zbi-meta.json",
+ "type": "host_tool"
+ },
+ {
+ "meta": "tools/zxdb-meta.json",
+ "type": "host_tool"
+ }
+ ],
+ "schema_version": "1"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/meta/schemas/cc_prebuilt_library.json b/third_party/fuchsia-sdk/meta/schemas/cc_prebuilt_library.json
new file mode 100644
index 0000000..9a72c8e
--- /dev/null
+++ b/third_party/fuchsia-sdk/meta/schemas/cc_prebuilt_library.json
@@ -0,0 +1,117 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "id": "http://fuchsia.com/schemas/sdk/cc_prebuilt_library.json",
+ "description": "A prebuilt C/C++ library",
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "common.json#/definitions/sdk_element"
+ },
+ {
+ "properties": {
+ "type": {
+ "allOf": [
+ {
+ "$ref": "common.json#/definitions/type"
+ },
+ {
+ "enum": [
+ "cc_prebuilt_library"
+ ]
+ }
+ ]
+ },
+ "name": {
+ "description": "Name of the library",
+ "$ref": "common.json#/definitions/cc_library_name"
+ },
+ "root": {
+ "description": "The root of the element in the SDK",
+ "type": "string"
+ },
+ "format": {
+ "description": "The distribution format of the binaries",
+ "type": "string",
+ "enum": [
+ "shared",
+ "static"
+ ]
+ },
+ "headers": {
+ "description": "List of public headers",
+ "type": "array",
+ "items": {
+ "$ref": "common.json#/definitions/file"
+ }
+ },
+ "include_dir": {
+ "description": "Path to the base directory for includes",
+ "$ref": "common.json#/definitions/file"
+ },
+ "deps": {
+ "description": "List of C/C++ libraries this library depends on",
+ "type": "array",
+ "items": {
+ "$ref": "common.json#/definitions/cc_library_name"
+ }
+ },
+ "binaries": {
+ "description": "The binary files for the library, per architecture",
+ "type": "object",
+ "properties": {
+ "x64": {
+ "description": "Binaries for the x64 architecture",
+ "$ref": "#/definitions/binaryGroup"
+ },
+ "arm64": {
+ "description": "Binaries for the arm64 architecture",
+ "$ref": "#/definitions/binaryGroup"
+ }
+ },
+ "additionalProperties": false,
+ "minProperties": 1,
+ "maxProperties": 2
+ }
+ },
+ "required": [
+ "binaries",
+ "deps",
+ "format",
+ "headers",
+ "include_dir",
+ "root",
+
+ "name",
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ],
+ "definitions": {
+ "binaryGroup": {
+ "description": "A set of binary files compiled for a given architecture",
+ "type": "object",
+ "properties": {
+ "link": {
+ "description": "The link-time version of the library",
+ "$ref": "common.json#/definitions/file"
+ },
+ "dist": {
+ "description": "The version of the library to add to Fuchsia packages",
+ "$ref": "common.json#/definitions/file"
+ },
+ "dist_path": {
+ "description": "Path where the library should be installed in Fuchsia packages",
+ "$ref": "common.json#/definitions/file"
+ },
+ "debug": {
+ "description": "The unstripped version of the library",
+ "$ref": "common.json#/definitions/file"
+ }
+ },
+ "required": [
+ "link"
+ ]
+ }
+ }
+}
diff --git a/third_party/fuchsia-sdk/meta/schemas/cc_source_library.json b/third_party/fuchsia-sdk/meta/schemas/cc_source_library.json
new file mode 100644
index 0000000..36ceb11
--- /dev/null
+++ b/third_party/fuchsia-sdk/meta/schemas/cc_source_library.json
@@ -0,0 +1,88 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "id": "http://fuchsia.com/schemas/sdk/cc_source_library.json",
+ "description": "A set of C/C++ sources",
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "common.json#/definitions/sdk_element"
+ },
+ {
+ "properties": {
+ "type": {
+ "allOf": [
+ {
+ "$ref": "common.json#/definitions/type"
+ },
+ {
+ "enum": [
+ "cc_source_library"
+ ]
+ }
+ ]
+ },
+ "name": {
+ "description": "Name of the library",
+ "$ref": "common.json#/definitions/cc_library_name"
+ },
+ "root": {
+ "description": "The root of the element in the SDK",
+ "type": "string"
+ },
+ "sources": {
+ "description": "List of library sources",
+ "type": "array",
+ "items": {
+ "$ref": "common.json#/definitions/file"
+ }
+ },
+ "headers": {
+ "description": "List of public headers",
+ "type": "array",
+ "minItems": 1,
+ "items": {
+ "$ref": "common.json#/definitions/file"
+ }
+ },
+ "include_dir": {
+ "description": "Path to the base directory for includes",
+ "$ref": "common.json#/definitions/file"
+ },
+ "deps": {
+ "description": "List of C/C++ libraries this library depends on",
+ "type": "array",
+ "items": {
+ "$ref": "common.json#/definitions/cc_library_name"
+ }
+ },
+ "fidl_deps": {
+ "description": "List of FIDL libraries this library depends on",
+ "type": "array",
+ "items": {
+ "$ref": "common.json#/definitions/fidl_library_name"
+ }
+ },
+ "banjo_deps": {
+ "description": "List of BANJO libraries this library depends on",
+ "type": "array",
+ "items": {
+ "$ref": "common.json#/definitions/banjo_library_name"
+ }
+ }
+ },
+ "required": [
+ "banjo_deps",
+ "deps",
+ "fidl_deps",
+ "headers",
+ "include_dir",
+ "root",
+ "sources",
+
+ "name",
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+}
diff --git a/third_party/fuchsia-sdk/meta/schemas/common.json b/third_party/fuchsia-sdk/meta/schemas/common.json
new file mode 100644
index 0000000..b02b160
--- /dev/null
+++ b/third_party/fuchsia-sdk/meta/schemas/common.json
@@ -0,0 +1,52 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "id": "http://fuchsia.com/schemas/sdk/common.json",
+ "definitions": {
+ "file": {
+ "description": "Path to a file from the root of the SDK",
+ "type": "string"
+ },
+ "type": {
+ "description": "Represents the type of an SDK element",
+ "type": "string"
+ },
+ "sdk_element": {
+ "description": "Base type for SDK elements",
+ "type": "object",
+ "properties": {
+ "type": {
+ "description": "The type of the element",
+ "$ref": "#/definitions/type"
+ },
+ "name": {
+ "description": "The name of the element",
+ "type": "string"
+ }
+ },
+ "required": [
+ "name",
+ "type"
+ ]
+ },
+ "banjo_library_name": {
+ "description": "Name of a BANJO library",
+ "type": "string"
+ },
+ "fidl_library_name": {
+ "description": "Name of a FIDL library",
+ "type": "string"
+ },
+ "cc_library_name": {
+ "description": "Name of a C/C++ library",
+ "type": "string"
+ },
+ "target_arch": {
+ "description": "Target architecture",
+ "type": "string",
+ "enum": [
+ "arm64",
+ "x64"
+ ]
+ }
+ }
+}
diff --git a/third_party/fuchsia-sdk/meta/schemas/dart_library.json b/third_party/fuchsia-sdk/meta/schemas/dart_library.json
new file mode 100644
index 0000000..9a77d08
--- /dev/null
+++ b/third_party/fuchsia-sdk/meta/schemas/dart_library.json
@@ -0,0 +1,99 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "id": "http://fuchsia.com/schemas/sdk/dart_library.json",
+ "description": "A Dart library",
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "common.json#/definitions/sdk_element"
+ },
+ {
+ "properties": {
+ "type": {
+ "allOf": [
+ {
+ "$ref": "common.json#/definitions/type"
+ },
+ {
+ "enum": [
+ "dart_library"
+ ]
+ }
+ ]
+ },
+ "name": {
+ "description": "Name of the library",
+ "$ref": "#/definitions/package_name"
+ },
+ "root": {
+ "description": "The root of the element in the SDK",
+ "$ref": "common.json#/definitions/file"
+ },
+ "sources": {
+ "description": "List of library sources",
+ "type": "array",
+ "minItems": 1,
+ "items": {
+ "$ref": "common.json#/definitions/file"
+ }
+ },
+ "deps": {
+ "description": "List of Dart libraries this library depends on",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/package_name"
+ }
+ },
+ "third_party_deps": {
+ "description": "List of third-party dependencies",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/third_party_library"
+ }
+ },
+ "fidl_deps": {
+ "description": "List of FIDL libraries this library depends on",
+ "type": "array",
+ "items": {
+ "$ref": "common.json#/definitions/fidl_library_name"
+ }
+ }
+ },
+ "required": [
+ "deps",
+ "fidl_deps",
+ "root",
+ "sources",
+ "third_party_deps",
+
+ "name",
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ],
+ "definitions": {
+ "package_name": {
+ "description": "A Dart package name",
+ "type": "string"
+ },
+ "third_party_library": {
+ "description": "A third-party Dart package",
+ "type": "object",
+ "properties": {
+ "name": {
+ "description": "Name of the package",
+ "$ref": "#/definitions/package_name"
+ },
+ "version": {
+ "description": "Version number of the package",
+ "type": "string"
+ }
+ },
+ "required": [
+ "name",
+ "version"
+ ]
+ }
+ }
+}
diff --git a/third_party/fuchsia-sdk/meta/schemas/device_profile.json b/third_party/fuchsia-sdk/meta/schemas/device_profile.json
new file mode 100644
index 0000000..48f1c41
--- /dev/null
+++ b/third_party/fuchsia-sdk/meta/schemas/device_profile.json
@@ -0,0 +1,52 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "id": "http://fuchsia.com/schemas/sdk/device_profile.json",
+ "description": "A supported device configuration for SDK development",
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "common.json#/definitions/sdk_element"
+ },
+ {
+ "properties": {
+ "type": {
+ "allOf": [
+ {
+ "$ref": "common.json#/definitions/type"
+ },
+ {
+ "enum": [
+ "device_profile"
+ ]
+ }
+ ]
+ },
+ "name": {
+ "description": "Name of the profile",
+ "type": "string"
+ },
+ "description": {
+ "description": "A description of the device's configuration",
+ "type": "string"
+ },
+ "images_url": {
+ "description": "GCS URL of the archive containing system images",
+ "type": "string"
+ },
+ "packages_url": {
+ "description": "GCS URL of the archive containing a package repository",
+ "type": "string"
+ }
+ },
+ "required": [
+ "description",
+ "images_url",
+ "packages_url",
+
+ "name",
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+}
diff --git a/third_party/fuchsia-sdk/meta/schemas/documentation.json b/third_party/fuchsia-sdk/meta/schemas/documentation.json
new file mode 100644
index 0000000..040ccd6
--- /dev/null
+++ b/third_party/fuchsia-sdk/meta/schemas/documentation.json
@@ -0,0 +1,46 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "id": "http://fuchsia.com/schemas/sdk/documentation.json",
+ "description": "A set of documents",
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "common.json#/definitions/sdk_element"
+ },
+ {
+ "properties": {
+ "type": {
+ "allOf": [
+ {
+ "$ref": "common.json#/definitions/type"
+ },
+ {
+ "enum": [
+ "documentation"
+ ]
+ }
+ ]
+ },
+ "name": {
+ "description": "Name of the document set",
+ "type": "string"
+ },
+ "docs": {
+ "description": "The list of documents pertaining to the set",
+ "type": "array",
+ "minItems": 1,
+ "items": {
+ "$ref": "common.json#/definitions/file"
+ }
+ }
+ },
+ "required": [
+ "docs",
+
+ "name",
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+}
diff --git a/third_party/fuchsia-sdk/meta/schemas/fidl_library.json b/third_party/fuchsia-sdk/meta/schemas/fidl_library.json
new file mode 100644
index 0000000..eec1fe3
--- /dev/null
+++ b/third_party/fuchsia-sdk/meta/schemas/fidl_library.json
@@ -0,0 +1,59 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "id": "http://fuchsia.com/schemas/sdk/fidl_library.json",
+ "description": "A FIDL library",
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "common.json#/definitions/sdk_element"
+ },
+ {
+ "properties": {
+ "type": {
+ "allOf": [
+ {
+ "$ref": "common.json#/definitions/type"
+ },
+ {
+ "enum": [
+ "fidl_library"
+ ]
+ }
+ ]
+ },
+ "name": {
+ "description": "Name of the library",
+ "$ref": "common.json#/definitions/fidl_library_name"
+ },
+ "root": {
+ "description": "The root of the element in the SDK",
+ "type": "string"
+ },
+ "sources": {
+ "description": "List of library sources",
+ "type": "array",
+ "minItems": 1,
+ "items": {
+ "$ref": "common.json#/definitions/file"
+ }
+ },
+ "deps": {
+ "description": "List of libraries this library depends on",
+ "type": "array",
+ "items": {
+ "$ref": "common.json#/definitions/fidl_library_name"
+ }
+ }
+ },
+ "required": [
+ "deps",
+ "root",
+ "sources",
+
+ "name",
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+}
diff --git a/third_party/fuchsia-sdk/meta/schemas/host_tool.json b/third_party/fuchsia-sdk/meta/schemas/host_tool.json
new file mode 100644
index 0000000..97c9cc3
--- /dev/null
+++ b/third_party/fuchsia-sdk/meta/schemas/host_tool.json
@@ -0,0 +1,72 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "id": "http://fuchsia.com/schemas/sdk/host_tool.json",
+ "description": "A host tool",
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "common.json#/definitions/sdk_element"
+ },
+ {
+ "properties": {
+ "type": {
+ "allOf": [
+ {
+ "$ref": "common.json#/definitions/type"
+ },
+ {
+ "enum": [
+ "host_tool"
+ ]
+ }
+ ]
+ },
+ "name": {
+ "description": "Name of the tool",
+ "type": "string"
+ },
+ "root": {
+ "description": "The root of the element in the SDK",
+ "type": "string"
+ },
+ "files": {
+ "description": "The list of files pertaining to the element",
+ "$ref": "#/definitions/fileGroup"
+ },
+ "target_files": {
+ "description": "The target-specific files, per architecture",
+ "type": "object",
+ "properties": {
+ "x64": {
+ "description": "Files for the x64 architecture",
+ "$ref": "#/definitions/fileGroup"
+ },
+ "arm64": {
+ "description": "Files for the arm64 architecture",
+ "$ref": "#/definitions/fileGroup"
+ }
+ },
+ "additionalProperties": false,
+ "minProperties": 1,
+ "maxProperties": 2
+ }
+ },
+ "required": [
+ "root",
+
+ "name",
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ],
+ "definitions": {
+ "fileGroup": {
+ "description": "A collection of files",
+ "type": "array",
+ "items": {
+ "$ref": "common.json#/definitions/file"
+ }
+ }
+ }
+}
diff --git a/third_party/fuchsia-sdk/meta/schemas/loadable_module.json b/third_party/fuchsia-sdk/meta/schemas/loadable_module.json
new file mode 100644
index 0000000..308b45c
--- /dev/null
+++ b/third_party/fuchsia-sdk/meta/schemas/loadable_module.json
@@ -0,0 +1,76 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "id": "http://fuchsia.com/schemas/sdk/loadable_module.json",
+ "description": "A collection of object files that can be loaded at runtime",
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "common.json#/definitions/sdk_element"
+ },
+ {
+ "properties": {
+ "type": {
+ "allOf": [
+ {
+ "$ref": "common.json#/definitions/type"
+ },
+ {
+ "enum": [
+ "loadable_module"
+ ]
+ }
+ ]
+ },
+ "name": {
+ "description": "Name of the module",
+ "type": "string"
+ },
+ "root": {
+ "description": "The root of the element in the SDK",
+ "type": "string"
+ },
+ "resources": {
+ "description": "Resource files associated with the module",
+ "type": "array",
+ "items": {
+ "$ref": "common.json#/definitions/file"
+ }
+ },
+ "binaries": {
+ "description": "The binary files for the module, per architecture",
+ "type": "object",
+ "properties": {
+ "x64": {
+ "description": "Binaries for the x64 architecture",
+ "$ref": "#/definitions/binaryGroup"
+ },
+ "arm64": {
+ "description": "Binaries for the arm64 architecture",
+ "$ref": "#/definitions/binaryGroup"
+ }
+ },
+ "additionalProperties": false,
+ "minProperties": 1,
+ "maxProperties": 2
+ }
+ },
+ "required": [
+ "binaries",
+ "resources",
+
+ "name",
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ],
+ "definitions": {
+ "binaryGroup": {
+ "description": "A set of binary files compiled for a given architecture",
+ "type": "array",
+ "items": {
+ "$ref": "common.json#/definitions/file"
+ }
+ }
+ }
+}
diff --git a/third_party/fuchsia-sdk/meta/schemas/manifest.json b/third_party/fuchsia-sdk/meta/schemas/manifest.json
new file mode 100644
index 0000000..5c3be80
--- /dev/null
+++ b/third_party/fuchsia-sdk/meta/schemas/manifest.json
@@ -0,0 +1,68 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "id": "http://fuchsia.com/schemas/sdk/manifest.json",
+ "description": "The manifest describing the contents of the SDK",
+ "type": "object",
+ "properties": {
+ "arch": {
+ "description": "The various architectures encountered in the SDK",
+ "type": "object",
+ "properties": {
+ "host": {
+ "description": "The host architecture",
+ "type": "string"
+ },
+ "target": {
+ "description": "The target architectures",
+ "type": "array",
+ "items": {
+ "$ref": "common.json#/definitions/target_arch"
+ }
+ }
+ },
+ "additionalProperties": false,
+ "required": [
+ "host",
+ "target"
+ ]
+ },
+ "id": {
+ "description": "An opaque identifier for this SDK",
+ "type": "string"
+ },
+ "parts": {
+ "description": "The elements in this SDK",
+ "type": "array",
+ "minItems": 1,
+ "items": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "description": "The type of the element",
+ "$ref": "common.json#/definitions/type"
+ },
+ "meta": {
+ "description": "The metadata file for the element",
+ "$ref": "common.json#/definitions/file"
+ }
+ },
+ "required": [
+ "meta",
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "schema_version": {
+ "description": "An opaque identifier for metadata schemas in the SDK",
+ "type": "string"
+ }
+ },
+ "required": [
+ "arch",
+ "id",
+ "parts",
+ "schema_version"
+ ],
+ "additionalProperties": false
+}
diff --git a/third_party/fuchsia-sdk/meta/schemas/sysroot.json b/third_party/fuchsia-sdk/meta/schemas/sysroot.json
new file mode 100644
index 0000000..9924ce2
--- /dev/null
+++ b/third_party/fuchsia-sdk/meta/schemas/sysroot.json
@@ -0,0 +1,116 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "id": "http://fuchsia.com/schemas/sdk/sysroot.json",
+ "description": "The sysroot",
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "common.json#/definitions/sdk_element"
+ },
+ {
+ "properties": {
+ "type": {
+ "allOf": [
+ {
+ "$ref": "common.json#/definitions/type"
+ },
+ {
+ "enum": [
+ "sysroot"
+ ]
+ }
+ ]
+ },
+ "name": {
+ "description": "Always 'sysroot'",
+ "type": "string",
+ "enum": [
+ "sysroot"
+ ]
+ },
+ "versions": {
+ "description": "The various versions of the sysroot, per architecture",
+ "type": "object",
+ "properties": {
+ "x64": {
+ "description": "x64 version",
+ "$ref": "#/definitions/version"
+ },
+ "arm64": {
+ "description": "arm64 version",
+ "$ref": "#/definitions/version"
+ }
+ },
+ "additionalProperties": false,
+ "minProperties": 1,
+ "maxProperties": 2
+ }
+ },
+ "required": [
+ "versions",
+
+ "name",
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ],
+ "definitions": {
+ "version": {
+ "description": "Sysroot files for a given architecture",
+ "type": "object",
+ "properties": {
+ "root": {
+ "description": "Path to the root of the sysroot",
+ "$ref": "common.json#/definitions/file"
+ },
+ "headers": {
+ "description": "List of public headers",
+ "type": "array",
+ "items": {
+ "$ref": "common.json#/definitions/file"
+ }
+ },
+ "dist_dir": {
+ "description": "Path to the base directory for prebuilt libraries",
+ "$ref": "common.json#/definitions/file"
+ },
+ "include_dir": {
+ "description": "Path to the base directory for includes",
+ "$ref": "common.json#/definitions/file"
+ },
+ "link_libs": {
+ "description": "List of link-time libraries",
+ "type": "array",
+ "items": {
+ "$ref": "common.json#/definitions/file"
+ }
+ },
+ "dist_libs": {
+ "description": "List of libraries for inclusion in packages",
+ "type": "array",
+ "items": {
+ "$ref": "common.json#/definitions/file"
+ }
+ },
+ "debug_libs": {
+ "description": "List of libraries for debugging",
+ "type": "array",
+ "items": {
+ "$ref": "common.json#/definitions/file"
+ }
+ }
+ },
+ "required": [
+ "root",
+ "headers",
+ "include_dir",
+ "link_libs",
+ "dist_libs",
+ "debug_libs",
+ "dist_dir"
+ ],
+ "additionalProperties": false
+ }
+ }
+}
diff --git a/third_party/fuchsia-sdk/pkg/async-cpp/BUILD.gn b/third_party/fuchsia-sdk/pkg/async-cpp/BUILD.gn
new file mode 100644
index 0000000..832b458
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-cpp/BUILD.gn
@@ -0,0 +1,41 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("async-cpp") {
+ sources = [
+ "executor.cc",
+ "irq.cc",
+ "paged_vmo.cc",
+ "receiver.cc",
+ "task.cc",
+ "trap.cc",
+ "wait.cc",
+ "include/lib/async/cpp/executor.h",
+ "include/lib/async/cpp/irq.h",
+ "include/lib/async/cpp/paged_vmo.h",
+ "include/lib/async/cpp/receiver.h",
+ "include/lib/async/cpp/task.h",
+ "include/lib/async/cpp/time.h",
+ "include/lib/async/cpp/trap.h",
+ "include/lib/async/cpp/wait.h",
+ ]
+ include_dirs = [ "include" ]
+ public_deps = [
+ "../async",
+ "../fit",
+ "../zx",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":async-cpp",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/async-cpp/executor.cc b/third_party/fuchsia-sdk/pkg/async-cpp/executor.cc
new file mode 100644
index 0000000..27b3835
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-cpp/executor.cc
@@ -0,0 +1,228 @@
+// 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.
+
+#include <lib/async/cpp/executor.h>
+
+#include <zircon/assert.h>
+
+namespace async {
+
+Executor::Executor(async_dispatcher_t* dispatcher)
+ : dispatcher_(new DispatcherImpl(dispatcher, this)) {}
+
+Executor::~Executor() {
+ dispatcher_->Shutdown();
+}
+
+void Executor::schedule_task(fit::pending_task task) {
+ ZX_DEBUG_ASSERT(task);
+ dispatcher_->ScheduleTask(std::move(task));
+}
+
+Executor::DispatcherImpl::DispatcherImpl(async_dispatcher_t* dispatcher,
+ Executor* executor)
+ : async_task_t{{ASYNC_STATE_INIT}, &DispatcherImpl::Dispatch, 0},
+ dispatcher_(dispatcher), executor_(executor) {
+ ZX_DEBUG_ASSERT(dispatcher_ != nullptr);
+ ZX_DEBUG_ASSERT(executor_ != nullptr);
+}
+
+Executor::DispatcherImpl::~DispatcherImpl() {
+ std::lock_guard<std::mutex> lock(guarded_.mutex_);
+ ZX_DEBUG_ASSERT(guarded_.was_shutdown_);
+ ZX_DEBUG_ASSERT(!guarded_.dispatch_pending_);
+ ZX_DEBUG_ASSERT(!guarded_.scheduler_.has_runnable_tasks());
+ ZX_DEBUG_ASSERT(!guarded_.scheduler_.has_suspended_tasks());
+ ZX_DEBUG_ASSERT(!guarded_.scheduler_.has_outstanding_tickets());
+ ZX_DEBUG_ASSERT(guarded_.incoming_tasks_.empty());
+ ZX_DEBUG_ASSERT(!guarded_.task_running_);
+}
+
+// Unfortunately std::unique_lock does not support thread-safety annotations
+void Executor::DispatcherImpl::Shutdown() FIT_NO_THREAD_SAFETY_ANALYSIS {
+ std::unique_lock<std::mutex> lock(guarded_.mutex_);
+ ZX_DEBUG_ASSERT(!guarded_.was_shutdown_);
+ ZX_ASSERT_MSG(!guarded_.task_running_,
+ "async::Executor must not be destroyed while tasks may "
+ "be running concurrently on the dispatcher because the "
+ "task's context holds a pointer to the executor.");
+ guarded_.was_shutdown_ = true;
+ PurgeTasksAndMaybeDeleteSelfLocked(std::move(lock));
+}
+
+void Executor::DispatcherImpl::ScheduleTask(fit::pending_task task) {
+ std::lock_guard<std::mutex> lock(guarded_.mutex_);
+ ZX_DEBUG_ASSERT(!guarded_.was_shutdown_);
+
+ // Try to post the task first.
+ // This may fail if the loop is being shut down, in which case we
+ // will let the task be destroyed once it goes out of scope.
+ if (!guarded_.loop_failure_ && ScheduleDispatchLocked()) {
+ guarded_.incoming_tasks_.push(std::move(task));
+ } // else drop the task once the function returns
+}
+
+void Executor::DispatcherImpl::Dispatch(
+ async_dispatcher_t* dispatcher, async_task_t* task, zx_status_t status) {
+ DispatcherImpl* self = static_cast<DispatcherImpl*>(task);
+ self->Dispatch(status);
+}
+
+// Unfortunately std::unique_lock does not support thread-safety annotations
+void Executor::DispatcherImpl::Dispatch(zx_status_t status)
+ FIT_NO_THREAD_SAFETY_ANALYSIS {
+ std::unique_lock<std::mutex> lock(guarded_.mutex_);
+ ZX_DEBUG_ASSERT(guarded_.dispatch_pending_);
+ ZX_DEBUG_ASSERT(!guarded_.loop_failure_);
+ ZX_DEBUG_ASSERT(!guarded_.task_running_);
+
+ if (status == ZX_OK) {
+ // Accept incoming tasks only once before entering the loop.
+ //
+ // This ensures that each invocation of |Dispatch()| has a bounded
+ // amount of work to perform. Specifically, it will only execute
+ // incoming tasks, tasks that are already runnable, and tasks that are
+ // currently suspended but become runnable while the loop is executing.
+ // Once finished, the loop returns control back to the async dispatcher.
+ //
+ // The purpose of this deconstruction is to prevent other units of work
+ // scheduled by the async dispatcher from being starved in the event
+ // that there is a continuous stream of new tasks being scheduled on the
+ // executor. As an extreme example, we must ensure that the async
+ // dispatcher has an opportunity to process its own quit message and
+ // shut down in that scenario.
+ //
+ // An alternative way to solve this problem would be to not loop at all.
+ // Unfortunately, that would significantly increase the overhead of
+ // processing tasks resumed by other tasks.
+ AcceptIncomingTasksLocked();
+ while (!guarded_.was_shutdown_) {
+ guarded_.scheduler_.take_runnable_tasks(&runnable_tasks_);
+ if (runnable_tasks_.empty()) {
+ guarded_.dispatch_pending_ = false;
+ if (guarded_.incoming_tasks_.empty() ||
+ ScheduleDispatchLocked()) {
+ return; // all done
+ }
+ break; // a loop failure occurred, we need to clean up
+ }
+
+ // Drop lock while running tasks then reaquire it.
+ guarded_.task_running_ = true;
+ lock.unlock();
+ do {
+ RunTask(&runnable_tasks_.front());
+ runnable_tasks_.pop(); // the task may be destroyed here if it was not suspended
+ } while (!runnable_tasks_.empty());
+ lock.lock();
+ guarded_.task_running_ = false;
+ }
+ } else {
+ guarded_.loop_failure_ = true;
+ }
+ guarded_.dispatch_pending_ = false;
+ PurgeTasksAndMaybeDeleteSelfLocked(std::move(lock));
+}
+
+void Executor::DispatcherImpl::RunTask(fit::pending_task* task) {
+ ZX_DEBUG_ASSERT(current_task_ticket_ == 0);
+ const bool finished = (*task)(*this);
+ ZX_DEBUG_ASSERT(!*task == finished);
+ if (current_task_ticket_ == 0) {
+ return; // task was not suspended, no ticket was produced
+ }
+
+ std::lock_guard<std::mutex> lock(guarded_.mutex_);
+ guarded_.scheduler_.finalize_ticket(current_task_ticket_, task);
+ current_task_ticket_ = 0;
+}
+
+// Must only be called while |run_task()| is running a task.
+// This happens when the task's continuation calls |context::suspend_task()|
+// upon the context it received as an argument.
+fit::suspended_task Executor::DispatcherImpl::suspend_task() {
+ std::lock_guard<std::mutex> lock(guarded_.mutex_);
+ ZX_DEBUG_ASSERT(guarded_.task_running_);
+ if (current_task_ticket_ == 0) {
+ current_task_ticket_ = guarded_.scheduler_.obtain_ticket(
+ 2 /*initial_refs*/);
+ } else {
+ guarded_.scheduler_.duplicate_ticket(current_task_ticket_);
+ }
+ return fit::suspended_task(this, current_task_ticket_);
+}
+
+fit::suspended_task::ticket Executor::DispatcherImpl::duplicate_ticket(
+ fit::suspended_task::ticket ticket) {
+ std::lock_guard<std::mutex> lock(guarded_.mutex_);
+ guarded_.scheduler_.duplicate_ticket(ticket);
+ return ticket;
+}
+
+// Unfortunately std::unique_lock does not support thread-safety annotations
+void Executor::DispatcherImpl::resolve_ticket(
+ fit::suspended_task::ticket ticket, bool resume_task)
+ FIT_NO_THREAD_SAFETY_ANALYSIS {
+ fit::pending_task abandoned_task; // drop outside of the lock
+ {
+ std::unique_lock<std::mutex> lock(guarded_.mutex_);
+ bool did_resume = false;
+ if (resume_task) {
+ did_resume = guarded_.scheduler_.resume_task_with_ticket(ticket);
+ } else {
+ abandoned_task = guarded_.scheduler_.release_ticket(ticket);
+ }
+ if (!guarded_.was_shutdown_ && !guarded_.loop_failure_ &&
+ (!did_resume || ScheduleDispatchLocked())) {
+ return; // all done
+ }
+ PurgeTasksAndMaybeDeleteSelfLocked(std::move(lock));
+ }
+}
+
+bool Executor::DispatcherImpl::ScheduleDispatchLocked() {
+ ZX_DEBUG_ASSERT(!guarded_.was_shutdown_ && !guarded_.loop_failure_);
+ if (guarded_.dispatch_pending_) {
+ return true; // nothing to do
+ }
+ zx_status_t status = async_post_task(dispatcher_, this);
+ ZX_ASSERT_MSG(status == ZX_OK || status == ZX_ERR_BAD_STATE,
+ "status=%d", status);
+ if (status == ZX_OK) {
+ guarded_.dispatch_pending_ = true;
+ return true; // everything's ok
+ }
+ guarded_.loop_failure_ = true;
+ return false; // failed
+}
+
+void Executor::DispatcherImpl::AcceptIncomingTasksLocked() {
+ while (!guarded_.incoming_tasks_.empty()) {
+ guarded_.scheduler_.schedule_task(
+ std::move(guarded_.incoming_tasks_.front()));
+ guarded_.incoming_tasks_.pop();
+ }
+}
+
+// Unfortunately std::unique_lock does not support thread-safety annotations
+void Executor::DispatcherImpl::PurgeTasksAndMaybeDeleteSelfLocked(
+ std::unique_lock<std::mutex> lock) FIT_NO_THREAD_SAFETY_ANALYSIS {
+ ZX_DEBUG_ASSERT(lock.owns_lock());
+ ZX_DEBUG_ASSERT(guarded_.was_shutdown_ || guarded_.loop_failure_);
+
+ fit::subtle::scheduler::task_queue tasks;
+ AcceptIncomingTasksLocked();
+ guarded_.scheduler_.take_all_tasks(&tasks);
+ const bool can_delete_self = guarded_.was_shutdown_ &&
+ !guarded_.dispatch_pending_ &&
+ !guarded_.scheduler_.has_outstanding_tickets();
+
+ lock.unlock();
+
+ if (can_delete_self) {
+ delete this;
+ }
+}
+
+} // namespace async
diff --git a/third_party/fuchsia-sdk/pkg/async-cpp/include/lib/async/cpp/executor.h b/third_party/fuchsia-sdk/pkg/async-cpp/include/lib/async/cpp/executor.h
new file mode 100644
index 0000000..00d6a10
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-cpp/include/lib/async/cpp/executor.h
@@ -0,0 +1,174 @@
+// 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.
+
+#ifndef LIB_ASYNC_CPP_EXECUTOR_H_
+#define LIB_ASYNC_CPP_EXECUTOR_H_
+
+#include <mutex>
+
+#include <lib/async/dispatcher.h>
+#include <lib/async/task.h>
+#include <lib/fit/promise.h>
+#include <lib/fit/scheduler.h>
+#include <lib/fit/thread_safety.h>
+#include <lib/zx/time.h>
+
+namespace async {
+
+// Execution context for an asynchronous task that runs within the scope
+// of an |async_dispatcher_t|'s dispatch loop, such as a |async::Promise|.
+class Context : public fit::context {
+public:
+ // Gets the executor's |async_dispatcher_t|, never null.
+ virtual async_dispatcher_t* dispatcher() const = 0;
+
+protected:
+ virtual ~Context() = default;
+};
+
+// An asynchronous task executor that wraps an |async_dispatcher_t|.
+//
+// This allows asynchronous tasks, such as promises, to be evaluated alongside
+// other asynchronous operations managed by the |async_dispatcher_t|.
+class Executor final : public fit::executor {
+public:
+ // Wraps the specified dispatcher.
+ //
+ // |dispatcher| must not be null and it must outlive the executor itself.
+ explicit Executor(async_dispatcher_t* dispatcher);
+
+ // Destroys the executor along with all of its remaining scheduled tasks
+ // that have yet to complete.
+ ~Executor() override;
+
+ // Gets the executor's |async_dispatcher_t|, never null.
+ async_dispatcher_t* dispatcher() const { return dispatcher_->dispatcher(); }
+
+ // Schedules a task for eventual execution by the executor.
+ //
+ // This method is thread-safe.
+ void schedule_task(fit::pending_task task) override;
+
+ Executor(const Executor&) = delete;
+ Executor(Executor&&) = delete;
+ Executor& operator=(const Executor&) = delete;
+ Executor& operator=(Executor&&) = delete;
+
+private:
+ // The dispatcher runs tasks, provides the suspended task resolver, and
+ // provides the task context.
+ //
+ // The lifetime of this object is somewhat complex since there are pointers
+ // to it from multiple sources which are released in different ways.
+ //
+ // - |Executor| holds a pointer in |dispatcher_| which it releases after
+ // calling |Shutdown()| to inform the dispatcher of its own demise
+ // - |suspended_task| holds a pointer to the dispatcher's resolver
+ // interface and the number of outstanding pointers corresponds to the
+ // number of outstanding suspended task tickets tracked by |scheduler_|.
+ // - |async_dispatcher_t| holds a pointer to the dispatcher's async task
+ // interface whenever dispatch is pending as indicated by |dispatch_pending_|.
+ //
+ // The dispatcher deletes itself once all pointers have been released.
+ // See also |PurgeTasksAndMaybeDeleteSelfLocked()|.
+ class DispatcherImpl final : public fit::suspended_task::resolver,
+ public async::Context,
+ public async_task_t {
+ public:
+ DispatcherImpl(async_dispatcher_t* dispatcher,
+ Executor* executor);
+
+ void Shutdown();
+ void ScheduleTask(fit::pending_task task);
+
+ // |executor()| and |dispatcher()| are presented on the |async::Context|
+ // so they are only accessible while |task_running_| is true which
+ // implies that |executor_| and |dispatcher_| have not been destroyed.
+ Executor* executor() const override { return executor_; }
+ async_dispatcher_t* dispatcher() const override { return dispatcher_; }
+
+ // Suspends the currently running task. This method is presented
+ // on the |async::Context| so it can only be called while
+ // |task_running_| is true as above.
+ fit::suspended_task suspend_task() override;
+
+ // These methods implement the suspended task token contract.
+ // They may be called on any thread at any time.
+ fit::suspended_task::ticket duplicate_ticket(
+ fit::suspended_task::ticket ticket) override;
+ void resolve_ticket(
+ fit::suspended_task::ticket ticket, bool resume_task) override;
+
+ private:
+ ~DispatcherImpl() override;
+
+ // Callback from |async_dispatcher_t*|.
+ // Invokes |Dispatch()| to run all runnable tasks.
+ static void Dispatch(async_dispatcher_t* dispatcher,
+ async_task_t* task, zx_status_t status);
+ void Dispatch(zx_status_t status);
+
+ // Runs the specified task. Called by |Dispatch()|.
+ void RunTask(fit::pending_task* task);
+
+ // Attempts to schedule a call to |Dispatch()| on the async dispatcher.
+ // Returns true if a dispatch is pending.
+ bool ScheduleDispatchLocked() FIT_REQUIRES(guarded_.mutex_);
+
+ // Moves all tasks from |incoming_tasks_| to the |scheduler_| runnable queue.
+ void AcceptIncomingTasksLocked() FIT_REQUIRES(guarded_.mutex_);
+
+ // When |was_shutdown_| or |loop_failure_| is true, purges any tasks
+ // that remain and deletes the dispatcher if all outstanding references
+ // to it have gone away. Should be called at points where one of these
+ // conditions changes. Takes ownership of the lock and drops it.
+ void PurgeTasksAndMaybeDeleteSelfLocked(
+ std::unique_lock<std::mutex> lock) FIT_REQUIRES(guarded_.mutex_);
+
+ async_dispatcher_t* const dispatcher_;
+ Executor* const executor_;
+
+ // The queue of runnable tasks.
+ // Only accessed by |RunTask()| and |suspend_task()| which happens
+ // on the dispatch thread.
+ fit::subtle::scheduler::task_queue runnable_tasks_;
+
+ // The current suspended task ticket or 0 if none.
+ // Only accessed by |RunTask()| and |suspend_task()| which happens
+ // on the dispatch thread.
+ fit::suspended_task::ticket current_task_ticket_ = 0;
+
+ // A bunch of state that is guarded by a mutex.
+ struct {
+ std::mutex mutex_;
+
+ // True if the executor is about to be destroyed.
+ bool was_shutdown_ FIT_GUARDED(mutex_) = false;
+
+ // True if the underlying async_dispatcher_t reported an error.
+ bool loop_failure_ FIT_GUARDED(mutex_) = false;
+
+ // True if a call to |Dispatch()| is pending.
+ bool dispatch_pending_ FIT_GUARDED(mutex_) = false;
+
+ // True while |RunTask| is running a task.
+ bool task_running_ FIT_GUARDED(mutex_) = false;
+
+ // Holds tasks that have been scheduled on this dispatcher.
+ fit::subtle::scheduler scheduler_ FIT_GUARDED(mutex_);
+
+ // Newly scheduled tasks which have yet to be added to the
+ // runnable queue. This allows the dispatch to distinguish between
+ // newly scheduled tasks and resumed tasks so it can manage them
+ // separately. See comments in |Dispatch()|.
+ fit::subtle::scheduler::task_queue incoming_tasks_ FIT_GUARDED(mutex_);
+ } guarded_;
+ };
+
+ DispatcherImpl* dispatcher_;
+};
+
+} // namespace async
+
+#endif // LIB_ASYNC_CPP_EXECUTOR_H_
diff --git a/third_party/fuchsia-sdk/pkg/async-cpp/include/lib/async/cpp/irq.h b/third_party/fuchsia-sdk/pkg/async-cpp/include/lib/async/cpp/irq.h
new file mode 100644
index 0000000..ec1e2b7
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-cpp/include/lib/async/cpp/irq.h
@@ -0,0 +1,144 @@
+// 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.
+
+#ifndef LIB_ASYNC_CPP_irq_H_
+#define LIB_ASYNC_CPP_irq_H_
+
+#include <lib/async/irq.h>
+#include <lib/fit/function.h>
+
+#include <utility>
+
+namespace async {
+
+// Holds context for an irq and its handler, with RAII semantics.
+// Automatically unbinds the irq when it goes out of scope.
+//
+// This class must only be used with single-threaded asynchronous dispatchers
+// and must only be accessed on the dispatch thread since it lacks internal
+// synchronization of its state.
+//
+// Concrete implementations: |async::Irq|, |async::IrqMethod|.
+// Please do not create subclasses of IrqBase outside of this library.
+class IrqBase {
+ protected:
+ explicit IrqBase(zx_handle_t object, zx_signals_t trigger, uint32_t options,
+ async_irq_handler_t* handler);
+ ~IrqBase();
+
+ IrqBase(const IrqBase&) = delete;
+ IrqBase(IrqBase&&) = delete;
+ IrqBase& operator=(const IrqBase&) = delete;
+ IrqBase& operator=(IrqBase&&) = delete;
+
+ public:
+ // Gets or sets the interrupt object.
+ zx_handle_t object() const { return irq_.object; }
+ void set_object(zx_handle_t object) { irq_.object = object; }
+
+ // Begins asynchronously waiting for the object to receive one or more of
+ // the trigger signals. Invokes the handler when the irq is triggered.
+ //
+ // Returns |ZX_OK| if the irq was successfully begun.
+ // Returns |ZX_ERR_BAD_STATE| if the dispatcher is shutting down.
+ // Returns |ZX_ERR_NOT_SUPPORTED| if not supported by the dispatcher.
+ zx_status_t Begin(async_dispatcher_t* dispatcher);
+
+ // Cancels the irq.
+ //
+ // If successful, the irq's handler will not run.
+ //
+ // Returns |ZX_OK| if the irq was pending and it has been successfully
+ // canceled; its handler will not run again and can be released immediately.
+ // Returns |ZX_ERR_NOT_FOUND| if there was no pending irq either because it
+ // already completed, or had not been started.
+ // Returns |ZX_ERR_NOT_SUPPORTED| if not supported by the dispatcher.
+ zx_status_t Cancel();
+
+ protected:
+ template <typename T>
+ static T* Dispatch(async_irq* irq) {
+ static_assert(offsetof(IrqBase, irq_) == 0, "");
+ auto self = reinterpret_cast<IrqBase*>(irq);
+ return static_cast<T*>(self);
+ }
+
+ private:
+ async_irq_t irq_;
+ async_dispatcher_t* dispatcher_ = nullptr;
+};
+
+// An asynchronous IRQ whose handler is bound to a |async::irq::Handler| function.
+//
+// Prefer using |async::IrqMethod| instead for binding to a fixed class member
+// function since it is more efficient to dispatch.
+class Irq final : public IrqBase {
+ public:
+ // Handles completion of asynchronous irq operations.
+ //
+ // The |status| is |ZX_OK| if the irq was satisfied and |signal| is non-null.
+ // The |status| is |ZX_ERR_CANCELED| if the dispatcher was shut down before
+ // the task's handler ran or the task was canceled.
+ using Handler = fit::function<void(async_dispatcher_t* dispatcher, async::Irq* irq,
+ zx_status_t status, const zx_packet_interrupt_t* interrupt)>;
+
+ // Creates a irq with options == 0.
+ explicit Irq(zx_handle_t object = ZX_HANDLE_INVALID, zx_signals_t trigger = ZX_SIGNAL_NONE,
+ Handler handler = nullptr)
+ : Irq(object, trigger, 0, std::move(handler)) {}
+
+ // Creates a irq with the provided |options|.
+ explicit Irq(zx_handle_t object, zx_signals_t trigger, uint32_t options,
+ Handler handler = nullptr);
+
+ ~Irq();
+
+ void set_handler(Handler handler) { handler_ = std::move(handler); }
+ bool has_handler() const { return !!handler_; }
+
+ private:
+ static void CallHandler(async_dispatcher_t* dispatcher, async_irq_t* irq, zx_status_t status,
+ const zx_packet_interrupt_t* signal);
+
+ Handler handler_;
+};
+
+// An asynchronous irq whose handler is bound to a fixed class member function.
+//
+// Usage:
+//
+// class Foo {
+// void Handle(async_dispatcher_t* dispatcher, async::IrqBase* irq, zx_status_t status,
+// const zx_packet_interrupt_t* interrupt) { ... }
+// async::IrqMethod<Foo, &Foo::Handle> irq_{this};
+// };
+template <class Class,
+ void (Class::*method)(async_dispatcher_t* dispatcher, async::IrqBase* irq,
+ zx_status_t status, const zx_packet_interrupt_t* interrupt)>
+class IrqMethod final : public IrqBase {
+ public:
+ // Creates a irqMethod with options == 0.
+ explicit IrqMethod(Class* instance, zx_handle_t object = ZX_HANDLE_INVALID,
+ zx_signals_t trigger = ZX_SIGNAL_NONE)
+ : IrqMethod(instance, object, trigger, 0) {}
+
+ // Creates a IrqMethod with the provided |options|.
+ explicit IrqMethod(Class* instance, zx_handle_t object, zx_signals_t trigger, uint32_t options)
+ : IrqBase(object, trigger, options, &IrqMethod::CallHandler), instance_(instance) {}
+
+ ~IrqMethod() = default;
+
+ private:
+ static void CallHandler(async_dispatcher_t* dispatcher, async_irq_t* irq, zx_status_t status,
+ const zx_packet_interrupt_t* interrupt) {
+ auto self = Dispatch<IrqMethod>(irq);
+ (self->instance_->*method)(dispatcher, self, status, interrupt);
+ }
+
+ Class* const instance_;
+};
+
+} // namespace async
+
+#endif // LIB_ASYNC_CPP_irq_H_
diff --git a/third_party/fuchsia-sdk/pkg/async-cpp/include/lib/async/cpp/paged_vmo.h b/third_party/fuchsia-sdk/pkg/async-cpp/include/lib/async/cpp/paged_vmo.h
new file mode 100644
index 0000000..e337ccc
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-cpp/include/lib/async/cpp/paged_vmo.h
@@ -0,0 +1,127 @@
+// 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.
+
+#ifndef LIB_ASYNC_CPP_PAGED_VMO_H_
+#define LIB_ASYNC_CPP_PAGED_VMO_H_
+
+#include <lib/async/paged_vmo.h>
+#include <lib/fit/function.h>
+#include <lib/zx/pager.h>
+#include <lib/zx/vmo.h>
+
+namespace async {
+
+// Holds content for a paged vmo packet receiver and its handler.
+//
+// After successfully binding the port, the client is responsible for
+// retaining the structure in memory (and unmodified) until all packets have
+// been received by the handler or the dispatcher shuts down.
+//
+// Concrete implementations: |async::PagedVmo|, |async::PagedVmoMethod|.
+// Please do not create subclasses of PagedVmoBase outside of this library.
+class PagedVmoBase {
+ protected:
+ explicit PagedVmoBase(async_paged_vmo_handler_t* handler);
+ ~PagedVmoBase();
+
+ PagedVmoBase(const PagedVmoBase&) = delete;
+ PagedVmoBase(PagedVmoBase&&) = delete;
+ PagedVmoBase& operator=(const PagedVmoBase&) = delete;
+ PagedVmoBase& operator=(PagedVmoBase&&) = delete;
+
+ template <typename T>
+ static T* Dispatch(async_paged_vmo_t* paged_vmo, zx_status_t status) {
+ static_assert(offsetof(PagedVmoBase, paged_vmo_) == 0, "Non-castable offset");
+ auto self = reinterpret_cast<PagedVmoBase*>(paged_vmo);
+ if (status != ZX_OK) {
+ self->dispatcher_ = nullptr;
+ }
+ return static_cast<T*>(self);
+ }
+
+ public:
+ // Return true if this object is bound to a VMO.
+ bool is_bound() const { return dispatcher_ != nullptr; }
+
+ // Creates a paged VMO registered with |pager|, which will receive notifications on the
+ // receiver provided in the constructor of |PagedVmoBase|.
+ //
+ // Returns |ZX_ERR_ALREADY_EXISTS| if this object is already associated with a VMO.
+ // May return any error from |async_create_paged_vmo()|.
+ zx_status_t CreateVmo(async_dispatcher_t* dispatcher, zx::unowned_pager pager, uint32_t options,
+ uint64_t vmo_size, zx::vmo* vmo_out);
+
+ // Detach the paged VMO from the underlying port.
+ //
+ // Returns |ZX_OK| if the VMO is successfully detached.
+ // Returns |ZX_ERR_NOT_FOUND| if this object is not bound.
+ // May return any error from |async_detach_paged_vmo()|.
+ zx_status_t Detach();
+
+ private:
+ async_paged_vmo_t paged_vmo_ = {};
+ async_dispatcher_t* dispatcher_ = nullptr;
+};
+
+// A receiver whose handler is bound to a |async::PagedVmo::Handler| function.
+//
+// Prefer using |async::PagedVmoMethod| instead for binding to a fixed class member
+// function since it is more efficient to dispatch.
+class PagedVmo final : public PagedVmoBase {
+ public:
+ // Handles receipt of packets containing page requests.
+ //
+ // The |status| is |ZX_OK| if the packet was successfully delivered and |page_request|
+ // contains the information from the packet, otherwise |page_request| is null.
+ using Handler =
+ fit::function<void(async_dispatcher_t* dispatcher, async::PagedVmo* paged_vmo,
+ zx_status_t status, const zx_packet_page_request_t* page_request)>;
+
+ explicit PagedVmo(Handler handler = nullptr);
+ ~PagedVmo();
+
+ void set_handler(Handler handler) { handler_ = std::move(handler); }
+ bool has_handler() const { return !!handler_; }
+
+ private:
+ static void CallHandler(async_dispatcher_t* dispatcher, async_paged_vmo_t* paged_vmo,
+ zx_status_t status, const zx_packet_page_request_t* page_request);
+
+ Handler handler_;
+};
+
+// A receiver whose handler is bound to a fixed class member function.
+//
+// Usage:
+//
+// class Foo {
+// void Handle(async_dispatcher_t* dispatcher,
+// async::PagedVmoBase* paged_vmo,
+// zx_status_t status,
+// const zx_packet_page_request_t* page_request) {
+// ...
+// }
+// async::PagedVmoMethod<Foo, &Foo::Handle> paged_vmo_{this};
+// };
+template <class Class,
+ void (Class::*method)(async_dispatcher_t* dispatcher, async::PagedVmoBase* receiver,
+ zx_status_t status, const zx_packet_page_request_t* page_request)>
+class PagedVmoMethod final : public PagedVmoBase {
+ public:
+ explicit PagedVmoMethod(Class* instance)
+ : PagedVmoBase(&PagedVmoMethod::CallHandler), instance_(instance) {}
+
+ private:
+ static void CallHandler(async_dispatcher_t* dispatcher, async_paged_vmo_t* paged_vmo,
+ zx_status_t status, const zx_packet_page_request_t* page_request) {
+ auto self = Dispatch<PagedVmoMethod>(paged_vmo, status);
+ (self->instance_->*method)(dispatcher, self, status, page_request);
+ }
+
+ Class* const instance_;
+};
+
+} // namespace async
+
+#endif // LIB_ASYNC_CPP_PAGED_VMO_H_
diff --git a/third_party/fuchsia-sdk/pkg/async-cpp/include/lib/async/cpp/receiver.h b/third_party/fuchsia-sdk/pkg/async-cpp/include/lib/async/cpp/receiver.h
new file mode 100644
index 0000000..273049f
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-cpp/include/lib/async/cpp/receiver.h
@@ -0,0 +1,115 @@
+// Copyright 2017 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.
+
+#ifndef LIB_ASYNC_CPP_RECEIVER_H_
+#define LIB_ASYNC_CPP_RECEIVER_H_
+
+#include <lib/async/receiver.h>
+#include <lib/fit/function.h>
+
+#include <utility>
+
+namespace async {
+
+// Holds content for a packet receiver and its handler.
+//
+// After successfully queuing packets to the receiver, the client is responsible
+// for retaining the structure in memory (and unmodified) until all packets have
+// been received by the handler or the dispatcher shuts down. There is no way
+// to cancel a packet which has been queued.
+//
+// Multiple packets may be delivered to the same receiver concurrently.
+//
+// Concrete implementations: |async::Receiver|, |async::ReceiverMethod|.
+// Please do not create subclasses of ReceiverBase outside of this library.
+class ReceiverBase {
+ protected:
+ explicit ReceiverBase(async_receiver_handler_t* handler);
+ ~ReceiverBase();
+
+ ReceiverBase(const ReceiverBase&) = delete;
+ ReceiverBase(ReceiverBase&&) = delete;
+ ReceiverBase& operator=(const ReceiverBase&) = delete;
+ ReceiverBase& operator=(ReceiverBase&&) = delete;
+
+ public:
+ // Enqueues a packet of data for delivery to a receiver.
+ //
+ // The |data| will be copied into the packet. May be NULL to create a
+ // zero-initialized packet payload.
+ //
+ // Returns |ZX_OK| if the packet was successfully enqueued.
+ // Returns |ZX_ERR_BAD_STATE| if the dispatcher is shutting down.
+ // Returns |ZX_ERR_NOT_SUPPORTED| if not supported by the dispatcher.
+ zx_status_t QueuePacket(async_dispatcher_t* dispatcher, const zx_packet_user_t* data = nullptr);
+
+ protected:
+ template <typename T>
+ static T* Dispatch(async_receiver_t* receiver) {
+ static_assert(offsetof(ReceiverBase, receiver_) == 0, "");
+ auto self = reinterpret_cast<ReceiverBase*>(receiver);
+ return static_cast<T*>(self);
+ }
+
+ private:
+ async_receiver_t receiver_;
+};
+
+// A receiver whose handler is bound to a |async::Task::Handler| function.
+//
+// Prefer using |async::ReceiverMethod| instead for binding to a fixed class member
+// function since it is more efficient to dispatch.
+class Receiver final : public ReceiverBase {
+ public:
+ // Handles receipt of packets containing user supplied data.
+ //
+ // The |status| is |ZX_OK| if the packet was successfully delivered and |data|
+ // contains the information from the packet, otherwise |data| is null.
+ using Handler = fit::function<void(async_dispatcher_t* dispatcher, async::Receiver* receiver,
+ zx_status_t status, const zx_packet_user_t* data)>;
+
+ explicit Receiver(Handler handler = nullptr);
+ ~Receiver();
+
+ void set_handler(Handler handler) { handler_ = std::move(handler); }
+ bool has_handler() const { return !!handler_; }
+
+ private:
+ static void CallHandler(async_dispatcher_t* dispatcher, async_receiver_t* receiver,
+ zx_status_t status, const zx_packet_user_t* data);
+
+ Handler handler_;
+};
+
+// A receiver whose handler is bound to a fixed class member function.
+//
+// Usage:
+//
+// class Foo {
+// void Handle(async_dispatcher_t* dispatcher, async::ReceiverBase* receiver, zx_status_t
+// status,
+// const zx_packet_user_t* data) { ... }
+// async::ReceiverMethod<Foo, &Foo::Handle> receiver_{this};
+// };
+template <class Class,
+ void (Class::*method)(async_dispatcher_t* dispatcher, async::ReceiverBase* receiver,
+ zx_status_t status, const zx_packet_user_t* data)>
+class ReceiverMethod final : public ReceiverBase {
+ public:
+ explicit ReceiverMethod(Class* instance)
+ : ReceiverBase(&ReceiverMethod::CallHandler), instance_(instance) {}
+
+ private:
+ static void CallHandler(async_dispatcher_t* dispatcher, async_receiver_t* receiver,
+ zx_status_t status, const zx_packet_user_t* data) {
+ auto self = Dispatch<ReceiverMethod>(receiver);
+ (self->instance_->*method)(dispatcher, self, status, data);
+ }
+
+ Class* const instance_;
+};
+
+} // namespace async
+
+#endif // LIB_ASYNC_CPP_RECEIVER_H_
diff --git a/third_party/fuchsia-sdk/pkg/async-cpp/include/lib/async/cpp/task.h b/third_party/fuchsia-sdk/pkg/async-cpp/include/lib/async/cpp/task.h
new file mode 100644
index 0000000..a7cbc9f
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-cpp/include/lib/async/cpp/task.h
@@ -0,0 +1,234 @@
+// Copyright 2017 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.
+
+#ifndef LIB_ASYNC_CPP_TASK_H_
+#define LIB_ASYNC_CPP_TASK_H_
+
+#include <lib/async/task.h>
+#include <lib/fit/function.h>
+#include <lib/zx/time.h>
+
+#include <utility>
+
+namespace async {
+
+// Posts a task to invoke |handler| with a deadline of now.
+//
+// The handler will not run if the dispatcher shuts down before it comes due.
+//
+// Returns |ZX_OK| if the task was successfully posted.
+// Returns |ZX_ERR_BAD_STATE| if the dispatcher is shutting down.
+// Returns |ZX_ERR_NOT_SUPPORTED| if not supported by the dispatcher.
+zx_status_t PostTask(async_dispatcher_t* dispatcher, fit::closure handler);
+
+// Posts a task to invoke |handler| with a deadline expressed as a |delay| from now.
+//
+// The handler will not run if the dispatcher shuts down before it comes due.
+//
+// Returns |ZX_OK| if the task was successfully posted.
+// Returns |ZX_ERR_BAD_STATE| if the dispatcher is shutting down.
+// Returns |ZX_ERR_NOT_SUPPORTED| if not supported by the dispatcher.
+zx_status_t PostDelayedTask(async_dispatcher_t* dispatcher, fit::closure handler,
+ zx::duration delay);
+
+// Posts a task to invoke |handler| with the specified |deadline|.
+//
+// The handler will not run if the dispatcher shuts down before it comes due.
+//
+// Returns |ZX_OK| if the task was successfully posted.
+// Returns |ZX_ERR_BAD_STATE| if the dispatcher is shutting down.
+// Returns |ZX_ERR_NOT_SUPPORTED| if not supported by the dispatcher.
+zx_status_t PostTaskForTime(async_dispatcher_t* dispatcher, fit::closure handler,
+ zx::time deadline);
+
+// Holds context for a task and its handler, with RAII semantics.
+// Automatically cancels the task when it goes out of scope.
+//
+// After successfully posting the task, the client is responsible for retaining
+// the structure in memory (and unmodified) until the task's handler runs, the task
+// is successfully canceled, or the dispatcher shuts down. Thereafter, the task
+// may be posted again or destroyed.
+//
+// This class must only be used with single-threaded asynchronous dispatchers
+// and must only be accessed on the dispatch thread since it lacks internal
+// synchronization of its state.
+//
+// Concrete implementations: |async::Task|, |async::TaskMethod|,
+// |async::TaskClosure|, |async::TaskClosureMethod|.
+// Please do not create subclasses of TaskBase outside of this library.
+class TaskBase {
+ protected:
+ explicit TaskBase(async_task_handler_t* handler);
+ ~TaskBase();
+
+ TaskBase(const TaskBase&) = delete;
+ TaskBase(TaskBase&&) = delete;
+ TaskBase& operator=(const TaskBase&) = delete;
+ TaskBase& operator=(TaskBase&&) = delete;
+
+ public:
+ // Returns true if the task has been posted and has not yet executed or been canceled.
+ bool is_pending() const { return dispatcher_ != nullptr; }
+
+ // The last deadline with which the task was posted, or |zx::time::infinite()|
+ // if it has never been posted.
+ zx::time last_deadline() const { return zx::time(task_.deadline); }
+
+ // Posts a task to invoke the handler with a deadline of now.
+ //
+ // Returns |ZX_OK| if the task was successfully posted.
+ // Returns |ZX_ERR_BAD_STATE| if the dispatcher is shutting down or if the
+ // task is already pending.
+ // Returns |ZX_ERR_ALREADY_EXISTS| if the task is already pending.
+ // Returns |ZX_ERR_NOT_SUPPORTED| if not supported by the dispatcher.
+ zx_status_t Post(async_dispatcher_t* dispatcher);
+
+ // Posts a task to invoke the handler with a deadline expressed as a |delay| from now.
+ //
+ // Returns |ZX_OK| if the task was successfully posted.
+ // Returns |ZX_ERR_BAD_STATE| if the dispatcher is shutting down or if the
+ // task is already pending.
+ // Returns |ZX_ERR_ALREADY_EXISTS| if the task is already pending.
+ // Returns |ZX_ERR_NOT_SUPPORTED| if not supported by the dispatcher.
+ zx_status_t PostDelayed(async_dispatcher_t* dispatcher, zx::duration delay);
+
+ // Posts a task to invoke the handler with the specified |deadline|.
+ //
+ // The |deadline| must be expressed in the time base used by the asynchronous
+ // dispatcher (usually |ZX_CLOCK_MONOTONIC| except in unit tests).
+ // See |async_now()| for details.
+ //
+ // Returns |ZX_OK| if the task was successfully posted.
+ // Returns |ZX_ERR_BAD_STATE| if the dispatcher is shutting down or if the
+ // task is already pending.
+ // Returns |ZX_ERR_ALREADY_EXISTS| if the task is already pending.
+ // Returns |ZX_ERR_NOT_SUPPORTED| if not supported by the dispatcher.
+ zx_status_t PostForTime(async_dispatcher_t* dispatcher, zx::time deadline);
+
+ // Cancels the task.
+ //
+ // If successful, the task's handler will not run.
+ //
+ // Returns |ZX_OK| if the task was pending and it has been successfully
+ // canceled; its handler will not run again and can be released immediately.
+ // Returns |ZX_ERR_NOT_FOUND| if task was not pending either because its
+ // handler already ran, or the task had not been posted.
+ // Returns |ZX_ERR_NOT_SUPPORTED| if not supported by the dispatcher.
+ zx_status_t Cancel();
+
+ protected:
+ template <typename T>
+ static T* Dispatch(async_task_t* task) {
+ static_assert(offsetof(TaskBase, task_) == 0, "");
+ auto self = reinterpret_cast<TaskBase*>(task);
+ self->dispatcher_ = nullptr;
+ return static_cast<T*>(self);
+ }
+
+ private:
+ async_task_t task_;
+ async_dispatcher_t* dispatcher_ = nullptr;
+};
+
+// A task whose handler is bound to a |async::Task::Handler| function.
+//
+// Prefer using |async::TaskMethod| instead for binding to a fixed class member
+// function since it is more efficient to dispatch.
+class Task final : public TaskBase {
+ public:
+ // Handles execution of a posted task.
+ //
+ // The |status| is |ZX_OK| if the task's deadline elapsed and the task should run.
+ // The |status| is |ZX_ERR_CANCELED| if the dispatcher was shut down before
+ // the task's handler ran or the task was canceled.
+ using Handler =
+ fit::function<void(async_dispatcher_t* dispatcher, async::Task* task, zx_status_t status)>;
+
+ explicit Task(Handler handler = nullptr);
+ ~Task();
+
+ void set_handler(Handler handler) { handler_ = std::move(handler); }
+ bool has_handler() const { return !!handler_; }
+
+ private:
+ static void CallHandler(async_dispatcher_t* dispatcher, async_task_t* task, zx_status_t status);
+
+ Handler handler_;
+};
+
+// A task whose handler is bound to a fixed class member function.
+//
+// Usage:
+//
+// class Foo {
+// void Handle(async_dispatcher_t* dispatcher, async::TaskBase* task, zx_status_t status) { ...
+// } async::TaskMethod<Foo, &Foo::Handle> task_{this};
+// };
+template <class Class, void (Class::*method)(async_dispatcher_t* dispatcher, async::TaskBase* task,
+ zx_status_t status)>
+class TaskMethod final : public TaskBase {
+ public:
+ explicit TaskMethod(Class* instance) : TaskBase(&TaskMethod::CallHandler), instance_(instance) {}
+ ~TaskMethod() = default;
+
+ private:
+ static void CallHandler(async_dispatcher_t* dispatcher, async_task_t* task, zx_status_t status) {
+ auto self = Dispatch<TaskMethod>(task);
+ (self->instance_->*method)(dispatcher, self, status);
+ }
+
+ Class* const instance_;
+};
+
+// A task whose handler is bound to a |fit::closure| function with no arguments.
+// The closure is not invoked when errors occur since it doesn't have a |zx_status_t|
+// argument.
+//
+// Prefer using |async::TaskClosureMethod| instead for binding to a fixed class member
+// function since it is more efficient to dispatch.
+class TaskClosure final : public TaskBase {
+ public:
+ explicit TaskClosure(fit::closure handler = nullptr);
+ ~TaskClosure();
+
+ void set_handler(fit::closure handler) { handler_ = std::move(handler); }
+ bool has_handler() const { return !!handler_; }
+
+ private:
+ static void CallHandler(async_dispatcher_t* dispatcher, async_task_t* task, zx_status_t status);
+
+ fit::closure handler_;
+};
+
+// A task whose handler is bound to a fixed class member function with no arguments.
+// The closure is not invoked when errors occur since it doesn't have a |zx_status_t|
+// argument.
+//
+// Usage:
+//
+// class Foo {
+// void Handle() { ... }
+// async::TaskClosureMethod<Foo, &Foo::Handle> trap_{this};
+// };
+template <class Class, void (Class::*method)()>
+class TaskClosureMethod final : public TaskBase {
+ public:
+ explicit TaskClosureMethod(Class* instance)
+ : TaskBase(&TaskClosureMethod::CallHandler), instance_(instance) {}
+ ~TaskClosureMethod() = default;
+
+ private:
+ static void CallHandler(async_dispatcher_t* dispatcher, async_task_t* task, zx_status_t status) {
+ auto self = Dispatch<TaskClosureMethod>(task); // must do this if status is not ok
+ if (status == ZX_OK) {
+ (self->instance_->*method)();
+ }
+ }
+
+ Class* const instance_;
+};
+
+} // namespace async
+
+#endif // LIB_ASYNC_CPP_TASK_H_
diff --git a/third_party/fuchsia-sdk/pkg/async-cpp/include/lib/async/cpp/time.h b/third_party/fuchsia-sdk/pkg/async-cpp/include/lib/async/cpp/time.h
new file mode 100644
index 0000000..df7950e
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-cpp/include/lib/async/cpp/time.h
@@ -0,0 +1,20 @@
+// Copyright 2018 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.
+
+#ifndef LIB_ASYNC_CPP_TIME_H_
+#define LIB_ASYNC_CPP_TIME_H_
+
+#include <lib/async/time.h>
+#include <lib/zx/time.h>
+
+namespace async {
+
+// Returns the current time in the dispatcher's timebase.
+// For most loops, this is generally obtained from |ZX_CLOCK_MONOTONIC|
+// but certain loops may use a different timebase, notably for testing.
+inline zx::time Now(async_dispatcher_t* dispatcher) { return zx::time(async_now(dispatcher)); }
+
+} // namespace async
+
+#endif // LIB_ASYNC_CPP_TIME_H_
diff --git a/third_party/fuchsia-sdk/pkg/async-cpp/include/lib/async/cpp/trap.h b/third_party/fuchsia-sdk/pkg/async-cpp/include/lib/async/cpp/trap.h
new file mode 100644
index 0000000..35f06ec
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-cpp/include/lib/async/cpp/trap.h
@@ -0,0 +1,123 @@
+// Copyright 2018 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.
+
+#ifndef LIB_ASYNC_CPP_TRAP_H_
+#define LIB_ASYNC_CPP_TRAP_H_
+
+#include <lib/async/trap.h>
+#include <lib/fit/function.h>
+#include <lib/zx/guest.h>
+
+#include <utility>
+
+namespace async {
+
+// Holds context for a bell trap and its handler.
+//
+// After successfully posting setting the trap, the client is responsible for retaining
+// the structure in memory (and unmodified) until the guest has been destroyed or the
+// dispatcher shuts down. There is no way to cancel a trap which has been set.
+//
+// Concrete implementations: |async::GuestBellTrap|, |async::GuestBellTrapMethod|.
+// Please do not create subclasses of GuestBellTrapBase outside of this library.
+class GuestBellTrapBase {
+ protected:
+ explicit GuestBellTrapBase(async_guest_bell_trap_handler_t* handler);
+ ~GuestBellTrapBase();
+
+ GuestBellTrapBase(const GuestBellTrapBase&) = delete;
+ GuestBellTrapBase(GuestBellTrapBase&&) = delete;
+ GuestBellTrapBase& operator=(const GuestBellTrapBase&) = delete;
+ GuestBellTrapBase& operator=(GuestBellTrapBase&&) = delete;
+
+ public:
+ // Sets a bell trap in the guest to be handled asynchronously via a handler.
+ //
+ // |guest| is the handle of the guest the trap will be set on.
+ // |addr| is the base address for the trap in the guest's physical address space.
+ // |length| is the size of the trap in the guest's physical address space.
+ //
+ // Returns |ZX_OK| if the trap was successfully set.
+ // Returns |ZX_ERR_ACCESS_DENIED| if the guest does not have |ZX_RIGHT_WRITE|.
+ // Returns |ZX_ERR_ALREADY_EXISTS| if a bell trap with the same |addr| exists.
+ // Returns |ZX_ERR_INVALID_ARGS| if |addr| or |length| are invalid.
+ // Returns |ZX_ERR_OUT_OF_RANGE| if |addr| or |length| are out of range of the
+ // address space.
+ // Returns |ZX_ERR_WRONG_TYPE| if |guest| is not a handle to a guest.
+ // Returns |ZX_ERR_BAD_STATE| if the dispatcher is shutting down.
+ // Returns |ZX_ERR_NOT_SUPPORTED| if not supported by the dispatcher.
+ //
+ // This operation is thread-safe.
+ zx_status_t SetTrap(async_dispatcher_t* dispatcher, const zx::guest& guest, zx_vaddr_t addr,
+ size_t length);
+
+ protected:
+ template <typename T>
+ static T* Dispatch(async_guest_bell_trap_t* trap) {
+ static_assert(offsetof(GuestBellTrapBase, trap_) == 0, "");
+ auto self = reinterpret_cast<GuestBellTrapBase*>(trap);
+ return static_cast<T*>(self);
+ }
+
+ private:
+ async_guest_bell_trap_t trap_;
+};
+
+// A bell trap whose handler is bound to a |async::Task::Handler| function.
+//
+// Prefer using |async::GuestBellTrapMethod| instead for binding to a fixed class member
+// function since it is more efficient to dispatch.
+class GuestBellTrap final : public GuestBellTrapBase {
+ public:
+ // Handles an asynchronous trap access.
+ //
+ // The |status| is |ZX_OK| if the bell was received and |bell| contains the
+ // information from the packet, otherwise |bell| is null.
+ using Handler = fit::function<void(async_dispatcher_t* dispatcher, async::GuestBellTrap* trap,
+ zx_status_t status, const zx_packet_guest_bell_t* bell)>;
+
+ explicit GuestBellTrap(Handler handler = nullptr);
+ ~GuestBellTrap();
+
+ void set_handler(Handler handler) { handler_ = std::move(handler); }
+ bool has_handler() const { return !!handler_; }
+
+ private:
+ static void CallHandler(async_dispatcher_t* dispatcher, async_guest_bell_trap_t* trap,
+ zx_status_t status, const zx_packet_guest_bell_t* bell);
+
+ Handler handler_;
+};
+
+// A bell trap whose handler is bound to a fixed class member function.
+//
+// Usage:
+//
+// class Foo {
+// void Handle(async_dispatcher_t* dispatcher, async::GuestBellTrapBase* trap, zx_status_t
+// status,
+// const zx_packet_guest_bell_t* bell) { ... }
+// async::GuestBellTrapMethod<Foo, &Foo::Handle> trap_{this};
+// };
+template <class Class,
+ void (Class::*method)(async_dispatcher_t* dispatcher, async::GuestBellTrapBase* trap,
+ zx_status_t status, const zx_packet_guest_bell_t* bell)>
+class GuestBellTrapMethod final : public GuestBellTrapBase {
+ public:
+ explicit GuestBellTrapMethod(Class* instance)
+ : GuestBellTrapBase(&GuestBellTrapMethod::CallHandler), instance_(instance) {}
+
+ private:
+ static void CallHandler(async_dispatcher_t* dispatcher, async_guest_bell_trap_t* trap,
+ zx_status_t status, const zx_packet_guest_bell_t* bell) {
+ auto self = Dispatch<GuestBellTrapMethod>(trap);
+ (self->instance_->*method)(dispatcher, self, status, bell);
+ }
+
+ Class* const instance_;
+};
+
+} // namespace async
+
+#endif // LIB_ASYNC_CPP_TRAP_H_
diff --git a/third_party/fuchsia-sdk/pkg/async-cpp/include/lib/async/cpp/wait.h b/third_party/fuchsia-sdk/pkg/async-cpp/include/lib/async/cpp/wait.h
new file mode 100644
index 0000000..f927a49
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-cpp/include/lib/async/cpp/wait.h
@@ -0,0 +1,154 @@
+// Copyright 2017 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.
+
+#ifndef LIB_ASYNC_CPP_WAIT_H_
+#define LIB_ASYNC_CPP_WAIT_H_
+
+#include <lib/async/wait.h>
+#include <lib/fit/function.h>
+
+#include <utility>
+
+namespace async {
+
+// Holds context for an asynchronous wait and its handler, with RAII semantics.
+// Automatically cancels the wait when it goes out of scope.
+//
+// After successfully beginning the wait, the client is responsible for retaining
+// the structure in memory (and unmodified) until the wait's handler runs, the wait
+// is successfully canceled, or the dispatcher shuts down. Thereafter, the wait
+// may be begun again or destroyed.
+//
+// This class must only be used with single-threaded asynchronous dispatchers
+// and must only be accessed on the dispatch thread since it lacks internal
+// synchronization of its state.
+//
+// Concrete implementations: |async::Wait|, |async::WaitMethod|.
+// Please do not create subclasses of WaitBase outside of this library.
+class WaitBase {
+ protected:
+ explicit WaitBase(zx_handle_t object, zx_signals_t trigger, uint32_t options,
+ async_wait_handler_t* handler);
+ ~WaitBase();
+
+ WaitBase(const WaitBase&) = delete;
+ WaitBase(WaitBase&&) = delete;
+ WaitBase& operator=(const WaitBase&) = delete;
+ WaitBase& operator=(WaitBase&&) = delete;
+
+ public:
+ // Gets or sets the object to wait for signals on.
+ zx_handle_t object() const { return wait_.object; }
+ void set_object(zx_handle_t object) { wait_.object = object; }
+
+ // Gets or sets the signals to wait for.
+ zx_signals_t trigger() const { return wait_.trigger; }
+ void set_trigger(zx_signals_t trigger) { wait_.trigger = trigger; }
+
+ // Gets or sets the options to wait with. See zx_object_wait_async().
+ uint32_t options() const { return wait_.options; }
+ void set_options(uint32_t options) { wait_.options = options; }
+
+ // Returns true if the wait has begun and not yet completed or been canceled.
+ bool is_pending() const { return dispatcher_ != nullptr; }
+
+ // Begins asynchronously waiting for the object to receive one or more of
+ // the trigger signals. Invokes the handler when the wait completes.
+ //
+ // The wait's handler will be invoked exactly once unless the wait is canceled.
+ // When the dispatcher is shutting down (being destroyed), the handlers of
+ // all remaining waits will be invoked with a status of |ZX_ERR_CANCELED|.
+ //
+ // Returns |ZX_OK| if the wait was successfully begun.
+ // Returns |ZX_ERR_ACCESS_DENIED| if the object does not have |ZX_RIGHT_WAIT|.
+ // Returns |ZX_ERR_BAD_STATE| if the dispatcher is shutting down.
+ // Returns |ZX_ERR_NOT_SUPPORTED| if not supported by the dispatcher.
+ zx_status_t Begin(async_dispatcher_t* dispatcher);
+
+ // Cancels the wait.
+ //
+ // If successful, the wait's handler will not run.
+ //
+ // Returns |ZX_OK| if the wait was pending and it has been successfully
+ // canceled; its handler will not run again and can be released immediately.
+ // Returns |ZX_ERR_NOT_FOUND| if there was no pending wait either because it
+ // already completed, or had not been started.
+ // Returns |ZX_ERR_NOT_SUPPORTED| if not supported by the dispatcher.
+ zx_status_t Cancel();
+
+ protected:
+ template <typename T>
+ static T* Dispatch(async_wait* wait) {
+ static_assert(offsetof(WaitBase, wait_) == 0, "");
+ auto self = reinterpret_cast<WaitBase*>(wait);
+ self->dispatcher_ = nullptr;
+ return static_cast<T*>(self);
+ }
+
+ private:
+ async_wait_t wait_;
+ async_dispatcher_t* dispatcher_ = nullptr;
+};
+
+// An asynchronous wait whose handler is bound to a |async::Wait::Handler| function.
+//
+// Prefer using |async::WaitMethod| instead for binding to a fixed class member
+// function since it is more efficient to dispatch.
+class Wait final : public WaitBase {
+ public:
+ // Handles completion of asynchronous wait operations.
+ //
+ // The |status| is |ZX_OK| if the wait was satisfied and |signal| is non-null.
+ // The |status| is |ZX_ERR_CANCELED| if the dispatcher was shut down before
+ // the task's handler ran or the task was canceled.
+ using Handler = fit::function<void(async_dispatcher_t* dispatcher, async::Wait* wait,
+ zx_status_t status, const zx_packet_signal_t* signal)>;
+
+ explicit Wait(zx_handle_t object = ZX_HANDLE_INVALID, zx_signals_t trigger = ZX_SIGNAL_NONE,
+ uint32_t options = 0, Handler handler = nullptr);
+
+ ~Wait();
+
+ void set_handler(Handler handler) { handler_ = std::move(handler); }
+ bool has_handler() const { return !!handler_; }
+
+ private:
+ static void CallHandler(async_dispatcher_t* dispatcher, async_wait_t* wait, zx_status_t status,
+ const zx_packet_signal_t* signal);
+
+ Handler handler_;
+};
+
+// An asynchronous wait whose handler is bound to a fixed class member function.
+//
+// Usage:
+//
+// class Foo {
+// void Handle(async_dispatcher_t* dispatcher, async::WaitBase* wait, zx_status_t status,
+// const zx_packet_signal_t* signal) { ... }
+// async::WaitMethod<Foo, &Foo::Handle> wait_{this};
+// };
+template <class Class, void (Class::*method)(async_dispatcher_t* dispatcher, async::WaitBase* wait,
+ zx_status_t status, const zx_packet_signal_t* signal)>
+class WaitMethod final : public WaitBase {
+ public:
+ explicit WaitMethod(Class* instance, zx_handle_t object = ZX_HANDLE_INVALID,
+ zx_signals_t trigger = ZX_SIGNAL_NONE, uint32_t options = 0)
+ : WaitBase(object, trigger, options, &WaitMethod::CallHandler), instance_(instance) {}
+
+ ~WaitMethod() = default;
+
+ private:
+ static void CallHandler(async_dispatcher_t* dispatcher, async_wait_t* wait, zx_status_t status,
+ const zx_packet_signal_t* signal) {
+ auto self = Dispatch<WaitMethod>(wait);
+ (self->instance_->*method)(dispatcher, self, status, signal);
+ }
+
+ Class* const instance_;
+};
+
+} // namespace async
+
+#endif // LIB_ASYNC_CPP_WAIT_H_
diff --git a/third_party/fuchsia-sdk/pkg/async-cpp/irq.cc b/third_party/fuchsia-sdk/pkg/async-cpp/irq.cc
new file mode 100644
index 0000000..d4cc9af
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-cpp/irq.cc
@@ -0,0 +1,64 @@
+// 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.
+
+#include <lib/async/cpp/irq.h>
+#include <zircon/assert.h>
+
+#include <utility>
+
+namespace async {
+
+IrqBase::IrqBase(zx_handle_t object, zx_signals_t trigger, uint32_t options,
+ async_irq_handler_t* handler)
+ : irq_{{ASYNC_STATE_INIT}, handler, object} {}
+
+IrqBase::~IrqBase() {
+ if (dispatcher_) {
+ // Failure to cancel here may result in a dangling pointer...
+ zx_status_t status = async_unbind_irq(dispatcher_, &irq_);
+ ZX_ASSERT_MSG(status == ZX_OK, "status=%d", status);
+ }
+}
+
+zx_status_t IrqBase::Begin(async_dispatcher_t* dispatcher) {
+ if (dispatcher_)
+ return ZX_ERR_ALREADY_EXISTS;
+
+ dispatcher_ = dispatcher;
+ zx_status_t status = async_bind_irq(dispatcher, &irq_);
+ if (status != ZX_OK) {
+ dispatcher_ = nullptr;
+ }
+ return status;
+}
+
+zx_status_t IrqBase::Cancel() {
+ if (!dispatcher_)
+ return ZX_ERR_NOT_FOUND;
+
+ async_dispatcher_t* dispatcher = dispatcher_;
+ dispatcher_ = nullptr;
+
+ zx_status_t status = async_unbind_irq(dispatcher, &irq_);
+ // |dispatcher| is required to be single-threaded, Cancel() is
+ // only supposed to be called on |dispatcher|'s thread, and
+ // we verified that the wait was pending before calling
+ // async_cancel_wait(). Assuming that |dispatcher| never queues
+ // a wait, |wait_| must have been pending with |dispatcher|.
+ ZX_DEBUG_ASSERT(status != ZX_ERR_NOT_FOUND);
+ return status;
+}
+
+Irq::Irq(zx_handle_t object, zx_signals_t trigger, uint32_t options, Handler handler)
+ : IrqBase(object, trigger, options, &Irq::CallHandler), handler_(std::move(handler)) {}
+
+Irq::~Irq() = default;
+
+void Irq::CallHandler(async_dispatcher_t* dispatcher, async_irq_t* irq, zx_status_t status,
+ const zx_packet_interrupt_t* signal) {
+ auto self = Dispatch<Irq>(irq);
+ self->handler_(dispatcher, self, status, signal);
+}
+
+} // namespace async
diff --git a/third_party/fuchsia-sdk/pkg/async-cpp/meta.json b/third_party/fuchsia-sdk/pkg/async-cpp/meta.json
new file mode 100644
index 0000000..887d54c
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-cpp/meta.json
@@ -0,0 +1,32 @@
+{
+ "banjo_deps": [],
+ "deps": [
+ "async",
+ "zx",
+ "fit"
+ ],
+ "fidl_deps": [],
+ "headers": [
+ "pkg/async-cpp/include/lib/async/cpp/executor.h",
+ "pkg/async-cpp/include/lib/async/cpp/paged_vmo.h",
+ "pkg/async-cpp/include/lib/async/cpp/receiver.h",
+ "pkg/async-cpp/include/lib/async/cpp/task.h",
+ "pkg/async-cpp/include/lib/async/cpp/time.h",
+ "pkg/async-cpp/include/lib/async/cpp/trap.h",
+ "pkg/async-cpp/include/lib/async/cpp/wait.h",
+ "pkg/async-cpp/include/lib/async/cpp/irq.h"
+ ],
+ "include_dir": "pkg/async-cpp/include",
+ "name": "async-cpp",
+ "root": "pkg/async-cpp",
+ "sources": [
+ "pkg/async-cpp/executor.cc",
+ "pkg/async-cpp/irq.cc",
+ "pkg/async-cpp/paged_vmo.cc",
+ "pkg/async-cpp/receiver.cc",
+ "pkg/async-cpp/task.cc",
+ "pkg/async-cpp/trap.cc",
+ "pkg/async-cpp/wait.cc"
+ ],
+ "type": "cc_source_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/async-cpp/paged_vmo.cc b/third_party/fuchsia-sdk/pkg/async-cpp/paged_vmo.cc
new file mode 100644
index 0000000..6e4be85
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-cpp/paged_vmo.cc
@@ -0,0 +1,63 @@
+// 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.
+
+#include <lib/async/cpp/paged_vmo.h>
+#include <zircon/assert.h>
+
+#include <utility>
+
+namespace async {
+
+PagedVmoBase::PagedVmoBase(async_paged_vmo_handler_t* handler)
+ : paged_vmo_{{ASYNC_STATE_INIT}, handler, ZX_HANDLE_INVALID, ZX_HANDLE_INVALID} {
+ ZX_DEBUG_ASSERT(handler);
+}
+
+PagedVmoBase::~PagedVmoBase() { Detach(); }
+
+zx_status_t PagedVmoBase::CreateVmo(async_dispatcher_t* dispatcher, zx::unowned_pager pager,
+ uint32_t options, uint64_t vmo_size, zx::vmo* vmo_out) {
+ if (dispatcher_) {
+ return ZX_ERR_ALREADY_EXISTS;
+ }
+
+ zx_status_t status = async_create_paged_vmo(dispatcher, &paged_vmo_, options, pager->get(),
+ vmo_size, vmo_out->reset_and_get_address());
+ if (status != ZX_OK) {
+ return status;
+ }
+ dispatcher_ = dispatcher;
+ paged_vmo_.pager = pager->get();
+ paged_vmo_.vmo = vmo_out->get();
+ return ZX_OK;
+}
+
+zx_status_t PagedVmoBase::Detach() {
+ if (!dispatcher_) {
+ return ZX_ERR_NOT_FOUND;
+ }
+
+ auto dispatcher = dispatcher_;
+ dispatcher_ = nullptr;
+
+ zx_status_t status = async_detach_paged_vmo(dispatcher, &paged_vmo_);
+ // |dispatcher| is required to be single-threaded, Detach() is only supposed to be called on
+ // |dispatcher|'s thread, and we verified that the port was bound before calling
+ // async_detach_paged_vmo().
+ ZX_DEBUG_ASSERT(status != ZX_ERR_NOT_FOUND);
+ return status;
+}
+
+PagedVmo::PagedVmo(Handler handler)
+ : PagedVmoBase(&PagedVmo::CallHandler), handler_(std::move(handler)) {}
+
+PagedVmo::~PagedVmo() = default;
+
+void PagedVmo::CallHandler(async_dispatcher_t* dispatcher, async_paged_vmo_t* paged_vmo,
+ zx_status_t status, const zx_packet_page_request_t* request) {
+ auto self = Dispatch<PagedVmo>(paged_vmo, status);
+ self->handler_(dispatcher, self, status, request);
+}
+
+} // namespace async
diff --git a/third_party/fuchsia-sdk/pkg/async-cpp/receiver.cc b/third_party/fuchsia-sdk/pkg/async-cpp/receiver.cc
new file mode 100644
index 0000000..f1077b9
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-cpp/receiver.cc
@@ -0,0 +1,32 @@
+// Copyright 2017 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.
+
+#include <lib/async/cpp/receiver.h>
+
+#include <utility>
+
+namespace async {
+
+ReceiverBase::ReceiverBase(async_receiver_handler_t* handler)
+ : receiver_{{ASYNC_STATE_INIT}, handler} {}
+
+ReceiverBase::~ReceiverBase() = default;
+
+zx_status_t ReceiverBase::QueuePacket(async_dispatcher_t* dispatcher,
+ const zx_packet_user_t* data) {
+ return async_queue_packet(dispatcher, &receiver_, data);
+}
+
+Receiver::Receiver(Handler handler)
+ : ReceiverBase(&Receiver::CallHandler), handler_(std::move(handler)) {}
+
+Receiver::~Receiver() = default;
+
+void Receiver::CallHandler(async_dispatcher_t* dispatcher, async_receiver_t* receiver,
+ zx_status_t status, const zx_packet_user_t* data) {
+ auto self = Dispatch<Receiver>(receiver);
+ self->handler_(dispatcher, self, status, data);
+}
+
+} // namespace async
diff --git a/third_party/fuchsia-sdk/pkg/async-cpp/task.cc b/third_party/fuchsia-sdk/pkg/async-cpp/task.cc
new file mode 100644
index 0000000..9f2937d
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-cpp/task.cc
@@ -0,0 +1,123 @@
+// Copyright 2017 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.
+
+#include <lib/async/cpp/task.h>
+
+#include <lib/async/cpp/time.h>
+#include <zircon/assert.h>
+
+#include <utility>
+
+namespace async {
+namespace internal {
+
+struct RetainedTask : public async_task_t {
+ RetainedTask(fit::closure handler, zx::time deadline)
+ : async_task_t{{ASYNC_STATE_INIT}, &RetainedTask::Handler, deadline.get()},
+ handler(static_cast<fit::closure&&>(handler)) {}
+
+ fit::closure handler;
+
+ static void Handler(async_dispatcher_t* dispatcher, async_task_t* task, zx_status_t status) {
+ auto self = static_cast<RetainedTask*>(task);
+ if (status == ZX_OK)
+ self->handler();
+ delete self;
+ }
+};
+
+} // namespace internal
+
+zx_status_t PostTask(async_dispatcher_t* dispatcher, fit::closure handler) {
+ return PostTaskForTime(dispatcher, static_cast<fit::closure&&>(handler), async::Now(dispatcher));
+}
+
+zx_status_t PostDelayedTask(async_dispatcher_t* dispatcher, fit::closure handler,
+ zx::duration delay) {
+ return PostTaskForTime(dispatcher, static_cast<fit::closure&&>(handler),
+ async::Now(dispatcher) + delay);
+}
+
+zx_status_t PostTaskForTime(async_dispatcher_t* dispatcher, fit::closure handler,
+ zx::time deadline) {
+ auto* task = new internal::RetainedTask(static_cast<fit::closure&&>(handler), deadline);
+ zx_status_t status = async_post_task(dispatcher, task);
+ if (status != ZX_OK)
+ delete task;
+ return status;
+}
+
+TaskBase::TaskBase(async_task_handler_t* handler)
+ : task_{{ASYNC_STATE_INIT}, handler, ZX_TIME_INFINITE} {}
+
+TaskBase::~TaskBase() {
+ if (dispatcher_) {
+ // Failure to cancel here may result in a dangling pointer...
+ zx_status_t status = async_cancel_task(dispatcher_, &task_);
+ ZX_ASSERT_MSG(status == ZX_OK, "status=%d", status);
+ }
+}
+
+zx_status_t TaskBase::Post(async_dispatcher_t* dispatcher) {
+ return PostForTime(dispatcher, async::Now(dispatcher));
+}
+
+zx_status_t TaskBase::PostDelayed(async_dispatcher_t* dispatcher, zx::duration delay) {
+ return PostForTime(dispatcher, async::Now(dispatcher) + delay);
+}
+
+zx_status_t TaskBase::PostForTime(async_dispatcher_t* dispatcher, zx::time deadline) {
+ if (dispatcher_)
+ return ZX_ERR_ALREADY_EXISTS;
+
+ dispatcher_ = dispatcher;
+ task_.deadline = deadline.get();
+ zx_status_t status = async_post_task(dispatcher, &task_);
+ if (status != ZX_OK) {
+ dispatcher_ = nullptr;
+ }
+ return status;
+}
+
+zx_status_t TaskBase::Cancel() {
+ if (!dispatcher_)
+ return ZX_ERR_NOT_FOUND;
+
+ async_dispatcher_t* dispatcher = dispatcher_;
+ dispatcher_ = nullptr;
+
+ zx_status_t status = async_cancel_task(dispatcher, &task_);
+ // |dispatcher| is required to be single-threaded, Cancel() is
+ // only supposed to be called on |dispatcher|'s thread, and we
+ // verified that the task was pending before calling
+ // async_cancel_task(). Assuming that |dispatcher| does not yield
+ // between removing the task and invoking the task's handler,
+ // |task_| must have been pending with |dispatcher|.
+ ZX_DEBUG_ASSERT(status != ZX_ERR_NOT_FOUND);
+ return status;
+}
+
+Task::Task(Handler handler) : TaskBase(&Task::CallHandler), handler_(std::move(handler)) {}
+
+Task::~Task() = default;
+
+void Task::CallHandler(async_dispatcher_t* dispatcher, async_task_t* task, zx_status_t status) {
+ auto self = Dispatch<Task>(task);
+ self->handler_(dispatcher, self, status);
+}
+
+TaskClosure::TaskClosure(fit::closure handler)
+ : TaskBase(&TaskClosure::CallHandler), handler_(std::move(handler)) {}
+
+TaskClosure::~TaskClosure() = default;
+
+void TaskClosure::CallHandler(async_dispatcher_t* dispatcher, async_task_t* task,
+ zx_status_t status) {
+ auto self = Dispatch<TaskClosure>(task); // must do this if status is not ok
+ if (status == ZX_OK) {
+ self->handler_();
+ }
+}
+
+} // namespace async
diff --git a/third_party/fuchsia-sdk/pkg/async-cpp/trap.cc b/third_party/fuchsia-sdk/pkg/async-cpp/trap.cc
new file mode 100644
index 0000000..dc3781f
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-cpp/trap.cc
@@ -0,0 +1,32 @@
+// Copyright 2017 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.
+
+#include <lib/async/cpp/trap.h>
+
+#include <utility>
+
+namespace async {
+
+GuestBellTrapBase::GuestBellTrapBase(async_guest_bell_trap_handler_t* handler)
+ : trap_{{ASYNC_STATE_INIT}, handler} {}
+
+GuestBellTrapBase::~GuestBellTrapBase() = default;
+
+zx_status_t GuestBellTrapBase::SetTrap(async_dispatcher_t* dispatcher, const zx::guest& guest,
+ zx_vaddr_t addr, size_t length) {
+ return async_set_guest_bell_trap(dispatcher, &trap_, guest.get(), addr, length);
+}
+
+GuestBellTrap::GuestBellTrap(Handler handler)
+ : GuestBellTrapBase(&GuestBellTrap::CallHandler), handler_(std::move(handler)) {}
+
+GuestBellTrap::~GuestBellTrap() = default;
+
+void GuestBellTrap::CallHandler(async_dispatcher_t* dispatcher, async_guest_bell_trap_t* trap,
+ zx_status_t status, const zx_packet_guest_bell_t* bell) {
+ auto self = Dispatch<GuestBellTrap>(trap);
+ self->handler_(dispatcher, self, status, bell);
+}
+
+} // namespace async
diff --git a/third_party/fuchsia-sdk/pkg/async-cpp/wait.cc b/third_party/fuchsia-sdk/pkg/async-cpp/wait.cc
new file mode 100644
index 0000000..5e2c7cb
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-cpp/wait.cc
@@ -0,0 +1,65 @@
+// Copyright 2017 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.
+
+#include <lib/async/cpp/wait.h>
+
+#include <utility>
+
+#include <zircon/assert.h>
+
+namespace async {
+
+WaitBase::WaitBase(zx_handle_t object, zx_signals_t trigger, uint32_t options,
+ async_wait_handler_t* handler)
+ : wait_{{ASYNC_STATE_INIT}, handler, object, trigger, options} {}
+
+WaitBase::~WaitBase() {
+ if (dispatcher_) {
+ // Failure to cancel here may result in a dangling pointer...
+ zx_status_t status = async_cancel_wait(dispatcher_, &wait_);
+ ZX_ASSERT_MSG(status == ZX_OK, "status=%d", status);
+ }
+}
+
+zx_status_t WaitBase::Begin(async_dispatcher_t* dispatcher) {
+ if (dispatcher_)
+ return ZX_ERR_ALREADY_EXISTS;
+
+ dispatcher_ = dispatcher;
+ zx_status_t status = async_begin_wait(dispatcher, &wait_);
+ if (status != ZX_OK) {
+ dispatcher_ = nullptr;
+ }
+ return status;
+}
+
+zx_status_t WaitBase::Cancel() {
+ if (!dispatcher_)
+ return ZX_ERR_NOT_FOUND;
+
+ async_dispatcher_t* dispatcher = dispatcher_;
+ dispatcher_ = nullptr;
+
+ zx_status_t status = async_cancel_wait(dispatcher, &wait_);
+ // |dispatcher| is required to be single-threaded, Cancel() is
+ // only supposed to be called on |dispatcher|'s thread, and
+ // we verified that the wait was pending before calling
+ // async_cancel_wait(). Assuming that |dispatcher| never queues
+ // a wait, |wait_| must have been pending with |dispatcher|.
+ ZX_DEBUG_ASSERT(status != ZX_ERR_NOT_FOUND);
+ return status;
+}
+
+Wait::Wait(zx_handle_t object, zx_signals_t trigger, uint32_t options, Handler handler)
+ : WaitBase(object, trigger, options, &Wait::CallHandler), handler_(std::move(handler)) {}
+
+Wait::~Wait() = default;
+
+void Wait::CallHandler(async_dispatcher_t* dispatcher, async_wait_t* wait, zx_status_t status,
+ const zx_packet_signal_t* signal) {
+ auto self = Dispatch<Wait>(wait);
+ self->handler_(dispatcher, self, status, signal);
+}
+
+} // namespace async
diff --git a/third_party/fuchsia-sdk/pkg/async-default/BUILD.gn b/third_party/fuchsia-sdk/pkg/async-default/BUILD.gn
new file mode 100644
index 0000000..4f70305
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-default/BUILD.gn
@@ -0,0 +1,27 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("async-default") {
+ shared_libs = [ "async-default" ]
+
+ deps = [
+ "../async",
+ ]
+ sources = [
+ "include/lib/async/default.h",
+ ]
+ include_dirs = [ "include" ]
+}
+
+group("all"){
+ deps = [
+ ":async-default",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/async-default/include/lib/async/default.h b/third_party/fuchsia-sdk/pkg/async-default/include/lib/async/default.h
new file mode 100644
index 0000000..b171058
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-default/include/lib/async/default.h
@@ -0,0 +1,23 @@
+// Copyright 2017 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.
+
+#ifndef LIB_ASYNC_DEFAULT_H_
+#define LIB_ASYNC_DEFAULT_H_
+
+#include <lib/async/dispatcher.h>
+#include <zircon/compiler.h>
+
+__BEGIN_CDECLS
+
+// Gets the current thread's default asynchronous dispatcher interface.
+// Returns |NULL| if none.
+__EXPORT async_dispatcher_t* async_get_default_dispatcher(void);
+
+// Sets the current thread's default asynchronous dispatcher interface.
+// May be set to |NULL| if this thread doesn't have a default dispatcher.
+__EXPORT void async_set_default_dispatcher(async_dispatcher_t* dispatcher);
+
+__END_CDECLS
+
+#endif // LIB_ASYNC_DEFAULT_H_
diff --git a/third_party/fuchsia-sdk/pkg/async-default/meta.json b/third_party/fuchsia-sdk/pkg/async-default/meta.json
new file mode 100644
index 0000000..383a614
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-default/meta.json
@@ -0,0 +1,27 @@
+{
+ "binaries": {
+ "arm64": {
+ "debug": ".build-id/07/b0d3ac8f42e1e7.debug",
+ "dist": "arch/arm64/dist/libasync-default.so",
+ "dist_path": "lib/libasync-default.so",
+ "link": "arch/arm64/lib/libasync-default.so"
+ },
+ "x64": {
+ "debug": ".build-id/2f/61d6b2df790300.debug",
+ "dist": "arch/x64/dist/libasync-default.so",
+ "dist_path": "lib/libasync-default.so",
+ "link": "arch/x64/lib/libasync-default.so"
+ }
+ },
+ "deps": [
+ "async"
+ ],
+ "format": "shared",
+ "headers": [
+ "pkg/async-default/include/lib/async/default.h"
+ ],
+ "include_dir": "pkg/async-default/include",
+ "name": "async-default",
+ "root": "pkg/async-default",
+ "type": "cc_prebuilt_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/async-loop-cpp/BUILD.gn b/third_party/fuchsia-sdk/pkg/async-loop-cpp/BUILD.gn
new file mode 100644
index 0000000..2e17161
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-loop-cpp/BUILD.gn
@@ -0,0 +1,28 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("async-loop-cpp") {
+ sources = [
+ "loop_wrapper.cc",
+ "include/lib/async-loop/cpp/loop.h",
+ ]
+ include_dirs = [ "include" ]
+ public_deps = [
+ "../async",
+ "../async-loop",
+ "../zx",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":async-loop-cpp",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/async-loop-cpp/include/lib/async-loop/cpp/loop.h b/third_party/fuchsia-sdk/pkg/async-loop-cpp/include/lib/async-loop/cpp/loop.h
new file mode 100644
index 0000000..02cae75
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-loop-cpp/include/lib/async-loop/cpp/loop.h
@@ -0,0 +1,125 @@
+// Copyright 2017 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.
+
+#ifndef LIB_ASYNC_LOOP_CPP_LOOP_H_
+#define LIB_ASYNC_LOOP_CPP_LOOP_H_
+
+#include <lib/async-loop/loop.h>
+#include <lib/zx/time.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <threads.h>
+#include <zircon/compiler.h>
+
+namespace async {
+
+/// C++ wrapper for an asynchronous dispatch loop.
+///
+/// This class is thread-safe.
+class Loop {
+ public:
+ /// Creates a message loop.
+ /// All operations on the message loop are thread-safe (except destroy).
+ ///
+ /// Note that it's ok to run the loop on a different thread from the one
+ /// upon which it was created.
+ ///
+ /// |config| provides configuration for the message loop. Must not be null.
+ ///
+ /// See also |kAsyncLoopConfigNeverAttachToThread|,
+ /// |kAsyncLoopConfigAttachToCurrentThread|, and
+ /// |kAsyncLoopConfigNoAttachToCurrentThread|.
+ explicit Loop(const async_loop_config_t* config);
+
+ Loop(const Loop&) = delete;
+ Loop(Loop&&) = delete;
+ Loop& operator=(const Loop&) = delete;
+ Loop& operator=(Loop&&) = delete;
+
+ /// Destroys the message loop.
+ /// Implicitly calls |Shutdown()|.
+ ~Loop();
+
+ /// Gets the underlying message loop structure.
+ async_loop_t* loop() const { return loop_; }
+
+ /// Gets the loop's asynchronous dispatch interface.
+ async_dispatcher_t* dispatcher() const { return async_loop_get_dispatcher(loop_); }
+
+ /// Shuts down the message loop, notifies handlers which asked to handle shutdown.
+ /// The message loop must not currently be running on any threads other than
+ /// those started by |StartThread()| which this function will join.
+ ///
+ /// Does nothing if already shutting down.
+ void Shutdown();
+
+ /// Runs the message loop on the current thread.
+ /// This function can be called on multiple threads to setup a multi-threaded
+ /// dispatcher.
+ ///
+ /// Dispatches events until the |deadline| expires or the loop is quitted.
+ /// Use |ZX_TIME_INFINITE| to dispatch events indefinitely.
+ ///
+ /// If |once| is true, performs a single unit of work then returns.
+ ///
+ /// Returns |ZX_OK| if the dispatcher returns after one cycle.
+ /// Returns |ZX_ERR_TIMED_OUT| if the deadline expired.
+ /// Returns |ZX_ERR_CANCELED| if the loop quitted.
+ /// Returns |ZX_ERR_BAD_STATE| if the loop was shut down with |Shutdown()|.
+ zx_status_t Run(zx::time deadline = zx::time::infinite(), bool once = false);
+
+ /// Dispatches events until there are none remaining, and then returns
+ /// without waiting. This is useful for unit testing, because the behavior
+ /// doesn't depend on time.
+ ///
+ /// Returns |ZX_OK| if the dispatcher reaches an idle state.
+ /// Returns |ZX_ERR_CANCELED| if the loop quitted.
+ /// Returns |ZX_ERR_BAD_STATE| if the loop was shut down with |Shutdown()|.
+ zx_status_t RunUntilIdle();
+
+ /// Quits the message loop.
+ /// Active invocations of |Run()| and threads started using |StartThread()|
+ /// will eventually terminate upon completion of their current unit of work.
+ ///
+ /// Subsequent calls to |Run()| or |StartThread()| will return immediately
+ /// until |ResetQuit()| is called.
+ void Quit();
+
+ /// Resets the quit state of the message loop so that it can be restarted
+ /// using |Run()| or |StartThread()|.
+ ///
+ /// This function must only be called when the message loop is not running.
+ /// The caller must ensure all active invocations of |Run()| and threads
+ /// started using |StartThread()| have terminated before resetting the quit state.
+ ///
+ /// Returns |ZX_OK| if the loop's state was |ASYNC_LOOP_RUNNABLE| or |ASYNC_LOOP_QUIT|.
+ /// Returns |ZX_ERR_BAD_STATE| if the loop's state was |ASYNC_LOOP_SHUTDOWN| or if
+ /// the message loop is currently active on one or more threads.
+ zx_status_t ResetQuit();
+
+ /// Returns the current state of the message loop.
+ async_loop_state_t GetState() const;
+
+ /// Starts a message loop running on a new thread.
+ /// The thread will run until the loop quits.
+ ///
+ /// |name| is the desired name for the new thread, may be NULL.
+ /// If |out_thread| is not NULL, it is set to the new thread identifier.
+ ///
+ /// Returns |ZX_OK| on success.
+ /// Returns |ZX_ERR_BAD_STATE| if the loop was shut down with |async_loop_shutdown()|.
+ /// Returns |ZX_ERR_NO_MEMORY| if allocation or thread creation failed.
+ zx_status_t StartThread(const char* name = nullptr, thrd_t* out_thread = nullptr);
+
+ /// Blocks until all dispatch threads started with |StartThread()|
+ /// have terminated.
+ void JoinThreads();
+
+ private:
+ async_loop_t* loop_;
+};
+
+} // namespace async
+
+#endif // LIB_ASYNC_LOOP_CPP_LOOP_H_
diff --git a/third_party/fuchsia-sdk/pkg/async-loop-cpp/loop_wrapper.cc b/third_party/fuchsia-sdk/pkg/async-loop-cpp/loop_wrapper.cc
new file mode 100644
index 0000000..f94ed06
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-loop-cpp/loop_wrapper.cc
@@ -0,0 +1,38 @@
+// Copyright 2017 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.
+
+#include <lib/async-loop/cpp/loop.h>
+
+#include <zircon/assert.h>
+
+namespace async {
+
+Loop::Loop(const async_loop_config_t* config) {
+ zx_status_t status = async_loop_create(config, &loop_);
+ ZX_ASSERT_MSG(status == ZX_OK, "status=%d", status);
+}
+
+Loop::~Loop() { async_loop_destroy(loop_); }
+
+void Loop::Shutdown() { async_loop_shutdown(loop_); }
+
+zx_status_t Loop::Run(zx::time deadline, bool once) {
+ return async_loop_run(loop_, deadline.get(), once);
+}
+
+zx_status_t Loop::RunUntilIdle() { return async_loop_run_until_idle(loop_); }
+
+void Loop::Quit() { async_loop_quit(loop_); }
+
+zx_status_t Loop::ResetQuit() { return async_loop_reset_quit(loop_); }
+
+async_loop_state_t Loop::GetState() const { return async_loop_get_state(loop_); }
+
+zx_status_t Loop::StartThread(const char* name, thrd_t* out_thread) {
+ return async_loop_start_thread(loop_, name, out_thread);
+}
+
+void Loop::JoinThreads() { async_loop_join_threads(loop_); }
+
+} // namespace async
diff --git a/third_party/fuchsia-sdk/pkg/async-loop-cpp/meta.json b/third_party/fuchsia-sdk/pkg/async-loop-cpp/meta.json
new file mode 100644
index 0000000..ca1f542
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-loop-cpp/meta.json
@@ -0,0 +1,19 @@
+{
+ "banjo_deps": [],
+ "deps": [
+ "async",
+ "async-loop",
+ "zx"
+ ],
+ "fidl_deps": [],
+ "headers": [
+ "pkg/async-loop-cpp/include/lib/async-loop/cpp/loop.h"
+ ],
+ "include_dir": "pkg/async-loop-cpp/include",
+ "name": "async-loop-cpp",
+ "root": "pkg/async-loop-cpp",
+ "sources": [
+ "pkg/async-loop-cpp/loop_wrapper.cc"
+ ],
+ "type": "cc_source_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/async-loop-default/BUILD.gn b/third_party/fuchsia-sdk/pkg/async-loop-default/BUILD.gn
new file mode 100644
index 0000000..b29c0ba
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-loop-default/BUILD.gn
@@ -0,0 +1,28 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("async-loop-default") {
+ static_libs = [ "async-loop-default" ]
+
+ deps = [
+ "../async-default",
+ "../async-loop",
+ ]
+ sources = [
+ "include/lib/async-loop/default.h",
+ ]
+ include_dirs = [ "include" ]
+}
+
+group("all"){
+ deps = [
+ ":async-loop-default",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/async-loop-default/include/lib/async-loop/default.h b/third_party/fuchsia-sdk/pkg/async-loop-default/include/lib/async-loop/default.h
new file mode 100644
index 0000000..bbe6c35
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-loop-default/include/lib/async-loop/default.h
@@ -0,0 +1,27 @@
+// 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.
+
+#ifndef LIB_ASYNC_LOOP_DEFAULT_H_
+#define LIB_ASYNC_LOOP_DEFAULT_H_
+
+#include <lib/async-loop/loop.h>
+#include <zircon/compiler.h>
+
+__BEGIN_CDECLS
+
+/// Simple config that when passed to async_loop_create will create a loop
+/// that will automatically register itself as the default
+/// dispatcher for the thread upon which it was created and will
+/// automatically unregister itself when destroyed (which must occur on
+/// the same thread).
+extern const async_loop_config_t kAsyncLoopConfigAttachToCurrentThread;
+
+/// Simple config that when passed to async_loop_create will create a loop
+/// that is not registered to the current thread, but any threads created with
+/// async_loop_start_thread will have the loop registered.
+extern const async_loop_config_t kAsyncLoopConfigNoAttachToCurrentThread;
+
+__END_CDECLS
+
+#endif // LIB_ASYNC_LOOP_LOOP_H_
diff --git a/third_party/fuchsia-sdk/pkg/async-loop-default/meta.json b/third_party/fuchsia-sdk/pkg/async-loop-default/meta.json
new file mode 100644
index 0000000..96c7841
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-loop-default/meta.json
@@ -0,0 +1,22 @@
+{
+ "binaries": {
+ "arm64": {
+ "link": "arch/arm64/lib/libasync-loop-default.a"
+ },
+ "x64": {
+ "link": "arch/x64/lib/libasync-loop-default.a"
+ }
+ },
+ "deps": [
+ "async-default",
+ "async-loop"
+ ],
+ "format": "static",
+ "headers": [
+ "pkg/async-loop-default/include/lib/async-loop/default.h"
+ ],
+ "include_dir": "pkg/async-loop-default/include",
+ "name": "async-loop-default",
+ "root": "pkg/async-loop-default",
+ "type": "cc_prebuilt_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/async-loop/BUILD.gn b/third_party/fuchsia-sdk/pkg/async-loop/BUILD.gn
new file mode 100644
index 0000000..1575180
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-loop/BUILD.gn
@@ -0,0 +1,26 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("async-loop") {
+ sources = [
+ "loop.c",
+ "include/lib/async-loop/loop.h",
+ ]
+ include_dirs = [ "include" ]
+ public_deps = [
+ "../async",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":async-loop",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/async-loop/include/lib/async-loop/loop.h b/third_party/fuchsia-sdk/pkg/async-loop/include/lib/async-loop/loop.h
new file mode 100644
index 0000000..a3d3252
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-loop/include/lib/async-loop/loop.h
@@ -0,0 +1,195 @@
+// Copyright 2017 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.
+
+//
+// Provides an implementation of a simple thread-safe asynchronous
+// dispatcher based on a Zircon completion port. The implementation
+// is designed to avoid most dynamic memory allocation except for that
+// which is required to create the loop in the first place or to manage
+// the list of running threads.
+//
+// See README.md for example usage.
+//
+
+#ifndef LIB_ASYNC_LOOP_LOOP_H_
+#define LIB_ASYNC_LOOP_LOOP_H_
+
+#include <lib/async/dispatcher.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <threads.h>
+#include <zircon/compiler.h>
+
+__BEGIN_CDECLS
+
+/// Pointer to a message loop created using |async_loop_create()|.
+typedef struct async_loop async_loop_t;
+
+/// Accessors for getting/setting the "default" async loop for the thread upon
+/// which an async loop is created.
+typedef async_dispatcher_t*(async_loop_get_default_dispatcher_t)(void);
+typedef void(async_loop_set_default_dispatcher_t)(async_dispatcher_t*);
+typedef struct {
+ async_loop_get_default_dispatcher_t* getter;
+ async_loop_set_default_dispatcher_t* setter;
+} async_loop_default_accessors_t;
+
+/// Message loop configuration structure.
+typedef void(async_loop_callback_t)(async_loop_t* loop, void* data);
+typedef struct async_loop_config {
+ /// If specified, these functions will be used to register the loop as the default
+ /// dispatcher on the thread on which they are called and will be used to
+ /// automatically unregister the loop when it is destroyed.
+ ///
+ /// If NULL, the loop will not do this. The loop's creator is then
+ /// responsible for retrieving the loop's dispatcher using |async_loop_get_dispatcher()|
+ /// and passing it around explicitly.
+ ///
+ /// It is an error for only one of the functions to be non-NULL.
+ ///
+ /// Note that the loop can be used even without setting it as the current
+ /// thread's default.
+ async_loop_default_accessors_t default_accessors;
+
+ /// If true, then uses default_accessors.setter to register the loop as the
+ /// default dispatcher for the thread upon which the loop was created.
+ ///
+ /// TRANSITIONAL BEHAVIOR:
+ /// If default_accesors are not specified and this flag is true, then behaves as if
+ /// async_get_default_dispatcher/async_set_default_dispatcher were specified
+ /// as the default_accessors.
+ bool make_default_for_current_thread;
+
+ /// A function to call before the dispatcher invokes each handler, or NULL if none.
+ async_loop_callback_t* prologue;
+
+ /// A function to call after the dispatcher invokes each handler, or NULL if none.
+ async_loop_callback_t* epilogue;
+
+ /// Data to pass to the callback functions.
+ void* data;
+
+ /// True if IRQs should be supported
+ bool irq_support;
+} async_loop_config_t;
+
+/// Simple config that when passed to async_loop_create will create a loop
+/// that is not registered to the current thread or any threads created with
+/// async_loop_start_thread
+extern const async_loop_config_t kAsyncLoopConfigNeverAttachToThread;
+
+/// Creates a message loop and returns a pointer to it in |out_loop|.
+/// All operations on the message loop are thread-safe (except destroy).
+///
+/// Note that it's ok to run the loop on a different thread from the one
+/// upon which it was created.
+///
+/// |config| provides configuration for the message loop. Must not be null.
+///
+/// Returns |ZX_OK| on success.
+/// Returns |ZX_ERR_NO_MEMORY| if allocation failed.
+/// May return other errors if the necessary internal handles could not be created.
+///
+/// See also |kAsyncLoopConfigNeverAttachToThread|,
+/// |kAsyncLoopConfigAttachToCurrentThread|, and
+/// |kAsyncLoopConfigNoAttachToCurrentThread|.
+zx_status_t async_loop_create(const async_loop_config_t* config, async_loop_t** out_loop);
+
+/// Gets the message loop's asynchronous dispatch interface.
+async_dispatcher_t* async_loop_get_dispatcher(async_loop_t* loop);
+
+/// Gets the message loop associated with the specified asynchronous dispatch interface
+///
+/// This function assumes the dispatcher is backed by an |async_loop_t| which was created
+/// using |async_loop_create()|. Its behavior is undefined if used with other dispatcher
+/// implementations.
+async_loop_t* async_loop_from_dispatcher(async_dispatcher_t* dispatcher);
+
+/// Shuts down the message loop, notifies handlers which asked to handle shutdown.
+/// The message loop must not currently be running on any threads other than
+/// those started by |async_loop_start_thread()| which this function will join.
+///
+/// Does nothing if already shutting down.
+void async_loop_shutdown(async_loop_t* loop);
+
+/// Destroys the message loop.
+/// Implicitly calls |async_loop_shutdown()| and joins all threads started
+/// using |async_loop_start_thread()| before destroying the loop itself.
+///
+/// If `make_default_for_current_thread` was true in the config used to create
+/// the loop, then this method must be called on the same thread that called
+/// async_loop_create.
+void async_loop_destroy(async_loop_t* loop);
+
+/// Runs the message loop on the current thread.
+/// This function can be called on multiple threads to setup a multi-threaded
+/// dispatcher.
+///
+/// Dispatches events until the |deadline| expires or the loop is quitted.
+/// Use |ZX_TIME_INFINITE| to dispatch events indefinitely.
+///
+/// If |once| is true, performs a single unit of work then returns.
+///
+/// Returns |ZX_OK| if the dispatcher returns after one cycle.
+/// Returns |ZX_ERR_TIMED_OUT| if the deadline expired.
+/// Returns |ZX_ERR_CANCELED| if the loop quitted.
+/// Returns |ZX_ERR_BAD_STATE| if the loop was shut down with |async_loop_shutdown()|.
+zx_status_t async_loop_run(async_loop_t* loop, zx_time_t deadline, bool once);
+
+/// Dispatches events until there are none remaining, and then returns without
+/// waiting. This is useful for unit testing, because the behavior doesn't depend
+/// on time.
+///
+/// Returns |ZX_OK| if the dispatcher reaches an idle state.
+/// Returns |ZX_ERR_CANCELED| if the loop quitted.
+/// Returns |ZX_ERR_BAD_STATE| if the loop was shut down with |async_loop_shutdown()|.
+zx_status_t async_loop_run_until_idle(async_loop_t* loop);
+
+/// Quits the message loop.
+/// Active invocations of |async_loop_run()| and threads started using
+/// |async_loop_start_thread()| will eventually terminate upon completion of their
+/// current unit of work.
+///
+/// Subsequent calls to |async_loop_run()| or |async_loop_start_thread()|
+/// will return immediately until |async_loop_reset_quit()| is called.
+void async_loop_quit(async_loop_t* loop);
+
+/// Resets the quit state of the message loop so that it can be restarted
+/// using |async_loop_run()| or |async_loop_start_thread()|.
+///
+/// This function must only be called when the message loop is not running.
+/// The caller must ensure all active invocations of |async_loop_run()| and
+/// threads started using |async_loop_start_thread()| have terminated before
+/// resetting the quit state.
+///
+/// Returns |ZX_OK| if the loop's state was |ASYNC_LOOP_RUNNABLE| or |ASYNC_LOOP_QUIT|.
+/// Returns |ZX_ERR_BAD_STATE| if the loop's state was |ASYNC_LOOP_SHUTDOWN| or if
+/// the message loop is currently active on one or more threads.
+zx_status_t async_loop_reset_quit(async_loop_t* loop);
+
+/// Returns the current state of the message loop.
+typedef uint32_t async_loop_state_t;
+#define ASYNC_LOOP_RUNNABLE ((async_loop_state_t)0)
+#define ASYNC_LOOP_QUIT ((async_loop_state_t)1)
+#define ASYNC_LOOP_SHUTDOWN ((async_loop_state_t)2)
+async_loop_state_t async_loop_get_state(async_loop_t* loop);
+
+/// Starts a message loop running on a new thread.
+/// The thread will run until the loop quits.
+///
+/// |name| is the desired name for the new thread, may be NULL.
+/// If |out_thread| is not NULL, it is set to the new thread identifier.
+///
+/// Returns |ZX_OK| on success.
+/// Returns |ZX_ERR_BAD_STATE| if the loop was shut down with |async_loop_shutdown()|.
+/// Returns |ZX_ERR_NO_MEMORY| if allocation or thread creation failed.
+zx_status_t async_loop_start_thread(async_loop_t* loop, const char* name, thrd_t* out_thread);
+
+/// Blocks until all dispatch threads started with |async_loop_start_thread()|
+/// have terminated.
+void async_loop_join_threads(async_loop_t* loop);
+
+__END_CDECLS
+
+#endif // LIB_ASYNC_LOOP_LOOP_H_
diff --git a/third_party/fuchsia-sdk/pkg/async-loop/loop.c b/third_party/fuchsia-sdk/pkg/async-loop/loop.c
new file mode 100644
index 0000000..4c00a38
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-loop/loop.c
@@ -0,0 +1,847 @@
+// Copyright 2017 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.
+
+#ifndef _ALL_SOURCE
+#define _ALL_SOURCE // Enables thrd_create_with_name in <threads.h>.
+#endif
+#include <assert.h>
+#include <lib/async-loop/loop.h>
+#include <lib/async/irq.h>
+#include <lib/async/paged_vmo.h>
+#include <lib/async/receiver.h>
+#include <lib/async/task.h>
+#include <lib/async/trap.h>
+#include <lib/async/wait.h>
+#include <stdatomic.h>
+#include <stdlib.h>
+#include <zircon/assert.h>
+#include <zircon/listnode.h>
+#include <zircon/syscalls.h>
+#include <zircon/syscalls/hypervisor.h>
+
+// The port wait key associated with the dispatcher's control messages.
+#define KEY_CONTROL (0u)
+
+static zx_time_t async_loop_now(async_dispatcher_t* dispatcher);
+static zx_status_t async_loop_begin_wait(async_dispatcher_t* dispatcher, async_wait_t* wait);
+static zx_status_t async_loop_cancel_wait(async_dispatcher_t* dispatcher, async_wait_t* wait);
+static zx_status_t async_loop_post_task(async_dispatcher_t* dispatcher, async_task_t* task);
+static zx_status_t async_loop_cancel_task(async_dispatcher_t* dispatcher, async_task_t* task);
+static zx_status_t async_loop_queue_packet(async_dispatcher_t* dispatcher,
+ async_receiver_t* receiver,
+ const zx_packet_user_t* data);
+static zx_status_t async_loop_set_guest_bell_trap(async_dispatcher_t* dispatcher,
+ async_guest_bell_trap_t* trap, zx_handle_t guest,
+ zx_vaddr_t addr, size_t length);
+static zx_status_t async_loop_bind_irq(async_dispatcher_t* dispatcher, async_irq_t* irq);
+static zx_status_t async_loop_unbind_irq(async_dispatcher_t* dispatcher, async_irq_t* irq);
+static zx_status_t async_loop_create_paged_vmo(async_dispatcher_t* async,
+ async_paged_vmo_t* paged_vmo, uint32_t options,
+ zx_handle_t pager, uint64_t vmo_size,
+ zx_handle_t* vmo_out);
+static zx_status_t async_loop_detach_paged_vmo(async_dispatcher_t* dispatcher,
+ async_paged_vmo_t* paged_vmo);
+
+static const async_ops_t async_loop_ops = {
+ .version = ASYNC_OPS_V2,
+ .reserved = 0,
+ .v1 =
+ {
+ .now = async_loop_now,
+ .begin_wait = async_loop_begin_wait,
+ .cancel_wait = async_loop_cancel_wait,
+ .post_task = async_loop_post_task,
+ .cancel_task = async_loop_cancel_task,
+ .queue_packet = async_loop_queue_packet,
+ .set_guest_bell_trap = async_loop_set_guest_bell_trap,
+ },
+ .v2 = {
+ .bind_irq = async_loop_bind_irq,
+ .unbind_irq = async_loop_unbind_irq,
+ .create_paged_vmo = async_loop_create_paged_vmo,
+ .detach_paged_vmo = async_loop_detach_paged_vmo,
+ }};
+
+typedef struct thread_record {
+ list_node_t node;
+ thrd_t thread;
+} thread_record_t;
+
+const async_loop_config_t kAsyncLoopConfigNeverAttachToThread = {
+ .make_default_for_current_thread = false,
+ .default_accessors = {.getter = NULL, .setter = NULL}};
+
+typedef struct async_loop {
+ async_dispatcher_t dispatcher; // must be first (the loop inherits from async_dispatcher_t)
+ async_loop_config_t config; // immutable
+ zx_handle_t port; // immutable
+ zx_handle_t timer; // immutable
+
+ _Atomic async_loop_state_t state;
+ atomic_uint active_threads; // number of active dispatch threads
+
+ mtx_t lock; // guards the lists and the dispatching tasks flag
+ bool dispatching_tasks; // true while the loop is busy dispatching tasks
+ list_node_t wait_list; // most recently added first
+ list_node_t task_list; // pending tasks, earliest deadline first
+ list_node_t due_list; // due tasks, earliest deadline first
+ list_node_t thread_list; // earliest created thread first
+ list_node_t irq_list; // list of IRQs
+ list_node_t paged_vmo_list; // most recently added first
+ bool timer_armed; // true if timer has been set and has not fired yet
+} async_loop_t;
+
+static zx_status_t async_loop_run_once(async_loop_t* loop, zx_time_t deadline);
+static zx_status_t async_loop_dispatch_wait(async_loop_t* loop, async_wait_t* wait,
+ zx_status_t status, const zx_packet_signal_t* signal);
+static zx_status_t async_loop_dispatch_irq(async_loop_t* loop, async_irq_t* irq, zx_status_t status,
+ const zx_packet_interrupt_t* interrupt);
+static zx_status_t async_loop_dispatch_tasks(async_loop_t* loop);
+static void async_loop_dispatch_task(async_loop_t* loop, async_task_t* task, zx_status_t status);
+static zx_status_t async_loop_dispatch_packet(async_loop_t* loop, async_receiver_t* receiver,
+ zx_status_t status, const zx_packet_user_t* data);
+static zx_status_t async_loop_dispatch_guest_bell_trap(async_loop_t* loop,
+ async_guest_bell_trap_t* trap,
+ zx_status_t status,
+ const zx_packet_guest_bell_t* bell);
+static zx_status_t async_loop_dispatch_paged_vmo(async_loop_t* loop, async_paged_vmo_t* paged_vmo,
+ zx_status_t status,
+ const zx_packet_page_request_t* page_request);
+static zx_status_t async_loop_cancel_paged_vmo(async_paged_vmo_t* paged_vmo);
+static void async_loop_wake_threads(async_loop_t* loop);
+static void async_loop_insert_task_locked(async_loop_t* loop, async_task_t* task);
+static void async_loop_restart_timer_locked(async_loop_t* loop);
+static void async_loop_invoke_prologue(async_loop_t* loop);
+static void async_loop_invoke_epilogue(async_loop_t* loop);
+
+static_assert(sizeof(list_node_t) <= sizeof(async_state_t), "async_state_t too small");
+
+#define TO_NODE(type, ptr) ((list_node_t*)&ptr->state)
+#define FROM_NODE(type, ptr) ((type*)((char*)(ptr)-offsetof(type, state)))
+
+static inline list_node_t* wait_to_node(async_wait_t* wait) { return TO_NODE(async_wait_t, wait); }
+
+static inline async_wait_t* node_to_wait(list_node_t* node) {
+ return FROM_NODE(async_wait_t, node);
+}
+
+static inline list_node_t* irq_to_node(async_irq_t* irq) { return TO_NODE(async_irq_t, irq); }
+
+static inline list_node_t* task_to_node(async_task_t* task) { return TO_NODE(async_task_t, task); }
+
+static inline async_task_t* node_to_task(list_node_t* node) {
+ return FROM_NODE(async_task_t, node);
+}
+
+static inline async_irq_t* node_to_irq(list_node_t* node) { return FROM_NODE(async_irq_t, node); }
+
+static inline list_node_t* paged_vmo_to_node(async_paged_vmo_t* paged_vmo) {
+ return TO_NODE(async_paged_vmo_t, paged_vmo);
+}
+
+static inline async_paged_vmo_t* node_to_paged_vmo(list_node_t* node) {
+ return FROM_NODE(async_paged_vmo_t, node);
+}
+
+zx_status_t async_loop_create(const async_loop_config_t* config, async_loop_t** out_loop) {
+ ZX_DEBUG_ASSERT(out_loop);
+ ZX_DEBUG_ASSERT(config != NULL);
+ // If a setter was given, a getter should have been, too.
+ ZX_ASSERT((config->default_accessors.setter != NULL) ==
+ (config->default_accessors.getter != NULL));
+
+ async_loop_t* loop = calloc(1u, sizeof(async_loop_t));
+ if (!loop)
+ return ZX_ERR_NO_MEMORY;
+ atomic_init(&loop->state, ASYNC_LOOP_RUNNABLE);
+ atomic_init(&loop->active_threads, 0u);
+
+ loop->dispatcher.ops = (const async_ops_t*)&async_loop_ops;
+ loop->config = *config;
+ mtx_init(&loop->lock, mtx_plain);
+ list_initialize(&loop->wait_list);
+ list_initialize(&loop->irq_list);
+ list_initialize(&loop->task_list);
+ list_initialize(&loop->due_list);
+ list_initialize(&loop->thread_list);
+ list_initialize(&loop->paged_vmo_list);
+
+ zx_status_t status =
+ zx_port_create(config->irq_support ? ZX_PORT_BIND_TO_INTERRUPT : 0, &loop->port);
+ if (status == ZX_OK)
+ status = zx_timer_create(ZX_TIMER_SLACK_LATE, ZX_CLOCK_MONOTONIC, &loop->timer);
+ if (status == ZX_OK) {
+ *out_loop = loop;
+ if (loop->config.make_default_for_current_thread) {
+ ZX_DEBUG_ASSERT(loop->config.default_accessors.getter() == NULL);
+ loop->config.default_accessors.setter(&loop->dispatcher);
+ }
+ } else {
+ // Adjust this flag so we don't trip an assert trying to clear a default dispatcher we never
+ // installed.
+ loop->config.make_default_for_current_thread = false;
+ async_loop_destroy(loop);
+ }
+ return status;
+}
+
+void async_loop_destroy(async_loop_t* loop) {
+ ZX_DEBUG_ASSERT(loop);
+
+ async_loop_shutdown(loop);
+
+ zx_handle_close(loop->port);
+ zx_handle_close(loop->timer);
+ mtx_destroy(&loop->lock);
+ free(loop);
+}
+
+void async_loop_shutdown(async_loop_t* loop) {
+ ZX_DEBUG_ASSERT(loop);
+
+ async_loop_state_t prior_state =
+ atomic_exchange_explicit(&loop->state, ASYNC_LOOP_SHUTDOWN, memory_order_acq_rel);
+ if (prior_state == ASYNC_LOOP_SHUTDOWN)
+ return;
+
+ async_loop_wake_threads(loop);
+ async_loop_join_threads(loop);
+
+ list_node_t* node;
+ while ((node = list_remove_head(&loop->wait_list))) {
+ async_wait_t* wait = node_to_wait(node);
+ // Since the wait is being canceled, it would make sense to call zx_port_cancel()
+ // here before invoking the callback to ensure that the waited-upon handle is
+ // no longer attached to the port. However, the port is about to be destroyed
+ // so we can optimize that step away.
+ async_loop_dispatch_wait(loop, wait, ZX_ERR_CANCELED, NULL);
+ }
+ while ((node = list_remove_head(&loop->due_list))) {
+ async_task_t* task = node_to_task(node);
+ async_loop_dispatch_task(loop, task, ZX_ERR_CANCELED);
+ }
+ while ((node = list_remove_head(&loop->task_list))) {
+ async_task_t* task = node_to_task(node);
+ async_loop_dispatch_task(loop, task, ZX_ERR_CANCELED);
+ }
+ while ((node = list_remove_head(&loop->irq_list))) {
+ async_irq_t* task = node_to_irq(node);
+ async_loop_dispatch_irq(loop, task, ZX_ERR_CANCELED, NULL);
+ }
+ while ((node = list_remove_head(&loop->paged_vmo_list))) {
+ async_paged_vmo_t* paged_vmo = node_to_paged_vmo(node);
+ // The loop owns the association between the pager and the VMO so when the
+ // loop is shutting down, it is responsible for breaking that association
+ // then notifying the callback that the wait has been canceled.
+ async_loop_cancel_paged_vmo(paged_vmo);
+ async_loop_dispatch_paged_vmo(loop, paged_vmo, ZX_ERR_CANCELED, NULL);
+ }
+
+ if (loop->config.make_default_for_current_thread) {
+ ZX_DEBUG_ASSERT(loop->config.default_accessors.getter() == &loop->dispatcher);
+ loop->config.default_accessors.setter(NULL);
+ }
+}
+
+zx_status_t async_loop_run(async_loop_t* loop, zx_time_t deadline, bool once) {
+ ZX_DEBUG_ASSERT(loop);
+
+ zx_status_t status;
+ atomic_fetch_add_explicit(&loop->active_threads, 1u, memory_order_acq_rel);
+ do {
+ status = async_loop_run_once(loop, deadline);
+ } while (status == ZX_OK && !once);
+ atomic_fetch_sub_explicit(&loop->active_threads, 1u, memory_order_acq_rel);
+ return status;
+}
+
+zx_status_t async_loop_run_until_idle(async_loop_t* loop) {
+ zx_status_t status = async_loop_run(loop, 0, false);
+ if (status == ZX_ERR_TIMED_OUT) {
+ status = ZX_OK;
+ }
+ return status;
+}
+
+static zx_status_t async_loop_run_once(async_loop_t* loop, zx_time_t deadline) {
+ async_loop_state_t state = atomic_load_explicit(&loop->state, memory_order_acquire);
+ if (state == ASYNC_LOOP_SHUTDOWN)
+ return ZX_ERR_BAD_STATE;
+ if (state != ASYNC_LOOP_RUNNABLE)
+ return ZX_ERR_CANCELED;
+
+ zx_port_packet_t packet;
+ zx_status_t status = zx_port_wait(loop->port, deadline, &packet);
+ if (status != ZX_OK)
+ return status;
+
+ if (packet.key == KEY_CONTROL) {
+ // Handle wake-up packets.
+ if (packet.type == ZX_PKT_TYPE_USER)
+ return ZX_OK;
+
+ // Handle task timer expirations.
+ if (packet.type == ZX_PKT_TYPE_SIGNAL_ONE && packet.signal.observed & ZX_TIMER_SIGNALED) {
+ return async_loop_dispatch_tasks(loop);
+ }
+ } else {
+ // Handle wait completion packets.
+ if (packet.type == ZX_PKT_TYPE_SIGNAL_ONE) {
+ async_wait_t* wait = (void*)(uintptr_t)packet.key;
+ mtx_lock(&loop->lock);
+ list_delete(wait_to_node(wait));
+ mtx_unlock(&loop->lock);
+ return async_loop_dispatch_wait(loop, wait, packet.status, &packet.signal);
+ }
+
+ // Handle queued user packets.
+ if (packet.type == ZX_PKT_TYPE_USER) {
+ async_receiver_t* receiver = (void*)(uintptr_t)packet.key;
+ return async_loop_dispatch_packet(loop, receiver, packet.status, &packet.user);
+ }
+
+ // Handle guest bell trap packets.
+ if (packet.type == ZX_PKT_TYPE_GUEST_BELL) {
+ async_guest_bell_trap_t* trap = (void*)(uintptr_t)packet.key;
+ return async_loop_dispatch_guest_bell_trap(loop, trap, packet.status, &packet.guest_bell);
+ }
+
+ // Handle interrupt packets.
+ if (packet.type == ZX_PKT_TYPE_INTERRUPT) {
+ async_irq_t* irq = (void*)(uintptr_t)packet.key;
+ return async_loop_dispatch_irq(loop, irq, packet.status, &packet.interrupt);
+ }
+ // Handle pager packets.
+ if (packet.type == ZX_PKT_TYPE_PAGE_REQUEST) {
+ async_paged_vmo_t* paged_vmo = (void*)(uintptr_t)packet.key;
+ return async_loop_dispatch_paged_vmo(loop, paged_vmo, packet.status, &packet.page_request);
+ }
+ }
+
+ ZX_DEBUG_ASSERT(false);
+ return ZX_ERR_INTERNAL;
+}
+
+async_dispatcher_t* async_loop_get_dispatcher(async_loop_t* loop) {
+ // Note: The loop's implementation inherits from async_t so we can upcast to it.
+ return (async_dispatcher_t*)loop;
+}
+
+async_loop_t* async_loop_from_dispatcher(async_dispatcher_t* async) { return (async_loop_t*)async; }
+
+static zx_status_t async_loop_dispatch_guest_bell_trap(async_loop_t* loop,
+ async_guest_bell_trap_t* trap,
+ zx_status_t status,
+ const zx_packet_guest_bell_t* bell) {
+ async_loop_invoke_prologue(loop);
+ trap->handler((async_dispatcher_t*)loop, trap, status, bell);
+ async_loop_invoke_epilogue(loop);
+ return ZX_OK;
+}
+
+static zx_status_t async_loop_dispatch_wait(async_loop_t* loop, async_wait_t* wait,
+ zx_status_t status, const zx_packet_signal_t* signal) {
+ async_loop_invoke_prologue(loop);
+ wait->handler((async_dispatcher_t*)loop, wait, status, signal);
+ async_loop_invoke_epilogue(loop);
+ return ZX_OK;
+}
+
+static zx_status_t async_loop_dispatch_irq(async_loop_t* loop, async_irq_t* irq, zx_status_t status,
+ const zx_packet_interrupt_t* interrupt) {
+ async_loop_invoke_prologue(loop);
+ irq->handler((async_dispatcher_t*)loop, irq, status, interrupt);
+ async_loop_invoke_epilogue(loop);
+ return ZX_OK;
+}
+
+static zx_status_t async_loop_dispatch_tasks(async_loop_t* loop) {
+ // Dequeue and dispatch one task at a time in case an earlier task wants
+ // to cancel a later task which has also come due. At most one thread
+ // can dispatch tasks at any given moment (to preserve serial ordering).
+ // Timer restarts are suppressed until we run out of tasks to dispatch.
+ mtx_lock(&loop->lock);
+ if (!loop->dispatching_tasks) {
+ loop->dispatching_tasks = true;
+
+ // Extract all of the tasks that are due into |due_list| for dispatch
+ // unless we already have some waiting from a previous iteration which
+ // we would like to process in order.
+ list_node_t* node;
+ if (list_is_empty(&loop->due_list)) {
+ zx_time_t due_time = async_loop_now((async_dispatcher_t*)loop);
+ list_node_t* tail = NULL;
+ list_for_every(&loop->task_list, node) {
+ if (node_to_task(node)->deadline > due_time)
+ break;
+ tail = node;
+ }
+ if (tail) {
+ list_node_t* head = loop->task_list.next;
+ loop->task_list.next = tail->next;
+ tail->next->prev = &loop->task_list;
+ loop->due_list.next = head;
+ head->prev = &loop->due_list;
+ loop->due_list.prev = tail;
+ tail->next = &loop->due_list;
+ }
+ }
+
+ // Dispatch all due tasks. Note that they might be canceled concurrently
+ // so we need to grab the lock during each iteration to fetch the next
+ // item from the list.
+ while ((node = list_remove_head(&loop->due_list))) {
+ mtx_unlock(&loop->lock);
+
+ // Invoke the handler. Note that it might destroy itself.
+ async_task_t* task = node_to_task(node);
+ async_loop_dispatch_task(loop, task, ZX_OK);
+
+ mtx_lock(&loop->lock);
+ async_loop_state_t state = atomic_load_explicit(&loop->state, memory_order_acquire);
+ if (state != ASYNC_LOOP_RUNNABLE)
+ break;
+ }
+
+ loop->dispatching_tasks = false;
+ loop->timer_armed = false;
+ async_loop_restart_timer_locked(loop);
+ }
+ mtx_unlock(&loop->lock);
+ return ZX_OK;
+}
+
+static void async_loop_dispatch_task(async_loop_t* loop, async_task_t* task, zx_status_t status) {
+ // Invoke the handler. Note that it might destroy itself.
+ async_loop_invoke_prologue(loop);
+ task->handler((async_dispatcher_t*)loop, task, status);
+ async_loop_invoke_epilogue(loop);
+}
+
+static zx_status_t async_loop_dispatch_packet(async_loop_t* loop, async_receiver_t* receiver,
+ zx_status_t status, const zx_packet_user_t* data) {
+ // Invoke the handler. Note that it might destroy itself.
+ async_loop_invoke_prologue(loop);
+ receiver->handler((async_dispatcher_t*)loop, receiver, status, data);
+ async_loop_invoke_epilogue(loop);
+ return ZX_OK;
+}
+
+static zx_status_t async_loop_dispatch_paged_vmo(async_loop_t* loop, async_paged_vmo_t* paged_vmo,
+ zx_status_t status,
+ const zx_packet_page_request_t* page_request) {
+ // Invoke the handler. Note that it might destroy itself.
+ async_loop_invoke_prologue(loop);
+ paged_vmo->handler((async_dispatcher_t*)loop, paged_vmo, status, page_request);
+ async_loop_invoke_epilogue(loop);
+ return ZX_OK;
+}
+
+void async_loop_quit(async_loop_t* loop) {
+ ZX_DEBUG_ASSERT(loop);
+
+ async_loop_state_t expected_state = ASYNC_LOOP_RUNNABLE;
+ if (!atomic_compare_exchange_strong_explicit(&loop->state, &expected_state, ASYNC_LOOP_QUIT,
+ memory_order_acq_rel, memory_order_acquire))
+ return;
+
+ async_loop_wake_threads(loop);
+}
+
+static void async_loop_wake_threads(async_loop_t* loop) {
+ // Queue enough packets to awaken all active threads.
+ // This is safe because any new threads which join the pool first increment the
+ // active thread count then check the loop state, so the count we observe here
+ // cannot be less than the number of threads which might be blocked in |port_wait|.
+ // Issuing too many packets is also harmless.
+ uint32_t n = atomic_load_explicit(&loop->active_threads, memory_order_acquire);
+ for (uint32_t i = 0u; i < n; i++) {
+ zx_port_packet_t packet = {.key = KEY_CONTROL, .type = ZX_PKT_TYPE_USER, .status = ZX_OK};
+ zx_status_t status = zx_port_queue(loop->port, &packet);
+ ZX_ASSERT_MSG(status == ZX_OK, "zx_port_queue: status=%d", status);
+ }
+}
+
+zx_status_t async_loop_reset_quit(async_loop_t* loop) {
+ ZX_DEBUG_ASSERT(loop);
+
+ // Ensure that there are no active threads before resetting the quit state.
+ // This check is inherently racy but not dangerously so. It's mainly a
+ // sanity check for client code so we can make a stronger statement about
+ // how |async_loop_reset_quit()| is supposed to be used.
+ uint32_t n = atomic_load_explicit(&loop->active_threads, memory_order_acquire);
+ if (n != 0)
+ return ZX_ERR_BAD_STATE;
+
+ async_loop_state_t expected_state = ASYNC_LOOP_QUIT;
+ if (atomic_compare_exchange_strong_explicit(&loop->state, &expected_state, ASYNC_LOOP_RUNNABLE,
+ memory_order_acq_rel, memory_order_acquire)) {
+ return ZX_OK;
+ }
+
+ async_loop_state_t state = atomic_load_explicit(&loop->state, memory_order_acquire);
+ if (state == ASYNC_LOOP_RUNNABLE)
+ return ZX_OK;
+ return ZX_ERR_BAD_STATE;
+}
+
+async_loop_state_t async_loop_get_state(async_loop_t* loop) {
+ ZX_DEBUG_ASSERT(loop);
+
+ return atomic_load_explicit(&loop->state, memory_order_acquire);
+}
+
+zx_time_t async_loop_now(async_dispatcher_t* dispatcher) { return zx_clock_get_monotonic(); }
+
+static zx_status_t async_loop_begin_wait(async_dispatcher_t* async, async_wait_t* wait) {
+ async_loop_t* loop = (async_loop_t*)async;
+ ZX_DEBUG_ASSERT(loop);
+ ZX_DEBUG_ASSERT(wait);
+
+ if (atomic_load_explicit(&loop->state, memory_order_acquire) == ASYNC_LOOP_SHUTDOWN)
+ return ZX_ERR_BAD_STATE;
+
+ mtx_lock(&loop->lock);
+
+ zx_status_t status =
+ zx_object_wait_async(wait->object, loop->port, (uintptr_t)wait, wait->trigger, wait->options);
+ if (status == ZX_OK) {
+ list_add_head(&loop->wait_list, wait_to_node(wait));
+ } else {
+ ZX_ASSERT_MSG(status == ZX_ERR_ACCESS_DENIED, "zx_object_wait_async: status=%d", status);
+ }
+
+ mtx_unlock(&loop->lock);
+ return status;
+}
+
+static zx_status_t async_loop_cancel_wait(async_dispatcher_t* async, async_wait_t* wait) {
+ async_loop_t* loop = (async_loop_t*)async;
+ ZX_DEBUG_ASSERT(loop);
+ ZX_DEBUG_ASSERT(wait);
+
+ // Note: We need to process cancellations even while the loop is being
+ // destroyed in case the client is counting on the handler not being
+ // invoked again past this point.
+
+ mtx_lock(&loop->lock);
+
+ // First, confirm that the wait is actually pending.
+ list_node_t* node = wait_to_node(wait);
+ if (!list_in_list(node)) {
+ mtx_unlock(&loop->lock);
+ return ZX_ERR_NOT_FOUND;
+ }
+
+ // Next, cancel the wait. This may be racing with another thread that
+ // has read the wait's packet but not yet dispatched it. So if we fail
+ // to cancel then we assume we lost the race.
+ zx_status_t status = zx_port_cancel(loop->port, wait->object, (uintptr_t)wait);
+ if (status == ZX_OK) {
+ list_delete(node);
+ } else {
+ ZX_ASSERT_MSG(status == ZX_ERR_NOT_FOUND, "zx_port_cancel: status=%d", status);
+ }
+
+ mtx_unlock(&loop->lock);
+ return status;
+}
+
+static zx_status_t async_loop_post_task(async_dispatcher_t* async, async_task_t* task) {
+ async_loop_t* loop = (async_loop_t*)async;
+ ZX_DEBUG_ASSERT(loop);
+ ZX_DEBUG_ASSERT(task);
+
+ if (atomic_load_explicit(&loop->state, memory_order_acquire) == ASYNC_LOOP_SHUTDOWN)
+ return ZX_ERR_BAD_STATE;
+
+ mtx_lock(&loop->lock);
+
+ async_loop_insert_task_locked(loop, task);
+ if (!loop->dispatching_tasks && task_to_node(task)->prev == &loop->task_list) {
+ // Task inserted at head. Earliest deadline changed.
+ async_loop_restart_timer_locked(loop);
+ }
+
+ mtx_unlock(&loop->lock);
+ return ZX_OK;
+}
+
+static zx_status_t async_loop_cancel_task(async_dispatcher_t* async, async_task_t* task) {
+ async_loop_t* loop = (async_loop_t*)async;
+ ZX_DEBUG_ASSERT(loop);
+ ZX_DEBUG_ASSERT(task);
+
+ // Note: We need to process cancellations even while the loop is being
+ // destroyed in case the client is counting on the handler not being
+ // invoked again past this point. Also, the task we're removing here
+ // might be present in the dispatcher's |due_list| if it is pending
+ // dispatch instead of in the loop's |task_list| as usual. The same
+ // logic works in both cases.
+
+ mtx_lock(&loop->lock);
+ list_node_t* node = task_to_node(task);
+ if (!list_in_list(node)) {
+ mtx_unlock(&loop->lock);
+ return ZX_ERR_NOT_FOUND;
+ }
+
+ // Determine whether the head task was canceled and following task has
+ // a later deadline. If so, we will bump the timer along to that deadline.
+ bool must_restart =
+ !loop->dispatching_tasks && node->prev == &loop->task_list &&
+ (node->next == &loop->task_list || node_to_task(node->next)->deadline > task->deadline);
+ list_delete(node);
+ if (must_restart)
+ async_loop_restart_timer_locked(loop);
+
+ mtx_unlock(&loop->lock);
+ return ZX_OK;
+}
+
+static zx_status_t async_loop_queue_packet(async_dispatcher_t* async, async_receiver_t* receiver,
+ const zx_packet_user_t* data) {
+ async_loop_t* loop = (async_loop_t*)async;
+ ZX_DEBUG_ASSERT(loop);
+ ZX_DEBUG_ASSERT(receiver);
+
+ if (atomic_load_explicit(&loop->state, memory_order_acquire) == ASYNC_LOOP_SHUTDOWN)
+ return ZX_ERR_BAD_STATE;
+
+ zx_port_packet_t packet = {.key = (uintptr_t)receiver, .type = ZX_PKT_TYPE_USER, .status = ZX_OK};
+ if (data)
+ packet.user = *data;
+ return zx_port_queue(loop->port, &packet);
+}
+
+static zx_status_t async_loop_set_guest_bell_trap(async_dispatcher_t* async,
+ async_guest_bell_trap_t* trap, zx_handle_t guest,
+ zx_vaddr_t addr, size_t length) {
+ async_loop_t* loop = (async_loop_t*)async;
+ ZX_DEBUG_ASSERT(loop);
+ ZX_DEBUG_ASSERT(trap);
+
+ if (atomic_load_explicit(&loop->state, memory_order_acquire) == ASYNC_LOOP_SHUTDOWN)
+ return ZX_ERR_BAD_STATE;
+
+ zx_status_t status =
+ zx_guest_set_trap(guest, ZX_GUEST_TRAP_BELL, addr, length, loop->port, (uintptr_t)trap);
+ if (status != ZX_OK) {
+ ZX_ASSERT_MSG(status == ZX_ERR_ACCESS_DENIED || status == ZX_ERR_ALREADY_EXISTS ||
+ status == ZX_ERR_INVALID_ARGS || status == ZX_ERR_OUT_OF_RANGE ||
+ status == ZX_ERR_WRONG_TYPE,
+ "zx_guest_set_trap: status=%d", status);
+ }
+ return status;
+}
+
+static zx_status_t async_loop_create_paged_vmo(async_dispatcher_t* async,
+ async_paged_vmo_t* paged_vmo, uint32_t options,
+ zx_handle_t pager, uint64_t vmo_size,
+ zx_handle_t* vmo_out) {
+ async_loop_t* loop = (async_loop_t*)async;
+ if (atomic_load_explicit(&loop->state, memory_order_acquire) == ASYNC_LOOP_SHUTDOWN) {
+ return ZX_ERR_BAD_STATE;
+ }
+
+ zx_status_t status =
+ zx_pager_create_vmo(pager, options, loop->port, (uintptr_t)paged_vmo, vmo_size, vmo_out);
+ if (status != ZX_OK) {
+ return status;
+ }
+
+ list_add_head(&loop->paged_vmo_list, paged_vmo_to_node(paged_vmo));
+ return ZX_OK;
+}
+
+static zx_status_t async_loop_detach_paged_vmo(async_dispatcher_t* async,
+ async_paged_vmo_t* paged_vmo) {
+ list_node_t* node = paged_vmo_to_node(paged_vmo);
+ if (!list_in_list(node)) {
+ return ZX_ERR_NOT_FOUND;
+ }
+
+ zx_status_t status = zx_pager_detach_vmo(paged_vmo->pager, paged_vmo->vmo);
+ if (status != ZX_OK) {
+ return status;
+ }
+
+ // NOTE: the client owns the VMO and is responsible for freeing it.
+ list_delete(node);
+ return status;
+}
+
+static zx_status_t async_loop_cancel_paged_vmo(async_paged_vmo_t* paged_vmo) {
+ // This function gets called from the async loop shutdown path. The handler will not receive any
+ // detach callbacks as the loop is shutting down. So explicitly detach the VMO from the pager.
+ return zx_pager_detach_vmo(paged_vmo->pager, paged_vmo->vmo);
+}
+
+static void async_loop_insert_task_locked(async_loop_t* loop, async_task_t* task) {
+ // TODO(ZX-976): We assume that tasks are inserted in quasi-monotonic order and
+ // that insertion into the task queue will typically take no more than a few steps.
+ // If this assumption proves false and the cost of insertion becomes a problem, we
+ // should consider using a more efficient representation for maintaining order.
+ list_node_t* node;
+ for (node = loop->task_list.prev; node != &loop->task_list; node = node->prev) {
+ if (task->deadline >= node_to_task(node)->deadline)
+ break;
+ }
+ list_add_after(node, task_to_node(task));
+}
+
+static zx_time_t async_loop_next_deadline_locked(async_loop_t* loop) {
+ if (list_is_empty(&loop->due_list)) {
+ list_node_t* head = list_peek_head(&loop->task_list);
+ if (!head)
+ return ZX_TIME_INFINITE;
+ async_task_t* task = node_to_task(head);
+ if (task->deadline == ZX_TIME_INFINITE)
+ return ZX_TIME_INFINITE;
+ else
+ return task->deadline;
+ }
+ // Fire now.
+ return 0ULL;
+}
+
+static void async_loop_restart_timer_locked(async_loop_t* loop) {
+ zx_status_t status;
+ zx_time_t deadline = async_loop_next_deadline_locked(loop);
+
+ if (deadline == ZX_TIME_INFINITE) {
+ // Nothing is left on the queue to fire.
+ if (loop->timer_armed) {
+ status = zx_timer_cancel(loop->timer);
+ ZX_ASSERT_MSG(status == ZX_OK, "zx_timer_cancel: status=%d", status);
+ // ZX_ERR_NOT_FOUND can happen here when a pending timer fires and
+ // the packet is picked up by port_wait in another thread but has
+ // not reached dispatch.
+ status = zx_port_cancel(loop->port, loop->timer, KEY_CONTROL);
+ ZX_ASSERT_MSG(status == ZX_OK || status == ZX_ERR_NOT_FOUND, "zx_port_cancel: status=%d",
+ status);
+ loop->timer_armed = false;
+ }
+
+ return;
+ }
+
+ status = zx_timer_set(loop->timer, deadline, 0);
+ ZX_ASSERT_MSG(status == ZX_OK, "zx_timer_set: status=%d", status);
+
+ if (!loop->timer_armed) {
+ loop->timer_armed = true;
+ status = zx_object_wait_async(loop->timer, loop->port, KEY_CONTROL, ZX_TIMER_SIGNALED,
+ ZX_WAIT_ASYNC_ONCE);
+ ZX_ASSERT_MSG(status == ZX_OK, "zx_object_wait_async: status=%d", status);
+ }
+}
+
+static void async_loop_invoke_prologue(async_loop_t* loop) {
+ if (loop->config.prologue)
+ loop->config.prologue(loop, loop->config.data);
+}
+
+static void async_loop_invoke_epilogue(async_loop_t* loop) {
+ if (loop->config.epilogue)
+ loop->config.epilogue(loop, loop->config.data);
+}
+
+static zx_status_t async_loop_bind_irq(async_dispatcher_t* dispatcher, async_irq_t* irq) {
+ async_loop_t* loop = (async_loop_t*)dispatcher;
+ ZX_DEBUG_ASSERT(loop);
+ ZX_DEBUG_ASSERT(irq);
+
+ if (atomic_load_explicit(&loop->state, memory_order_acquire) == ASYNC_LOOP_SHUTDOWN)
+ return ZX_ERR_BAD_STATE;
+
+ mtx_lock(&loop->lock);
+
+ zx_status_t status =
+ zx_interrupt_bind(irq->object, loop->port, (uintptr_t)irq, ZX_INTERRUPT_BIND);
+ if (status == ZX_OK) {
+ list_add_head(&loop->irq_list, irq_to_node(irq));
+ } else {
+ ZX_ASSERT_MSG(status == ZX_ERR_ACCESS_DENIED, "zx_object_wait_async: status=%d", status);
+ }
+
+ mtx_unlock(&loop->lock);
+ return status;
+}
+
+static zx_status_t async_loop_unbind_irq(async_dispatcher_t* dispatcher, async_irq_t* irq) {
+ async_loop_t* loop = (async_loop_t*)dispatcher;
+ ZX_DEBUG_ASSERT(loop);
+ ZX_DEBUG_ASSERT(irq);
+
+ if (atomic_load_explicit(&loop->state, memory_order_acquire) == ASYNC_LOOP_SHUTDOWN)
+ return ZX_ERR_BAD_STATE;
+
+ mtx_lock(&loop->lock);
+
+ zx_status_t status =
+ zx_interrupt_bind(irq->object, loop->port, (uintptr_t)irq, ZX_INTERRUPT_UNBIND);
+ if (status == ZX_OK) {
+ list_delete(irq_to_node(irq));
+ } else {
+ ZX_ASSERT_MSG(status == ZX_ERR_ACCESS_DENIED, "zx_object_wait_async: status=%d", status);
+ }
+ mtx_unlock(&loop->lock);
+ return status;
+}
+
+static int async_loop_run_thread(void* data) {
+ async_loop_t* loop = (async_loop_t*)data;
+ if (loop->config.default_accessors.setter) {
+ loop->config.default_accessors.setter(&loop->dispatcher);
+ }
+ async_loop_run(loop, ZX_TIME_INFINITE, false);
+ return 0;
+}
+
+zx_status_t async_loop_start_thread(async_loop_t* loop, const char* name, thrd_t* out_thread) {
+ ZX_DEBUG_ASSERT(loop);
+
+ // This check is inherently racy. The client should not be racing shutdown
+ // with attempts to start new threads. This is mainly a sanity check.
+ async_loop_state_t state = atomic_load_explicit(&loop->state, memory_order_acquire);
+ if (state == ASYNC_LOOP_SHUTDOWN)
+ return ZX_ERR_BAD_STATE;
+
+ thread_record_t* rec = calloc(1u, sizeof(thread_record_t));
+ if (!rec)
+ return ZX_ERR_NO_MEMORY;
+
+ if (thrd_create_with_name(&rec->thread, async_loop_run_thread, loop, name) != thrd_success) {
+ free(rec);
+ return ZX_ERR_NO_MEMORY;
+ }
+
+ mtx_lock(&loop->lock);
+ list_add_tail(&loop->thread_list, &rec->node);
+ mtx_unlock(&loop->lock);
+
+ if (out_thread)
+ *out_thread = rec->thread;
+ return ZX_OK;
+}
+
+void async_loop_join_threads(async_loop_t* loop) {
+ ZX_DEBUG_ASSERT(loop);
+
+ mtx_lock(&loop->lock);
+ for (;;) {
+ thread_record_t* rec = (thread_record_t*)list_remove_head(&loop->thread_list);
+ if (!rec)
+ break;
+
+ mtx_unlock(&loop->lock);
+ thrd_t thread = rec->thread;
+ free(rec);
+ int result = thrd_join(thread, NULL);
+ ZX_DEBUG_ASSERT(result == thrd_success);
+ mtx_lock(&loop->lock);
+ }
+ mtx_unlock(&loop->lock);
+}
diff --git a/third_party/fuchsia-sdk/pkg/async-loop/meta.json b/third_party/fuchsia-sdk/pkg/async-loop/meta.json
new file mode 100644
index 0000000..95ad5b0
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-loop/meta.json
@@ -0,0 +1,17 @@
+{
+ "banjo_deps": [],
+ "deps": [
+ "async"
+ ],
+ "fidl_deps": [],
+ "headers": [
+ "pkg/async-loop/include/lib/async-loop/loop.h"
+ ],
+ "include_dir": "pkg/async-loop/include",
+ "name": "async-loop",
+ "root": "pkg/async-loop",
+ "sources": [
+ "pkg/async-loop/loop.c"
+ ],
+ "type": "cc_source_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/async-testing/BUILD.gn b/third_party/fuchsia-sdk/pkg/async-testing/BUILD.gn
new file mode 100644
index 0000000..b72575c
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-testing/BUILD.gn
@@ -0,0 +1,35 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("async-testing") {
+ sources = [
+ "dispatcher_stub.cc",
+ "test_loop.cc",
+ "test_loop_dispatcher.cc",
+ "include/lib/async-testing/dispatcher_stub.h",
+ "include/lib/async-testing/test_loop.h",
+ "include/lib/async-testing/test_loop_dispatcher.h",
+ "include/lib/async-testing/test_subloop.h",
+ ]
+ include_dirs = [ "include" ]
+ public_deps = [
+ "../async",
+ "../async-cpp",
+ "../async-default",
+ "../fdio",
+ "../zx",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":async-testing",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/async-testing/dispatcher_stub.cc b/third_party/fuchsia-sdk/pkg/async-testing/dispatcher_stub.cc
new file mode 100644
index 0000000..be26dac
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-testing/dispatcher_stub.cc
@@ -0,0 +1,123 @@
+// Copyright 2017 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.
+
+#include <lib/async-testing/dispatcher_stub.h>
+
+namespace async {
+
+namespace {
+
+zx_time_t stub_now(async_dispatcher_t* dispatcher) {
+ return (static_cast<DispatcherStub*>(dispatcher)->Now()).get();
+}
+
+zx_status_t stub_begin_wait(async_dispatcher_t* dispatcher, async_wait_t* wait) {
+ return static_cast<DispatcherStub*>(dispatcher)->BeginWait(wait);
+}
+
+zx_status_t stub_cancel_wait(async_dispatcher_t* dispatcher, async_wait_t* wait) {
+ return static_cast<DispatcherStub*>(dispatcher)->CancelWait(wait);
+}
+
+zx_status_t stub_post_task(async_dispatcher_t* dispatcher, async_task_t* task) {
+ return static_cast<DispatcherStub*>(dispatcher)->PostTask(task);
+}
+
+zx_status_t stub_cancel_task(async_dispatcher_t* dispatcher, async_task_t* task) {
+ return static_cast<DispatcherStub*>(dispatcher)->CancelTask(task);
+}
+
+zx_status_t stub_queue_packet(async_dispatcher_t* dispatcher, async_receiver_t* receiver,
+ const zx_packet_user_t* data) {
+ return static_cast<DispatcherStub*>(dispatcher)->QueuePacket(receiver, data);
+}
+
+zx_status_t stub_set_guest_bell_trap(async_dispatcher_t* dispatcher, async_guest_bell_trap_t* trap,
+ zx_handle_t guest, zx_vaddr_t addr, size_t length) {
+ return static_cast<DispatcherStub*>(dispatcher)
+ ->SetGuestBellTrap(trap, *zx::unowned_guest(guest), addr, length);
+}
+
+zx_status_t stub_bind_irq(async_dispatcher_t* dispatcher, async_irq_t* irq) {
+ return static_cast<DispatcherStub*>(dispatcher)->BindIrq(irq);
+}
+
+zx_status_t stub_unbind_irq(async_dispatcher_t* dispatcher, async_irq_t* irq) {
+ return static_cast<DispatcherStub*>(dispatcher)->UnbindIrq(irq);
+}
+
+zx_status_t stub_create_paged_vmo(async_dispatcher_t* dispatcher, async_paged_vmo_t* paged_vmo,
+ uint32_t options, zx_handle_t pager, uint64_t vmo_size,
+ zx_handle_t* vmo_out) {
+ return static_cast<DispatcherStub*>(dispatcher)
+ ->CreatePagedVmo(paged_vmo, pager, options, vmo_size, vmo_out);
+}
+
+zx_status_t stub_detach_paged_vmo(async_dispatcher_t* dispatcher, async_paged_vmo_t* paged_vmo) {
+ return static_cast<DispatcherStub*>(dispatcher)->DetachPagedVmo(paged_vmo);
+}
+
+const async_ops_t g_stub_ops = {
+ .version = ASYNC_OPS_V2,
+ .reserved = 0,
+ .v1 =
+ {
+ .now = stub_now,
+ .begin_wait = stub_begin_wait,
+ .cancel_wait = stub_cancel_wait,
+ .post_task = stub_post_task,
+ .cancel_task = stub_cancel_task,
+ .queue_packet = stub_queue_packet,
+ .set_guest_bell_trap = stub_set_guest_bell_trap,
+ },
+ .v2 =
+ {
+
+ .bind_irq = stub_bind_irq,
+ .unbind_irq = stub_unbind_irq,
+ .create_paged_vmo = stub_create_paged_vmo,
+ .detach_paged_vmo = stub_detach_paged_vmo,
+ },
+};
+
+} // namespace
+
+DispatcherStub::DispatcherStub() : async_dispatcher_t{&g_stub_ops} {}
+
+DispatcherStub::~DispatcherStub() {}
+
+zx::time DispatcherStub::Now() { return zx::time(0); }
+
+zx_status_t DispatcherStub::BeginWait(async_wait_t* wait) { return ZX_ERR_NOT_SUPPORTED; }
+
+zx_status_t DispatcherStub::CancelWait(async_wait_t* wait) { return ZX_ERR_NOT_SUPPORTED; }
+
+zx_status_t DispatcherStub::PostTask(async_task_t* task) { return ZX_ERR_NOT_SUPPORTED; }
+
+zx_status_t DispatcherStub::CancelTask(async_task_t* task) { return ZX_ERR_NOT_SUPPORTED; }
+
+zx_status_t DispatcherStub::QueuePacket(async_receiver_t* receiver, const zx_packet_user_t* data) {
+ return ZX_ERR_NOT_SUPPORTED;
+}
+
+zx_status_t DispatcherStub::SetGuestBellTrap(async_guest_bell_trap_t* trap, const zx::guest& guest,
+ zx_vaddr_t addr, size_t length) {
+ return ZX_ERR_NOT_SUPPORTED;
+}
+
+zx_status_t DispatcherStub::BindIrq(async_irq_t* irq) { return ZX_ERR_NOT_SUPPORTED; }
+
+zx_status_t DispatcherStub::UnbindIrq(async_irq_t* irq) { return ZX_ERR_NOT_SUPPORTED; }
+
+zx_status_t DispatcherStub::CreatePagedVmo(async_paged_vmo_t* paged_vmo, zx_handle_t pager,
+ uint32_t options, uint64_t vmo_size,
+ zx_handle_t* vmo_out) {
+ return ZX_ERR_NOT_SUPPORTED;
+}
+
+zx_status_t DispatcherStub::DetachPagedVmo(async_paged_vmo_t* paged_vmo) {
+ return ZX_ERR_NOT_SUPPORTED;
+}
+
+} // namespace async
diff --git a/third_party/fuchsia-sdk/pkg/async-testing/include/lib/async-testing/dispatcher_stub.h b/third_party/fuchsia-sdk/pkg/async-testing/include/lib/async-testing/dispatcher_stub.h
new file mode 100644
index 0000000..aa51c15
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-testing/include/lib/async-testing/dispatcher_stub.h
@@ -0,0 +1,42 @@
+// Copyright 2017 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.
+
+#ifndef LIB_ASYNC_TESTING_DISPATCHER_STUB_H_
+#define LIB_ASYNC_TESTING_DISPATCHER_STUB_H_
+
+#include <lib/async/dispatcher.h>
+#include <lib/zx/guest.h>
+#include <lib/zx/time.h>
+
+namespace async {
+
+struct DispatcherStub : public async_dispatcher_t {
+ public:
+ DispatcherStub();
+ virtual ~DispatcherStub();
+
+ DispatcherStub(const DispatcherStub&) = delete;
+ DispatcherStub& operator=(const DispatcherStub&) = delete;
+
+ DispatcherStub(DispatcherStub&&) = delete;
+ DispatcherStub& operator=(DispatcherStub&&) = delete;
+
+ virtual zx::time Now();
+ virtual zx_status_t BeginWait(async_wait_t* wait);
+ virtual zx_status_t CancelWait(async_wait_t* wait);
+ virtual zx_status_t PostTask(async_task_t* task);
+ virtual zx_status_t CancelTask(async_task_t* task);
+ virtual zx_status_t QueuePacket(async_receiver_t* receiver, const zx_packet_user_t* data);
+ virtual zx_status_t SetGuestBellTrap(async_guest_bell_trap_t* trap, const zx::guest& guest,
+ zx_vaddr_t addr, size_t length);
+ virtual zx_status_t BindIrq(async_irq_t* irq);
+ virtual zx_status_t UnbindIrq(async_irq_t* irq);
+ virtual zx_status_t CreatePagedVmo(async_paged_vmo_t* paged_vmo, zx_handle_t pager,
+ uint32_t options, uint64_t vmo_size, zx_handle_t* vmo_out);
+ virtual zx_status_t DetachPagedVmo(async_paged_vmo_t* paged_vmo);
+};
+
+} // namespace async
+
+#endif // LIB_ASYNC_TESTING_DISPATCHER_STUB_H_
diff --git a/third_party/fuchsia-sdk/pkg/async-testing/include/lib/async-testing/test_loop.h b/third_party/fuchsia-sdk/pkg/async-testing/include/lib/async-testing/test_loop.h
new file mode 100644
index 0000000..88cc05c
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-testing/include/lib/async-testing/test_loop.h
@@ -0,0 +1,168 @@
+// Copyright 2018 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.
+
+#ifndef LIB_ASYNC_TESTING_TEST_LOOP_H_
+#define LIB_ASYNC_TESTING_TEST_LOOP_H_
+
+#include <lib/async-testing/test_subloop.h>
+#include <lib/async/dispatcher.h>
+#include <lib/fit/function.h>
+#include <lib/zx/time.h>
+
+#include <memory>
+#include <vector>
+
+namespace async {
+
+// A minimal, abstract async dispatcher-based message loop interface.
+class LoopInterface {
+ public:
+ virtual ~LoopInterface() = default;
+ virtual async_dispatcher_t* dispatcher() = 0;
+};
+
+// A registration token for a subloop of the test loop.
+class SubloopToken {
+ public:
+ virtual ~SubloopToken() = default;
+};
+
+// A message loop with a fake clock, to be controlled within a test setting.
+class TestLoop final {
+ public:
+ // Constructs a TestLoop with a seed from the environment, or a random
+ // seed if absent.
+ TestLoop();
+ // If state is nonzero, constructs a TestLoop with the given seed.
+ // Otherwise, uses a seed from the environment or a random seed.
+ explicit TestLoop(uint32_t state);
+ ~TestLoop();
+
+ TestLoop(const TestLoop&) = delete;
+ TestLoop& operator=(const TestLoop&) = delete;
+
+ TestLoop(TestLoop&&) = delete;
+ TestLoop& operator=(TestLoop&&) = delete;
+
+ // Returns the test loop's asynchronous dispatcher.
+ async_dispatcher_t* dispatcher();
+
+ // Returns a loop interface simulating the starting up of a new message
+ // loop. Each successive call to this method corresponds to a new
+ // subloop. The subloop is unregistered and destructed when the returned
+ // interface is destructed. The returned interface must not outlive the test
+ // loop.
+ std::unique_ptr<LoopInterface> StartNewLoop();
+
+ // Registers a new loop. The test loop takes ownership of the subloop. The
+ // subloop is unregistered and finalized when the returned registration
+ // token is destructed. The token must not outlive the test loop.
+ std::unique_ptr<SubloopToken> RegisterLoop(async_test_subloop_t* loop);
+
+ // Returns the current fake clock time.
+ zx::time Now() const;
+
+ // Quits the message loop. If called while running, it will immediately
+ // exit and dispatch no further tasks or waits; if called before running,
+ // then next call to run will immediately exit. Further calls to run will
+ // dispatch as usual.
+ void Quit();
+
+ // This method must be called while running. It will block the current subloop
+ // until |condition| is realized. Other subloops will continue to run. Returns
+ // |true| when |condition| is realized, and |false| if |condition| is not
+ // realized and no further progress is possible.
+ bool BlockCurrentSubLoopAndRunOthersUntil(fit::function<bool()> condition);
+
+ // Advances the fake clock time by the smallest possible amount.
+ // This doesn't run the loop.
+ void AdvanceTimeByEpsilon();
+
+ // Dispatches all waits and all tasks with deadlines up until |deadline|,
+ // progressively advancing the fake clock.
+ // Returns true iff any tasks or waits were invoked during the run.
+ bool RunUntil(zx::time deadline);
+
+ // Dispatches all waits and all tasks with deadlines up until |duration|
+ // from the the current time, progressively advancing the fake clock.
+ // Returns true iff any tasks or waits were invoked during the run.
+ bool RunFor(zx::duration duration);
+
+ // Dispatches all waits and all tasks with deadlines up until the current
+ // time, progressively advancing the fake clock.
+ // Returns true iff any tasks or waits were invoked during the run.
+ bool RunUntilIdle();
+
+ // The initial value of the state of the TestLoop.
+ uint32_t initial_state() { return initial_state_; }
+
+ private:
+ // An implementation of LoopInterface.
+ class TestLoopInterface;
+
+ // An implementation of LoopToken.
+ class TestSubloopToken;
+
+ // Wraps a subloop in a friendly interface.
+ class TestSubloop;
+
+ // Whether there are any due tasks or waits across |dispatchers_|.
+ bool HasPendingWork();
+
+ // Returns the next due task time across |dispatchers_|.
+ zx::time GetNextTaskDueTime();
+
+ // Advances the time to |time| and notifies the subloops.
+ void AdvanceTimeTo(zx::time time);
+
+ // Returns whether the given subloop is locked.
+ bool IsLockedSubLoop(TestSubloop* subloop);
+
+ // Runs the loop until either:
+ // - The loop quit method is called.
+ // - No unlocked subloop has any available task.
+ // - An event on the current loop must be run when the current loop is locked.
+ //
+ // This method returns |true| if an event has been dispatched while running,
+ // or some event could be run but the method returned due to trying
+ // dispatching an event on the current locked loop.
+ // |current_subloop_| is guaranteed to be unchanged when this method returns.
+ bool Run();
+
+ // The current time. Invariant: all subloops have been notified of the
+ // current time.
+ zx::time current_time_;
+
+ // The interface to the loop associated with the default async dispatcher.
+ std::unique_ptr<LoopInterface> default_loop_;
+
+ // The default async dispatcher.
+ async_dispatcher_t* default_dispatcher_;
+
+ // The dispatchers running in this test loop.
+ std::vector<TestSubloop> subloops_;
+
+ // The subloop dispatching the currently run event.
+ TestSubloop* current_subloop_ = nullptr;
+
+ // The set of subloop currently blocked on |BlockCurrentSubLoopAndRunOthersUntil|.
+ std::vector<TestSubloop*> locked_subloops_;
+
+ // The seed of a pseudo-random number used to determinisitically determine the
+ // dispatching order across |dispatchers_|.
+ uint32_t initial_state_;
+ // The current state of the pseudo-random generator.
+ uint32_t state_;
+
+ // The deadline of the current run of the loop.
+ zx::time deadline_;
+ // Quit state of the loop.
+ bool has_quit_ = false;
+ // Whether the loop is currently running.
+ bool is_running_ = false;
+};
+
+} // namespace async
+
+#endif // LIB_ASYNC_TESTING_TEST_LOOP_H_
diff --git a/third_party/fuchsia-sdk/pkg/async-testing/include/lib/async-testing/test_loop_dispatcher.h b/third_party/fuchsia-sdk/pkg/async-testing/include/lib/async-testing/test_loop_dispatcher.h
new file mode 100644
index 0000000..7eb41ee
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-testing/include/lib/async-testing/test_loop_dispatcher.h
@@ -0,0 +1,19 @@
+// Copyright 2018 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.
+
+#ifndef LIB_ASYNC_TESTING_TEST_LOOP_DISPATCHER_H_
+#define LIB_ASYNC_TESTING_TEST_LOOP_DISPATCHER_H_
+
+#include <lib/async-testing/test_subloop.h>
+#include <lib/async/dispatcher.h>
+
+namespace async {
+
+// Creates a new async dispatcher-based test loop. Returns the async dispatcher
+// in |dispatcher| and the interface to control it in |loop|.
+void NewTestLoopDispatcher(async_dispatcher_t** dispatcher, async_test_subloop_t** loop);
+
+} // namespace async
+
+#endif // LIB_ASYNC_TESTING_TEST_LOOP_DISPATCHER_H_
diff --git a/third_party/fuchsia-sdk/pkg/async-testing/include/lib/async-testing/test_subloop.h b/third_party/fuchsia-sdk/pkg/async-testing/include/lib/async-testing/test_subloop.h
new file mode 100644
index 0000000..dfb4681
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-testing/include/lib/async-testing/test_subloop.h
@@ -0,0 +1,44 @@
+// Copyright 2018 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.
+
+#ifndef LIB_ASYNC_TESTING_TEST_SUBLOOP_H_
+#define LIB_ASYNC_TESTING_TEST_SUBLOOP_H_
+
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// An FFI-friendly generic interface for test loops.
+//
+// Implementations of this interface may be thread-unsafe and
+// non-reentrant. Clients of an async_test_subloop_t* must ensure that the
+// operations are only called with a pointer to the subloop that provides them,
+// and that no operation is called after a call to finalize.
+typedef struct async_test_subloop async_test_subloop_t;
+
+typedef struct async_test_subloop_ops {
+ // Sets the fake time. This will always been called with increasing time,
+ // and will be called at least once prior to calling any other function.
+ void (*advance_time_to)(async_test_subloop_t*, zx_time_t);
+ // Dispatches the next due action. Returns non-zero iff a message was
+ // dispatched. Calling this may change the default async dispatcher; the
+ // caller is responsible for restoring it to its original value.
+ uint8_t (*dispatch_next_due_message)(async_test_subloop_t*);
+ // Returns what |dispatch_next_due_message| would return but does not
+ // perform any work.
+ uint8_t (*has_pending_work)(async_test_subloop_t*);
+ // Returns the next time at which this loop should be woken up if nothing
+ // else happens, or ZX_TIME_INFINITE.
+ zx_time_t (*get_next_task_due_time)(async_test_subloop_t*);
+ // Destroys the state associated with this loop provider.
+ void (*finalize)(async_test_subloop_t*);
+} async_test_subloop_ops_t;
+
+struct async_test_subloop {
+ const async_test_subloop_ops_t* ops;
+};
+
+__END_CDECLS
+
+#endif // LIB_ASYNC_TESTING_TEST_SUBLOOP_H_
diff --git a/third_party/fuchsia-sdk/pkg/async-testing/meta.json b/third_party/fuchsia-sdk/pkg/async-testing/meta.json
new file mode 100644
index 0000000..f93f568
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-testing/meta.json
@@ -0,0 +1,26 @@
+{
+ "banjo_deps": [],
+ "deps": [
+ "async-cpp",
+ "async-default",
+ "fdio",
+ "async",
+ "zx"
+ ],
+ "fidl_deps": [],
+ "headers": [
+ "pkg/async-testing/include/lib/async-testing/dispatcher_stub.h",
+ "pkg/async-testing/include/lib/async-testing/test_loop.h",
+ "pkg/async-testing/include/lib/async-testing/test_loop_dispatcher.h",
+ "pkg/async-testing/include/lib/async-testing/test_subloop.h"
+ ],
+ "include_dir": "pkg/async-testing/include",
+ "name": "async-testing",
+ "root": "pkg/async-testing",
+ "sources": [
+ "pkg/async-testing/dispatcher_stub.cc",
+ "pkg/async-testing/test_loop.cc",
+ "pkg/async-testing/test_loop_dispatcher.cc"
+ ],
+ "type": "cc_source_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/async-testing/test_loop.cc b/third_party/fuchsia-sdk/pkg/async-testing/test_loop.cc
new file mode 100644
index 0000000..1c05c7c
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-testing/test_loop.cc
@@ -0,0 +1,265 @@
+// Copyright 2018 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.
+
+// TODO(joshuseaton): Once std lands in Zircon, simplify everything below.
+
+#include <lib/async-testing/test_loop.h>
+#include <lib/async-testing/test_loop_dispatcher.h>
+#include <lib/async/default.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <zircon/assert.h>
+#include <zircon/syscalls.h>
+
+#include <algorithm>
+#include <utility>
+
+namespace async {
+namespace {
+
+// Deterministically updates |m| to point to a pseudo-random number.
+void Randomize(uint32_t* m) {
+ uint32_t n = *m;
+ n ^= (n << 13);
+ n ^= (n >> 17);
+ n ^= (n << 5);
+ *m = n;
+}
+
+// Generates a random seed if the environment variable TEST_LOOP_RANDOM_SEED
+// is unset; else returns the value of the latter.
+uint32_t GetRandomSeed() {
+ uint32_t random_seed;
+ const char* preset = getenv("TEST_LOOP_RANDOM_SEED");
+
+ if (preset) {
+ size_t preset_length = strlen(preset);
+ char* endptr = nullptr;
+ long unsigned preset_seed = strtoul(preset, &endptr, 10);
+ ZX_ASSERT_MSG(preset_seed > 0 && endptr == preset + preset_length,
+ "ERROR: \"%s\" does not give a valid random seed\n", preset);
+
+ random_seed = static_cast<uint32_t>(preset_seed);
+ } else {
+ zx_cprng_draw(&random_seed, sizeof(uint32_t));
+ }
+
+ return random_seed;
+}
+
+} // namespace
+
+class TestLoop::TestSubloop {
+ public:
+ explicit TestSubloop(async_test_subloop_t* subloop) : subloop_(subloop) {}
+
+ void AdvanceTimeTo(zx::time time) {
+ return subloop_->ops->advance_time_to(subloop_.get(), time.get());
+ }
+
+ bool DispatchNextDueMessage() { return subloop_->ops->dispatch_next_due_message(subloop_.get()); }
+
+ bool HasPendingWork() { return subloop_->ops->has_pending_work(subloop_.get()); }
+
+ zx::time GetNextTaskDueTime() {
+ return zx::time(subloop_->ops->get_next_task_due_time(subloop_.get()));
+ }
+
+ async_test_subloop_t* get() { return subloop_.get(); }
+
+ private:
+ struct SubloopDeleter {
+ void operator()(async_test_subloop_t* loop) { loop->ops->finalize(loop); }
+ };
+
+ std::unique_ptr<async_test_subloop_t, SubloopDeleter> subloop_;
+};
+
+class TestLoop::TestSubloopToken : public SubloopToken {
+ public:
+ TestSubloopToken(TestLoop* loop, async_test_subloop_t* subloop)
+ : loop_(loop), subloop_(subloop) {}
+
+ ~TestSubloopToken() override {
+ auto& subloops = loop_->subloops_;
+ for (auto iterator = subloops.begin(); iterator != subloops.end(); iterator++) {
+ if (iterator->get() == subloop_) {
+ subloops.erase(iterator);
+ break;
+ }
+ }
+ }
+
+ private:
+ TestLoop* const loop_;
+ async_test_subloop_t* subloop_;
+};
+
+class TestLoop::TestLoopInterface : public LoopInterface {
+ public:
+ TestLoopInterface(std::unique_ptr<SubloopToken> token, async_dispatcher_t* dispatcher)
+ : token_(std::move(token)), dispatcher_(dispatcher) {}
+
+ ~TestLoopInterface() override = default;
+
+ async_dispatcher_t* dispatcher() override { return dispatcher_; }
+
+ private:
+ std::unique_ptr<SubloopToken> token_;
+ async_dispatcher_t* dispatcher_;
+};
+
+TestLoop::TestLoop() : TestLoop(0) {}
+
+TestLoop::TestLoop(uint32_t state)
+ : initial_state_((state != 0) ? state : GetRandomSeed()), state_(initial_state_) {
+ default_loop_ = StartNewLoop();
+ default_dispatcher_ = default_loop_->dispatcher();
+ async_set_default_dispatcher(default_dispatcher_);
+
+ printf("\nTEST_LOOP_RANDOM_SEED=\"%u\"\n", initial_state_);
+}
+
+TestLoop::~TestLoop() { async_set_default_dispatcher(nullptr); }
+
+async_dispatcher_t* TestLoop::dispatcher() { return default_dispatcher_; }
+
+bool TestLoop::BlockCurrentSubLoopAndRunOthersUntil(fit::function<bool()> condition) {
+ ZX_ASSERT(is_running_);
+ ZX_ASSERT(!IsLockedSubLoop(current_subloop_));
+ locked_subloops_.push_back(current_subloop_);
+ bool success = false;
+
+ // Store initial deadline.
+ auto initial_deadline = deadline_;
+
+ // Control advancing time. It is necessary to prevent Run() from advancing the
+ // time if |condition()| becomes true in the current run.
+ deadline_ = std::min(Now(), initial_deadline);
+ while (!success) {
+ // Run tasks, which may advance the current time up to |deadline_| but no further.
+ bool did_work = Run();
+
+ success = condition();
+ if (!did_work) {
+ // No work happened and the loop caught up with its deadline, no more
+ // event should be handled.
+ if (initial_deadline <= Now()) {
+ break;
+ }
+ // Advance the time to the next task due time.
+ deadline_ = std::min(GetNextTaskDueTime(), initial_deadline);
+ }
+ }
+
+ // Restore the initial deadline.
+ ZX_ASSERT(deadline_ <= initial_deadline);
+ deadline_ = initial_deadline;
+ ZX_ASSERT(locked_subloops_.back() == current_subloop_);
+ locked_subloops_.pop_back();
+ return success;
+}
+
+std::unique_ptr<LoopInterface> TestLoop::StartNewLoop() {
+ async_dispatcher_t* dispatcher_interface;
+ async_test_subloop_t* subloop;
+ NewTestLoopDispatcher(&dispatcher_interface, &subloop);
+ return std::make_unique<TestLoopInterface>(RegisterLoop(subloop), dispatcher_interface);
+}
+
+std::unique_ptr<SubloopToken> TestLoop::RegisterLoop(async_test_subloop_t* subloop) {
+ TestSubloop wrapped_subloop{subloop};
+ wrapped_subloop.AdvanceTimeTo(Now());
+ subloops_.push_back(std::move(wrapped_subloop));
+ return std::make_unique<TestSubloopToken>(this, subloop);
+}
+
+zx::time TestLoop::Now() const { return current_time_; }
+
+void TestLoop::Quit() { has_quit_ = true; }
+
+void TestLoop::AdvanceTimeByEpsilon() { AdvanceTimeTo(Now() + zx::duration(1)); }
+
+bool TestLoop::RunUntil(zx::time deadline) {
+ ZX_ASSERT(!is_running_);
+ is_running_ = true;
+ deadline_ = deadline;
+ bool did_work = Run();
+ has_quit_ = false;
+ is_running_ = false;
+ return did_work;
+}
+
+bool TestLoop::RunFor(zx::duration duration) { return RunUntil(Now() + duration); }
+
+bool TestLoop::RunUntilIdle() { return RunUntil(Now()); }
+
+bool TestLoop::HasPendingWork() {
+ for (auto& subloop : subloops_) {
+ if (IsLockedSubLoop(&subloop)) {
+ continue;
+ }
+ if (subloop.HasPendingWork()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+zx::time TestLoop::GetNextTaskDueTime() {
+ zx::time next_due_time = zx::time::infinite();
+ for (auto& subloop : subloops_) {
+ if (IsLockedSubLoop(&subloop)) {
+ continue;
+ }
+ next_due_time = std::min<zx::time>(next_due_time, subloop.GetNextTaskDueTime());
+ }
+ return next_due_time;
+}
+
+void TestLoop::AdvanceTimeTo(zx::time time) {
+ if (current_time_ < time) {
+ current_time_ = time;
+ for (auto& subloop : subloops_) {
+ subloop.AdvanceTimeTo(time);
+ }
+ }
+}
+
+bool TestLoop::IsLockedSubLoop(TestSubloop* subloop) {
+ return std::find(locked_subloops_.begin(), locked_subloops_.end(), subloop) !=
+ locked_subloops_.end();
+}
+
+bool TestLoop::Run() {
+ TestSubloop* initial_loop = current_subloop_;
+ bool did_work = false;
+ while (!has_quit_ || !locked_subloops_.empty()) {
+ if (!HasPendingWork()) {
+ zx::time next_due_time = GetNextTaskDueTime();
+ if (next_due_time > deadline_) {
+ AdvanceTimeTo(deadline_);
+ break;
+ }
+ AdvanceTimeTo(next_due_time);
+ }
+
+ Randomize(&state_);
+ size_t current_index = state_ % subloops_.size();
+ current_subloop_ = &subloops_[current_index];
+ if (IsLockedSubLoop(current_subloop_)) {
+ if (current_subloop_ == initial_loop) {
+ did_work = true;
+ break;
+ }
+ continue;
+ }
+
+ did_work |= current_subloop_->DispatchNextDueMessage();
+ }
+ current_subloop_ = initial_loop;
+ return did_work;
+}
+
+} // namespace async
diff --git a/third_party/fuchsia-sdk/pkg/async-testing/test_loop_dispatcher.cc b/third_party/fuchsia-sdk/pkg/async-testing/test_loop_dispatcher.cc
new file mode 100644
index 0000000..126975e
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async-testing/test_loop_dispatcher.cc
@@ -0,0 +1,377 @@
+// Copyright 2018 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.
+
+#include <lib/async-testing/dispatcher_stub.h>
+#include <lib/async-testing/test_loop_dispatcher.h>
+#include <lib/async/default.h>
+#include <lib/async/dispatcher.h>
+#include <lib/async/task.h>
+#include <lib/async/wait.h>
+#include <lib/fit/defer.h>
+#include <lib/zx/port.h>
+#include <lib/zx/time.h>
+#include <zircon/assert.h>
+#include <zircon/compiler.h>
+#include <zircon/errors.h>
+#include <zircon/status.h>
+#include <zircon/syscalls.h>
+#include <zircon/syscalls/port.h>
+
+#include <list>
+#include <memory>
+#include <mutex>
+#include <set>
+
+namespace async {
+namespace {
+
+// An asynchronous dispatcher with an abstracted sense of time, controlled by an
+// external time-keeping object, for use in testing.
+class TestLoopDispatcher : public DispatcherStub, public async_test_subloop_t {
+ public:
+ TestLoopDispatcher();
+ ~TestLoopDispatcher();
+ TestLoopDispatcher(const TestLoopDispatcher&) = delete;
+ TestLoopDispatcher& operator=(const TestLoopDispatcher&) = delete;
+
+ // async_dispatcher_t operation implementations.
+ zx::time Now() override __TA_EXCLUDES(&dispatcher_mtx_) {
+ std::lock_guard<std::mutex> lock(dispatcher_mtx_);
+ return NowLocked();
+ }
+ zx_status_t BeginWait(async_wait_t* wait) __TA_EXCLUDES(&dispatcher_mtx_) override;
+ zx_status_t CancelWait(async_wait_t* wait) __TA_EXCLUDES(&dispatcher_mtx_) override;
+ zx_status_t PostTask(async_task_t* task) __TA_EXCLUDES(&dispatcher_mtx_) override;
+ zx_status_t CancelTask(async_task_t* task) __TA_EXCLUDES(&dispatcher_mtx_) override;
+
+ // async_test_loop_provider_t operations implementations.
+ static void AdvanceTimeTo(async_test_subloop_t* subloop, zx_time_t time)
+ __TA_EXCLUDES(&dispatcher_mtx_);
+ static uint8_t DispatchNextDueMessage(async_test_subloop_t* subloop)
+ __TA_EXCLUDES(&dispatcher_mtx_);
+ static uint8_t HasPendingWork(async_test_subloop_t* subloop) __TA_EXCLUDES(&dispatcher_mtx_);
+ static zx_time_t GetNextTaskDueTime(async_test_subloop_t* subloop)
+ __TA_EXCLUDES(&dispatcher_mtx_);
+ static void Finalize(async_test_subloop_t* subloop) __TA_EXCLUDES(&dispatcher_mtx_);
+
+ private:
+ class Activated;
+ class TaskActivated;
+ class WaitActivated;
+
+ class AsyncTaskComparator {
+ public:
+ bool operator()(async_task_t* t1, async_task_t* t2) const {
+ return t1->deadline < t2->deadline;
+ }
+ };
+
+ // async_test_loop_provider_t operations implementations.
+ void AdvanceTimeTo(zx::time time) __TA_EXCLUDES(&dispatcher_mtx_);
+ bool DispatchNextDueMessage() __TA_EXCLUDES(&dispatcher_mtx_);
+ bool HasPendingWork() __TA_EXCLUDES(&dispatcher_mtx_);
+ zx::time GetNextTaskDueTime() __TA_EXCLUDES(&dispatcher_mtx_);
+
+ zx::time NowLocked() const __TA_REQUIRES(&dispatcher_mtx_) { return now_; }
+
+ // Extracts activated tasks and waits to |activated_|.
+ void ExtractActivatedLocked() __TA_REQUIRES(&dispatcher_mtx_);
+
+ // Removes the given task or wait from |activables_| and |activated_|.
+ zx_status_t CancelActivatedTaskOrWaitLocked(void* task_or_wait) __TA_REQUIRES(&dispatcher_mtx_);
+
+ // Dispatches all remaining posted waits and tasks, invoking their handlers
+ // with status ZX_ERR_CANCELED.
+ void Shutdown() __TA_EXCLUDES(&dispatcher_mtx_);
+
+ // Whether the loop is shutting down.
+ bool in_shutdown_ __TA_GUARDED(&dispatcher_mtx_) = false;
+
+ std::mutex dispatcher_mtx_;
+
+ // The current time.
+ zx::time now_ __TA_GUARDED(&dispatcher_mtx_) = zx::time::infinite_past();
+
+ // Pending tasks activable in the future.
+ // The ordering of the set is based on the task timeline. Multiple tasks
+ // with the same deadline will be equivalent, and be ordered by order of
+ // insertion.
+ std::multiset<async_task_t*, AsyncTaskComparator> future_tasks_ __TA_GUARDED(&dispatcher_mtx_);
+ // Pending waits.
+ std::set<async_wait_t*> pending_waits_ __TA_GUARDED(&dispatcher_mtx_);
+ // Activated elements, ready to be dispatched.
+ std::list<std::unique_ptr<Activated>> activated_ __TA_GUARDED(&dispatcher_mtx_);
+ // Port used to register waits.
+ zx::port port_;
+};
+
+const async_test_subloop_ops_t subloop_ops = {
+ TestLoopDispatcher::AdvanceTimeTo, TestLoopDispatcher::DispatchNextDueMessage,
+ TestLoopDispatcher::HasPendingWork, TestLoopDispatcher::GetNextTaskDueTime,
+ TestLoopDispatcher::Finalize,
+};
+
+// An element in the loop that can be activated. It is either a task or a wait.
+class TestLoopDispatcher::Activated {
+ public:
+ virtual ~Activated() {}
+
+ // Dispatch the element, calling its handler.
+ virtual void Dispatch() const = 0;
+ // Cancel the element, calling its handler with a canceled status.
+ virtual void Cancel() const = 0;
+ // Returns whether this |Activated| corresponds to the given task or wait.
+ virtual bool Matches(void* task_or_wait) const = 0;
+ // Returns the due time for this |Activable|. If the |Activable| is a task,
+ // this corresponds to its deadline, otherwise this is an infinite time in
+ // the future.
+ virtual zx::time DueTime() const = 0;
+};
+
+class TestLoopDispatcher::TaskActivated : public Activated {
+ public:
+ TaskActivated(async_dispatcher_t* dispatcher, async_task_t* task)
+ : dispatcher_(dispatcher), task_(task) {}
+
+ void Dispatch() const override { task_->handler(dispatcher_, task_, ZX_OK); }
+
+ void Cancel() const override { task_->handler(dispatcher_, task_, ZX_ERR_CANCELED); }
+
+ bool Matches(void* task_or_wait) const override { return task_or_wait == task_; }
+
+ zx::time DueTime() const override { return zx::time(task_->deadline); }
+
+ private:
+ async_dispatcher_t* const dispatcher_;
+ async_task_t* const task_;
+};
+
+class TestLoopDispatcher::WaitActivated : public Activated {
+ public:
+ WaitActivated(async_dispatcher_t* dispatcher, async_wait_t* wait, zx_port_packet_t packet)
+ : dispatcher_(dispatcher), wait_(wait), packet_(std::move(packet)) {}
+
+ void Dispatch() const override {
+ wait_->handler(dispatcher_, wait_, packet_.status, &packet_.signal);
+ }
+
+ void Cancel() const override { wait_->handler(dispatcher_, wait_, ZX_ERR_CANCELED, nullptr); }
+
+ bool Matches(void* task_or_wait) const override { return task_or_wait == wait_; }
+
+ zx::time DueTime() const override { return zx::time::infinite(); }
+
+ private:
+ async_dispatcher_t* const dispatcher_;
+ async_wait_t* const wait_;
+ zx_port_packet_t const packet_;
+};
+
+TestLoopDispatcher::TestLoopDispatcher() : async_test_subloop_t{&subloop_ops}, in_shutdown_(false) {
+ zx_status_t status = zx::port::create(0u, &port_);
+ ZX_ASSERT_MSG(status == ZX_OK, "zx_port_create: %s", zx_status_get_string(status));
+}
+
+TestLoopDispatcher::~TestLoopDispatcher() { Shutdown(); }
+
+zx_status_t TestLoopDispatcher::BeginWait(async_wait_t* wait) {
+ ZX_DEBUG_ASSERT(wait);
+
+ std::lock_guard<std::mutex> lock(dispatcher_mtx_);
+ if (in_shutdown_) {
+ return ZX_ERR_CANCELED;
+ }
+
+ zx_status_t status = zx_object_wait_async(
+ wait->object, port_.get(), reinterpret_cast<uintptr_t>(wait), wait->trigger, wait->options);
+ if (status != ZX_OK) {
+ return status;
+ }
+ pending_waits_.insert(wait);
+ return ZX_OK;
+}
+
+zx_status_t TestLoopDispatcher::CancelWait(async_wait_t* wait) {
+ ZX_DEBUG_ASSERT(wait);
+ std::lock_guard<std::mutex> lock(dispatcher_mtx_);
+ auto it = pending_waits_.find(wait);
+ if (it != pending_waits_.end()) {
+ pending_waits_.erase(it);
+ return zx_port_cancel(port_.get(), wait->object, reinterpret_cast<uintptr_t>(wait));
+ }
+
+ return CancelActivatedTaskOrWaitLocked(wait);
+}
+
+zx_status_t TestLoopDispatcher::PostTask(async_task_t* task) {
+ ZX_DEBUG_ASSERT(task);
+
+ std::lock_guard<std::mutex> lock(dispatcher_mtx_);
+ if (in_shutdown_) {
+ return ZX_ERR_CANCELED;
+ }
+
+ if (task->deadline <= NowLocked().get()) {
+ ExtractActivatedLocked();
+ activated_.push_back(std::make_unique<TaskActivated>(this, task));
+ return ZX_OK;
+ }
+
+ future_tasks_.insert(task);
+ return ZX_OK;
+}
+
+zx_status_t TestLoopDispatcher::CancelTask(async_task_t* task) {
+ ZX_DEBUG_ASSERT(task);
+ std::lock_guard<std::mutex> lock(dispatcher_mtx_);
+ auto task_it = std::find(future_tasks_.begin(), future_tasks_.end(), task);
+ if (task_it != future_tasks_.end()) {
+ future_tasks_.erase(task_it);
+ return ZX_OK;
+ }
+
+ return CancelActivatedTaskOrWaitLocked(task);
+}
+
+void TestLoopDispatcher::AdvanceTimeTo(zx::time time) {
+ std::lock_guard<std::mutex> lock(dispatcher_mtx_);
+ ZX_DEBUG_ASSERT(now_ <= time);
+ now_ = time;
+}
+
+zx::time TestLoopDispatcher::GetNextTaskDueTime() {
+ std::lock_guard<std::mutex> lock(dispatcher_mtx_);
+ for (const auto& activated : activated_) {
+ if (activated->DueTime() < zx::time::infinite()) {
+ return activated->DueTime();
+ }
+ }
+ if (!future_tasks_.empty()) {
+ return zx::time((*future_tasks_.begin())->deadline);
+ }
+ return zx::time::infinite();
+}
+
+bool TestLoopDispatcher::HasPendingWork() {
+ std::lock_guard<std::mutex> lock(dispatcher_mtx_);
+ ExtractActivatedLocked();
+ return !activated_.empty();
+}
+
+bool TestLoopDispatcher::DispatchNextDueMessage() {
+ std::unique_ptr<Activated> activated_element = nullptr;
+ {
+ std::lock_guard<std::mutex> lock(dispatcher_mtx_);
+ ExtractActivatedLocked();
+ if (activated_.empty()) {
+ return false;
+ }
+ activated_element = std::move(activated_.front());
+ activated_.erase(activated_.begin());
+ }
+ // Release the lock to avoid deadlocking on reentrant tasks.
+ async_dispatcher_t* previous_dispatcher = async_get_default_dispatcher();
+ async_set_default_dispatcher(this);
+ activated_element->Dispatch();
+ async_set_default_dispatcher(previous_dispatcher);
+
+ return true;
+}
+
+void TestLoopDispatcher::ExtractActivatedLocked() {
+ zx_port_packet_t packet;
+ while (port_.wait(zx::time(0), &packet) == ZX_OK) {
+ async_wait_t* wait = reinterpret_cast<async_wait_t*>(packet.key);
+ pending_waits_.erase(wait);
+ activated_.push_back(std::make_unique<WaitActivated>(this, wait, std::move(packet)));
+ }
+
+ // Move all tasks that reach their deadline to the activated list.
+ while (!future_tasks_.empty() && (*future_tasks_.begin())->deadline <= NowLocked().get()) {
+ activated_.push_back(std::make_unique<TaskActivated>(this, (*future_tasks_.begin())));
+ future_tasks_.erase(future_tasks_.begin());
+ }
+}
+
+// Unique lock does not support TA annotations.
+// Lock needs to be released for reentrant handlers.
+void TestLoopDispatcher::Shutdown() __TA_NO_THREAD_SAFETY_ANALYSIS {
+ std::unique_lock<std::mutex> lock(dispatcher_mtx_);
+
+ if (in_shutdown_) {
+ return;
+ }
+
+ in_shutdown_ = true;
+
+ while (!future_tasks_.empty()) {
+ auto task = *future_tasks_.begin();
+ future_tasks_.erase(future_tasks_.begin());
+ lock.unlock();
+ task->handler(this, task, ZX_ERR_CANCELED);
+ lock.lock();
+ }
+
+ while (!pending_waits_.empty()) {
+ auto wait = *pending_waits_.begin();
+ pending_waits_.erase(pending_waits_.begin());
+ lock.unlock();
+ wait->handler(this, wait, ZX_ERR_CANCELED, nullptr);
+ lock.lock();
+ }
+
+ while (!activated_.empty()) {
+ auto activated = std::move(activated_.front());
+ activated_.erase(activated_.begin());
+ lock.unlock();
+ activated->Cancel();
+ lock.lock();
+ }
+}
+
+zx_status_t TestLoopDispatcher::CancelActivatedTaskOrWaitLocked(void* task_or_wait) {
+ auto activated_it =
+ std::find_if(activated_.begin(), activated_.end(),
+ [&](const auto& activated) { return activated->Matches(task_or_wait); });
+ if (activated_it != activated_.end()) {
+ activated_.erase(activated_it);
+ return ZX_OK;
+ }
+
+ return ZX_ERR_NOT_FOUND;
+}
+
+void TestLoopDispatcher::AdvanceTimeTo(async_test_subloop_t* subloop, zx_time_t time) {
+ TestLoopDispatcher* self = static_cast<TestLoopDispatcher*>(subloop);
+ return self->AdvanceTimeTo(zx::time(time));
+}
+
+uint8_t TestLoopDispatcher::DispatchNextDueMessage(async_test_subloop_t* subloop) {
+ TestLoopDispatcher* self = static_cast<TestLoopDispatcher*>(subloop);
+ return self->DispatchNextDueMessage();
+}
+
+uint8_t TestLoopDispatcher::HasPendingWork(async_test_subloop_t* subloop) {
+ TestLoopDispatcher* self = static_cast<TestLoopDispatcher*>(subloop);
+ return self->HasPendingWork();
+}
+
+zx_time_t TestLoopDispatcher::GetNextTaskDueTime(async_test_subloop_t* subloop) {
+ TestLoopDispatcher* self = static_cast<TestLoopDispatcher*>(subloop);
+ return self->GetNextTaskDueTime().get();
+}
+
+void TestLoopDispatcher::Finalize(async_test_subloop_t* subloop) {
+ auto self = std::unique_ptr<TestLoopDispatcher>(static_cast<TestLoopDispatcher*>(subloop));
+}
+
+} // namespace
+
+void NewTestLoopDispatcher(async_dispatcher_t** dispatcher, async_test_subloop_t** loop) {
+ auto dispatcher_loop = std::make_unique<TestLoopDispatcher>();
+ *dispatcher = dispatcher_loop.get();
+ *loop = dispatcher_loop.release();
+}
+
+} // namespace async
diff --git a/third_party/fuchsia-sdk/pkg/async/BUILD.gn b/third_party/fuchsia-sdk/pkg/async/BUILD.gn
new file mode 100644
index 0000000..b2274a4
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async/BUILD.gn
@@ -0,0 +1,33 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("async") {
+ sources = [
+ "ops.c",
+ "include/lib/async/dispatcher.h",
+ "include/lib/async/irq.h",
+ "include/lib/async/paged_vmo.h",
+ "include/lib/async/receiver.h",
+ "include/lib/async/task.h",
+ "include/lib/async/time.h",
+ "include/lib/async/trap.h",
+ "include/lib/async/wait.h",
+ ]
+ include_dirs = [ "include" ]
+ public_deps = [
+ "../fit",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":async",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/async/include/lib/async/dispatcher.h b/third_party/fuchsia-sdk/pkg/async/include/lib/async/dispatcher.h
new file mode 100644
index 0000000..8542435
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async/include/lib/async/dispatcher.h
@@ -0,0 +1,119 @@
+// Copyright 2017 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.
+
+#ifndef LIB_ASYNC_DISPATCHER_H_
+#define LIB_ASYNC_DISPATCHER_H_
+
+#include <zircon/compiler.h>
+#include <zircon/syscalls/port.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// Dispatcher interface for performing asynchronous operations.
+// There may be multiple implementations of this interface.
+typedef struct async_dispatcher async_dispatcher_t;
+
+// Forward declarations for asynchronous operation structures.
+typedef struct async_guest_bell_trap async_guest_bell_trap_t;
+typedef struct async_wait async_wait_t;
+typedef struct async_task async_task_t;
+typedef struct async_receiver async_receiver_t;
+typedef struct async_irq async_irq_t;
+typedef struct async_paged_vmo async_paged_vmo_t;
+
+// Private state owned by the asynchronous dispatcher.
+// This allows the dispatcher to associate a small amount of state with pending
+// asynchronous operations without having to allocate additional heap storage of
+// its own.
+//
+// Clients must initialize the contents of this structure to zero using
+// |ASYNC_STATE_INIT| or with calloc, memset, or a similar means.
+typedef struct {
+ uintptr_t reserved[2];
+} async_state_t;
+
+#define ASYNC_STATE_INIT \
+ { 0u, 0u }
+
+// Asynchronous dispatcher interface.
+//
+// Clients should not call into this interface directly: use the wrapper functions
+// declared in other header files, such as |async_begin_wait()| in <lib/async/wait.h>.
+// See the documentation of those functions for details about each method's purpose
+// and behavior.
+//
+// This interface consists of several groups of methods:
+//
+// - Timing: |now|
+// - Waiting for signals: |begin_wait|, |cancel_wait|
+// - Posting tasks: |post_task|, |cancel_task|
+// - Queuing packets: |queue_packet|
+// - Virtual machine operations: |set_guest_bell_trap|
+//
+// To preserve binary compatibility, each successive version of this interface
+// is guaranteed to be backwards-compatible with clients of earlier versions.
+// New methods must only be added by extending the structure at the end and
+// declaring a new version number. Do not reorder the declarations or modify
+// existing versions.
+//
+// Implementations of this interface must provide valid (non-null) function pointers
+// for every method declared in the interface version they support. Unsupported
+// methods must return |ZX_ERR_NOT_SUPPORTED| and have no other side-effects.
+// Furthermore, if an implementation supports one method of a group, such as |begin_wait|,
+// then it must also support the other methods of the group, such as |cancel_wait|.
+//
+// Many clients assume that the dispatcher interface is fully implemented and may
+// fail to work with dispatchers that do not support the methods they need.
+// Therefore general-purpose dispatcher implementations are encouraged to support
+// the whole interface to ensure broad compatibility.
+typedef uint32_t async_ops_version_t;
+
+#define ASYNC_OPS_V1 ((async_ops_version_t)1)
+#define ASYNC_OPS_V2 ((async_ops_version_t)2)
+
+typedef struct async_ops {
+ // The interface version number, e.g. |ASYNC_OPS_V1|.
+ async_ops_version_t version;
+
+ // Reserved for future expansion, set to zero.
+ uint32_t reserved;
+
+ // Operations supported by |ASYNC_OPS_V1|.
+ struct v1 {
+ // See |async_now()| for details.
+ zx_time_t (*now)(async_dispatcher_t* dispatcher);
+ // See |async_begin_wait()| for details.
+ zx_status_t (*begin_wait)(async_dispatcher_t* dispatcher, async_wait_t* wait);
+ // See |async_cancel_wait()| for details.
+ zx_status_t (*cancel_wait)(async_dispatcher_t* dispatcher, async_wait_t* wait);
+ // See |async_post_task()| for details.
+ zx_status_t (*post_task)(async_dispatcher_t* dispatcher, async_task_t* task);
+ // See |async_cancel_task()| for details.
+ zx_status_t (*cancel_task)(async_dispatcher_t* dispatcher, async_task_t* task);
+ // See |async_queue_packet()| for details.
+ zx_status_t (*queue_packet)(async_dispatcher_t* dispatcher, async_receiver_t* receiver,
+ const zx_packet_user_t* data);
+ // See |async_set_guest_bell_trap()| for details.
+ zx_status_t (*set_guest_bell_trap)(async_dispatcher_t* dispatcher,
+ async_guest_bell_trap_t* trap, zx_handle_t guest,
+ zx_vaddr_t addr, size_t length);
+ } v1;
+ struct v2 {
+ zx_status_t (*bind_irq)(async_dispatcher_t* dispatcher, async_irq_t* irq);
+ zx_status_t (*unbind_irq)(async_dispatcher_t* dispatcher, async_irq_t* irq);
+ zx_status_t (*create_paged_vmo)(async_dispatcher_t* dispatcher, async_paged_vmo_t* paged_vmo,
+ uint32_t options, zx_handle_t pager, uint64_t vmo_size,
+ zx_handle_t* vmo_out);
+ zx_status_t (*detach_paged_vmo)(async_dispatcher_t* dispatcher, async_paged_vmo_t* paged_vmo);
+ } v2;
+} async_ops_t;
+
+struct async_dispatcher {
+ const async_ops_t* ops;
+};
+
+__END_CDECLS
+
+#endif // LIB_ASYNC_DISPATCHER_H_
diff --git a/third_party/fuchsia-sdk/pkg/async/include/lib/async/irq.h b/third_party/fuchsia-sdk/pkg/async/include/lib/async/irq.h
new file mode 100644
index 0000000..1ad2510
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async/include/lib/async/irq.h
@@ -0,0 +1,57 @@
+// Copyright 2017 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.
+
+#ifndef LIB_ASYNC_IRQ_H_
+#define LIB_ASYNC_IRQ_H_
+
+#include <lib/async/dispatcher.h>
+
+__BEGIN_CDECLS
+
+// Handles interrupt.
+//
+// The |status| is |ZX_OK| if the IRQ was signalled.
+// The |status| is |ZX_ERR_CANCELED| if the dispatcher was shut down before
+// the task's handler ran or the task was canceled.
+typedef void(async_irq_handler_t)(async_dispatcher_t* dispatcher, async_irq_t* irq,
+ zx_status_t status, const zx_packet_interrupt_t* signal);
+
+// Similar to async_wait, but holds state for an interrupt.
+struct async_irq {
+ // Private state owned by the dispatcher, initialize to zero with |ASYNC_STATE_INIT|.
+ async_state_t state;
+
+ // The wait's handler function.
+ async_irq_handler_t* handler;
+
+ // The object to wait for signals on.
+ zx_handle_t object;
+};
+
+// Begins asynchronously waiting on an IRQ specified in |irq|.
+// Invokes the handler when the wait completes.
+// The wait's handler will be invoked exactly once unless the wait is canceled.
+// When the dispatcher is shutting down (being destroyed), the handlers of
+// all remaining waits will be invoked with a status of |ZX_ERR_CANCELED|.
+//
+// Returns |ZX_OK| if the wait was successfully begun.
+// Returns |ZX_ERR_BAD_STATE| if the dispatcher is shutting down.
+// Returns |ZX_ERR_NOT_SUPPORTED| if not supported by the dispatcher.
+//
+// This operation is thread-safe.
+zx_status_t async_bind_irq(async_dispatcher_t* dispatcher, async_irq_t* irq);
+
+// Unbinds the IRQ associated with |irq|.
+//
+// If successful, the IRQ will be unbound from the async loop.
+//
+// Returns |ZX_OK| if the IRQ has been successfully unbound.
+// Returns |ZX_ERR_NOT_SUPPORTED| if not supported by the dispatcher.
+//
+// This operation is thread-safe.
+zx_status_t async_unbind_irq(async_dispatcher_t* dispatcher, async_irq_t* irq);
+
+__END_CDECLS
+
+#endif // LIB_ASYNC_IRQ_H_
diff --git a/third_party/fuchsia-sdk/pkg/async/include/lib/async/paged_vmo.h b/third_party/fuchsia-sdk/pkg/async/include/lib/async/paged_vmo.h
new file mode 100644
index 0000000..88b575b
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async/include/lib/async/paged_vmo.h
@@ -0,0 +1,62 @@
+// 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.
+
+#ifndef LIB_ASYNC_PAGED_VMO_H_
+#define LIB_ASYNC_PAGED_VMO_H_
+
+#include <lib/async/dispatcher.h>
+
+__BEGIN_CDECLS
+
+// Handles port packets containing page requests.
+//
+// The |status| is |ZX_OK| if the packet was successfully delivered and |request|
+// contains the information from the packet, otherwise |request| is null.
+// The |status| is |ZX_ERR_CANCELED| if the dispatcher was shut down.
+typedef void(async_paged_vmo_handler_t)(async_dispatcher_t* dispatcher,
+ async_paged_vmo_t* paged_vmo, zx_status_t status,
+ const zx_packet_page_request_t* request);
+
+// Holds content for a paged request packet receiver and its handler.
+//
+// The client is responsible for retaining the structure in memory
+// (and unmodified) until all packets have been received by the handler or the
+// dispatcher shuts down.
+struct async_paged_vmo {
+ // Private state owned by the dispatcher, initialize to zero with |ASYNC_STATE_INIT|.
+ async_state_t state;
+
+ // The handler to invoke when a packet is received.
+ async_paged_vmo_handler_t* handler;
+
+ // The associated pager when creating the VMO.
+ zx_handle_t pager;
+
+ // The VMO for this request.
+ zx_handle_t vmo;
+};
+
+// Create a pager owned VMO.
+//
+// Returns |ZX_ERR_BAD_STATE| if the dispatcher is shutting down.
+// Returns |ZX_ERR_NOT_SUPPORTED| if not supported by the dispatcher.
+// Other error values are possible. See the documentation for
+// |zx_pager_create_vmo()|.
+zx_status_t async_create_paged_vmo(async_dispatcher_t* dispatcher, async_paged_vmo_t* paged_vmo,
+ uint32_t options, zx_handle_t pager, uint64_t vmo_size,
+ zx_handle_t* vmo_out);
+
+// Detach ownership of VMO from pager.
+//
+// Returns |ZX_ERR_NOT_SUPPORTED| if not supported by the dispatcher.
+// Returns |ZX_ERR_BAD_HANDLE| if pager or vmo is not a valid handle.
+// Returns |ZX_ERR_WRONG_TYPE| if pager is not a pager handle or vmo is not a vmo handle.
+// Returns |ZX_ERR_INVALID_ARGS| if vmo is not a vmo created from pager.
+// Other error values are possible. See the documentation for
+// |zx_detach_paged_vmo()|.
+zx_status_t async_detach_paged_vmo(async_dispatcher_t* dispatcher, async_paged_vmo_t* paged_vmo);
+
+__END_CDECLS
+
+#endif // LIB_ASYNC_PAGED_VMO_H_
diff --git a/third_party/fuchsia-sdk/pkg/async/include/lib/async/receiver.h b/third_party/fuchsia-sdk/pkg/async/include/lib/async/receiver.h
new file mode 100644
index 0000000..ed60d7c
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async/include/lib/async/receiver.h
@@ -0,0 +1,50 @@
+// Copyright 2017 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.
+
+#ifndef LIB_ASYNC_RECEIVER_H_
+#define LIB_ASYNC_RECEIVER_H_
+
+#include <lib/async/dispatcher.h>
+
+__BEGIN_CDECLS
+
+// Handles receipt of packets containing user supplied data.
+//
+// The |status| is |ZX_OK| if the packet was successfully delivered and |data|
+// contains the information from the packet, otherwise |data| is null.
+typedef void(async_receiver_handler_t)(async_dispatcher_t* dispatcher, async_receiver_t* receiver,
+ zx_status_t status, const zx_packet_user_t* data);
+
+// Holds content for a packet receiver and its handler.
+//
+// After successfully queuing packets to the receiver, the client is responsible
+// for retaining the structure in memory (and unmodified) until all packets have
+// been received by the handler or the dispatcher shuts down. There is no way
+// to cancel a packet which has been queued.
+//
+// Multiple packets may be delivered to the same receiver concurrently.
+struct async_receiver {
+ // Private state owned by the dispatcher, initialize to zero with |ASYNC_STATE_INIT|.
+ async_state_t state;
+
+ // The handler to invoke when a packet is received.
+ async_receiver_handler_t* handler;
+};
+
+// Enqueues a packet of data for delivery to a receiver.
+//
+// The |data| will be copied into the packet. May be NULL to create a
+// zero-initialized packet payload.
+//
+// Returns |ZX_OK| if the packet was successfully enqueued.
+// Returns |ZX_ERR_BAD_STATE| if the dispatcher is shutting down.
+// Returns |ZX_ERR_NOT_SUPPORTED| if not supported by the dispatcher.
+//
+// This operation is thread-safe.
+zx_status_t async_queue_packet(async_dispatcher_t* dispatcher, async_receiver_t* receiver,
+ const zx_packet_user_t* data);
+
+__END_CDECLS
+
+#endif // LIB_ASYNC_RECEIVER_H_
diff --git a/third_party/fuchsia-sdk/pkg/async/include/lib/async/task.h b/third_party/fuchsia-sdk/pkg/async/include/lib/async/task.h
new file mode 100644
index 0000000..936270e
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async/include/lib/async/task.h
@@ -0,0 +1,69 @@
+// Copyright 2017 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.
+
+#ifndef LIB_ASYNC_TASK_H_
+#define LIB_ASYNC_TASK_H_
+
+#include <lib/async/dispatcher.h>
+
+__BEGIN_CDECLS
+
+// Handles execution of a posted task.
+//
+// The |status| is |ZX_OK| if the task's deadline elapsed and the task should run.
+// The |status| is |ZX_ERR_CANCELED| if the dispatcher was shut down before
+// the task's handler ran.
+typedef void(async_task_handler_t)(async_dispatcher_t* dispatcher, async_task_t* task,
+ zx_status_t status);
+
+// Holds context for a task and its handler.
+//
+// After successfully posting the task, the client is responsible for retaining
+// the structure in memory (and unmodified) until the task's handler runs, the task
+// is successfully canceled, or the dispatcher shuts down. Thereafter, the task
+// may be posted again or destroyed.
+struct async_task {
+ // Private state owned by the dispatcher, initialize to zero with |ASYNC_STATE_INIT|.
+ async_state_t state;
+
+ // The task's handler function.
+ async_task_handler_t* handler;
+
+ // The task's deadline must be expressed in the time base used by the asynchronous
+ // dispatcher (usually |ZX_CLOCK_MONOTONIC| except in unit tests).
+ // See |async_now()| for details.
+ zx_time_t deadline;
+};
+
+// Posts a task to run on or after its deadline following all posted
+// tasks with lesser or equal deadlines.
+//
+// The task's handler will be invoked exactly once unless the task is canceled.
+// When the dispatcher is shutting down (being destroyed), the handlers of
+// all remaining tasks will be invoked with a status of |ZX_ERR_CANCELED|.
+//
+// Returns |ZX_OK| if the task was successfully posted.
+// Returns |ZX_ERR_BAD_STATE| if the dispatcher is shutting down.
+// Returns |ZX_ERR_NOT_SUPPORTED| if not supported by the dispatcher.
+//
+// This operation is thread-safe.
+zx_status_t async_post_task(async_dispatcher_t* dispatcher, async_task_t* task);
+
+// Cancels the task associated with |task|.
+//
+// If successful, the task's handler will not run.
+//
+// Returns |ZX_OK| if the task was pending and it has been successfully
+// canceled; its handler will not run again and can be released immediately.
+// Returns |ZX_ERR_NOT_FOUND| if there was no pending task either because it
+// already ran, had not been posted, or has been dequeued and is pending
+// execution (perhaps on another thread).
+// Returns |ZX_ERR_NOT_SUPPORTED| if not supported by the dispatcher.
+//
+// This operation is thread-safe.
+zx_status_t async_cancel_task(async_dispatcher_t* dispatcher, async_task_t* task);
+
+__END_CDECLS
+
+#endif // LIB_ASYNC_TASK_H_
diff --git a/third_party/fuchsia-sdk/pkg/async/include/lib/async/time.h b/third_party/fuchsia-sdk/pkg/async/include/lib/async/time.h
new file mode 100644
index 0000000..c800099
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async/include/lib/async/time.h
@@ -0,0 +1,19 @@
+// Copyright 2018 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.
+
+#ifndef LIB_ASYNC_TIME_H_
+#define LIB_ASYNC_TIME_H_
+
+#include <lib/async/dispatcher.h>
+
+__BEGIN_CDECLS
+
+// Returns the current time in the dispatcher's timebase.
+// For most loops, this is generally obtained from |ZX_CLOCK_MONOTONIC|
+// but certain loops may use a different tiembase, notably for testing.
+zx_time_t async_now(async_dispatcher_t* dispatcher);
+
+__END_CDECLS
+
+#endif // LIB_ASYNC_TIME_H_
diff --git a/third_party/fuchsia-sdk/pkg/async/include/lib/async/trap.h b/third_party/fuchsia-sdk/pkg/async/include/lib/async/trap.h
new file mode 100644
index 0000000..6bd62c6
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async/include/lib/async/trap.h
@@ -0,0 +1,55 @@
+// Copyright 2018 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.
+
+#ifndef LIB_ASYNC_TRAP_H_
+#define LIB_ASYNC_TRAP_H_
+
+#include <lib/async/dispatcher.h>
+
+__BEGIN_CDECLS
+
+// Handles an asynchronous trap access.
+//
+// The |status| is |ZX_OK| if the bell was received and |bell| contains the
+// information from the packet, otherwise |bell| is null.
+typedef void(async_guest_bell_trap_handler_t)(async_dispatcher_t* dispatcher,
+ async_guest_bell_trap_t* trap, zx_status_t status,
+ const zx_packet_guest_bell_t* bell);
+
+// Holds context for a bell trap and its handler.
+//
+// After successfully posting setting the trap, the client is responsible for retaining
+// the structure in memory (and unmodified) until the guest has been destroyed or the
+// dispatcher shuts down. There is no way to cancel a trap which has been set.
+struct async_guest_bell_trap {
+ // Private state owned by the dispatcher, initialize to zero with |ASYNC_STATE_INIT|.
+ async_state_t state;
+
+ // The handler to invoke to handle the trap access.
+ async_guest_bell_trap_handler_t* handler;
+};
+
+// Sets a bell trap in the guest to be handled asynchronously via a handler.
+//
+// |guest| is the handle of the guest the trap will be set on.
+// |addr| is the base address for the trap in the guest's physical address space.
+// |length| is the size of the trap in the guest's physical address space.
+//
+// Returns |ZX_OK| if the trap was successfully set.
+// Returns |ZX_ERR_ACCESS_DENIED| if the guest does not have |ZX_RIGHT_WRITE|.
+// Returns |ZX_ERR_ALREADY_EXISTS| if a bell trap with the same |addr| exists.
+// Returns |ZX_ERR_INVALID_ARGS| if |addr| or |length| are invalid.
+// Returns |ZX_ERR_OUT_OF_RANGE| if |addr| or |length| are out of range of the
+// address space.
+// Returns |ZX_ERR_WRONG_TYPE| if |guest| is not a handle to a guest.
+// Returns |ZX_ERR_BAD_STATE| if the dispatcher is shutting down.
+// Returns |ZX_ERR_NOT_SUPPORTED| if not supported by the dispatcher.
+//
+// This operation is thread-safe.
+zx_status_t async_set_guest_bell_trap(async_dispatcher_t* dispatcher, async_guest_bell_trap_t* trap,
+ zx_handle_t guest, zx_vaddr_t addr, size_t length);
+
+__END_CDECLS
+
+#endif // LIB_ASYNC_TRAP_H_
diff --git a/third_party/fuchsia-sdk/pkg/async/include/lib/async/wait.h b/third_party/fuchsia-sdk/pkg/async/include/lib/async/wait.h
new file mode 100644
index 0000000..713986f
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async/include/lib/async/wait.h
@@ -0,0 +1,75 @@
+// Copyright 2017 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.
+
+#ifndef LIB_ASYNC_WAIT_H_
+#define LIB_ASYNC_WAIT_H_
+
+#include <lib/async/dispatcher.h>
+
+__BEGIN_CDECLS
+
+// Handles completion of asynchronous wait operations.
+//
+// The |status| is |ZX_OK| if the wait was satisfied and |signal| is non-null.
+// The |status| is |ZX_ERR_CANCELED| if the dispatcher was shut down before
+// the task's handler ran or the task was canceled.
+typedef void(async_wait_handler_t)(async_dispatcher_t* dispatcher, async_wait_t* wait,
+ zx_status_t status, const zx_packet_signal_t* signal);
+
+// Holds context for an asynchronous wait operation and its handler.
+//
+// After successfully beginning the wait, the client is responsible for retaining
+// the structure in memory (and unmodified) until the wait's handler runs, the wait
+// is successfully canceled, or the dispatcher shuts down. Thereafter, the wait
+// may be started begun or destroyed.
+struct async_wait {
+ // Private state owned by the dispatcher, initialize to zero with |ASYNC_STATE_INIT|.
+ async_state_t state;
+
+ // The wait's handler function.
+ async_wait_handler_t* handler;
+
+ // The object to wait for signals on.
+ zx_handle_t object;
+
+ // The set of signals to wait for.
+ zx_signals_t trigger;
+
+ // Wait options, see zx_object_wait_async().
+ uint32_t options;
+};
+
+// Begins asynchronously waiting for an object to receive one or more signals
+// specified in |wait|. Invokes the handler when the wait completes.
+//
+// The wait's handler will be invoked exactly once unless the wait is canceled.
+// When the dispatcher is shutting down (being destroyed), the handlers of
+// all remaining waits will be invoked with a status of |ZX_ERR_CANCELED|.
+//
+// Returns |ZX_OK| if the wait was successfully begun.
+// Returns |ZX_ERR_ACCESS_DENIED| if the object does not have |ZX_RIGHT_WAIT|.
+// Returns |ZX_ERR_BAD_STATE| if the dispatcher is shutting down.
+// Returns |ZX_ERR_NOT_SUPPORTED| if not supported by the dispatcher.
+//
+// This operation is thread-safe.
+zx_status_t async_begin_wait(async_dispatcher_t* dispatcher, async_wait_t* wait);
+
+// Cancels the wait associated with |wait|.
+//
+// If successful, the wait's handler will not run.
+//
+// Returns |ZX_OK| if the wait was pending and it has been successfully
+// canceled; its handler will not run again and can be released immediately.
+// Returns |ZX_ERR_NOT_FOUND| if there was no pending wait either because it
+// already completed, had not been started, or its completion packet has been
+// dequeued from the port and is pending delivery to its handler (perhaps on
+// another thread).
+// Returns |ZX_ERR_NOT_SUPPORTED| if not supported by the dispatcher.
+//
+// This operation is thread-safe.
+zx_status_t async_cancel_wait(async_dispatcher_t* dispatcher, async_wait_t* wait);
+
+__END_CDECLS
+
+#endif // LIB_ASYNC_WAIT_H_
diff --git a/third_party/fuchsia-sdk/pkg/async/meta.json b/third_party/fuchsia-sdk/pkg/async/meta.json
new file mode 100644
index 0000000..e1492b3
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async/meta.json
@@ -0,0 +1,24 @@
+{
+ "banjo_deps": [],
+ "deps": [
+ "fit"
+ ],
+ "fidl_deps": [],
+ "headers": [
+ "pkg/async/include/lib/async/dispatcher.h",
+ "pkg/async/include/lib/async/paged_vmo.h",
+ "pkg/async/include/lib/async/receiver.h",
+ "pkg/async/include/lib/async/task.h",
+ "pkg/async/include/lib/async/time.h",
+ "pkg/async/include/lib/async/trap.h",
+ "pkg/async/include/lib/async/wait.h",
+ "pkg/async/include/lib/async/irq.h"
+ ],
+ "include_dir": "pkg/async/include",
+ "name": "async",
+ "root": "pkg/async",
+ "sources": [
+ "pkg/async/ops.c"
+ ],
+ "type": "cc_source_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/async/ops.c b/third_party/fuchsia-sdk/pkg/async/ops.c
new file mode 100644
index 0000000..4bea01a
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/async/ops.c
@@ -0,0 +1,68 @@
+// Copyright 2017 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.
+
+#include <lib/async/receiver.h>
+#include <lib/async/task.h>
+#include <lib/async/time.h>
+#include <lib/async/trap.h>
+#include <lib/async/wait.h>
+
+zx_time_t async_now(async_dispatcher_t* dispatcher) { return dispatcher->ops->v1.now(dispatcher); }
+
+zx_status_t async_begin_wait(async_dispatcher_t* dispatcher, async_wait_t* wait) {
+ return dispatcher->ops->v1.begin_wait(dispatcher, wait);
+}
+
+zx_status_t async_cancel_wait(async_dispatcher_t* dispatcher, async_wait_t* wait) {
+ return dispatcher->ops->v1.cancel_wait(dispatcher, wait);
+}
+
+zx_status_t async_post_task(async_dispatcher_t* dispatcher, async_task_t* task) {
+ return dispatcher->ops->v1.post_task(dispatcher, task);
+}
+
+zx_status_t async_cancel_task(async_dispatcher_t* dispatcher, async_task_t* task) {
+ return dispatcher->ops->v1.cancel_task(dispatcher, task);
+}
+
+zx_status_t async_queue_packet(async_dispatcher_t* dispatcher, async_receiver_t* receiver,
+ const zx_packet_user_t* data) {
+ return dispatcher->ops->v1.queue_packet(dispatcher, receiver, data);
+}
+
+zx_status_t async_set_guest_bell_trap(async_dispatcher_t* dispatcher, async_guest_bell_trap_t* trap,
+ zx_handle_t guest, zx_vaddr_t addr, size_t length) {
+ return dispatcher->ops->v1.set_guest_bell_trap(dispatcher, trap, guest, addr, length);
+}
+
+zx_status_t async_bind_irq(async_dispatcher_t* dispatcher, async_irq_t* irq) {
+ if (dispatcher->ops->version < ASYNC_OPS_V2) {
+ return ZX_ERR_NOT_SUPPORTED;
+ }
+ return dispatcher->ops->v2.bind_irq(dispatcher, irq);
+}
+
+zx_status_t async_unbind_irq(async_dispatcher_t* dispatcher, async_irq_t* irq) {
+ if (dispatcher->ops->version < ASYNC_OPS_V2) {
+ return ZX_ERR_NOT_SUPPORTED;
+ }
+ return dispatcher->ops->v2.unbind_irq(dispatcher, irq);
+}
+
+zx_status_t async_create_paged_vmo(async_dispatcher_t* dispatcher, async_paged_vmo_t* paged_vmo,
+ uint32_t options, zx_handle_t pager, uint64_t vmo_size,
+ zx_handle_t* vmo_out) {
+ if (dispatcher->ops->version < ASYNC_OPS_V2) {
+ return ZX_ERR_NOT_SUPPORTED;
+ }
+ return dispatcher->ops->v2.create_paged_vmo(dispatcher, paged_vmo, options, pager, vmo_size,
+ vmo_out);
+}
+
+zx_status_t async_detach_paged_vmo(async_dispatcher_t* dispatcher, async_paged_vmo_t* paged_vmo) {
+ if (dispatcher->ops->version < ASYNC_OPS_V2) {
+ return ZX_ERR_NOT_SUPPORTED;
+ }
+ return dispatcher->ops->v2.detach_paged_vmo(dispatcher, paged_vmo);
+}
diff --git a/third_party/fuchsia-sdk/pkg/fdio/BUILD.gn b/third_party/fuchsia-sdk/pkg/fdio/BUILD.gn
new file mode 100644
index 0000000..5eb7c92
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fdio/BUILD.gn
@@ -0,0 +1,36 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("fdio") {
+ shared_libs = [ "fdio" ]
+
+ deps = [
+ ]
+ sources = [
+ "include/lib/fdio/directory.h",
+ "include/lib/fdio/fd.h",
+ "include/lib/fdio/fdio.h",
+ "include/lib/fdio/io.h",
+ "include/lib/fdio/limits.h",
+ "include/lib/fdio/namespace.h",
+ "include/lib/fdio/private.h",
+ "include/lib/fdio/spawn.h",
+ "include/lib/fdio/unsafe.h",
+ "include/lib/fdio/vfs.h",
+ "include/lib/fdio/watcher.h",
+ ]
+ include_dirs = [ "include" ]
+}
+
+group("all"){
+ deps = [
+ ":fdio",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/directory.h b/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/directory.h
new file mode 100644
index 0000000..772723c
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/directory.h
@@ -0,0 +1,144 @@
+// 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.
+
+#ifndef LIB_FDIO_DIRECTORY_H_
+#define LIB_FDIO_DIRECTORY_H_
+
+#include <lib/fdio/fd.h>
+#include <lib/fdio/fdio.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// Connects to a service at the given |path|.
+//
+// The |path| is looked up in the namespace for the current process. If found in
+// the namespace, the object at the path is opened, passing the |request| to
+// the remote party.
+//
+// Upon success, the |request| is handed off to the remote party. The operation
+// completes asynchronously, which means a ZX_OK result does not ensure that the
+// requested service actually exists.
+//
+// |request| must be a channel.
+//
+// Always consumes |request|.
+//
+// # Errors
+//
+// ZX_ERR_INVALID_ARGS: |path| is invalid.
+//
+// ZX_ERR_NOT_FOUND: A prefix of |path| cannot be found in the namespace for the
+// current process.
+//
+// ZX_ERR_NOT_SUPPORTED: The requested |path| was found in the namespace for the
+// current process but the namespace entry does not support connecting to
+// services.
+//
+// ZX_ERR_ACCESS_DENIED: The namespace entry has insufficient rights to connect
+// to services.
+zx_status_t fdio_service_connect(const char* path, zx_handle_t request);
+
+// Connects to a service at the given |path| relative to the given |directory|.
+//
+// Upon success, the |request| is handed off to the remote party. The operation
+// completes asynchronously, which means a ZX_OK result does not ensure that the
+// requested service actually exists.
+//
+// |directory| must be a channel that implements the |fuchsia.io.Directory|
+// protocol.
+//
+// |request| must be a channel.
+//
+// Always consumes |request|.
+//
+// # Errors
+//
+// ZX_ERR_INVALID_ARGS: |directory| or |path| is invalid.
+//
+// ZX_ERR_ACCESS_DENIED: |directory| has insufficient rights to connect to
+// services.
+zx_status_t fdio_service_connect_at(zx_handle_t directory, const char* path, zx_handle_t request);
+
+// Opens the remote object at the given |path| relative to the root of the namespace with the given
+// |flags| asynchronously.
+//
+// |flags| is a bit field of |fuchsia.io.OPEN_*|.
+//
+// Always consumes |request|.
+//
+// See |fdio_service_connect| for details.
+zx_status_t fdio_open(const char* path, uint32_t flags, zx_handle_t request);
+
+// Opens the remote object at the given |path| relative to the given |directory| with the given
+// |flags| asynchronously.
+//
+// |flags| is a bit field of |fuchsia.io.OPEN_*|.
+//
+// Always consumes |request|.
+//
+// See |fdio_service_connect_at| for details.
+zx_status_t fdio_open_at(zx_handle_t directory, const char* path, uint32_t flags,
+ zx_handle_t request);
+
+// Opens the remote object at the given |path| relative to the root of the namespace with the given
+// |flags| synchronously, and on success, binds that channel to a file descriptor, returned via
+// |out_fd|.
+//
+// Note that unlike fdio_open, this function is synchronous. This is because it produces a file
+// descriptor, which requires synchronously waiting for the open to complete.
+//
+// |flags| is a bit field of |fuchsia.io.OPEN_*|.
+//
+// See |fdio_service_connect| for details.
+zx_status_t fdio_open_fd(const char* path, uint32_t flags, int* out_fd);
+
+// Opens the remote object at the given |path| relative to the given |dir_fd| with the given |flags|
+// synchronously, and on success, binds that channel to a file descriptor, returned via |out_fd|.
+//
+// Note that unlike fdio_open, this function is synchronous. This is because it produces a file
+// descriptor, which requires synchronously waiting for the open to complete.
+//
+// |flags| is a bit field of |fuchsia.io.OPEN_*|.
+//
+// See |fdio_service_connect| fort details.
+zx_status_t fdio_open_fd_at(int dir_fd, const char* path, uint32_t flags, int* out_fd);
+
+// Clone the given |node| asynchronously.
+//
+// |node| must be a channel that implements the |fuchsia.io.Node| protocol.
+//
+// Upon success, returns a handle to a newly created channel whose remote
+// endpoint has been sent to |node| as a request for a clone.
+//
+// The |node| is cloned as readable and writable.
+//
+// Upon failure, returns |ZX_HANDLE_INVALID|.
+zx_handle_t fdio_service_clone(zx_handle_t node);
+
+// Requests that |request| be connected to a clone of the given |node|
+// asynchronously.
+//
+// |node| must be a channel that implements the |fuchsia.io.Node| protocol.
+//
+// |request| must be a channel.
+//
+// Upon success, |request| has been sent to |node| as a request for a clone.
+//
+// The |node| is cloned as readable and writable.
+//
+// # Errors
+//
+// |ZX_ERR_INVALID_ARGS|: |node| or |request| is invalid.
+//
+// Returns transport- and application-level errors associated with
+// |fuchsia.io.Node/Clone|.
+zx_status_t fdio_service_clone_to(zx_handle_t node, zx_handle_t request);
+
+__END_CDECLS
+
+#endif // LIB_FDIO_DIRECTORY_H_
diff --git a/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/fd.h b/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/fd.h
new file mode 100644
index 0000000..37e1a3b
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/fd.h
@@ -0,0 +1,99 @@
+// 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.
+
+#ifndef LIB_FDIO_FD_H_
+#define LIB_FDIO_FD_H_
+
+#include <zircon/types.h>
+#include <zircon/compiler.h>
+
+__BEGIN_CDECLS
+
+// Create a file descriptor from a |zx_handle_t|.
+//
+// The |handle| must be to a channel, socket, vmo, or debuglog object.
+//
+// If the |zx_handle_t| is a channel, then the channel must implement the
+// |fuchsia.io.Node| protocol.
+//
+// For more precise control over which file descriptor is allocated, consider
+// using |fdio_create| and |fdio_bind_to_fd|.
+//
+// Always consumes |handle|.
+//
+// Upon success, |fd_out| contains a file descriptor that can be used to access
+// |handle|.
+//
+// # Errors
+//
+// TODO: Catalog errors.
+zx_status_t fdio_fd_create(zx_handle_t handle, int* fd_out);
+
+// Clones the current working directory.
+//
+// Upon success, |out_handle| contains a handle that represents the current
+// working directory. This handle is suitable for tranferring to another
+// process.
+//
+// # Errors
+//
+// ZX_ERR_NOT_SUPPORTED: The cwd cannot be represented as a |zx_handle_t|.
+//
+// ZX_ERR_BAD_STATE: The cwd cannot be cloned in its current state.
+//
+// ZX_ERR_ACCESS_DENIED: The cwd has insufficient rights to clone the underlying
+// object.
+zx_status_t fdio_cwd_clone(zx_handle_t* out_handle);
+
+// Clones a file descriptor.
+//
+// Upon success, |out_handle| contains a handle that represents the given file
+// descriptor. This handle is suitable for tranferring to another process.
+//
+// |fd| is not modified by this function.
+//
+// # Errors
+//
+// ZX_ERR_INVALID_ARGS: |fd| is not a valid file descriptor.
+//
+// ZX_ERR_NOT_SUPPORTED: |fd| cannot be represented as a |zx_handle_t|.
+//
+// ZX_ERR_BAD_STATE: |fd| cannot be cloned in its current state.
+//
+// ZX_ERR_ACCESS_DENIED: |fd| has insufficient rights to clone the underlying
+// object.
+zx_status_t fdio_fd_clone(int fd, zx_handle_t* out_handle);
+
+// Prepares a file descriptor for transfer to another process.
+//
+// Upon success, |out_handle| contains a handle that represents the given file
+// descriptor, and the given file descriptor has been removed from the file
+// descriptor table for this process.
+//
+// Upon failure, |fd| might or might not be removed from the file descriptor
+// table for this process, depending on the error condition. If this function
+// returns |ZX_ERR_INVALID_ARGS| or |ZX_ERR_UNAVAILABLE|, the file descriptor
+// is not consumed. Otherwise, the file descriptor is consumed.
+//
+// TODO(REVIEW): This function should always consume the file descriptor.
+//
+// # Errors
+//
+// ZX_ERR_INVALID_ARGS: |fd| is not a valid file descriptor.
+//
+// ZX_ERR_UNAVAILABLE: |fd| is busy or has been dup'ed and therefore is
+// referenced by multiple entries in the file descriptor table.
+//
+// ZX_ERR_NOT_SUPPORTED: |fd| cannot be represented as a |zx_handle_t|.
+//
+// ZX_ERR_BAD_STATE: |fd| cannot be transferred to another process in its
+// current state.
+//
+// ZX_ERR_ACCESS_DENIED: |fd| has insufficient rights to clone the underlying
+// object.
+zx_status_t fdio_fd_transfer(int fd, zx_handle_t* out_handle);
+
+__END_CDECLS
+
+#endif // LIB_FDIO_FD_H_
diff --git a/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/fdio.h b/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/fdio.h
new file mode 100644
index 0000000..b0c010b
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/fdio.h
@@ -0,0 +1,114 @@
+// Copyright 2016 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.
+
+#ifndef LIB_FDIO_FDIO_H_
+#define LIB_FDIO_FDIO_H_
+
+#include <zircon/types.h>
+#include <zircon/compiler.h>
+#include <stdint.h>
+#include <unistd.h>
+
+__BEGIN_CDECLS
+
+// An opaque structure that represents the object to which a file descriptor
+// refers.
+typedef struct fdio fdio_t;
+
+// Creates an |fdio_t| from a |zx_handle_t|.
+//
+// The |handle| must be to a channel, socket, vmo, or debuglog object.
+//
+// If the |zx_handle_t| is a channel, then the channel must implement the
+// |fuchsia.io.Node| protocol.
+//
+// Always consumes |handle|.
+//
+// # Errors
+//
+// TODO: Catalog errors.
+zx_status_t fdio_create(zx_handle_t handle, fdio_t** out_io);
+
+// Creates an |fdio_t| that does nothing.
+fdio_t* fdio_null_create(void);
+
+// Install an |fdio_t| in the file descriptor table for this process.
+//
+// If fd >= 0, request a specific fd, and starting_fd is ignored.
+//
+// If fd < 0, request the first available fd >= starting_fd.
+//
+// Upon success, returns the allocated file descriptor. Returns -1 on failure.
+//
+// Upon success, takes ownership of the given reference to the |fdio_t|. That
+// reference is owned by the file descriptor table. Upon failure, the caller
+// retains ownership of that reference. Specifically, the caller is responsible
+// for calling |fdio_unsafe_release| upon failure.
+//
+// TODO(REVIEW): This function should always take ownership of the given
+// |fdio_t| reference.
+int fdio_bind_to_fd(fdio_t* io, int fd, int starting_fd);
+
+// Removes a file descriptor from the file descriptor table for this process.
+//
+// Upon success, the |fdio_t| underlying the file descriptor is returned in
+// |io_out|, and the caller receives ownership of one reference to |fdio_t|.
+// Specifically, the caller is responsible for calling |fdio_unsafe_release|
+// upon success.
+//
+// Upon failure, the file descriptor is not removed from the file descriptor
+// table for this process.
+//
+// TODO(REVIEW): This function should always consume the file descriptor.
+//
+// # Errors
+//
+// ZX_ERR_INVALID_ARGS: |fd| is not a valid file descriptor.
+//
+// ZX_ERR_UNAVAILABLE: |fd| is busy or has been dup'ed and therefore is
+// referenced by multiple entries in the file descriptor table.
+zx_status_t fdio_unbind_from_fd(int fd, fdio_t** io_out);
+
+// If this fd represents a "service" (an rpc channel speaking
+// an unknown fidl protocol or a fuchsia.io.* protocol),
+// this call will return ZX_OK and return the underlying handle.
+// On both success and failure, the fd is effectively closed.
+//
+// ZX_ERR_NOT_SUPPORTED is returned if this fd does not represent
+// a FIDL transport
+//
+// ZX_ERR_UNAVAILABLE is returned if this fd has been dup()'d and
+// duplicates are sharing the FIDL transport
+//
+// TODO: Can also return ZX_ERR_NOT_FOUND. Maybe should be ZX_ERR_INVALID_ARGS?
+// TODO: This function appears to work only for |fuchsia.io| protocols now.
+// Should we rename it to something like |fdio_take_remote|?
+zx_status_t fdio_get_service_handle(int fd, zx_handle_t* out);
+
+// Storage for a ZXIO object.
+//
+// See <lib/zxio/ops.h> for more information.
+typedef struct zxio_storage zxio_storage_t;
+
+// Creates an |fdio_t| that is backed by a |zxio_t|.
+//
+// The |zxio_t| is initialized with a null ops table. The |zxio_storage_t| for
+// the |zxio_t| is returned via |out_storage|. The client can re-initialize the
+// |zxio_storage_t| to customize the behavior of the |zxio_t|.
+//
+// The returned |zxio_storage_t| is valid for the lifetime of the returned
+// |fdio_t|.
+//
+// To bind the |fdio_t| to a file descriptor, use |fdio_bind_to_fd|.
+//
+// Upon success, the caller receives ownership of one reference to |fdio_t|.
+// Specifically, the caller is responsible for calling |fdio_unsafe_release|
+// upon success.
+//
+// Upon failure, returns NULL.
+fdio_t* fdio_zxio_create(zxio_storage_t** out_storage);
+
+__END_CDECLS
+
+#endif // LIB_FDIO_FDIO_H_
diff --git a/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/io.h b/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/io.h
new file mode 100644
index 0000000..6f75f98
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/io.h
@@ -0,0 +1,72 @@
+// Copyright 2016 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.
+
+#ifndef LIB_FDIO_IO_H_
+#define LIB_FDIO_IO_H_
+
+#include <lib/fdio/limits.h>
+#include <limits.h>
+#include <poll.h>
+#include <stdbool.h>
+#include <unistd.h> // for ssize_t
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+// flag on handle args in processargs
+// instructing that this fd should be dup'd to 0/1/2
+// and be used for all of stdio
+#define FDIO_FLAG_USE_FOR_STDIO 0x8000
+
+// events for fdio_wait_fd()
+#define FDIO_EVT_READABLE POLLIN
+#define FDIO_EVT_WRITABLE POLLOUT
+#define FDIO_EVT_ERROR POLLERR
+#define FDIO_EVT_PEER_CLOSED POLLRDHUP
+#define FDIO_EVT_ALL (POLLIN | POLLOUT | POLLERR | POLLRDHUP)
+
+__BEGIN_CDECLS
+
+// wait until one or more events are pending
+zx_status_t fdio_wait_fd(int fd, uint32_t events, uint32_t* pending, zx_time_t deadline);
+
+// create a fd that works with wait APIs (epoll, select, etc.) from a handle
+// and expected signals (signals_in/signals_out correspond to POLLIN/POLLOUT
+// events respectively). The handle will be closed when the fd is closed, unless
+// shared_handle is true.
+int fdio_handle_fd(zx_handle_t h, zx_signals_t signals_in, zx_signals_t signals_out,
+ bool shared_handle);
+
+// Creates a pipe. The first argument returns the file descriptor representing
+// the pipe, and the second argument returns the handle of the socket used to
+// communicate with the pipe.
+//
+// # Errors
+//
+// ZX_ERR_NO_MEMORY: Failed due to a lack of memory.
+//
+// ZX_ERR_NO_RESOURCES: Failed to bind to the file descriptor.
+zx_status_t fdio_pipe_half(int* out_fd, zx_handle_t* out_handle);
+
+// Get a read-only VMO containing the whole contents of the file.
+// This function creates a clone of the underlying VMO when possible, falling
+// back to eagerly reading the contents into a freshly-created VMO.
+zx_status_t fdio_get_vmo_copy(int fd, zx_handle_t* out_vmo);
+
+// Gets a read-only VMO containing a clone of the underlying VMO.
+// This function will fail rather than copying the contents if it cannot clone.
+zx_status_t fdio_get_vmo_clone(int fd, zx_handle_t* out_vmo);
+
+// Get a read-only handle to the exact VMO used by the file system server to
+// represent the file. This function fails if the server does not have an exact
+// VMO representation of the file (e.g., if fdio_get_vmo would need to copy
+// or clone data into a new VMO).
+zx_status_t fdio_get_vmo_exact(int fd, zx_handle_t* out_vmo);
+
+// Get a read + execute VMO containing a clone of the underlying VMO.
+// This function will fail rather than copying the contents if it cannot clone.
+zx_status_t fdio_get_vmo_exec(int fd, zx_handle_t* out_vmo);
+
+__END_CDECLS
+
+#endif // LIB_FDIO_IO_H_
diff --git a/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/limits.h b/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/limits.h
new file mode 100644
index 0000000..e8b6607
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/limits.h
@@ -0,0 +1,22 @@
+// Copyright 2017 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.
+
+#ifndef LIB_FDIO_LIMITS_H_
+#define LIB_FDIO_LIMITS_H_
+
+#include <limits.h>
+
+// Maximum number of fds per process.
+// TODO(ZX-3951): Investigate making the array expand dynamically to avoid
+// having to increase this further.
+#define FDIO_MAX_FD 1024
+
+// fdio_ops_t's read/write are able to do io of
+// at least this size.
+#define FDIO_CHUNK_SIZE 8192
+
+// Maximum length of a filename.
+#define FDIO_MAX_FILENAME NAME_MAX
+
+#endif // LIB_FDIO_LIMITS_H_
diff --git a/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/namespace.h b/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/namespace.h
new file mode 100644
index 0000000..bfcd8b1
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/namespace.h
@@ -0,0 +1,103 @@
+// Copyright 2017 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.
+
+#ifndef LIB_FDIO_NAMESPACE_H_
+#define LIB_FDIO_NAMESPACE_H_
+
+#include <stdint.h>
+
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+typedef struct fdio_namespace fdio_ns_t;
+
+// Create a new, empty namespace
+zx_status_t fdio_ns_create(fdio_ns_t** out);
+
+// Destroy and deallocate a namespace.
+//
+// If the namespace is in-use, it will be destroyed once it is
+// no longer referenced.
+//
+// This function always returns |ZX_OK|.
+zx_status_t fdio_ns_destroy(fdio_ns_t* ns);
+
+// Create a new directory within a namespace, bound to the
+// directory-protocol-compatible handle h
+// The path must be an absolute path, like "/x/y/z", containing
+// no "." nor ".." entries. It is relative to the root of the
+// namespace.
+//
+// Ownership of |h| is transferred to |ns|: it is closed on error.
+zx_status_t fdio_ns_bind(fdio_ns_t* ns, const char* path, zx_handle_t h);
+
+// Unbinds |path| from a namespace, closing the handle within |ns| that
+// corresponds to that path when all references to the node go out of scope.
+//
+// Returns ZX_ERR_NOT_FOUND if |path| is not a remote.
+// Returns ZX_ERR_NOT_SUPPORTED if |path| is the root of the namespace.
+// Returns ZX_ERR_INVALID_ARGS if |path| is otherwise invalid.
+zx_status_t fdio_ns_unbind(fdio_ns_t* ns, const char* path);
+
+// Create a new directory within a namespace, bound to the
+// directory referenced by the file descriptor fd.
+// The path must be an absolute path, like "/x/y/z", containing
+// no "." nor ".." entries. It is relative to the root of the
+// namespace.
+//
+// |fd| is borrowed by this function, but is not closed on success or error.
+// Closing the fd after success does not affect namespace.
+//
+// Failures:
+// ZX_ERR_BAD_STATE: Namespace is already in use and immutable.
+// ZX_ERR_ALREADY_EXISTS: There is already a mounted directory there.
+// ZX_ERR_NOT_SUPPORTED: This path would shadow a mounted directory.
+zx_status_t fdio_ns_bind_fd(fdio_ns_t* ns, const char* path, int fd);
+
+// Open the root directory of the namespace as a file descriptor
+int fdio_ns_opendir(fdio_ns_t* ns);
+
+// chdir to / in the provided namespace
+zx_status_t fdio_ns_chdir(fdio_ns_t* ns);
+
+// Retrieve the fdio "global" namespace (if any).
+zx_status_t fdio_ns_get_installed(fdio_ns_t** ns);
+
+// flat_namespace contains parallel arrays of handles, path names, and types. The number of
+// elements of these arrays is given by |count|. For any given offset i:
+// - handle[i] is the zx_handle_t representing that element in the namespace
+// - path[i] is the user-readable name of that element (e.g., "/bin")
+// - type[i] is a handle info entry as defined in zircon/processargs.h by PA_HND.
+typedef struct fdio_flat_namespace {
+ size_t count;
+ zx_handle_t* handle;
+ uint32_t* type;
+ const char* const* path;
+} fdio_flat_namespace_t;
+
+// On success the caller takes ownership of a fdio_flat_namespace_t
+// containing a flat representation of the exported namespace (the
+// one provided in 'ns' or the active root namespace, respectively.)
+// The handles are CLONEs of the handles in the namespace and also
+// belong to the caller.
+// The whole data structure can be released with fdio_ns_free_flat_ns().
+zx_status_t fdio_ns_export(fdio_ns_t* ns, fdio_flat_namespace_t** out);
+zx_status_t fdio_ns_export_root(fdio_flat_namespace_t** out);
+
+// Attempt to connect to a service through the namespace.
+// The handle is always consumed. It will be closed on error
+// or passed to the remote service on success.
+// The path must be an absolute path starting with / and containing
+// no ".." or "." or empty segments.
+zx_status_t fdio_ns_connect(fdio_ns_t* ns, const char* path, uint32_t zxflags, zx_handle_t h);
+
+// Frees a flat namespace.
+// Closes all handles contained within |ns|.
+void fdio_ns_free_flat_ns(fdio_flat_namespace_t* ns);
+
+__END_CDECLS
+
+#endif // LIB_FDIO_NAMESPACE_H_
diff --git a/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/private.h b/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/private.h
new file mode 100644
index 0000000..be23e5a
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/private.h
@@ -0,0 +1,25 @@
+// Copyright 2017 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.
+
+#ifndef LIB_FDIO_PRIVATE_H_
+#define LIB_FDIO_PRIVATE_H_
+
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+#include <stdint.h>
+
+__BEGIN_CDECLS
+
+// WARNING: These APIs are subject to change
+
+// __fdio_cleanpath cleans an input path, placing the output
+// in out, which is a buffer of at least "PATH_MAX" bytes.
+//
+// 'outlen' returns the length of the path placed in out, and 'is_dir'
+// is set to true if the returned path must be a directory.
+zx_status_t __fdio_cleanpath(const char* in, char* out, size_t* outlen, bool* is_dir);
+
+__END_CDECLS
+
+#endif // LIB_FDIO_PRIVATE_H_
diff --git a/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/spawn.h b/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/spawn.h
new file mode 100644
index 0000000..975c8f5
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/spawn.h
@@ -0,0 +1,267 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FDIO_SPAWN_H_
+#define LIB_FDIO_SPAWN_H_
+
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+__BEGIN_CDECLS
+
+// The |fdio_spawn| and |fdio_spawn_etc| functions allow some or all of the
+// environment of the running process to be shared with the process being
+// spawned.
+
+// Provides the spawned process with the job in which the process was created.
+//
+// The spawned process receives the job using the |PA_JOB_DEFAULT| process
+// argument.
+#define FDIO_SPAWN_CLONE_JOB ((uint32_t)0x0001u)
+
+// Provides the spawned process with the shared library loader resolved via
+// fuchsia.process.Resolver (if resolved), or that which is used by this
+// process.
+//
+// The shared library loader is passed as |PA_LDSVC_LOADER|.
+#define FDIO_SPAWN_DEFAULT_LDSVC ((uint32_t)0x0002u)
+// FDIO_SPAWN_CLONE_LDSVC is the same as FDIO_SPAWN_DEFAULT_LDSVC.
+// TODO(ZX-3031): this name is deprecated.
+#define FDIO_SPAWN_CLONE_LDSVC ((uint32_t)0x0002u)
+
+// Clones the filesystem namespace into the spawned process.
+#define FDIO_SPAWN_CLONE_NAMESPACE ((uint32_t)0x0004u)
+
+// Clones file descriptors 0, 1, and 2 into the spawned process.
+//
+// Skips any of these file descriptors that are closed without generating an
+// error.
+#define FDIO_SPAWN_CLONE_STDIO ((uint32_t)0x0008u)
+
+// Clones the environment into the spawned process.
+#define FDIO_SPAWN_CLONE_ENVIRON ((uint32_t)0x0010u)
+
+// Clones all of the above into the spawned process.
+#define FDIO_SPAWN_CLONE_ALL ((uint32_t)0xFFFFu)
+
+// Spawn a process in the given job.
+//
+// The program for the process is loaded from the given |path| and passed |argv|.
+// The aspects of this process' environment indicated by |flags| are shared with
+// the process. If the target program begins with |#!resolve | then the binary is
+// resolved by url via |fuchsia.process.Resolver|.
+//
+// The |argv| array must be terminated with a null pointer.
+//
+// If |job| is |ZX_HANDLE_INVALID|, then the process is spawned in
+// |zx_job_default()|. Does not take ownership of |job|.
+//
+// Upon success, |process_out| will be a handle to the process.
+//
+// # Errors
+//
+// ZX_ERR_NOT_FOUND: |path| cannot be opened.
+//
+// ZX_ERR_BAD_HANDLE: |path| cannot be opened as an executable VMO.
+//
+// Returns the result of |fdio_spawn_vmo| in all other cases.
+zx_status_t fdio_spawn(zx_handle_t job, uint32_t flags, const char* path, const char* const* argv,
+ zx_handle_t* process_out);
+
+// The |fdio_spawn_etc| function allows the running process to control the file
+// descriptor table in the process being spawned.
+
+// Duplicate a descriptor |local_fd| into |target_fd| in the spawned process.
+//
+// Uses the |fd| entry in the |fdio_spawn_action_t| union.
+#define FDIO_SPAWN_ACTION_CLONE_FD ((uint32_t)0x0001u)
+
+// Transfer local descriptor |local_fd| into |target_fd| in the spawned process.
+//
+// This action will fail if |local_fd| is not a valid |local_fd|, if |local_fd|
+// has been duplicated, if |local_fd| is being used in an io operation, or if
+// |local_fd| does not support this operation.
+//
+// From the point of view of the calling process, the |local_fd| will appear to
+// have been closed, regardless of whether the |fdio_spawn_etc| call succeeds.
+//
+// Uses the |fd| entry in the |fdio_spawn_action_t| union.
+#define FDIO_SPAWN_ACTION_TRANSFER_FD ((uint32_t)0x0002u)
+
+// Add the given entry to the namespace of the spawned process.
+//
+// If |FDIO_SPAWN_CLONE_NAMESPACE| is specified via |flags|, the namespace entry
+// is added to the cloned namespace from the calling process.
+//
+// The namespace entries are added in the order they appear in the action list.
+// If |FDIO_SPAWN_CLONE_NAMESPACE| is specified via |flags|, the entries from
+// the calling process are added before any entries specified with
+// |FDIO_SPAWN_ACTION_ADD_NS_ENTRY|.
+//
+// The spawned process decides how to process and interpret the namespace
+// entries. Typically, the spawned process with disregard duplicate entries
+// (i.e., the first entry for a given name wins) and will ignore nested entries
+// (e.g., |/foo/bar| when |/foo| has already been added to the namespace).
+//
+// To override or replace an entry in the namespace of the calling process,
+// use |fdio_ns_export_root| to export the namespace table of the calling
+// process and construct the namespace for the spawned process explicitly using
+// |FDIO_SPAWN_ACTION_ADD_NS_ENTRY|.
+//
+// The given handle will be closed regardless of whether the |fdio_spawn_etc|
+// call succeeds.
+//
+// Uses the |ns| entry in the |fdio_spawn_action_t| union.
+#define FDIO_SPAWN_ACTION_ADD_NS_ENTRY ((uint32_t)0x0003u)
+
+// Add the given handle to the process arguments of the spawned process.
+//
+// The given handle will be closed regardless of whether the |fdio_spawn_etc|
+// call succeeds.
+//
+// Uses the |h| entry in the |fdio_spawn_action_t| union.
+#define FDIO_SPAWN_ACTION_ADD_HANDLE ((uint32_t)0x0004u)
+
+// Sets the name of the spawned process to the given name.
+//
+// Overrides the default of use the first argument to name the process.
+//
+// Uses the |name| entry in the |fdio_spawn_action_t| union.
+#define FDIO_SPAWN_ACTION_SET_NAME ((uint32_t)0x0005u)
+
+// Shares the given directory by installing it into the namespace of spawned
+// process.
+//
+// Uses the |dir| entry in the |fdio_spawn_action_t| union
+#define FDIO_SPAWN_ACTION_CLONE_DIR ((uint32_t)0x0006u)
+
+// Instructs |fdio_spawn_etc| which actions to take.
+typedef struct fdio_spawn_action fdio_spawn_action_t;
+struct fdio_spawn_action {
+ // The action to take.
+ //
+ // See |FDIO_SPAWN_ACTION_*| above. If |action| is invalid, the action will
+ // be ignored (rather than generate an error).
+ uint32_t action;
+ union {
+ struct {
+ // The file descriptor in this process to clone or transfer.
+ int local_fd;
+
+ // The file descriptor in the spawned process that will receive the
+ // clone or transfer.
+ int target_fd;
+ } fd;
+ struct {
+ // The prefix in which to install the given handle in the namespace
+ // of the spawned process.
+ const char* prefix;
+
+ // The handle to install with the given prefix in the namespace of
+ // the spawned process.
+ zx_handle_t handle;
+ } ns;
+ struct {
+ // The process argument identifier of the handle to pass to the
+ // spawned process.
+ uint32_t id;
+
+ // The handle to pass to the process on startup.
+ zx_handle_t handle;
+ } h;
+ struct {
+ // The name to assign to the spawned process.
+ const char* data;
+ } name;
+ struct {
+ // The directory to share with the spawned process. |prefix| may match zero or more
+ // entries in the callers flat namespace.
+ const char* prefix;
+ } dir;
+ };
+};
+
+// The maximum size for error messages from |fdio_spawn_etc|.
+//
+// Including the null terminator.
+#define FDIO_SPAWN_ERR_MSG_MAX_LENGTH ((size_t)1024u)
+
+// Spawn a process in the given job.
+//
+// The binary for the process is loaded from the given |path| and passed |argv|.
+// The aspects of this process' environment indicated by |clone| are shared with
+// the process.
+//
+// The spawned process is also given |environ| as its environment and the given
+// |actions| are applied when creating the process.
+//
+// The |argv| array must be terminated with a null pointer.
+//
+// If non-null, the |environ| array must be terminated with a null pointer.
+//
+// If non-null, the |err_msg_out| buffer must have space for
+// |FDIO_SPAWN_ERR_MSG_MAX_LENGTH| bytes.
+//
+// If both |FDIO_SPAWN_CLONE_ENVIRON| and |environ| are specified, then the
+// spawned process is given |environ| as its environment. If both
+// |FDIO_SPAWN_CLONE_STDIO| and |actions| that target any of fds 0, 1, and 2 are
+// specified, then the actions that target those fds will control their
+// semantics in the spawned process.
+//
+// If |job| is |ZX_HANDLE_INVALID|, then the process is spawned in
+// |zx_job_default()|. Does not take ownership of |job|.
+//
+// Upon success, |process_out| will be a handle to the process. Upon failure, if
+// |err_msg_out| is not null, an error message will be we written to
+// |err_msg_out|, including a null terminator.
+//
+// # Errors
+//
+// ZX_ERR_NOT_FOUND: |path| cannot be opened.
+//
+// ZX_ERR_BAD_HANDLE: |path| cannot be opened as an executable VMO.
+//
+// Returns the result of |fdio_spawn_vmo| in all other cases.
+zx_status_t fdio_spawn_etc(zx_handle_t job, uint32_t flags, const char* path,
+ const char* const* argv, const char* const* environ, size_t action_count,
+ const fdio_spawn_action_t* actions, zx_handle_t* process_out,
+ char err_msg_out[FDIO_SPAWN_ERR_MSG_MAX_LENGTH]);
+
+// Spawn a process using the given executable in the given job.
+//
+// See |fdio_spawn_etc| for details. Rather than loading the binary for the
+// process from a path, this function receives the binary as the contents of a
+// vmo.
+//
+// Always consumes |executable_vmo|.
+//
+// # Errors
+//
+// ZX_ERR_INVALID_ARGS: any supplied action is invalid, or the process name is unset.
+//
+// ZX_ERR_IO_INVALID: the recursion limit is hit resolving the executable name.
+//
+// ZX_ERR_BAD_HANDLE: |executable_vmo| is not a valid handle.
+//
+// ZX_ERR_WRONG_TYPE: |executable_vmo| is not a VMO handle.
+//
+// ZX_ERR_ACCESS_DENIED: |executable_vmo| is not readable.
+//
+// ZX_ERR_OUT_OF_RANGE: |executable_vmo| is smaller than the resolver prefix.
+//
+// ZX_ERR_INTERNAL: Cannot connect to process launcher.
+//
+// May return other errors.
+zx_status_t fdio_spawn_vmo(zx_handle_t job, uint32_t flags, zx_handle_t executable_vmo,
+ const char* const* argv, const char* const* environ, size_t action_count,
+ const fdio_spawn_action_t* actions, zx_handle_t* process_out,
+ char err_msg_out[FDIO_SPAWN_ERR_MSG_MAX_LENGTH]);
+
+__END_CDECLS
+
+#endif // LIB_FDIO_SPAWN_H_
diff --git a/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/unsafe.h b/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/unsafe.h
new file mode 100644
index 0000000..0ee3fc2
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/unsafe.h
@@ -0,0 +1,68 @@
+// Copyright 2017 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.
+
+#ifndef LIB_FDIO_UNSAFE_H_
+#define LIB_FDIO_UNSAFE_H_
+
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+#include <stdint.h>
+
+__BEGIN_CDECLS
+
+// WARNING: These interfaces exist to allow integration of fdio file
+// descriptors with handle-centric message loops. If used incorrectly
+// they can seriously mess up the state of fdio, fds, etc.
+
+typedef struct fdio fdio_t;
+
+// This looks up a file descriptor, and if it exists,
+// upreferences the fdio_t under it and returns that.
+// fdio_unsafe_release() must be called later to release
+// the reference.
+//
+// If the fd does not exist, it returns NULL
+fdio_t* fdio_unsafe_fd_to_io(int fd);
+
+// Returns the handle corresponding to the underlying fdio,
+// if there is one. Returns ZX_HANDLE_INVALID otherwise.
+//
+// Since this handle is borrowed from the underlying fdio_t, it
+// is unsafe to close it or use it after fdio_unsafe_release is called.
+zx_handle_t fdio_unsafe_borrow_channel(fdio_t* io);
+
+// Releases a reference on a fdio_t. Used to "return"
+// a fdio_t obtained from fdio_unsafe_fd_to_io() when you're
+// done with it.
+void fdio_unsafe_release(fdio_t* io);
+
+// This given a fdio_t, and a bitmask of posix-style events
+// (EPOLLIN, EPOLLOUT, EPOLLERR), this returns a handle that
+// may be waited upon and a bitmask of which signals to
+// wait on for the desired events.
+//
+// The handle belongs to the fdio_t, is not duplicated,
+// and may be closed() by the fdio library but MUST NOT
+// be closed by the caller.
+//
+// If waiting is not supported by this fdio_t, the returned
+// handle is ZX_HANDLE_INVALID.
+//
+// This function is only safe to call on a fdio_t you
+// hold a reference to. It is not required that fdio_unsafe_wait_end() be
+// called after this.
+void fdio_unsafe_wait_begin(fdio_t* io, uint32_t events, zx_handle_t* handle_out,
+ zx_signals_t* signals_out);
+
+// This given a set of signals observed on a handle obtained
+// from fdio_unsafe_wait_begin() returns a set of posix-style events
+// that are indicated.
+//
+// This function is only safe to call on a fdio_t you
+// hold a reference to.
+void fdio_unsafe_wait_end(fdio_t* io, zx_signals_t signals, uint32_t* events_out);
+
+__END_CDECLS
+
+#endif // LIB_FDIO_UNSAFE_H_
diff --git a/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/vfs.h b/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/vfs.h
new file mode 100644
index 0000000..7dfc2f7
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/vfs.h
@@ -0,0 +1,87 @@
+// Copyright 2016 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.
+
+#ifndef LIB_FDIO_VFS_H_
+#define LIB_FDIO_VFS_H_
+
+#include <zircon/compiler.h>
+#include <zircon/listnode.h>
+#include <zircon/processargs.h>
+#include <zircon/types.h>
+
+#include <stdio.h>
+#include <unistd.h> // ssize_t
+
+__BEGIN_CDECLS
+
+// On Fuchsia, the Block Device is transmitted by file descriptor, rather than
+// by path. This can prevent some racy behavior relating to FS start-up.
+#ifdef __Fuchsia__
+#define FS_HANDLE_ROOT_ID PA_HND(PA_USER0, 0)
+#define FS_HANDLE_BLOCK_DEVICE_ID PA_HND(PA_USER0, 1)
+#endif
+
+// POSIX defines st_blocks to be the number of 512 byte blocks allocated
+// to the file. The "blkcnt" field of vnattr attempts to accomplish
+// this same goal, but by indirecting through VNATTR_BLKSIZE, we
+// reserve the right to change this "block size unit" (which is distinct from
+// "blksize", because POSIX) whenever we want.
+#define VNATTR_BLKSIZE 512
+
+typedef struct vnattr {
+ uint32_t valid; // mask of which bits to set for setattr
+ uint32_t mode;
+ uint64_t inode;
+ uint64_t size;
+ uint64_t blksize; // Block size for filesystem I/O
+ uint64_t blkcount; // Number of VNATTR_BLKSIZE byte blocks allocated
+ uint64_t nlink;
+ uint64_t create_time; // posix time (seconds since epoch)
+ uint64_t modify_time; // posix time
+} vnattr_t;
+
+// mask that identifies what fields to set in setattr
+#define ATTR_CTIME 0000001
+#define ATTR_MTIME 0000002
+#define ATTR_ATIME 0000004 // not yet implemented
+
+// bits compatible with POSIX stat
+#define V_TYPE_MASK 0170000
+#define V_TYPE_SOCK 0140000
+#define V_TYPE_LINK 0120000
+#define V_TYPE_FILE 0100000
+#define V_TYPE_BDEV 0060000
+#define V_TYPE_DIR 0040000
+#define V_TYPE_CDEV 0020000
+#define V_TYPE_PIPE 0010000
+
+#define V_ISUID 0004000
+#define V_ISGID 0002000
+#define V_ISVTX 0001000
+#define V_IRWXU 0000700
+#define V_IRUSR 0000400
+#define V_IWUSR 0000200
+#define V_IXUSR 0000100
+#define V_IRWXG 0000070
+#define V_IRGRP 0000040
+#define V_IWGRP 0000020
+#define V_IXGRP 0000010
+#define V_IRWXO 0000007
+#define V_IROTH 0000004
+#define V_IWOTH 0000002
+#define V_IXOTH 0000001
+
+#define VTYPE_TO_DTYPE(mode) (((mode)&V_TYPE_MASK) >> 12)
+#define DTYPE_TO_VTYPE(type) (((type)&15) << 12)
+
+typedef struct vdirent {
+ uint64_t ino;
+ uint8_t size;
+ uint8_t type;
+ char name[0];
+} __PACKED vdirent_t;
+
+__END_CDECLS
+
+#endif // LIB_FDIO_VFS_H_
diff --git a/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/watcher.h b/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/watcher.h
new file mode 100644
index 0000000..7b22691
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fdio/include/lib/fdio/watcher.h
@@ -0,0 +1,45 @@
+// Copyright 2016 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.
+
+#ifndef LIB_FDIO_WATCHER_H_
+#define LIB_FDIO_WATCHER_H_
+
+#include <lib/fdio/io.h>
+#include <zircon/compiler.h>
+
+__BEGIN_CDECLS
+
+typedef zx_status_t (*watchdir_func_t)(int dirfd, int event, const char* fn, void* cookie);
+
+// This event occurs when a file is added or removed, including
+// (for fdio_watch_directory()) files that already exist.
+#define WATCH_EVENT_ADD_FILE 1
+#define WATCH_EVENT_REMOVE_FILE 2
+
+// This event occurs, once, when fdio_watch_directory() runs
+// out of existing files and has to start waiting for new
+// files to be added.
+#define WATCH_EVENT_WAITING 3
+
+// Call the provided callback (cb) for each file in directory
+// and each time a new file is added to the directory.
+//
+// If the callback returns a status other than ZX_OK, watching
+// stops and the callback's status is returned to the caller
+// of fdio_watch_directory.
+//
+// If the deadline expires, ZX_ERR_TIMED_OUT is returned to the
+// caller. A deadline of ZX_TIME_INFINITE will never expire.
+//
+// The callback may use ZX_ERR_STOP as a way to signal to the
+// caller that it wants to stop because it found what it was
+// looking for, etc -- since this error code is not returned
+// by syscalls or public APIs, the callback does not need to
+// worry about it turning up normally.
+
+zx_status_t fdio_watch_directory(int dirfd, watchdir_func_t cb, zx_time_t deadline, void* cookie);
+
+__END_CDECLS
+
+#endif // LIB_FDIO_WATCHER_H_
diff --git a/third_party/fuchsia-sdk/pkg/fdio/meta.json b/third_party/fuchsia-sdk/pkg/fdio/meta.json
new file mode 100644
index 0000000..74d0dfe
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fdio/meta.json
@@ -0,0 +1,35 @@
+{
+ "binaries": {
+ "arm64": {
+ "debug": ".build-id/ff/6959a5ccf92c5b.debug",
+ "dist": "arch/arm64/dist/libfdio.so",
+ "dist_path": "lib/libfdio.so",
+ "link": "arch/arm64/lib/libfdio.so"
+ },
+ "x64": {
+ "debug": ".build-id/91/d1859cac2f8ed7.debug",
+ "dist": "arch/x64/dist/libfdio.so",
+ "dist_path": "lib/libfdio.so",
+ "link": "arch/x64/lib/libfdio.so"
+ }
+ },
+ "deps": [],
+ "format": "shared",
+ "headers": [
+ "pkg/fdio/include/lib/fdio/directory.h",
+ "pkg/fdio/include/lib/fdio/fd.h",
+ "pkg/fdio/include/lib/fdio/fdio.h",
+ "pkg/fdio/include/lib/fdio/io.h",
+ "pkg/fdio/include/lib/fdio/limits.h",
+ "pkg/fdio/include/lib/fdio/namespace.h",
+ "pkg/fdio/include/lib/fdio/private.h",
+ "pkg/fdio/include/lib/fdio/spawn.h",
+ "pkg/fdio/include/lib/fdio/unsafe.h",
+ "pkg/fdio/include/lib/fdio/vfs.h",
+ "pkg/fdio/include/lib/fdio/watcher.h"
+ ],
+ "include_dir": "pkg/fdio/include",
+ "name": "fdio",
+ "root": "pkg/fdio",
+ "type": "cc_prebuilt_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/fidl-async/BUILD.gn b/third_party/fuchsia-sdk/pkg/fidl-async/BUILD.gn
new file mode 100644
index 0000000..b8dd0ba
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl-async/BUILD.gn
@@ -0,0 +1,27 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("fidl-async") {
+ sources = [
+ "bind.c",
+ "include/lib/fidl-async/bind.h",
+ ]
+ include_dirs = [ "include" ]
+ public_deps = [
+ "../async",
+ "../fidl",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fidl-async",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/fidl-async/bind.c b/third_party/fuchsia-sdk/pkg/fidl-async/bind.c
new file mode 100644
index 0000000..1c3147f
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl-async/bind.c
@@ -0,0 +1,152 @@
+// Copyright 2018 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.
+
+#include <lib/async/wait.h>
+#include <lib/fidl-async/bind.h>
+#include <stdlib.h>
+#include <string.h>
+#include <zircon/assert.h>
+#include <zircon/syscalls.h>
+
+typedef struct fidl_binding {
+ async_wait_t wait;
+ fidl_dispatch_t* dispatch;
+ async_dispatcher_t* dispatcher;
+ void* ctx;
+ const void* ops;
+} fidl_binding_t;
+
+typedef struct fidl_connection {
+ fidl_txn_t txn;
+ zx_handle_t channel;
+ zx_txid_t txid;
+ fidl_binding_t* binding;
+} fidl_connection_t;
+
+static zx_status_t fidl_reply(fidl_txn_t* txn, const fidl_msg_t* msg) {
+ fidl_connection_t* conn = (fidl_connection_t*)txn;
+ if (conn->txid == 0u)
+ return ZX_ERR_BAD_STATE;
+ if (msg->num_bytes < sizeof(fidl_message_header_t))
+ return ZX_ERR_INVALID_ARGS;
+ fidl_message_header_t* hdr = (fidl_message_header_t*)msg->bytes;
+ hdr->txid = conn->txid;
+ conn->txid = 0u;
+ return zx_channel_write(conn->channel, 0, msg->bytes, msg->num_bytes, msg->handles,
+ msg->num_handles);
+}
+
+static void fidl_binding_destroy(fidl_binding_t* binding) {
+ zx_handle_close(binding->wait.object);
+ free(binding);
+}
+
+static void fidl_message_handler(async_dispatcher_t* dispatcher, async_wait_t* wait,
+ zx_status_t status, const zx_packet_signal_t* signal) {
+ fidl_binding_t* binding = (fidl_binding_t*)wait;
+ if (status != ZX_OK) {
+ goto shutdown;
+ }
+
+ if (signal->observed & ZX_CHANNEL_READABLE) {
+ char bytes[ZX_CHANNEL_MAX_MSG_BYTES];
+ zx_handle_t handles[ZX_CHANNEL_MAX_MSG_HANDLES];
+ for (uint64_t i = 0; i < signal->count; i++) {
+ fidl_msg_t msg = {
+ .bytes = bytes,
+ .handles = handles,
+ .num_bytes = 0u,
+ .num_handles = 0u,
+ };
+ status = zx_channel_read(wait->object, 0, bytes, handles, ZX_CHANNEL_MAX_MSG_BYTES,
+ ZX_CHANNEL_MAX_MSG_HANDLES, &msg.num_bytes, &msg.num_handles);
+ if (status == ZX_ERR_SHOULD_WAIT) {
+ // This occurs when someone else has read the message we were expecting.
+ goto shutdown;
+ }
+ if (status != ZX_OK || msg.num_bytes < sizeof(fidl_message_header_t)) {
+ goto shutdown;
+ }
+ fidl_message_header_t* hdr = (fidl_message_header_t*)msg.bytes;
+ fidl_connection_t conn = {
+ .txn.reply = fidl_reply,
+ .channel = wait->object,
+ .txid = hdr->txid,
+ .binding = binding,
+ };
+ status = binding->dispatch(binding->ctx, &conn.txn, &msg, binding->ops);
+ switch (status) {
+ case ZX_OK:
+ continue;
+ case ZX_ERR_ASYNC:
+ return;
+ default:
+ goto shutdown;
+ }
+ }
+
+ // Only |status| == ZX_OK will lead here
+ if (async_begin_wait(dispatcher, wait) == ZX_OK) {
+ return;
+ } else {
+ goto shutdown;
+ }
+ } else {
+ ZX_DEBUG_ASSERT(signal->observed & ZX_CHANNEL_PEER_CLOSED);
+ }
+
+shutdown:
+ fidl_binding_destroy(binding);
+}
+
+zx_status_t fidl_bind(async_dispatcher_t* dispatcher, zx_handle_t channel,
+ fidl_dispatch_t* dispatch, void* ctx, const void* ops) {
+ fidl_binding_t* binding = calloc(1, sizeof(fidl_binding_t));
+ binding->wait.handler = fidl_message_handler;
+ binding->wait.object = channel;
+ binding->wait.trigger = ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED;
+ binding->wait.options = 0;
+ binding->dispatch = dispatch;
+ binding->dispatcher = dispatcher;
+ binding->ctx = ctx;
+ binding->ops = ops;
+ zx_status_t status = async_begin_wait(dispatcher, &binding->wait);
+ if (status != ZX_OK) {
+ fidl_binding_destroy(binding);
+ }
+ return status;
+}
+
+typedef struct fidl_async_txn {
+ fidl_connection_t connection;
+} fidl_async_txn_t;
+
+fidl_async_txn_t* fidl_async_txn_create(fidl_txn_t* txn) {
+ fidl_connection_t* connection = (fidl_connection_t*)txn;
+
+ fidl_async_txn_t* async_txn = calloc(1, sizeof(fidl_async_txn_t));
+ memcpy(&async_txn->connection, connection, sizeof(*connection));
+
+ return async_txn;
+}
+
+fidl_txn_t* fidl_async_txn_borrow(fidl_async_txn_t* async_txn) {
+ return &async_txn->connection.txn;
+}
+
+zx_status_t fidl_async_txn_complete(fidl_async_txn_t* async_txn, bool rebind) {
+ zx_status_t status = ZX_OK;
+ if (rebind) {
+ status = async_begin_wait(async_txn->connection.binding->dispatcher,
+ &async_txn->connection.binding->wait);
+ if (status == ZX_OK) {
+ free(async_txn);
+ return ZX_OK;
+ }
+ }
+
+ fidl_binding_destroy(async_txn->connection.binding);
+ free(async_txn);
+ return status;
+}
diff --git a/third_party/fuchsia-sdk/pkg/fidl-async/include/lib/fidl-async/bind.h b/third_party/fuchsia-sdk/pkg/fidl-async/include/lib/fidl-async/bind.h
new file mode 100644
index 0000000..e90b11e
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl-async/include/lib/fidl-async/bind.h
@@ -0,0 +1,100 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_BIND_H_
+#define LIB_FIDL_BIND_H_
+
+#include <lib/async/dispatcher.h>
+#include <zircon/fidl.h>
+
+__BEGIN_CDECLS
+
+// A generic FIDL dispatch function.
+//
+// For FIDL interfaces with [Layout="Simple"], the C backend generates a
+// dispatch function that decodes the |msg| and calls through an |ops| table.
+//
+// This function signature matches the structure of these generated functions
+// but with the type of the |ops| table erased.
+//
+// Example:
+//
+// fidl_bind(dispatcher, channel, (fidl_dispatch_t*)spaceship_SpaceShip_dispatch, ctx, &kOps);
+//
+typedef zx_status_t(fidl_dispatch_t)(void* ctx, fidl_txn_t* txn, fidl_msg_t* msg, const void* ops);
+
+// Binds a |dispatch| function to |channel| using |dispatcher|.
+//
+// This function adds an |async_wait_t| to the given |dispatcher| that waits
+// asynchronously for new messages to arrive on |channel|. When a message
+// arrives, the |dispatch| function is called on one of the threads associated
+// with the |dispatcher| with the |fidl_msg_t| as well as the given |ctx| and
+// |ops|.
+//
+// Typically, the |dispatch| function is generated by the C backend for FIDL
+// interfaces with [Layout="Simple"] (see |fidl_dispatch_t|). These dispatch
+// functions decode the |fidl_msg_t| and call through the |ops| table
+// implementations of the interface's methods, passing along the |ctx| and a
+// |fidl_txn_t| (if the method has a reply message).
+//
+// The |fidl_txn_t| passed to |dispatch| is valid only until |dispatch| returns.
+// If the method has a reply message, the |reply| function on the |fidl_txn_t|
+// object must be called synchronously within the |dispatch| call.
+//
+// If a client wishes to reply to the message asynchronously, |fidl_async_txn_create|
+// must be invoked on |fidl_txn_t|, and ZX_ERR_ASYNC must be returned.
+//
+// Returns whether |fidl_bind| was able to begin waiting on the given |channel|.
+// Upon any error, |channel| is closed and the binding is terminated.
+//
+// The |dispatcher| takes ownership of the channel. Shutting down the |dispatcher|
+// results in |channel| being closed.
+//
+// It is safe to shutdown the dispatcher at any time.
+//
+// It is unsafe to destroy the dispatcher from within a dispatch function.
+// It is unsafe to destroy the dispatcher while any |fidl_async_txn_t| objects
+// are alive.
+zx_status_t fidl_bind(async_dispatcher_t* dispatcher, zx_handle_t channel,
+ fidl_dispatch_t* dispatch, void* ctx, const void* ops);
+
+// An asynchronous FIDL txn.
+//
+// This is an opaque wrapper around |fidl_txn_t| which can extend the lifetime
+// of the object beyond the dispatched function.
+typedef struct fidl_async_txn fidl_async_txn_t;
+
+// Takes ownership of |txn| and allows usage of the txn beyond the currently
+// dispatched function.
+//
+// If this function is invoked within a dispatched function, that function
+// must return ZX_ERR_ASYNC.
+//
+// The result must be destroyed with a call to |fidl_async_txn_complete|.
+fidl_async_txn_t* fidl_async_txn_create(fidl_txn_t* txn);
+
+// Acquire a reference to the |fidl_txn_t| backing this txn object.
+//
+// It is unsafe to use this |fidl_txn_t| after |async_txn| is completed.
+fidl_txn_t* fidl_async_txn_borrow(fidl_async_txn_t* async_txn);
+
+// Destroys an asynchronous transaction created with |fidl_async_txn_create|.
+// This function is intented to be the single termination function.
+//
+// If requested, rebinds the underlying txn against the binding.
+// Returns an error if |rebind| is true and the transaction could not be
+// re-bound.
+//
+// In all cases, the |async_txn| object is consumed.
+//
+// Note: Regardless of whether the client wants to rebind the txn or not,
+// `fidl_async_txn_complete` should be the final function invoked. As such, if
+// this function fails to rebind, there isn't much we can do with the
+// |async_txn| beyond that point, and we therefore prefer to consume it in all
+// cases.
+zx_status_t fidl_async_txn_complete(fidl_async_txn_t* async_txn, bool rebind);
+
+__END_CDECLS
+
+#endif // LIB_FIDL_BIND_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl-async/meta.json b/third_party/fuchsia-sdk/pkg/fidl-async/meta.json
new file mode 100644
index 0000000..c721500
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl-async/meta.json
@@ -0,0 +1,18 @@
+{
+ "banjo_deps": [],
+ "deps": [
+ "async",
+ "fidl"
+ ],
+ "fidl_deps": [],
+ "headers": [
+ "pkg/fidl-async/include/lib/fidl-async/bind.h"
+ ],
+ "include_dir": "pkg/fidl-async/include",
+ "name": "fidl-async",
+ "root": "pkg/fidl-async",
+ "sources": [
+ "pkg/fidl-async/bind.c"
+ ],
+ "type": "cc_source_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/fidl/BUILD.gn b/third_party/fuchsia-sdk/pkg/fidl/BUILD.gn
new file mode 100644
index 0000000..cf37bcf
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl/BUILD.gn
@@ -0,0 +1,27 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("fidl") {
+ sources = [
+ "epitaph.c",
+ "handle_closing.cc",
+ "include/lib/fidl/epitaph.h",
+ ]
+ include_dirs = [ "include" ]
+ public_deps = [
+ "../fidl_base",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fidl",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/fidl/epitaph.c b/third_party/fuchsia-sdk/pkg/fidl/epitaph.c
new file mode 100644
index 0000000..12bc884
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl/epitaph.c
@@ -0,0 +1,22 @@
+// Copyright 2018 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.
+
+#ifdef __Fuchsia__
+
+#include <lib/fidl/epitaph.h>
+#include <lib/fidl/txn_header.h>
+#include <string.h>
+#include <zircon/fidl.h>
+#include <zircon/syscalls.h>
+
+zx_status_t fidl_epitaph_write(zx_handle_t channel, zx_status_t error) {
+ fidl_epitaph_t epitaph;
+ memset(&epitaph, 0, sizeof(epitaph));
+ fidl_init_txn_header(&epitaph.hdr, 0, kFidlOrdinalEpitaph);
+ epitaph.error = error;
+
+ return zx_channel_write(channel, 0, &epitaph, sizeof(epitaph), NULL, 0);
+}
+
+#endif // __Fuchsia__
diff --git a/third_party/fuchsia-sdk/pkg/fidl/handle_closing.cc b/third_party/fuchsia-sdk/pkg/fidl/handle_closing.cc
new file mode 100644
index 0000000..bcb4c05
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl/handle_closing.cc
@@ -0,0 +1,132 @@
+// Copyright 2018 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.
+
+#include <lib/fidl/coding.h>
+#include <lib/fidl/internal.h>
+#include <lib/fidl/visitor.h>
+#include <lib/fidl/walker.h>
+#include <stdalign.h>
+#include <zircon/assert.h>
+#include <zircon/compiler.h>
+#include <zircon/syscalls.h>
+
+#include <cstdint>
+#include <cstdlib>
+#include <limits>
+
+namespace {
+
+struct Position;
+
+struct StartingPoint {
+ uint8_t* const addr;
+ Position ToPosition() const;
+};
+
+struct Position {
+ void* addr;
+ Position operator+(uint32_t size) const {
+ return Position{reinterpret_cast<void*>(reinterpret_cast<uint8_t*>(addr) + size)};
+ }
+ Position& operator+=(uint32_t size) {
+ *this = *this + size;
+ return *this;
+ }
+ template <typename T>
+ constexpr T* Get(StartingPoint start) const {
+ return reinterpret_cast<T*>(addr);
+ }
+};
+
+Position StartingPoint::ToPosition() const { return Position{reinterpret_cast<void*>(addr)}; }
+
+class FidlHandleCloser final
+ : public fidl::Visitor<fidl::MutatingVisitorTrait, StartingPoint, Position> {
+ public:
+ FidlHandleCloser(const char** out_error_msg) : out_error_msg_(out_error_msg) {}
+
+ using StartingPoint = StartingPoint;
+
+ using Position = Position;
+
+ static constexpr bool kContinueAfterConstraintViolation = true;
+
+ static constexpr bool kAllowNonNullableCollectionsToBeAbsent = false;
+
+ Status VisitPointer(Position ptr_position, PointeeType pointee_type,
+ ObjectPointerPointer object_ptr_ptr, uint32_t inline_size,
+ Position* out_position) {
+ // Just follow the pointer into the child object
+ *out_position = Position{*object_ptr_ptr};
+ return Status::kSuccess;
+ }
+
+ Status VisitHandle(Position handle_position, HandlePointer handle, zx_rights_t handle_rights,
+ zx_obj_type_t handle_subtype) {
+ // Close the handle and mark it as invalid
+ zx_handle_close(*handle);
+ *handle = ZX_HANDLE_INVALID;
+ return Status::kSuccess;
+ }
+
+ Status VisitVectorOrStringCount(CountPointer ptr) { return Status::kSuccess; }
+
+ Status VisitInternalPadding(Position padding_position, uint32_t padding_length) {
+ return Status::kSuccess;
+ }
+
+ Status EnterEnvelope(Position envelope_position, EnvelopePointer envelope,
+ const fidl_type_t* payload_type) {
+ return Status::kSuccess;
+ }
+
+ Status LeaveEnvelope(Position envelope_position, EnvelopePointer envelope) {
+ return Status::kSuccess;
+ }
+
+ void OnError(const char* error) { SetError(error); }
+
+ zx_status_t status() const { return status_; }
+
+ private:
+ void SetError(const char* error_msg) {
+ if (status_ == ZX_OK) {
+ status_ = ZX_ERR_INVALID_ARGS;
+ if (out_error_msg_ != nullptr) {
+ *out_error_msg_ = error_msg;
+ }
+ }
+ }
+
+ // Message state passed in to the constructor.
+ const char** const out_error_msg_;
+ zx_status_t status_ = ZX_OK;
+};
+
+} // namespace
+
+zx_status_t fidl_close_handles(const fidl_type_t* type, void* value, const char** out_error_msg) {
+ auto set_error = [&out_error_msg](const char* msg) {
+ if (out_error_msg)
+ *out_error_msg = msg;
+ };
+ if (value == nullptr) {
+ set_error("Cannot close handles for null message");
+ return ZX_ERR_INVALID_ARGS;
+ }
+ if (type == nullptr) {
+ set_error("Cannot close handles for a null fidl type");
+ return ZX_ERR_INVALID_ARGS;
+ }
+
+ FidlHandleCloser handle_closer(out_error_msg);
+ fidl::Walk(handle_closer, type, StartingPoint{reinterpret_cast<uint8_t*>(value)});
+
+ return handle_closer.status();
+}
+
+zx_status_t fidl_close_handles_msg(const fidl_type_t* type, const fidl_msg_t* msg,
+ const char** out_error_msg) {
+ return fidl_close_handles(type, msg->bytes, out_error_msg);
+}
diff --git a/third_party/fuchsia-sdk/pkg/fidl/include/lib/fidl/epitaph.h b/third_party/fuchsia-sdk/pkg/fidl/include/lib/fidl/epitaph.h
new file mode 100644
index 0000000..01b5080
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl/include/lib/fidl/epitaph.h
@@ -0,0 +1,23 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_EPITAPH_H_
+#define LIB_FIDL_EPITAPH_H_
+
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+#ifdef __Fuchsia__
+
+// Sends an epitaph with the given values down the channel.
+// See
+// https://fuchsia.dev/fuchsia-src/development/languages/fidl/languages/c.md#fidl_epitaph_write
+zx_status_t fidl_epitaph_write(zx_handle_t channel, zx_status_t error);
+
+#endif // __Fuchsia__
+
+__END_CDECLS
+
+#endif // LIB_FIDL_EPITAPH_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl/meta.json b/third_party/fuchsia-sdk/pkg/fidl/meta.json
new file mode 100644
index 0000000..bad61c8
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl/meta.json
@@ -0,0 +1,18 @@
+{
+ "banjo_deps": [],
+ "deps": [
+ "fidl_base"
+ ],
+ "fidl_deps": [],
+ "headers": [
+ "pkg/fidl/include/lib/fidl/epitaph.h"
+ ],
+ "include_dir": "pkg/fidl/include",
+ "name": "fidl",
+ "root": "pkg/fidl",
+ "sources": [
+ "pkg/fidl/epitaph.c",
+ "pkg/fidl/handle_closing.cc"
+ ],
+ "type": "cc_source_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/fidl_base/BUILD.gn b/third_party/fuchsia-sdk/pkg/fidl_base/BUILD.gn
new file mode 100644
index 0000000..5daf7e0
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_base/BUILD.gn
@@ -0,0 +1,51 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("fidl_base") {
+ sources = [
+ "builder.cc",
+ "decoding.cc",
+ "encoding.cc",
+ "formatting.cc",
+ "internal.c",
+ "linearizing.cc",
+ "message.cc",
+ "message_buffer.cc",
+ "message_builder.cc",
+ "transformer.cc",
+ "txn_header.c",
+ "validate_string.cc",
+ "validating.cc",
+ "walker.cc",
+ "include/lib/fidl/coding.h",
+ "include/lib/fidl/cpp/builder.h",
+ "include/lib/fidl/cpp/message.h",
+ "include/lib/fidl/cpp/message_buffer.h",
+ "include/lib/fidl/cpp/message_builder.h",
+ "include/lib/fidl/cpp/message_part.h",
+ "include/lib/fidl/envelope_frames.h",
+ "include/lib/fidl/internal.h",
+ "include/lib/fidl/internal_callable_traits.h",
+ "include/lib/fidl/transformer.h",
+ "include/lib/fidl/txn_header.h",
+ "include/lib/fidl/visitor.h",
+ "include/lib/fidl/walker.h",
+ ]
+ include_dirs = [ "include" ]
+ public_deps = [
+ "../fit",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fidl_base",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/fidl_base/builder.cc b/third_party/fuchsia-sdk/pkg/fidl_base/builder.cc
new file mode 100644
index 0000000..4e8359a
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_base/builder.cc
@@ -0,0 +1,56 @@
+// Copyright 2018 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.
+
+#include <lib/fidl/cpp/builder.h>
+#include <lib/fidl/internal.h>
+#include <string.h>
+
+namespace fidl {
+
+Builder::Builder() : capacity_(0u), at_(0u), buffer_(nullptr) {}
+
+Builder::Builder(void* buffer, uint32_t capacity)
+ : capacity_(capacity), at_(0u), buffer_(static_cast<uint8_t*>(buffer)) {}
+
+Builder::~Builder() = default;
+
+Builder::Builder(Builder&& other)
+ : capacity_(other.capacity_), at_(other.at_), buffer_(other.buffer_) {
+ other.Reset(nullptr, 0);
+}
+
+Builder& Builder::operator=(Builder&& other) {
+ if (this != &other) {
+ capacity_ = other.capacity_;
+ at_ = other.at_;
+ buffer_ = other.buffer_;
+ other.Reset(nullptr, 0);
+ }
+ return *this;
+}
+
+void* Builder::Allocate(uint32_t size) {
+ uint64_t limit = FidlAlign(at_ + size);
+ if (limit > capacity_)
+ return nullptr;
+ uint8_t* result = &buffer_[at_];
+ memset(buffer_ + at_, 0, limit - at_);
+ at_ = static_cast<uint32_t>(limit);
+ return result;
+}
+
+BytePart Builder::Finalize() {
+ BytePart bytes(buffer_, capacity_, at_);
+ capacity_ = 0u;
+ at_ = 0u;
+ return bytes;
+}
+
+void Builder::Reset(void* buffer, uint32_t capacity) {
+ buffer_ = static_cast<uint8_t*>(buffer);
+ capacity_ = capacity;
+ at_ = 0u;
+}
+
+} // namespace fidl
diff --git a/third_party/fuchsia-sdk/pkg/fidl_base/decoding.cc b/third_party/fuchsia-sdk/pkg/fidl_base/decoding.cc
new file mode 100644
index 0000000..62a267d
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_base/decoding.cc
@@ -0,0 +1,424 @@
+// Copyright 2017 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.
+
+#include <lib/fidl/coding.h>
+#include <lib/fidl/envelope_frames.h>
+#include <lib/fidl/internal.h>
+#include <lib/fidl/visitor.h>
+#include <lib/fidl/walker.h>
+#include <lib/fit/variant.h>
+#include <stdalign.h>
+#include <zircon/assert.h>
+#include <zircon/compiler.h>
+
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
+
+#ifdef __Fuchsia__
+#include <zircon/syscalls.h>
+#endif
+
+// TODO(kulakowski) Design zx_status_t error values.
+
+namespace {
+
+struct Position;
+
+struct StartingPoint {
+ uint8_t* const addr;
+ Position ToPosition() const;
+};
+
+struct Position {
+ uint32_t offset;
+ Position operator+(uint32_t size) const { return Position{offset + size}; }
+ Position& operator+=(uint32_t size) {
+ offset += size;
+ return *this;
+ }
+ template <typename T>
+ constexpr T* Get(StartingPoint start) const {
+ return reinterpret_cast<T*>(start.addr + offset);
+ }
+};
+
+Position StartingPoint::ToPosition() const { return Position{0}; }
+
+constexpr uintptr_t kAllocPresenceMarker = FIDL_ALLOC_PRESENT;
+constexpr uintptr_t kAllocAbsenceMarker = FIDL_ALLOC_ABSENT;
+
+using EnvelopeState = ::fidl::EnvelopeFrames::EnvelopeState;
+
+constexpr zx_rights_t subtract_rights(zx_rights_t minuend, zx_rights_t subtrahend) {
+ return minuend & ~subtrahend;
+}
+static_assert(subtract_rights(0b011, 0b101) == 0b010, "ensure rights subtraction works correctly");
+
+class FidlDecoder final
+ : public fidl::Visitor<fidl::MutatingVisitorTrait, StartingPoint, Position> {
+ public:
+ FidlDecoder(void* bytes, uint32_t num_bytes, const zx_handle_t* handles, uint32_t num_handles,
+ uint32_t next_out_of_line, const char** out_error_msg)
+ : bytes_(static_cast<uint8_t*>(bytes)),
+ num_bytes_(num_bytes),
+ num_handles_(num_handles),
+ next_out_of_line_(next_out_of_line),
+ out_error_msg_(out_error_msg) {
+ if (handles != nullptr) {
+ handles_ = handles;
+ }
+ }
+
+ FidlDecoder(void* bytes, uint32_t num_bytes, const zx_handle_info_t* handle_infos,
+ uint32_t num_handle_infos, uint32_t next_out_of_line, const char** out_error_msg)
+ : bytes_(static_cast<uint8_t*>(bytes)),
+ num_bytes_(num_bytes),
+ num_handles_(num_handle_infos),
+ next_out_of_line_(next_out_of_line),
+ out_error_msg_(out_error_msg) {
+ if (handle_infos != nullptr) {
+ handles_ = handle_infos;
+ }
+ }
+
+ using StartingPoint = StartingPoint;
+
+ using Position = Position;
+
+ static constexpr bool kContinueAfterConstraintViolation = false;
+
+ static constexpr bool kAllowNonNullableCollectionsToBeAbsent = false;
+
+ Status VisitPointer(Position ptr_position, PointeeType pointee_type,
+ ObjectPointerPointer object_ptr_ptr, uint32_t inline_size,
+ Position* out_position) {
+ if (reinterpret_cast<uintptr_t>(*object_ptr_ptr) != kAllocPresenceMarker) {
+ SetError("decoder encountered invalid pointer");
+ return Status::kConstraintViolationError;
+ }
+ uint32_t new_offset;
+ if (!FidlAddOutOfLine(next_out_of_line_, inline_size, &new_offset)) {
+ SetError("overflow updating out-of-line offset");
+ return Status::kMemoryError;
+ }
+ if (new_offset > num_bytes_) {
+ SetError("message tried to decode more than provided number of bytes");
+ return Status::kMemoryError;
+ }
+ auto status = ValidatePadding(&bytes_[next_out_of_line_ + inline_size],
+ new_offset - next_out_of_line_ - inline_size);
+ if (status != Status::kSuccess) {
+ return status;
+ }
+ *out_position = Position{next_out_of_line_};
+ *object_ptr_ptr = reinterpret_cast<void*>(&bytes_[next_out_of_line_]);
+
+ next_out_of_line_ = new_offset;
+ return Status::kSuccess;
+ }
+
+ Status VisitHandleInfo(Position handle_position, HandlePointer handle,
+ zx_rights_t required_handle_rights,
+ zx_obj_type_t required_handle_subtype) {
+ assert(has_handle_infos());
+ zx_handle_info_t received_handle_info = handle_infos()[handle_idx_];
+ zx_handle_t received_handle = received_handle_info.handle;
+ if (received_handle == ZX_HANDLE_INVALID) {
+ SetError("invalid handle detected in handle table");
+ return Status::kConstraintViolationError;
+ }
+
+ if (required_handle_subtype != received_handle_info.type &&
+ required_handle_subtype != ZX_OBJ_TYPE_NONE) {
+ SetError("decoded handle object type does not match expected type");
+ return Status::kConstraintViolationError;
+ }
+
+ // Special case: ZX_HANDLE_SAME_RIGHTS allows all handles through unchanged.
+ if (required_handle_rights == ZX_RIGHT_SAME_RIGHTS) {
+ *handle = received_handle;
+ handle_idx_++;
+ return Status::kSuccess;
+ }
+ // Check for required rights that are not present on the received handle.
+ if (subtract_rights(required_handle_rights, received_handle_info.rights) != 0) {
+ SetError("decoded handle missing required rights");
+ return Status::kConstraintViolationError;
+ }
+ // Check for non-requested rights that are present on the received handle.
+ if (subtract_rights(received_handle_info.rights, required_handle_rights)) {
+#ifdef __Fuchsia__
+ // The handle has more rights than required. Reduce the rights.
+ zx_status_t status =
+ zx_handle_replace(received_handle_info.handle, required_handle_rights, &received_handle);
+ assert(status != ZX_ERR_BAD_HANDLE);
+ if (status != ZX_OK) {
+ SetError("failed to replace handle");
+ return Status::kConstraintViolationError;
+ }
+#else
+ SetError("more rights received than required");
+ return Status::kConstraintViolationError;
+#endif
+ }
+ *handle = received_handle;
+ handle_idx_++;
+ return Status::kSuccess;
+ }
+
+ Status VisitHandle(Position handle_position, HandlePointer handle,
+ zx_rights_t required_handle_rights, zx_obj_type_t required_handle_subtype) {
+ if (*handle != FIDL_HANDLE_PRESENT) {
+ SetError("message tried to decode a garbage handle");
+ return Status::kConstraintViolationError;
+ }
+ if (handle_idx_ == num_handles_) {
+ SetError("message decoded too many handles");
+ return Status::kConstraintViolationError;
+ }
+
+ if (has_handles()) {
+ if (handles()[handle_idx_] == ZX_HANDLE_INVALID) {
+ SetError("invalid handle detected in handle table");
+ return Status::kConstraintViolationError;
+ }
+ *handle = handles()[handle_idx_];
+ handle_idx_++;
+ return Status::kSuccess;
+ } else if (has_handle_infos()) {
+ return VisitHandleInfo(handle_position, handle, required_handle_rights,
+ required_handle_subtype);
+ } else {
+ SetError("decoder noticed a handle is present but the handle table is empty");
+ *handle = ZX_HANDLE_INVALID;
+ return Status::kConstraintViolationError;
+ }
+ }
+
+ Status VisitVectorOrStringCount(CountPointer ptr) { return Status::kSuccess; }
+
+ Status VisitInternalPadding(Position padding_position, uint32_t padding_length) {
+ auto padding_ptr = padding_position.template Get<const uint8_t>(StartingPoint{bytes_});
+ return ValidatePadding(padding_ptr, padding_length);
+ }
+
+ Status EnterEnvelope(Position envelope_position, EnvelopePointer envelope,
+ const fidl_type_t* payload_type) {
+ if (envelope->presence == kAllocAbsenceMarker &&
+ (envelope->num_bytes != 0 || envelope->num_handles != 0)) {
+ SetError("Envelope has absent data pointer, yet has data and/or handles");
+ return Status::kConstraintViolationError;
+ }
+ if (envelope->presence != kAllocAbsenceMarker && envelope->num_bytes == 0) {
+ SetError("Envelope has present data pointer, but zero byte count");
+ return Status::kConstraintViolationError;
+ }
+ uint32_t expected_handle_count;
+ if (add_overflow(handle_idx_, envelope->num_handles, &expected_handle_count) ||
+ expected_handle_count > num_handles_) {
+ SetError("Envelope has more handles than expected");
+ return Status::kConstraintViolationError;
+ }
+ // Remember the current watermark of bytes and handles, so that after processing
+ // the envelope, we can validate that the claimed num_bytes/num_handles matches the reality.
+ if (!envelope_frames_.Push(EnvelopeState(next_out_of_line_, handle_idx_))) {
+ SetError("Overly deep nested envelopes");
+ return Status::kConstraintViolationError;
+ }
+ // If we do not have the coding table for this payload,
+ // treat it as unknown and close its contained handles
+ if (envelope->presence != kAllocAbsenceMarker && payload_type == nullptr &&
+ envelope->num_handles > 0) {
+ if (has_handles()) {
+ memcpy(&unknown_handles_[unknown_handle_idx_], &handles()[handle_idx_],
+ envelope->num_handles * sizeof(zx_handle_t));
+ handle_idx_ += envelope->num_handles;
+ unknown_handle_idx_ += envelope->num_handles;
+ } else if (has_handle_infos()) {
+ uint32_t end = handle_idx_ + envelope->num_handles;
+ for (; handle_idx_ < end; handle_idx_++, unknown_handle_idx_++) {
+ unknown_handles_[unknown_handle_idx_] = handle_infos()[handle_idx_].handle;
+ }
+ }
+ }
+ return Status::kSuccess;
+ }
+
+ Status LeaveEnvelope(Position envelope_position, EnvelopePointer envelope) {
+ // Now that the envelope has been consumed, check the correctness of the envelope header.
+ auto& starting_state = envelope_frames_.Pop();
+ uint32_t num_bytes = next_out_of_line_ - starting_state.bytes_so_far;
+ uint32_t num_handles = handle_idx_ - starting_state.handles_so_far;
+ if (envelope->num_bytes != num_bytes) {
+ SetError("Envelope num_bytes was mis-sized");
+ return Status::kConstraintViolationError;
+ }
+ if (envelope->num_handles != num_handles) {
+ SetError("Envelope num_handles was mis-sized");
+ return Status::kConstraintViolationError;
+ }
+ return Status::kSuccess;
+ }
+
+ void OnError(const char* error) { SetError(error); }
+
+ zx_status_t status() const { return status_; }
+
+ bool DidConsumeAllBytes() const { return next_out_of_line_ == num_bytes_; }
+
+ bool DidConsumeAllHandles() const { return handle_idx_ == num_handles_; }
+
+ uint32_t unknown_handle_idx() const { return unknown_handle_idx_; }
+
+ const zx_handle_t* unknown_handles() const { return unknown_handles_; }
+
+ private:
+ void SetError(const char* error) {
+ if (status_ != ZX_OK) {
+ return;
+ }
+ status_ = ZX_ERR_INVALID_ARGS;
+ if (!out_error_msg_) {
+ return;
+ }
+ *out_error_msg_ = error;
+ }
+
+ Status ValidatePadding(const uint8_t* padding_ptr, uint32_t padding_length) {
+ for (uint32_t i = 0; i < padding_length; i++) {
+ if (padding_ptr[i] != 0) {
+ SetError("non-zero padding bytes detected during decoding");
+ return Status::kConstraintViolationError;
+ }
+ }
+ return Status::kSuccess;
+ }
+
+ bool has_handles() const { return fit::holds_alternative<const zx_handle_t*>(handles_); }
+ bool has_handle_infos() const {
+ return fit::holds_alternative<const zx_handle_info_t*>(handles_);
+ }
+ const zx_handle_t* handles() const { return fit::get<const zx_handle_t*>(handles_); }
+ const zx_handle_info_t* handle_infos() const {
+ return fit::get<const zx_handle_info_t*>(handles_);
+ }
+
+ // Message state passed in to the constructor.
+ uint8_t* const bytes_;
+ const uint32_t num_bytes_;
+ fit::variant<fit::monostate, const zx_handle_t*, const zx_handle_info_t*> handles_;
+ const uint32_t num_handles_;
+ uint32_t next_out_of_line_;
+ const char** const out_error_msg_;
+
+ // Decoder state
+ zx_status_t status_ = ZX_OK;
+ uint32_t handle_idx_ = 0;
+ uint32_t unknown_handle_idx_ = 0;
+ zx_handle_t unknown_handles_[ZX_CHANNEL_MAX_MSG_HANDLES];
+ fidl::EnvelopeFrames envelope_frames_;
+};
+
+template <typename HandleType>
+zx_status_t fidl_decode_impl(const fidl_type_t* type, void* bytes, uint32_t num_bytes,
+ const HandleType* handles, uint32_t num_handles,
+ const char** out_error_msg,
+ void (*close_handles)(const HandleType*, uint32_t)) {
+ auto drop_all_handles = [&]() { close_handles(handles, num_handles); };
+ auto set_error = [&out_error_msg](const char* msg) {
+ if (out_error_msg)
+ *out_error_msg = msg;
+ };
+ if (handles == nullptr && num_handles != 0) {
+ set_error("Cannot provide non-zero handle count and null handle pointer");
+ return ZX_ERR_INVALID_ARGS;
+ }
+ if (bytes == nullptr) {
+ set_error("Cannot decode null bytes");
+ drop_all_handles();
+ return ZX_ERR_INVALID_ARGS;
+ }
+ if (!FidlIsAligned(reinterpret_cast<uint8_t*>(bytes))) {
+ set_error("Bytes must be aligned to FIDL_ALIGNMENT");
+ drop_all_handles();
+ return ZX_ERR_INVALID_ARGS;
+ }
+
+ uint32_t next_out_of_line;
+ zx_status_t status;
+ if ((status = fidl::StartingOutOfLineOffset(type, num_bytes, &next_out_of_line, out_error_msg)) !=
+ ZX_OK) {
+ drop_all_handles();
+ return status;
+ }
+
+ FidlDecoder decoder(bytes, num_bytes, handles, num_handles, next_out_of_line, out_error_msg);
+ fidl::Walk(decoder, type, StartingPoint{reinterpret_cast<uint8_t*>(bytes)});
+
+ if (decoder.status() != ZX_OK) {
+ drop_all_handles();
+ return decoder.status();
+ }
+ if (!decoder.DidConsumeAllBytes()) {
+ set_error("message did not decode all provided bytes");
+ drop_all_handles();
+ return ZX_ERR_INVALID_ARGS;
+ }
+ if (!decoder.DidConsumeAllHandles()) {
+ set_error("message did not decode all provided handles");
+ drop_all_handles();
+ return ZX_ERR_INVALID_ARGS;
+ }
+
+#ifdef __Fuchsia__
+ if (decoder.unknown_handle_idx() > 0) {
+ (void)zx_handle_close_many(decoder.unknown_handles(), decoder.unknown_handle_idx());
+ }
+#endif
+ return ZX_OK;
+}
+
+void close_handles_op(const zx_handle_t* handles, uint32_t max_idx) {
+#ifdef __Fuchsia__
+ if (handles) {
+ // Return value intentionally ignored. This is best-effort cleanup.
+ zx_handle_close_many(handles, max_idx);
+ }
+#endif
+}
+
+void close_handle_infos_op(const zx_handle_info_t* handle_infos, uint32_t max_idx) {
+#ifdef __Fuchsia__
+ if (handle_infos) {
+ zx_handle_t* handles = reinterpret_cast<zx_handle_t*>(alloca(sizeof(zx_handle_t) * max_idx));
+ for (uint32_t i = 0; i < max_idx; i++) {
+ handles[i] = handle_infos[i].handle;
+ }
+ // Return value intentionally ignored. This is best-effort cleanup.
+ zx_handle_close_many(handles, max_idx);
+ }
+#endif
+}
+
+} // namespace
+
+zx_status_t fidl_decode(const fidl_type_t* type, void* bytes, uint32_t num_bytes,
+ const zx_handle_t* handles, uint32_t num_handles,
+ const char** out_error_msg) {
+ return fidl_decode_impl<zx_handle_t>(type, bytes, num_bytes, handles, num_handles, out_error_msg,
+ close_handles_op);
+}
+
+zx_status_t fidl_decode_etc(const fidl_type_t* type, void* bytes, uint32_t num_bytes,
+ const zx_handle_info_t* handle_infos, uint32_t num_handle_infos,
+ const char** out_error_msg) {
+ return fidl_decode_impl<zx_handle_info_t>(type, bytes, num_bytes, handle_infos, num_handle_infos,
+ out_error_msg, close_handle_infos_op);
+}
+
+zx_status_t fidl_decode_msg(const fidl_type_t* type, fidl_msg_t* msg, const char** out_error_msg) {
+ return fidl_decode(type, msg->bytes, msg->num_bytes, msg->handles, msg->num_handles,
+ out_error_msg);
+}
diff --git a/third_party/fuchsia-sdk/pkg/fidl_base/encoding.cc b/third_party/fuchsia-sdk/pkg/fidl_base/encoding.cc
new file mode 100644
index 0000000..1db4298
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_base/encoding.cc
@@ -0,0 +1,362 @@
+// Copyright 2017 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.
+
+#include <lib/fidl/coding.h>
+#include <lib/fidl/envelope_frames.h>
+#include <lib/fidl/internal.h>
+#include <lib/fidl/visitor.h>
+#include <lib/fidl/walker.h>
+#include <lib/fit/variant.h>
+#include <stdalign.h>
+#include <zircon/assert.h>
+#include <zircon/compiler.h>
+
+#include <cstdint>
+#include <cstdlib>
+#include <limits>
+
+#ifdef __Fuchsia__
+#include <zircon/syscalls.h>
+#endif
+
+// TODO(kulakowski) Design zx_status_t error values.
+
+namespace {
+
+struct Position;
+
+struct StartingPoint {
+ uint8_t* const addr;
+ Position ToPosition() const;
+};
+
+struct Position {
+ uint32_t offset;
+ Position operator+(uint32_t size) const { return Position{offset + size}; }
+ Position& operator+=(uint32_t size) {
+ offset += size;
+ return *this;
+ }
+ template <typename T>
+ constexpr T* Get(StartingPoint start) const {
+ return reinterpret_cast<T*>(start.addr + offset);
+ }
+};
+
+Position StartingPoint::ToPosition() const { return Position{0}; }
+
+using EnvelopeState = ::fidl::EnvelopeFrames::EnvelopeState;
+
+class FidlEncoder final
+ : public fidl::Visitor<fidl::MutatingVisitorTrait, StartingPoint, Position> {
+ public:
+ FidlEncoder(void* bytes, uint32_t num_bytes, zx_handle_t* handles, uint32_t max_handles,
+ uint32_t next_out_of_line, const char** out_error_msg)
+ : bytes_(static_cast<uint8_t*>(bytes)),
+ num_bytes_(num_bytes),
+ max_handles_(max_handles),
+ next_out_of_line_(next_out_of_line),
+ out_error_msg_(out_error_msg) {
+ if (handles != nullptr) {
+ handles_ = handles;
+ }
+ }
+
+ FidlEncoder(void* bytes, uint32_t num_bytes, zx_handle_disposition_t* handle_dispositions,
+ uint32_t max_handle_dispositions, uint32_t next_out_of_line,
+ const char** out_error_msg)
+ : bytes_(static_cast<uint8_t*>(bytes)),
+ num_bytes_(num_bytes),
+ max_handles_(max_handle_dispositions),
+ next_out_of_line_(next_out_of_line),
+ out_error_msg_(out_error_msg) {
+ if (handle_dispositions != nullptr) {
+ handles_ = handle_dispositions;
+ }
+ }
+
+ using StartingPoint = StartingPoint;
+
+ using Position = Position;
+
+ static constexpr bool kContinueAfterConstraintViolation = true;
+
+ static constexpr bool kAllowNonNullableCollectionsToBeAbsent = false;
+
+ Status VisitPointer(Position ptr_position, PointeeType pointee_type,
+ ObjectPointerPointer object_ptr_ptr, uint32_t inline_size,
+ Position* out_position) {
+ // Make sure objects in secondary storage are contiguous
+ if (!ClaimOutOfLineStorage(static_cast<uint32_t>(inline_size), *object_ptr_ptr, out_position)) {
+ return Status::kMemoryError;
+ }
+ // Rewrite pointer as "present" placeholder
+ *object_ptr_ptr = reinterpret_cast<void*>(FIDL_ALLOC_PRESENT);
+ return Status::kSuccess;
+ }
+
+ Status VisitHandle(Position handle_position, HandlePointer handle, zx_rights_t handle_rights,
+ zx_obj_type_t handle_subtype) {
+ if (handle_idx_ == max_handles_) {
+ SetError("message tried to encode too many handles");
+ ThrowAwayHandle(handle);
+ return Status::kConstraintViolationError;
+ }
+
+ if (has_handles()) {
+ handles()[handle_idx_] = *handle;
+ } else if (has_handle_dispositions()) {
+ handle_dispositions()[handle_idx_] = zx_handle_disposition_t{
+ .operation = ZX_HANDLE_OP_MOVE,
+ .handle = *handle,
+ .type = handle_subtype,
+ .rights = handle_rights,
+ .result = ZX_OK,
+ };
+ } else {
+ SetError("did not provide place to store handles");
+ ThrowAwayHandle(handle);
+ return Status::kConstraintViolationError;
+ }
+
+ *handle = FIDL_HANDLE_PRESENT;
+ handle_idx_++;
+ return Status::kSuccess;
+ }
+
+ Status VisitVectorOrStringCount(CountPointer ptr) { return Status::kSuccess; }
+
+ Status VisitInternalPadding(Position padding_position, uint32_t padding_length) {
+ auto padding_ptr = padding_position.template Get<uint8_t>(StartingPoint{bytes_});
+ memset(padding_ptr, 0, padding_length);
+ return Status::kSuccess;
+ }
+
+ Status EnterEnvelope(Position envelope_position, EnvelopePointer envelope,
+ const fidl_type_t* payload_type) {
+ // Validate envelope data/bytes invariants
+ if (envelope->data == nullptr && (envelope->num_bytes != 0 || envelope->num_handles != 0)) {
+ SetError("Envelope has absent data pointer, yet has data and/or handles");
+ return Status::kConstraintViolationError;
+ }
+ if (envelope->data != nullptr && envelope->num_bytes == 0) {
+ SetError("Envelope has present data pointer, but zero byte count");
+ return Status::kConstraintViolationError;
+ }
+ if (envelope->data != nullptr && envelope->num_handles > 0 && payload_type == nullptr) {
+ // Since we do not know the shape of the objects in this envelope,
+ // we cannot move the handles scattered in the message.
+ SetError("Does not know how to encode for this ordinal");
+ return Status::kConstraintViolationError;
+ }
+ // Remember the current watermark of bytes and handles, so that after processing
+ // the envelope, we can validate that the claimed num_bytes/num_handles matches the reality.
+ if (!envelope_frames_.Push(EnvelopeState(next_out_of_line_, handle_idx_))) {
+ SetError("Overly deep nested envelopes");
+ return Status::kConstraintViolationError;
+ }
+ return Status::kSuccess;
+ }
+
+ Status LeaveEnvelope(Position envelope_position, EnvelopePointer envelope) {
+ // Now that the envelope has been consumed, check the correctness of the envelope header.
+ auto& starting_state = envelope_frames_.Pop();
+ uint32_t num_bytes = next_out_of_line_ - starting_state.bytes_so_far;
+ uint32_t num_handles = handle_idx_ - starting_state.handles_so_far;
+ if (envelope->num_bytes != num_bytes) {
+ SetError("Envelope num_bytes was mis-sized");
+ return Status::kConstraintViolationError;
+ }
+ if (envelope->num_handles != num_handles) {
+ SetError("Envelope num_handles was mis-sized");
+ return Status::kConstraintViolationError;
+ }
+ return Status::kSuccess;
+ }
+
+ void OnError(const char* error) { SetError(error); }
+
+ zx_status_t status() const { return status_; }
+
+ uint32_t handle_idx() const { return handle_idx_; }
+
+ bool DidConsumeAllBytes() const { return next_out_of_line_ == num_bytes_; }
+
+ private:
+ void SetError(const char* error) {
+ if (status_ == ZX_OK) {
+ status_ = ZX_ERR_INVALID_ARGS;
+ if (out_error_msg_ != nullptr) {
+ *out_error_msg_ = error;
+ }
+ }
+ }
+
+ void ThrowAwayHandle(HandlePointer handle) {
+#ifdef __Fuchsia__
+ zx_handle_close(*handle);
+#endif
+ *handle = ZX_HANDLE_INVALID;
+ }
+
+ bool ClaimOutOfLineStorage(uint32_t size, void* storage, Position* out_position) {
+ if (storage != &bytes_[next_out_of_line_]) {
+ SetError("noncontiguous out of line storage during encode");
+ return false;
+ }
+ uint32_t new_offset;
+ if (!FidlAddOutOfLine(next_out_of_line_, size, &new_offset)) {
+ SetError("overflow updating out-of-line offset");
+ return false;
+ }
+ if (new_offset > num_bytes_) {
+ SetError("message tried to encode more than provided number of bytes");
+ return false;
+ }
+ // Zero the padding gaps
+ memset(&bytes_[next_out_of_line_ + size], 0, new_offset - next_out_of_line_ - size);
+ *out_position = Position{next_out_of_line_};
+ next_out_of_line_ = new_offset;
+ return true;
+ }
+
+ bool has_handles() const { return fit::holds_alternative<zx_handle_t*>(handles_); }
+ bool has_handle_dispositions() const {
+ return fit::holds_alternative<zx_handle_disposition_t*>(handles_);
+ }
+ zx_handle_t* handles() const { return fit::get<zx_handle_t*>(handles_); }
+ zx_handle_disposition_t* handle_dispositions() const {
+ return fit::get<zx_handle_disposition_t*>(handles_);
+ }
+
+ // Message state passed in to the constructor.
+ uint8_t* const bytes_;
+ const uint32_t num_bytes_;
+ fit::variant<fit::monostate, zx_handle_t*, zx_handle_disposition_t*> handles_;
+ const uint32_t max_handles_;
+ uint32_t next_out_of_line_;
+ const char** const out_error_msg_;
+
+ // Encoder state
+ zx_status_t status_ = ZX_OK;
+ uint32_t handle_idx_ = 0;
+ fidl::EnvelopeFrames envelope_frames_;
+};
+
+template <typename HandleType>
+zx_status_t fidl_encode_impl(const fidl_type_t* type, void* bytes, uint32_t num_bytes,
+ HandleType* handles, uint32_t max_handles,
+ uint32_t* out_actual_handles, const char** out_error_msg,
+ void (*close_handles)(const HandleType*, uint32_t)) {
+ auto set_error = [&out_error_msg](const char* msg) {
+ if (out_error_msg)
+ *out_error_msg = msg;
+ };
+ if (bytes == nullptr) {
+ set_error("Cannot encode null bytes");
+ return ZX_ERR_INVALID_ARGS;
+ }
+ if (!FidlIsAligned(reinterpret_cast<uint8_t*>(bytes))) {
+ set_error("Bytes must be aligned to FIDL_ALIGNMENT");
+ return ZX_ERR_INVALID_ARGS;
+ }
+ if (num_bytes % FIDL_ALIGNMENT != 0) {
+ set_error("num_bytes must be aligned to FIDL_ALIGNMENT");
+ return ZX_ERR_INVALID_ARGS;
+ }
+
+ zx_status_t status;
+ uint32_t next_out_of_line;
+ if ((status = fidl::StartingOutOfLineOffset(type, num_bytes, &next_out_of_line, out_error_msg)) !=
+ ZX_OK) {
+ return status;
+ }
+
+ // Zero region between primary object and next out of line object.
+ size_t primary_size;
+ if ((status = fidl::PrimaryObjectSize(type, &primary_size, out_error_msg)) != ZX_OK) {
+ return status;
+ }
+ memset(reinterpret_cast<uint8_t*>(bytes) + primary_size, 0, next_out_of_line - primary_size);
+
+ FidlEncoder encoder(bytes, num_bytes, handles, max_handles, next_out_of_line, out_error_msg);
+ fidl::Walk(encoder, type, StartingPoint{reinterpret_cast<uint8_t*>(bytes)});
+
+ auto drop_all_handles = [&]() {
+ if (out_actual_handles) {
+ *out_actual_handles = 0;
+ }
+ close_handles(handles, encoder.handle_idx());
+ };
+
+ if (encoder.status() == ZX_OK) {
+ if (!encoder.DidConsumeAllBytes()) {
+ set_error("message did not encode all provided bytes");
+ drop_all_handles();
+ return ZX_ERR_INVALID_ARGS;
+ }
+ if (out_actual_handles == nullptr) {
+ set_error("Cannot encode with null out_actual_handles");
+ drop_all_handles();
+ return ZX_ERR_INVALID_ARGS;
+ }
+ *out_actual_handles = encoder.handle_idx();
+ } else {
+ drop_all_handles();
+ }
+
+ if (handles == nullptr && max_handles != 0) {
+ set_error("Cannot provide non-zero handle count and null handle pointer");
+ // When |handles| is nullptr, handles are closed as part of traversal.
+ return ZX_ERR_INVALID_ARGS;
+ }
+
+ return encoder.status();
+}
+
+void close_handles_op(const zx_handle_t* handles, uint32_t max_idx) {
+#ifdef __Fuchsia__
+ if (handles) {
+ // Return value intentionally ignored. This is best-effort cleanup.
+ zx_handle_close_many(handles, max_idx);
+ }
+#endif
+}
+
+void close_handle_dispositions_op(const zx_handle_disposition_t* handle_dispositions,
+ uint32_t max_idx) {
+#ifdef __Fuchsia__
+ if (handle_dispositions) {
+ zx_handle_t* handles = reinterpret_cast<zx_handle_t*>(alloca(sizeof(zx_handle_t) * max_idx));
+ for (uint32_t i = 0; i < max_idx; i++) {
+ handles[i] = handle_dispositions[i].handle;
+ }
+ // Return value intentionally ignored. This is best-effort cleanup.
+ zx_handle_close_many(handles, max_idx);
+ }
+#endif
+}
+
+} // namespace
+
+zx_status_t fidl_encode(const fidl_type_t* type, void* bytes, uint32_t num_bytes,
+ zx_handle_t* handles, uint32_t max_handles, uint32_t* out_actual_handles,
+ const char** out_error_msg) {
+ return fidl_encode_impl(type, bytes, num_bytes, handles, max_handles, out_actual_handles,
+ out_error_msg, close_handles_op);
+}
+
+zx_status_t fidl_encode_etc(const fidl_type_t* type, void* bytes, uint32_t num_bytes,
+ zx_handle_disposition_t* handle_dispositions,
+ uint32_t max_handle_dispositions, uint32_t* out_actual_handles,
+ const char** out_error_msg) {
+ return fidl_encode_impl(type, bytes, num_bytes, handle_dispositions, max_handle_dispositions,
+ out_actual_handles, out_error_msg, close_handle_dispositions_op);
+}
+
+zx_status_t fidl_encode_msg(const fidl_type_t* type, fidl_msg_t* msg, uint32_t* out_actual_handles,
+ const char** out_error_msg) {
+ return fidl_encode(type, msg->bytes, msg->num_bytes, msg->handles, msg->num_handles,
+ out_actual_handles, out_error_msg);
+}
diff --git a/third_party/fuchsia-sdk/pkg/fidl_base/formatting.cc b/third_party/fuchsia-sdk/pkg/fidl_base/formatting.cc
new file mode 100644
index 0000000..715d943
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_base/formatting.cc
@@ -0,0 +1,284 @@
+// Copyright 2017 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.
+
+#include <inttypes.h>
+#include <lib/fidl/coding.h>
+#include <lib/fidl/internal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <zircon/assert.h>
+#include <zircon/compiler.h>
+
+namespace {
+
+class StringBuilder {
+ public:
+ StringBuilder(char* buffer, size_t capacity) : buffer_(buffer), capacity_(capacity) {}
+
+ size_t length() const { return length_; }
+
+ void Append(const char* data, size_t length) {
+ size_t remaining = capacity_ - length_;
+ if (length > remaining) {
+ length = remaining;
+ }
+ memcpy(buffer_ + length_, data, length);
+ length_ += length;
+ }
+
+ void Append(const char* data) { Append(data, strlen(data)); }
+
+ void AppendPrintf(const char* format, ...) __PRINTFLIKE(2, 3) {
+ va_list ap;
+ va_start(ap, format);
+ AppendVPrintf(format, ap);
+ va_end(ap);
+ }
+
+ void AppendVPrintf(const char* format, va_list ap) {
+ size_t remaining = capacity_ - length_;
+ if (remaining == 0u) {
+ return;
+ }
+ int count = vsnprintf(buffer_ + length_, remaining, format, ap);
+ if (count <= 0) {
+ return;
+ }
+ size_t length = static_cast<size_t>(count);
+ length_ += (length >= remaining ? remaining : length);
+ }
+
+ private:
+ char* buffer_;
+ size_t capacity_;
+ size_t length_ = 0u;
+};
+
+void FormatNullability(StringBuilder* str, FidlNullability nullable) {
+ if (nullable == kFidlNullability_Nullable) {
+ str->Append("?");
+ }
+}
+
+void FormatEnumName(StringBuilder* str, const FidlCodedEnum* coded_enum) {
+ if (coded_enum->name) {
+ str->Append(coded_enum->name);
+ } else {
+ str->Append("enum");
+ }
+}
+
+void FormatBitsName(StringBuilder* str, const FidlCodedBits* coded_bits) {
+ if (coded_bits->name) {
+ str->Append(coded_bits->name);
+ } else {
+ str->Append("bits");
+ }
+}
+
+void FormatStructName(StringBuilder* str, const FidlCodedStruct* coded_struct) {
+ if (coded_struct->name) {
+ str->Append(coded_struct->name);
+ } else {
+ str->Append("struct");
+ }
+}
+
+void FormatUnionName(StringBuilder* str, const FidlCodedUnion* coded_union) {
+ if (coded_union->name) {
+ str->Append(coded_union->name);
+ } else {
+ str->Append("union");
+ }
+}
+
+void FormatTableName(StringBuilder* str, const FidlCodedTable* coded_table) {
+ if (coded_table->name) {
+ str->Append(coded_table->name);
+ } else {
+ str->Append("table");
+ }
+}
+
+void FormatXUnionName(StringBuilder* str, const FidlCodedXUnion* coded_xunion) {
+ if (coded_xunion->name) {
+ str->Append(coded_xunion->name);
+ } else {
+ str->Append("xunion");
+ }
+}
+
+void FormatTypeName(StringBuilder* str, const fidl_type_t* type);
+void FormatElementName(StringBuilder* str, const fidl_type_t* type) {
+ if (type) {
+ FormatTypeName(str, type);
+ } else {
+ // TODO(jeffbrown): Print the actual primitive type name, assuming we
+ // start recording that information in the tables.
+ str->Append("primitive");
+ }
+}
+
+void FormatTypeName(StringBuilder* str, const fidl_type_t* type) {
+ switch (type->type_tag) {
+ case kFidlTypeEnum:
+ FormatEnumName(str, &type->coded_enum);
+ break;
+ case kFidlTypeBits:
+ FormatBitsName(str, &type->coded_bits);
+ break;
+ case kFidlTypeStruct:
+ FormatStructName(str, &type->coded_struct);
+ break;
+ case kFidlTypeStructPointer:
+ FormatStructName(str, type->coded_struct_pointer.struct_type);
+ str->Append("?");
+ break;
+ case kFidlTypeUnion:
+ FormatUnionName(str, &type->coded_union);
+ break;
+ case kFidlTypeUnionPointer:
+ FormatUnionName(str, type->coded_union_pointer.union_type);
+ str->Append("?");
+ break;
+ case kFidlTypeArray:
+ str->Append("array<");
+ FormatElementName(str, type->coded_array.element);
+ str->Append(">");
+ str->AppendPrintf(":%" PRIu32, type->coded_array.array_size / type->coded_array.element_size);
+ break;
+ case kFidlTypeString:
+ str->Append("string");
+ if (type->coded_string.max_size != FIDL_MAX_SIZE) {
+ str->AppendPrintf(":%" PRIu32, type->coded_string.max_size);
+ }
+ FormatNullability(str, type->coded_string.nullable);
+ break;
+ case kFidlTypeHandle:
+ str->Append("handle");
+ if (type->coded_handle.handle_subtype) {
+ str->Append("<");
+ switch (type->coded_handle.handle_subtype) {
+ case ZX_OBJ_TYPE_NONE:
+ str->Append("handle");
+ break;
+ case ZX_OBJ_TYPE_BTI:
+ str->Append("bti");
+ break;
+ case ZX_OBJ_TYPE_CHANNEL:
+ str->Append("channel");
+ break;
+ case ZX_OBJ_TYPE_CLOCK:
+ str->Append("clock");
+ break;
+ case ZX_OBJ_TYPE_EVENT:
+ str->Append("event");
+ break;
+ case ZX_OBJ_TYPE_EVENTPAIR:
+ str->Append("eventpair");
+ break;
+ case ZX_OBJ_TYPE_EXCEPTION:
+ str->Append("exception");
+ break;
+ case ZX_OBJ_TYPE_FIFO:
+ str->Append("fifo");
+ break;
+ case ZX_OBJ_TYPE_GUEST:
+ str->Append("guest");
+ break;
+ case ZX_OBJ_TYPE_INTERRUPT:
+ str->Append("interrupt");
+ break;
+ case ZX_OBJ_TYPE_IOMMU:
+ str->Append("iommu");
+ break;
+ case ZX_OBJ_TYPE_JOB:
+ str->Append("job");
+ break;
+ case ZX_OBJ_TYPE_LOG:
+ str->Append("log");
+ break;
+ case ZX_OBJ_TYPE_PAGER:
+ str->Append("pager");
+ break;
+ case ZX_OBJ_TYPE_PCI_DEVICE:
+ str->Append("pcidevice");
+ break;
+ case ZX_OBJ_TYPE_PMT:
+ str->Append("pmt");
+ break;
+ case ZX_OBJ_TYPE_PORT:
+ str->Append("port");
+ break;
+ case ZX_OBJ_TYPE_PROCESS:
+ str->Append("process");
+ break;
+ case ZX_OBJ_TYPE_PROFILE:
+ str->Append("profile");
+ break;
+ case ZX_OBJ_TYPE_RESOURCE:
+ str->Append("resource");
+ break;
+ case ZX_OBJ_TYPE_SOCKET:
+ str->Append("socket");
+ break;
+ case ZX_OBJ_TYPE_SUSPEND_TOKEN:
+ str->Append("suspendtoken");
+ break;
+ case ZX_OBJ_TYPE_THREAD:
+ str->Append("thread");
+ break;
+ case ZX_OBJ_TYPE_TIMER:
+ str->Append("timer");
+ break;
+ case ZX_OBJ_TYPE_VCPU:
+ str->Append("vcpu");
+ break;
+ case ZX_OBJ_TYPE_VMAR:
+ str->Append("vmar");
+ break;
+ case ZX_OBJ_TYPE_VMO:
+ str->Append("vmo");
+ break;
+ default:
+ str->AppendPrintf("%" PRIu32, type->coded_handle.handle_subtype);
+ break;
+ }
+ str->Append(">");
+ }
+ FormatNullability(str, type->coded_handle.nullable);
+ break;
+ case kFidlTypeVector:
+ str->Append("vector<");
+ FormatElementName(str, type->coded_vector.element);
+ str->Append(">");
+ if (type->coded_vector.max_count != FIDL_MAX_SIZE) {
+ str->AppendPrintf(":%" PRIu32, type->coded_vector.max_count);
+ }
+ FormatNullability(str, type->coded_vector.nullable);
+ break;
+ case kFidlTypeTable:
+ FormatTableName(str, &type->coded_table);
+ break;
+ case kFidlTypeXUnion:
+ FormatXUnionName(str, &type->coded_xunion);
+ break;
+ case kFidlTypePrimitive:
+ ZX_PANIC("unrecognized tag");
+ break;
+ }
+}
+
+} // namespace
+
+size_t fidl_format_type_name(const fidl_type_t* type, char* buffer, size_t capacity) {
+ if (!type || !buffer || !capacity) {
+ return 0u;
+ }
+
+ StringBuilder str(buffer, capacity);
+ FormatTypeName(&str, type);
+ return str.length();
+}
diff --git a/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/coding.h b/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/coding.h
new file mode 100644
index 0000000..8e71e85
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/coding.h
@@ -0,0 +1,102 @@
+// Copyright 2017 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.
+
+#ifndef LIB_FIDL_CODING_H_
+#define LIB_FIDL_CODING_H_
+
+#include <zircon/compiler.h>
+#include <zircon/fidl.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// The maximum recursion depth the fidl encoder or decoder will
+// perform. Each nested aggregate type (structs, unions, arrays,
+// vectors, or tables) counts as one step in the recursion depth.
+#define FIDL_RECURSION_DEPTH 32
+
+// See
+// https://fuchsia.dev/fuchsia-src/development/languages/fidl/languages/c.md#fidl_encode-fidl_encode_msg
+zx_status_t fidl_encode(const fidl_type_t* type, void* bytes, uint32_t num_bytes,
+ zx_handle_t* handles, uint32_t max_handles, uint32_t* out_actual_handles,
+ const char** out_error_msg);
+zx_status_t fidl_encode_etc(const fidl_type_t* type, void* bytes, uint32_t num_bytes,
+ zx_handle_disposition_t* handle_dispositions,
+ uint32_t max_handle_dispositions,
+ uint32_t* out_actual_handle_dispositions, const char** out_error_msg);
+zx_status_t fidl_encode_msg(const fidl_type_t* type, fidl_msg_t* msg, uint32_t* out_actual_handles,
+ const char** out_error_msg);
+
+// See
+// https://fuchsia.dev/fuchsia-src/development/languages/fidl/languages/c.md#fidl_decode-fidl_decode_msg
+zx_status_t fidl_decode(const fidl_type_t* type, void* bytes, uint32_t num_bytes,
+ const zx_handle_t* handles, uint32_t num_handles,
+ const char** error_msg_out);
+zx_status_t fidl_decode_etc(const fidl_type_t* type, void* bytes, uint32_t num_bytes,
+ const zx_handle_info_t* handle_infos, uint32_t num_handle_infos,
+ const char** error_msg_out);
+zx_status_t fidl_decode_msg(const fidl_type_t* type, fidl_msg_t* msg, const char** out_error_msg);
+
+// Validates an encoded message against the given |type|.
+//
+// The |bytes| are not modified.
+zx_status_t fidl_validate(const fidl_type_t* type, const void* bytes, uint32_t num_bytes,
+ uint32_t num_handles, const char** out_error_msg);
+zx_status_t fidl_validate_msg(const fidl_type_t* type, const fidl_msg_t* msg,
+ const char** out_error_msg);
+
+// Validates a FIDL string, and verifies that it is a well-formed UTF-8 code
+// unit sequence. That is respect the UTF-8 encoding, and be formed solely of
+// unicode scalar value, i.e. any Unicode code point except high-surrogate
+// and low-surrogate code points.
+//
+// The |data| is not modified.
+//
+// See also http://www.unicode.org/versions/Unicode13.0.0/ch03.pdf#G7404
+zx_status_t fidl_validate_string(const char* data, uint64_t size);
+
+// Follow an object tree and copy the elements into the provided buffer, such that the
+// resulting buffer is ready for fidl_encode.
+//
+// Starting from the root of the objects specified in |value|,
+// This function assumes that |buffer| points to an uninitialized memory region
+// of size at least |num_bytes|, large enough to hold the entire encoded FIDL message.
+// It will follow pointers and pack secondary objects after the primary
+// as per the wire-format, in their correct order and ensuring alignment.
+// The resulting message length within the buffer is returned via |out_num_bytes|.
+//
+// Upon success, the handles in the object tree will be moved to the buffer;
+// the remaining contents in the original object tree are otherwise untouched.
+// In case of any failure, the handles in the original tree will stay intact.
+//
+// It will return ZX_ERR_BUFFER_TOO_SMALL if the provided buffer is not large enough
+// to hold the entire message.
+zx_status_t fidl_linearize(const fidl_type_t* type, void* value, uint8_t* buffer,
+ uint32_t num_bytes, uint32_t* out_num_bytes, const char** out_error_msg);
+
+// Stores the name of a fidl type into the provided buffer.
+// Truncates the name if it is too long to fit into the buffer.
+// Returns the number of characters written into the buffer.
+//
+// Note: This function does not write a trailing NUL.
+size_t fidl_format_type_name(const fidl_type_t* type, char* buffer, size_t capacity);
+
+// The following functions are only available under Fuchsia.
+
+#ifdef __Fuchsia__
+
+// Traverses a decoded FIDL message starting at |value|, closing all handles within it.
+// If the message is non-contiguous in memory, the function will follow pointers and close handles
+// in any scattered out-of-line objects.
+//
+// Handle values in |value| are replaced with ZX_HANDLE_INVALID.
+zx_status_t fidl_close_handles(const fidl_type_t* type, void* value, const char** out_error_msg);
+zx_status_t fidl_close_handles_msg(const fidl_type_t* type, const fidl_msg_t* msg,
+ const char** out_error_msg);
+
+#endif
+
+__END_CDECLS
+
+#endif // LIB_FIDL_CODING_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/cpp/builder.h b/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/cpp/builder.h
new file mode 100644
index 0000000..01bd943
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/cpp/builder.h
@@ -0,0 +1,104 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_BUILDER_H_
+#define LIB_FIDL_CPP_BUILDER_H_
+
+#include <lib/fidl/cpp/message_part.h>
+#include <stdalign.h>
+#include <stdint.h>
+#include <zircon/compiler.h>
+#include <zircon/fidl.h>
+#include <zircon/types.h>
+
+#include <new> // For placement new.
+
+namespace fidl {
+
+// Builder helps FIDL clients store decoded objects in a buffer.
+//
+// Objects are allocated sequentially in the buffer with appropriate alignment
+// for in-place encoding. The client is responsible for ordering the objects in
+// the buffer appropriately.
+class Builder {
+ public:
+ // Creates a buffer without any storage.
+ Builder();
+
+ // Creates a buffer that stores objects in the given memory.
+ //
+ // The constructed |Builder| object does not take ownership of the given
+ // storage.
+ Builder(void* buffer, uint32_t capacity);
+ ~Builder();
+
+ Builder(const Builder& other) = delete;
+ Builder& operator=(const Builder& other) = delete;
+
+ Builder(Builder&& other);
+ Builder& operator=(Builder&& other);
+
+ // Allocates storage in the buffer of sufficient size to store an object of
+ // type |T|. The object must have alignment constraints that are compatible
+ // with FIDL messages.
+ //
+ // If there is insufficient storage in the builder's buffer, this method
+ // returns nullptr.
+ template <typename T>
+ T* New() {
+ static_assert(alignof(T) <= FIDL_ALIGNMENT, "");
+ static_assert(sizeof(T) <= ZX_CHANNEL_MAX_MSG_BYTES, "");
+ if (void* ptr = Allocate(sizeof(T)))
+ return new (ptr) T;
+ return nullptr;
+ }
+
+ // Allocates storage in the buffer of sufficient size to store |count|
+ // objects of type |T|. The object must have alignment constraints that are
+ // compatible with FIDL messages.
+ //
+ // If there is insufficient storage in the builder's buffer, this method
+ // returns nullptr.
+ template <typename T>
+ T* NewArray(uint32_t count) {
+ static_assert(alignof(T) <= FIDL_ALIGNMENT, "");
+ static_assert(sizeof(T) <= ZX_CHANNEL_MAX_MSG_BYTES, "");
+ if (sizeof(T) * static_cast<uint64_t>(count) > UINT32_MAX)
+ return nullptr;
+ if (void* ptr = Allocate(static_cast<uint32_t>(sizeof(T) * count)))
+ return new (ptr) T[count];
+ return nullptr;
+ }
+
+ // Completes the building and returns a |MesssagePart| containing the
+ // allocated objects.
+ //
+ // The allocated objects are placed in the returned buffer in the order in
+ // which they were allocated, with appropriate alignment for a FIDL message.
+ // The returned buffer's capacity corresponds to the capacity originally
+ // provided to this builder in its constructor.
+ BytePart Finalize();
+
+ // Attaches the given storage to the |Builder|.
+ //
+ // The |Builder| object does not take ownership of the given storage. The
+ // next object will be allocated at the start of the buffer.
+ void Reset(void* buffer, uint32_t capacity);
+
+ protected:
+ uint8_t* buffer() const { return buffer_; }
+ uint32_t capacity() const { return capacity_; }
+
+ private:
+ // Returns |size| bytes of zeroed memory aligned to at least FIDL_ALIGNMENT
+ void* Allocate(uint32_t size);
+
+ uint32_t capacity_;
+ uint32_t at_;
+ uint8_t* buffer_;
+};
+
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_BUILDER_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/cpp/message.h b/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/cpp/message.h
new file mode 100644
index 0000000..1e5bfb6
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/cpp/message.h
@@ -0,0 +1,183 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_MESSAGE_H_
+#define LIB_FIDL_CPP_MESSAGE_H_
+
+#include <lib/fidl/coding.h>
+#include <lib/fidl/cpp/message_part.h>
+#include <lib/fidl/transformer.h>
+#include <lib/fidl/txn_header.h>
+#include <zircon/fidl.h>
+
+#include <vector>
+
+namespace fidl {
+
+const fidl_type_t* get_alt_type(const fidl_type_t* type);
+
+// This is a higher level wrapper around fidl_transform that is responsible for
+// allocating memory for the transformed bytes, then calls the provided callback
+// on the transformed bytes.
+//
+// This function will avoid calling fidl_transform whenever possible by checking
+// the fidl_type_t's contains_union field, and will also stack or heap allocate
+// depending on the possible size of the output bytes.
+zx_status_t FidlTransformWithCallback(
+ fidl_transformation_t transformation, const fidl_type_t* type, const uint8_t* src_bytes,
+ uint32_t src_num_bytes, const char** out_error_msg,
+ const std::function<zx_status_t(const uint8_t* dst_bytes, uint32_t dst_num_bytes)>& callback);
+
+// A FIDL message.
+//
+// A FIDL message has two parts: the bytes and the handles. The bytes are
+// divided into a header (of type fidl_message_header_t) and a payload, which
+// follows the header.
+//
+// A Message object does not own the storage for the message parts.
+class Message {
+ public:
+ // Creates a message without any storage.
+ Message();
+
+ // Creates a message whose storage is backed by |bytes| and |handles|.
+ //
+ // The constructed |Message| object does not take ownership of the given
+ // storage, although does take ownership of zircon handles contained withing
+ // handles.
+ Message(BytePart bytes, HandlePart handles);
+
+ ~Message();
+
+ Message(const Message& other) = delete;
+ Message& operator=(const Message& other) = delete;
+
+ Message(Message&& other);
+ Message& operator=(Message&& other);
+
+ // The header at the start of the message.
+ const fidl_message_header_t& header() const {
+ return *reinterpret_cast<fidl_message_header_t*>(bytes_.data());
+ }
+ fidl_message_header_t& header() {
+ return *reinterpret_cast<fidl_message_header_t*>(bytes_.data());
+ }
+
+ // The transaction ID in the message header.
+ zx_txid_t txid() const { return header().txid; }
+ void set_txid(zx_txid_t txid) { header().txid = txid; }
+
+ // The ordinal in the message header.
+ uint64_t ordinal() const { return header().ordinal; }
+
+ // Whether this message is in a supported version of the wire format.
+ bool is_supported_version() const {
+ return fidl_validate_txn_header(GetBytesAs<fidl_message_header_t>()) == ZX_OK;
+ }
+
+ // The message payload that follows the header.
+ BytePart payload() const {
+ constexpr uint32_t n = sizeof(fidl_message_header_t);
+ return BytePart(bytes_.data() + n, bytes_.capacity() - n, bytes_.actual() - n);
+ }
+
+ // The message bytes interpreted as the given type.
+ template <typename T>
+ T* GetBytesAs() const {
+ return reinterpret_cast<T*>(bytes_.data());
+ }
+
+ // The message payload that follows the header interpreted as the given type.
+ template <typename T>
+ T* GetPayloadAs() const {
+ return reinterpret_cast<T*>(bytes_.data() + sizeof(fidl_message_header_t));
+ }
+
+ // The storage for the bytes of the message.
+ BytePart& bytes() { return bytes_; }
+ const BytePart& bytes() const { return bytes_; }
+ void set_bytes(BytePart bytes) { bytes_ = static_cast<BytePart&&>(bytes); }
+
+ // The storage for the handles of the message.
+ //
+ // When the message is encoded, the handle values are stored in this part of
+ // the message. When the message is decoded, this part of the message is
+ // empty and the handle values are stored in the bytes().
+ HandlePart& handles() { return handles_; }
+ const HandlePart& handles() const { return handles_; }
+
+ // Encodes the message in-place.
+ //
+ // The message must previously have been in a decoded state, for example,
+ // either by being built in a decoded state using a |Builder| or having been
+ // decoded using the |Decode| method.
+ zx_status_t Encode(const fidl_type_t* type, const char** error_msg_out);
+
+ // Decodes the message in-place.
+ //
+ // The message must previously have been in an encoded state, for example,
+ // either by being read from a zx_channel_t or having been encoded using the
+ // |Encode| method.
+ zx_status_t Decode(const fidl_type_t* type, const char** error_msg_out);
+
+ // Validates the message in-place.
+ //
+ // The message must already be in an encoded state, for example, either by
+ // being read from a zx_channel_t or having been created in that state.
+ //
+ // Does not modify the message.
+ zx_status_t Validate(const fidl_type_t* type, const char** error_msg_out) const;
+
+ // Read a message from the given channel.
+ //
+ // The bytes read from the channel are stored in bytes() and the handles
+ // read from the channel are stored in handles(). Existing data in these
+ // buffers is overwritten.
+ zx_status_t Read(zx_handle_t channel, uint32_t flags);
+
+ // Writes a message to the given channel.
+ //
+ // The bytes stored in bytes() are written to the channel and the handles
+ // stored in handles() are written to the channel.
+ //
+ // If this method returns ZX_OK, handles() will be empty because they were
+ // consumed by this operation.
+ zx_status_t Write(zx_handle_t channel, uint32_t flags);
+
+ // Writes a message to the given channel, possibly transforming it first.
+ //
+ // This method is similar to Write, but also takes in a fidl_type_t
+ // to transform the message (if it contains a union) to the v1 wire format
+ // before sending it. Since FIDL bindings automatically do this, the
+ // WriteTransform method is intended primarily for usecases where FIDL messages
+ // must be send manually.
+ zx_status_t WriteTransformV1(zx_handle_t channel, uint32_t flags, const fidl_type_t* type);
+
+ // Issues a synchronous send and receive transaction on the given channel.
+ //
+ // The bytes stored in bytes() are written to the channel and the handles
+ // stored in handles() are written to the channel. The bytes read from the
+ // channel are stored in response->bytes() and the handles read from the
+ // channel are stored in response->handles().
+ //
+ // If this method returns ZX_OK, handles() will be empty because they were
+ // consumed by this operation.
+ zx_status_t Call(zx_handle_t channel, uint32_t flags, zx_time_t deadline, Message* response);
+
+ // Stop tracking the handles in stored in handles(), without closing them.
+ //
+ // Typically, these handles will be extracted during decode or the
+ // message's destructor, so this function will be unnecessary. However,
+ // for clients of ulib/fidl which decode message manually, this function
+ // is necessary to prevent extracted handles from being closed.
+ void ClearHandlesUnsafe();
+
+ private:
+ BytePart bytes_;
+ HandlePart handles_;
+};
+
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_MESSAGE_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/cpp/message_buffer.h b/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/cpp/message_buffer.h
new file mode 100644
index 0000000..f0c0a12
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/cpp/message_buffer.h
@@ -0,0 +1,56 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_MESSAGE_BUFFER_H_
+#define LIB_FIDL_CPP_MESSAGE_BUFFER_H_
+
+#include <lib/fidl/cpp/builder.h>
+#include <lib/fidl/cpp/message.h>
+#include <stdint.h>
+#include <zircon/fidl.h>
+#include <zircon/types.h>
+
+namespace fidl {
+
+class MessageBuffer {
+ public:
+ // Creates a |MessageBuffer| that allocates buffers for message of the
+ // given capacities.
+ //
+ // The buffers are freed when the |MessageBuffer| is destructed.
+ explicit MessageBuffer(uint32_t bytes_capacity = ZX_CHANNEL_MAX_MSG_BYTES,
+ uint32_t handles_capacity = ZX_CHANNEL_MAX_MSG_HANDLES);
+
+ // The memory that backs the message is freed by this destructor.
+ ~MessageBuffer();
+
+ // The memory in which bytes can be stored in this buffer.
+ uint8_t* bytes() const { return buffer_; }
+
+ // The total number of bytes that can be stored in this buffer.
+ uint32_t bytes_capacity() const { return bytes_capacity_; }
+
+ // The memory in which handles can be stored in this buffer.
+ zx_handle_t* handles() const;
+
+ // The total number of handles that can be stored in this buffer.
+ uint32_t handles_capacity() const { return handles_capacity_; }
+
+ // Creates a |Message| that is backed by the memory in this buffer.
+ //
+ // The returned |Message| contains no bytes or handles.
+ Message CreateEmptyMessage();
+
+ // Creates a |Builder| that is backed by the memory in this buffer.
+ Builder CreateBuilder();
+
+ private:
+ uint8_t* const buffer_;
+ const uint32_t bytes_capacity_;
+ const uint32_t handles_capacity_;
+};
+
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_MESSAGE_BUFFER_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/cpp/message_builder.h b/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/cpp/message_builder.h
new file mode 100644
index 0000000..5664325
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/cpp/message_builder.h
@@ -0,0 +1,74 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_MESSAGE_BUILDER_H_
+#define LIB_FIDL_CPP_MESSAGE_BUILDER_H_
+
+#include <lib/fidl/cpp/builder.h>
+#include <lib/fidl/cpp/message.h>
+#include <lib/fidl/cpp/message_buffer.h>
+#include <stdint.h>
+#include <zircon/fidl.h>
+#include <zircon/types.h>
+
+namespace fidl {
+
+// A builder for FIDL messages that owns the memory for the message.
+//
+// A |MessageBuilder| is a |Builder| that uses the heap to back the memory for
+// the message. If you wish to manage the memory yourself, you can use |Builder|
+// and |Message| directly.
+//
+// Upon creation, the |MessageBuilder| creates a FIDL message header, which you
+// can modify using |header()|.
+class MessageBuilder : public Builder {
+ public:
+ // Creates a |MessageBuilder| for the given |type| that allocates buffers
+ // for message of the given capacities.
+ //
+ // The bytes buffer is initialied by adding a |fidl_message_header_t|
+ // header.
+ //
+ // The buffers are freed when the |MessageBuilder| is destructed.
+ explicit MessageBuilder(const fidl_type_t* type,
+ uint32_t bytes_capacity = ZX_CHANNEL_MAX_MSG_BYTES,
+ uint32_t handles_capacity = ZX_CHANNEL_MAX_MSG_HANDLES);
+
+ // The memory that backs the message is freed by this destructor.
+ ~MessageBuilder();
+
+ // The type of the message payload this object is building.
+ const fidl_type_t* type() const { return type_; }
+
+ // The header for the message.
+ //
+ // The message header is allocated by the |MessageBuilder| itself.
+ fidl_message_header_t* header() const {
+ return reinterpret_cast<fidl_message_header_t*>(buffer());
+ }
+
+ // Encodes a message of the given |type|.
+ //
+ // The memory that backs the message returned by this function is owned by
+ // the |MessageBuilder|, which means the |MessageBuilder| must remain alive
+ // as long as the |Message| object is in use.
+ //
+ // The |message| parameter might be modified even if this method returns an
+ // error.
+ zx_status_t Encode(Message* message_out, const char** error_msg_out);
+
+ // Resets all the data in the |MessageBuffer|.
+ //
+ // The underlying buffer is retained and reused. The next object will be
+ // allocated at the start of the buffer.
+ void Reset();
+
+ private:
+ const fidl_type_t* type_;
+ MessageBuffer buffer_;
+};
+
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_MESSAGE_BUILDER_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/cpp/message_part.h b/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/cpp/message_part.h
new file mode 100644
index 0000000..7ebb351
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/cpp/message_part.h
@@ -0,0 +1,114 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_MESSAGE_PART_H_
+#define LIB_FIDL_CPP_MESSAGE_PART_H_
+
+#include <stdint.h>
+#include <string.h>
+#include <zircon/types.h>
+
+namespace fidl {
+
+// Part of a FIDL message.
+//
+// A FIDL message has two parts: the bytes and the handles. This class is used
+// to represent both kinds of parts.
+//
+// Each part of the message has a data buffer, which contains the actual data
+// for that part of the message, a capacity for that buffer, and the actual
+// amount of data stored in the buffer, which might be less that the capacity if
+// the buffer is not completely full.
+template <typename T>
+class MessagePart {
+ public:
+ using value_type = T;
+ using const_iterator = const T*;
+
+ // A message part with no storage.
+ MessagePart() : data_(nullptr), capacity_(0u), actual_(0u) {}
+
+ // A message part that uses the given storage.
+ //
+ // The constructed |MessagePart| object does not take ownership of the given
+ // storage.
+ MessagePart(T* data, uint32_t capacity, uint32_t actual = 0u)
+ : data_(data), capacity_(capacity), actual_(actual) {}
+
+ MessagePart(const MessagePart& other) = delete;
+ MessagePart& operator=(const MessagePart& other) = delete;
+
+ MessagePart(MessagePart&& other)
+ : data_(other.data_), capacity_(other.capacity_), actual_(other.actual_) {
+ other.data_ = nullptr;
+ other.capacity_ = 0u;
+ other.actual_ = 0u;
+ }
+
+ MessagePart& operator=(MessagePart&& other) {
+ if (this == &other)
+ return *this;
+ data_ = other.data_;
+ capacity_ = other.capacity_;
+ actual_ = other.actual_;
+ other.data_ = nullptr;
+ other.capacity_ = 0u;
+ other.actual_ = 0u;
+ return *this;
+ }
+
+ // Constructs a full |MessagePart| wrapping an array.
+ // The array is assumed to be initialized with data, such that |actual()|
+ // will match exactly the length of the array.
+ template <size_t N>
+ static MessagePart WrapFull(T (&array)[N]) {
+ return MessagePart(array, N, N);
+ }
+
+ // Constructs an empty |MessagePart| wrapping an array.
+ // The array is assumed to be uninitialized, hence |actual()| is set to 0.
+ template <size_t N>
+ static MessagePart WrapEmpty(T (&array)[N]) {
+ return MessagePart(array, N, 0);
+ }
+
+ // The data stored in this part of the message.
+ T* data() const { return data_; }
+
+ // The total amount of storage available for this part of the message.
+ //
+ // This part of the message might not actually use all of this storage. To
+ // determine how much storage is actually being used, see |actual()|.
+ uint32_t capacity() const { return capacity_; }
+
+ // The amount of storage that is actually being used for this part of the
+ // message.
+ //
+ // There might be more storage available than is actually being used. To
+ // determine how much storage is available, see |capacity()|.
+ uint32_t actual() const { return actual_; }
+ void set_actual(uint32_t actual) { actual_ = actual; }
+
+ T* begin() { return data_; }
+ const T* begin() const { return data_; }
+ const T* cbegin() const { return data_; }
+
+ T* end() { return data_ + actual_; }
+ const T* end() const { return data_ + actual_; }
+ const T* cend() const { return data_ + actual_; }
+
+ size_t size() const { return actual_; }
+
+ private:
+ T* data_;
+ uint32_t capacity_;
+ uint32_t actual_;
+};
+
+using BytePart = MessagePart<uint8_t>;
+using HandlePart = MessagePart<zx_handle_t>;
+
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_MESSAGE_PART_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/envelope_frames.h b/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/envelope_frames.h
new file mode 100644
index 0000000..09bc519
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/envelope_frames.h
@@ -0,0 +1,56 @@
+// 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.
+
+#ifndef LIB_FIDL_ENVELOPE_FRAMES_H_
+#define LIB_FIDL_ENVELOPE_FRAMES_H_
+
+#include <lib/fidl/coding.h>
+#include <stdalign.h>
+#include <zircon/assert.h>
+#include <zircon/compiler.h>
+
+#include <cstdint>
+#include <cstdlib>
+
+namespace fidl {
+
+class EnvelopeFrames {
+ public:
+ struct EnvelopeState {
+ uint32_t bytes_so_far;
+ uint32_t handles_so_far;
+
+ EnvelopeState(uint32_t bytes_so_far, uint32_t handles_so_far)
+ : bytes_so_far(bytes_so_far), handles_so_far(handles_so_far) {}
+
+ private:
+ // Default constructor used by |EnvelopeFrames| to avoid unnecessarily zeroing
+ // the |envelope_states_| array.
+ EnvelopeState() = default;
+ friend class EnvelopeFrames;
+ };
+
+ const EnvelopeState& Pop() {
+ ZX_ASSERT(envelope_depth_ != 0);
+ envelope_depth_--;
+ return envelope_states_[envelope_depth_];
+ }
+
+ bool Push(const EnvelopeState& state) {
+ if (envelope_depth_ == FIDL_RECURSION_DEPTH) {
+ return false;
+ }
+ envelope_states_[envelope_depth_] = state;
+ envelope_depth_++;
+ return true;
+ }
+
+ private:
+ uint32_t envelope_depth_ = 0;
+ EnvelopeState envelope_states_[FIDL_RECURSION_DEPTH];
+};
+
+} // namespace fidl
+
+#endif // LIB_FIDL_ENVELOPE_FRAMES_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/internal.h b/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/internal.h
new file mode 100644
index 0000000..68de99f
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/internal.h
@@ -0,0 +1,290 @@
+// Copyright 2017 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.
+
+#ifndef LIB_FIDL_INTERNAL_H_
+#define LIB_FIDL_INTERNAL_H_
+
+#include <assert.h>
+#include <lib/fidl/coding.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <zircon/syscalls/object.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// All sizes here are given as uint32_t. Fidl message sizes are bounded to well below UINT32_MAX.
+// This also applies to arrays and vectors. For arrays, element_count * element_size will always fit
+// with 32 bits. For vectors, max_count * element_size will always fit within 32 bits.
+
+// Pointers to other type tables within a type are always nonnull, with the exception of vectors.
+// In that case, a null pointer indicates that the element type of the vector has no interesting
+// information to be decoded (i.e. no pointers or handles). The vector type still needs to be
+// emitted as it contains the information about the size of its secondary object. Contrast this with
+// arrays: being inline, ones with no interesting coding information can be elided, just like a
+// uint32 field in a struct is elided.
+
+typedef bool FidlNullability;
+static const bool kFidlNullability_Nonnullable = false;
+static const bool kFidlNullability_Nullable = true;
+
+typedef bool FidlStrictness;
+static const bool kFidlStrictness_Flexible = false;
+static const bool kFidlStrictness_Strict = true;
+
+// TODO(fxb/42792): Remove either this FidlAlign function or the FIDL_ALIGN macro in zircon/fidl.h.
+// clang-format off
+#ifdef __cplusplus
+constexpr
+#endif // __cplusplus
+static inline uint64_t FidlAlign(uint32_t offset) {
+ const uint64_t alignment_mask = FIDL_ALIGNMENT - 1;
+ return (offset + alignment_mask) & ~alignment_mask;
+}
+// clang-format on
+
+// Determine if the pointer is aligned to |FIDL_ALIGNMENT|.
+static inline bool FidlIsAligned(const uint8_t* ptr) {
+ uintptr_t uintptr = (uintptr_t)(ptr);
+ const uintptr_t kAlignment = FIDL_ALIGNMENT;
+ return uintptr % kAlignment == 0;
+}
+
+// Add |size| to out-of-line |offset|, maintaining alignment. For example, a pointer to a struct
+// that is 4 bytes still needs to advance the next out-of-line offset by 8 to maintain
+// the aligned-to-FIDL_ALIGNMENT property.
+// Returns false on overflow. Otherwise, resulting offset is stored in |out_offset|.
+static inline bool FidlAddOutOfLine(uint32_t offset, uint32_t size, uint32_t* out_offset) {
+ const uint32_t kMask = FIDL_ALIGNMENT - 1;
+ uint32_t new_offset = offset;
+ if (add_overflow(new_offset, size, &new_offset) || add_overflow(new_offset, kMask, &new_offset)) {
+ return false;
+ }
+ new_offset &= ~kMask;
+ *out_offset = new_offset;
+ return true;
+}
+
+struct FidlStructField {
+ const fidl_type_t* type;
+
+ // If |type| is not nullptr, |offset| stores the offset of the struct member.
+ // If |type| is nullptr, |padding_offset| stores the offset where padding starts.
+ union {
+ uint32_t offset;
+ uint32_t padding_offset;
+ };
+ uint8_t padding;
+
+#ifdef __cplusplus
+ constexpr FidlStructField(const fidl_type* type, uint32_t offset, uint8_t padding)
+ : type(type), offset(offset), padding(padding) {}
+#endif // __cplusplus
+};
+
+struct FidlUnionField {
+ const fidl_type_t* type;
+ uint32_t padding;
+ uint32_t xunion_ordinal;
+};
+
+struct FidlTableField {
+ const fidl_type_t* type;
+ uint32_t ordinal;
+};
+
+struct FidlXUnionField {
+ const fidl_type_t* type;
+ uint32_t ordinal;
+ uint32_t hashed_ordinal;
+ uint32_t explicit_ordinal;
+};
+
+// TODO(fxb/42793): Consider starting enum values for FidlTypeTag from 1, not 0.
+typedef uint32_t FidlTypeTag;
+static const uint32_t kFidlTypePrimitive = 0;
+static const uint32_t kFidlTypeEnum = 1;
+static const uint32_t kFidlTypeBits = 2;
+static const uint32_t kFidlTypeStruct = 3;
+static const uint32_t kFidlTypeStructPointer = 4;
+static const uint32_t kFidlTypeUnion = 5;
+static const uint32_t kFidlTypeUnionPointer = 6;
+static const uint32_t kFidlTypeArray = 7;
+static const uint32_t kFidlTypeString = 8;
+static const uint32_t kFidlTypeHandle = 9;
+static const uint32_t kFidlTypeVector = 10;
+static const uint32_t kFidlTypeTable = 11;
+static const uint32_t kFidlTypeXUnion = 12;
+
+// TODO(fxb/42793): Consider starting enum values for FidlCodedPrimitive from 1, not 0.
+typedef uint32_t FidlCodedPrimitive;
+static const uint32_t kFidlCodedPrimitive_Bool = 0;
+static const uint32_t kFidlCodedPrimitive_Int8 = 1;
+static const uint32_t kFidlCodedPrimitive_Int16 = 2;
+static const uint32_t kFidlCodedPrimitive_Int32 = 3;
+static const uint32_t kFidlCodedPrimitive_Int64 = 4;
+static const uint32_t kFidlCodedPrimitive_Uint8 = 5;
+static const uint32_t kFidlCodedPrimitive_Uint16 = 6;
+static const uint32_t kFidlCodedPrimitive_Uint32 = 7;
+static const uint32_t kFidlCodedPrimitive_Uint64 = 8;
+static const uint32_t kFidlCodedPrimitive_Float32 = 9;
+static const uint32_t kFidlCodedPrimitive_Float64 = 10;
+
+typedef bool (*EnumValidationPredicate)(uint64_t);
+
+struct FidlCodedEnum {
+ const FidlCodedPrimitive underlying_type;
+ const EnumValidationPredicate validate;
+ const char* name; // may be nullptr if omitted at compile time
+};
+
+struct FidlCodedBits {
+ const FidlCodedPrimitive underlying_type;
+ const uint64_t mask;
+ const char* name; // may be nullptr if omitted at compile time
+};
+
+// Though the |size| is implied by the fields, computing that information is not
+// the purview of this library. It's easier for the compiler to stash it.
+struct FidlCodedStruct {
+ const struct FidlStructField* const fields;
+ const uint32_t field_count;
+ const uint32_t size;
+ // The max_out_of_line and contains_union fields are only used by the HLCPP bindings for
+ // optimizations when validating v1 bytes of a transactional message before sending.
+ const uint32_t max_out_of_line;
+ const bool contains_union;
+ const char* name; // may be nullptr if omitted at compile time
+
+ // Pointer to the alternate ("alt") version of this FidlCodedStruct, which is the v1 version of
+ // the struct if this is the old struct; or the old version of the struct if this is the v1
+ // version.
+ const fidl_type_t* const alt_type;
+};
+
+struct FidlCodedStructPointer {
+ const struct FidlCodedStruct* const struct_type;
+};
+
+struct FidlCodedTable {
+ const struct FidlTableField* const fields;
+ const uint32_t field_count;
+ const char* name; // may be nullptr if omitted at compile time
+};
+
+// On-the-wire unions begin with a tag which is an index into |fields|.
+// |data_offset| is the offset of the data in the wire format (tag + padding).
+struct FidlCodedUnion {
+ const struct FidlUnionField* const fields;
+ const uint32_t field_count;
+ const uint32_t data_offset;
+ const uint32_t size;
+ const char* name; // may be nullptr if omitted at compile time
+
+ // Pointer to the alternate ("alt") version of this FidlCodedUnion, which is a FidlCodedXUnion
+ // if this is an old wire-format union.
+ const fidl_type_t* const alt_type;
+};
+
+struct FidlCodedUnionPointer {
+ const struct FidlCodedUnion* const union_type;
+};
+
+struct FidlCodedXUnion {
+ const uint32_t field_count;
+ const struct FidlXUnionField* const fields;
+ const FidlNullability nullable;
+ const char* name; // may be nullptr if omitted at compile time
+ const FidlStrictness strictness;
+
+ // Pointer to the alternate ("alt") version of this FidlCodedXUnion, which a FidlCodedUnion if
+ // this is a static union, or the same FidlCodedXUnion if this is an extensible union.
+ const fidl_type_t* const alt_type;
+};
+
+// An array is essentially a struct with |array_size / element_size| of the same field, named at
+// |element|.
+struct FidlCodedArray {
+ const fidl_type_t* const element;
+ const uint32_t array_size;
+ const uint32_t element_size;
+
+ // Pointer to the alternate ("alt") version of this FidlCodedArray, which is the v1 version of the
+ // array if this is for the old wire format; or the old version of the array if this is the v1
+ // version.
+ const fidl_type_t* const alt_type;
+};
+
+// TODO(fxb/39388): Switch to using this more ergonomic coding table for arrays.
+struct FidlCodedArrayNew {
+ const fidl_type_t* const element;
+ const uint64_t element_count;
+ const uint32_t element_size;
+ const uint32_t element_padding;
+
+ const fidl_type_t* const alt_type;
+};
+
+struct FidlCodedHandle {
+ const zx_obj_type_t handle_subtype;
+ const zx_rights_t handle_rights;
+ const FidlNullability nullable;
+
+ static_assert(ZX_OBJ_TYPE_UPPER_BOUND <= UINT32_MAX, "");
+};
+
+struct FidlCodedString {
+ const uint32_t max_size;
+ const FidlNullability nullable;
+};
+
+// Note that |max_count * element_size| is guaranteed to fit into a uint32_t. Unlike other types,
+// the |element| pointer may be null. This occurs when the element type contains no interesting bits
+// (i.e. pointers or handles).
+struct FidlCodedVector {
+ const fidl_type_t* const element;
+ const uint32_t max_count;
+ const uint32_t element_size;
+ const FidlNullability nullable;
+
+ // Pointer to the alternate ("alt") version of this FidlCodedVector, which is the v1 version of
+ // the vector if this is the old wire format; or the old version of the vector if this is the v1
+ // version.
+ const fidl_type_t* const alt_type;
+};
+
+struct fidl_type {
+ const FidlTypeTag type_tag;
+ const union {
+ const FidlCodedPrimitive coded_primitive;
+ const struct FidlCodedEnum coded_enum;
+ const struct FidlCodedBits coded_bits;
+ const struct FidlCodedStruct coded_struct;
+ const struct FidlCodedStructPointer coded_struct_pointer;
+ const struct FidlCodedTable coded_table;
+ const struct FidlCodedUnion coded_union;
+ const struct FidlCodedUnionPointer coded_union_pointer;
+ const struct FidlCodedXUnion coded_xunion;
+ const struct FidlCodedHandle coded_handle;
+ const struct FidlCodedString coded_string;
+ const struct FidlCodedArray coded_array;
+ const struct FidlCodedVector coded_vector;
+ };
+};
+
+extern const fidl_type_t fidl_internal_kBoolTable;
+extern const fidl_type_t fidl_internal_kInt8Table;
+extern const fidl_type_t fidl_internal_kInt16Table;
+extern const fidl_type_t fidl_internal_kInt32Table;
+extern const fidl_type_t fidl_internal_kInt64Table;
+extern const fidl_type_t fidl_internal_kUint8Table;
+extern const fidl_type_t fidl_internal_kUint16Table;
+extern const fidl_type_t fidl_internal_kUint32Table;
+extern const fidl_type_t fidl_internal_kUint64Table;
+extern const fidl_type_t fidl_internal_kFloat32Table;
+extern const fidl_type_t fidl_internal_kFloat64Table;
+
+__END_CDECLS
+
+#endif // LIB_FIDL_INTERNAL_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/internal_callable_traits.h b/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/internal_callable_traits.h
new file mode 100644
index 0000000..badad49
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/internal_callable_traits.h
@@ -0,0 +1,84 @@
+// 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.
+
+#ifndef LIB_FIDL_INTERNAL_CALLABLE_TRAITS_H_
+#define LIB_FIDL_INTERNAL_CALLABLE_TRAITS_H_
+
+#include <tuple>
+#include <type_traits>
+
+namespace fidl {
+
+namespace internal {
+
+// |callable_traits| captures elements of interest from function-like types (functions, function
+// pointers, and functors, including lambdas). Due to common usage patterns, const and non-const
+// functors are treated identically.
+//
+// Member types:
+// |args| - a |std::tuple| that captures the parameter types of the function.
+// |return_type| - the return type of the function.
+// |type| - the underlying functor or function pointer type. This member is absent if
+// |callable_traits| are requested for a raw function signature (as opposed to a
+// function pointer or functor; e.g. |callable_traits<void()>|).
+// |signature| - the type of the equivalent function.
+
+template <typename T>
+struct callable_traits : public callable_traits<decltype(&T::operator())> {};
+
+// Treat mutable call operators the same as const call operators.
+//
+// It would be equivalent to erase the const instead, but the common case is lambdas, which are
+// const, so prefer to nest less deeply for the common const case.
+template <typename FunctorType, typename ReturnType, typename... ArgTypes>
+struct callable_traits<ReturnType (FunctorType::*)(ArgTypes...)>
+ : public callable_traits<ReturnType (FunctorType::*)(ArgTypes...) const> {};
+
+// Common functor specialization.
+template <typename FunctorType, typename ReturnType, typename... ArgTypes>
+struct callable_traits<ReturnType (FunctorType::*)(ArgTypes...) const>
+ : public callable_traits<ReturnType (*)(ArgTypes...)> {
+ using type = FunctorType;
+};
+
+// Function pointer specialization.
+template <typename ReturnType, typename... ArgTypes>
+struct callable_traits<ReturnType (*)(ArgTypes...)>
+ : public callable_traits<ReturnType(ArgTypes...)> {
+ using type = ReturnType (*)(ArgTypes...);
+};
+
+// Base specialization.
+template <typename ReturnType, typename... ArgTypes>
+struct callable_traits<ReturnType(ArgTypes...)> {
+ using signature = ReturnType(ArgTypes...);
+ using return_type = ReturnType;
+ using args = std::tuple<ArgTypes...>;
+
+ callable_traits() = delete;
+};
+
+template <typename FuncA, typename FuncB>
+struct SameInterfaceImpl {
+ static constexpr bool args_equal = std::is_same<typename callable_traits<FuncA>::args,
+ typename callable_traits<FuncB>::args>::value;
+
+ static constexpr bool return_equal =
+ std::is_same<typename callable_traits<FuncA>::return_type,
+ typename callable_traits<FuncB>::return_type>::value;
+
+ static constexpr bool value = args_equal && return_equal;
+};
+
+template <typename FuncA, typename FuncB>
+constexpr bool SameInterface = SameInterfaceImpl<FuncA, FuncB>::value;
+
+template <typename FuncA, typename FuncB>
+constexpr bool SameArguments = SameInterfaceImpl<FuncA, FuncB>::args_equal;
+
+} // namespace internal
+
+} // namespace fidl
+
+#endif // LIB_FIDL_INTERNAL_CALLABLE_TRAITS_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/transformer.h b/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/transformer.h
new file mode 100644
index 0000000..4073eda
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/transformer.h
@@ -0,0 +1,67 @@
+// 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.
+
+#ifndef LIB_FIDL_TRANSFORMER_H_
+#define LIB_FIDL_TRANSFORMER_H_
+
+#include <zircon/fidl.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// Available transformations.
+typedef uint32_t fidl_transformation_t;
+
+// No-op transformation.
+//
+// See also `fidl_transform`.
+#define FIDL_TRANSFORMATION_NONE ((fidl_transformation_t)0u)
+
+// In the old wire format, a FIDL union is encoded as a static union. In the v1 wire format, a FIDL
+// union is encoded as an extensible union.
+//
+// Performing the FIDL_TRANSFORMATION_V1_TO_OLD transformation will transform a top-level struct
+// that contains FIDL unions from extensible unions to static unions. The |src_bytes| buffer passed
+// to `fidl_transform` MUST have been previously validated with `fidl_validate`, or the behavior is
+// undefined.
+//
+// See also `fidl_transform`.
+#define FIDL_TRANSFORMATION_V1_TO_OLD ((fidl_transformation_t)1u)
+
+// Performing FIDL_TRANSFORMATION_OLD_TO_V1 transformation will transform a top-level struct that
+// contains FIDL unions from static unions to extensible unions. The |src_bytes| buffer passed to
+// `fidl_transform` MUST have been previously validated with `fidl_validate`, or the behavior is
+// undefined.
+//
+// See also `fidl_transform`.
+#define FIDL_TRANSFORMATION_OLD_TO_V1 ((fidl_transformation_t)2u)
+
+// Transforms an encoded FIDL buffer from one wire format to another.
+//
+// Starting from the root of the encoded objects present in the |src_bytes|
+// buffer, this function traverses all objects and transforms them from one
+// wire format into another, placing the transformed encoded objects into the
+// |dst_bytes| buffer. Both |src_bytes| and |dst_bytes| should be aligned to
+// FIDL_ALIGNMENT.
+//
+// The provided |src_type| must describe the |src_bytes| buffer format, and the
+// alternate types (accessed via the various `alt_type` fields) must describe
+// the target buffer format.
+//
+// Upon success, this function returns `ZX_OK` and records the total size
+// of bytes written to the |dst_bytes| buffer into |out_dst_num_bytes|.
+//
+// Upon failure (and if provided) this function writes an error message
+// to |out_error_msg|. The caller is not responsible for the memory backing the
+// error message.
+//
+// See also `fidl_transformation_t` and `FIDL_TRANSFORMATION_...` constants.
+zx_status_t fidl_transform(fidl_transformation_t transformation, const fidl_type_t* src_type,
+ const uint8_t* src_bytes, uint32_t src_num_bytes, uint8_t* dst_bytes,
+ uint32_t dst_num_bytes_capacity, uint32_t* out_dst_num_bytes,
+ const char** out_error_msg);
+
+__END_CDECLS
+
+#endif // LIB_FIDL_TRANSFORMER_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/txn_header.h b/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/txn_header.h
new file mode 100644
index 0000000..6e802c3
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/txn_header.h
@@ -0,0 +1,22 @@
+// 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.
+
+#ifndef LIB_FIDL_TXN_HEADER_H_
+#define LIB_FIDL_TXN_HEADER_H_
+
+#include <zircon/fidl.h>
+
+#define FIDL_TXN_HEADER_UNION_FROM_XUNION_FLAG (1 << 0)
+
+__BEGIN_CDECLS
+
+// TODO(38643): make this inline
+// Initialize a txn header as per the Transaction Header v3 proposal (FTP-037)
+void fidl_init_txn_header(fidl_message_header_t* out_hdr, zx_txid_t txid, uint64_t ordinal);
+
+zx_status_t fidl_validate_txn_header(const fidl_message_header_t* hdr);
+
+__END_CDECLS
+
+#endif // LIB_FIDL_TXN_HEADER_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/visitor.h b/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/visitor.h
new file mode 100644
index 0000000..e54b43a
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/visitor.h
@@ -0,0 +1,241 @@
+// 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.
+
+#ifndef LIB_FIDL_VISITOR_H_
+#define LIB_FIDL_VISITOR_H_
+
+#include <lib/fidl/coding.h>
+#include <lib/fidl/internal.h>
+#include <lib/fidl/internal_callable_traits.h>
+#include <stdalign.h>
+#include <zircon/assert.h>
+#include <zircon/compiler.h>
+
+#include <cstdint>
+#include <cstdlib>
+#include <type_traits>
+#include <utility>
+
+namespace fidl {
+
+struct NonMutatingVisitorTrait {
+ // Types residing in the FIDL message buffer are const
+ static constexpr bool kIsConst = true;
+
+ // Message is const
+ using ObjectPointerPointer = const void* const* const;
+};
+
+struct MutatingVisitorTrait {
+ // Types residing in the FIDL message buffer are mutable
+ static constexpr bool kIsConst = false;
+
+ // Message is mutable
+ using ObjectPointerPointer = void** const;
+};
+
+namespace {
+
+// The interface of a FIDL message visitor.
+//
+// The walker class drives the message traversal, and encoders/decoders/validators etc.
+// implement this interface to perform their task.
+//
+// Visitors should inherit from this class, which has compile-time checks that all visitor interface
+// requirements have been met. The walker logic is always parameterized by a concrete implementation
+// of this interface, hence there is no virtual method call overhead. MutationTrait is one of
+// NonMutatingVisitorTrait or MutatingVisitorTrait.
+//
+// Many FIDL types do not need special treatment when encoding/decoding. Those that do include:
+// - Handles: Transferred to/from handle table.
+// - Indirections e.g. nullable fields, strings, vectors: Perform pointer patching.
+//
+// All pointers passed to the visitor are guaranteed to be alive throughout the duration
+// of the message traversal.
+// For all callbacks in the visitor, the return value indicates if an error has occurred.
+template <typename MutationTrait_, typename StartingPoint_, typename Position_>
+class Visitor {
+ public:
+ using MutationTrait = MutationTrait_;
+
+ template <typename T>
+ using Ptr = typename std::conditional<MutationTrait::kIsConst, typename std::add_const<T>::type,
+ T>::type*;
+
+ // A type encapsulating the starting point of message traversal.
+ //
+ // Implementations must have the following:
+ // - Position ToPosition() const, which returns a |Position| located at the starting point.
+ using StartingPoint = StartingPoint_;
+
+ // A type encapsulating the position of the walker within the message. This type is parametric,
+ // such that the walker does not assume any memory order between objects. |Position| is tracked
+ // by the walker at every level of the coding frame, hence we encourage using a smaller type
+ // for |Position|, and placing larger immutable values in |StartingPoint|. For example, in the
+ // encoder, |StartingPoint| can be a 64-bit buffer address, while |Position| is a 32-bit offset.
+ //
+ // Implementations must have the following:
+ // - Position operator+(uint32_t size) const, to advance position by |size| in the message.
+ // - Position& operator+=(uint32_t size), to advance position by |size| in the message.
+ // - template <typename T> Ptr<T> Get(StartingPoint start) const, to cast to a suitable pointer.
+ using Position = Position_;
+
+ // ObjectPointerPointer is ([const] void*) *[const]
+ using ObjectPointerPointer = typename MutationTrait::ObjectPointerPointer;
+
+ // HandlePointer is ([const] zx_handle_t)*
+ using HandlePointer = Ptr<zx_handle_t>;
+
+ // EnvelopePointer is ([const] fidl_envelope_t)*
+ using EnvelopePointer = Ptr<fidl_envelope_t>;
+
+ // CountPointer is ([const] uint64_t)*
+ using CountPointer = Ptr<uint64_t>;
+
+ // Status returned by visitor callbacks.
+ enum class Status {
+ kSuccess = 0,
+ kConstraintViolationError, // recoverable errors
+ kMemoryError // overflow/out-of-bounds etc. Non-recoverable.
+ };
+
+ enum class PointeeType { kVectorOrString, kOther };
+
+ // Compile-time interface checking. Code is invisible to the subclass.
+ private:
+ // Visit an indirection, which can be the data pointer of a string/vector, the data pointer
+ // of an envelope from a table, the pointer in a nullable type, etc.
+ //
+ // If kAllowNonNullableCollectionsToBeAbsent is false, this is only called when
+ // the pointer is present.
+ // Otherwise, this is called in case of present pointers, as well as non-nullable but absent
+ // vectors and strings.
+ //
+ // |ptr_position| Position of the pointer.
+ // |pointee_type| Type of the pointee.
+ // |object_ptr_ptr| Pointer to the data pointer, obtained from |ptr_position.Get(start)|.
+ // It can be used to patch the pointer.
+ // |inline_size| Size of the inline part of the target object.
+ // For vectors, this covers the inline part of all the elements.
+ // It will not contain any trailing padding between objects.
+ // |out_position| Returns the position where the walker will continue its object traversal.
+ Status VisitPointer(Position ptr_position, PointeeType pointee_type,
+ ObjectPointerPointer object_ptr_ptr, uint32_t inline_size,
+ Position* out_position) {
+ return Status::kSuccess;
+ }
+
+ // Visit a handle. The handle pointer will be mutable if the visitor is mutating.
+ // Only called when the handle is present.
+ // The handle pointer is derived from |handle_position.Get(start)|.
+ Status VisitHandle(Position handle_position, HandlePointer handle_ptr, zx_rights_t handle_rights,
+ zx_obj_type_t handle_subtype) {
+ return Status::kSuccess;
+ }
+
+ // Visit a vector or string count. The count pointer will be mutable if the visitor is mutating.
+ Status VisitVectorOrStringCount(CountPointer ptr) {}
+
+ // Visit a region of padding bytes within message objects. They may be between members of a
+ // struct, from after the last member to the end of the struct, or from after a union variant
+ // to the end of a union. They should be zero on the wire.
+ //
+ // N.B. A different type of paddings exist between out-of-line message objects, which are always
+ // aligned to |FIDL_ALIGNMENT|. They should be handled accordingly as part of |VisitPointer|.
+ //
+ // |padding_position| Position of the start of the padding region.
+ // |padding_length| Size of the padding region. It is always positive.
+ Status VisitInternalPadding(Position padding_position, uint32_t padding_length) {
+ return Status::kSuccess;
+ }
+
+ // Called when the walker encounters an envelope.
+ // The envelope may be empty or unknown. The implementation should respond accordingly.
+ //
+ // |payload_type| points to the coding table for the envelope payload. When it is null,
+ // either the payload does not require encoding/decoding (e.g. primitives), or the walker
+ // has encountered an unknown ordinal.
+ //
+ // When |EnterEnvelope| returns |Error::kSuccess|, since the data pointer of an envelope is also
+ // an indirection, |VisitPointer| will be called on the data pointer. Regardless if the envelope
+ // is empty, |LeaveEnvelope| will be called after processing this envelope.
+ //
+ // Return an error to indicate that the envelope should not be traversed.
+ // There will be no corresponding |LeaveEnvelope| call in this case.
+ Status EnterEnvelope(Position envelope_position, EnvelopePointer envelope_ptr,
+ const fidl_type_t* payload_type) {
+ return Status::kSuccess;
+ }
+
+ // Called when the walker finishes visiting all the data in an envelope.
+ // Decoder/encoder should validate that the expected number of bytes/handles have been consumed.
+ // Linearizer can use this opportunity to set the appropriate num_bytes/num_handles value.
+ // It is possible to have nested enter/leave envelope pairs.
+ // There will be a matching call to |LeaveEnvelope| for every successful |EnterEnvelope|.
+ //
+ // |envelope_position| Position of the envelope header.
+ // |envelope_ptr| Pointer to the envelope header that was just processed.
+ // It is derived from |envelope_position.Get(start)|.
+ Status LeaveEnvelope(Position envelope_position, EnvelopePointer envelope_ptr) {
+ return Status::kSuccess;
+ }
+
+ // Called when a traversal error is encountered on the walker side.
+ void OnError(const char* error) {}
+
+ template <typename Visitor_, typename ImplSubType_>
+ friend constexpr bool CheckVisitorInterface();
+};
+
+template <typename Visitor, typename ImplSubType>
+constexpr bool CheckVisitorInterface() {
+ static_assert(std::is_base_of<Visitor, ImplSubType>::value,
+ "ImplSubType should inherit from fidl::Visitor");
+
+ // kContinueAfterConstraintViolation:
+ // - When true, the walker will continue when constraints (e.g. string length) are violated.
+ // - When false, the walker will stop upon first error of any kind.
+ static_assert(
+ std::is_same<decltype(ImplSubType::kContinueAfterConstraintViolation), const bool>::value,
+ "ImplSubType must declare constexpr bool kContinueAfterConstraintViolation");
+
+ // kAllowNonNullableCollectionsToBeAbsent:
+ // - When true, the walker will allow non-nullable vectors/strings to have a null data pointer
+ // and zero count, treating them as if they are empty (non-null data pointer and zero count).
+ // - When false, the above case becomes a constraint violation error.
+ static_assert(std::is_same<decltype(ImplSubType::kAllowNonNullableCollectionsToBeAbsent),
+ const bool>::value,
+ "ImplSubType must declare constexpr bool kAllowNonNullableCollectionsToBeAbsent");
+
+ static_assert(std::is_same<typename internal::callable_traits<decltype(
+ &Visitor::StartingPoint::ToPosition)>::return_type,
+ typename Visitor::Position>::value,
+ "Incorrect/missing StartingPoint");
+
+ static_assert(internal::SameInterface<decltype(&Visitor::VisitPointer),
+ decltype(&ImplSubType::VisitPointer)>,
+ "Incorrect/missing VisitPointer");
+ static_assert(
+ internal::SameInterface<decltype(&Visitor::VisitHandle), decltype(&ImplSubType::VisitHandle)>,
+ "Incorrect/missing VisitHandle");
+ static_assert(internal::SameInterface<decltype(&Visitor::VisitInternalPadding),
+ decltype(&ImplSubType::VisitInternalPadding)>,
+ "Incorrect/missing VisitInternalPadding");
+ static_assert(internal::SameInterface<decltype(&Visitor::EnterEnvelope),
+ decltype(&ImplSubType::EnterEnvelope)>,
+ "Incorrect/missing EnterEnvelope");
+ static_assert(internal::SameInterface<decltype(&Visitor::LeaveEnvelope),
+ decltype(&ImplSubType::LeaveEnvelope)>,
+ "Incorrect/missing LeaveEnvelope");
+ static_assert(
+ internal::SameInterface<decltype(&Visitor::OnError), decltype(&ImplSubType::OnError)>,
+ "Incorrect/missing OnError");
+ return true;
+}
+
+} // namespace
+
+} // namespace fidl
+
+#endif // LIB_FIDL_VISITOR_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/walker.h b/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/walker.h
new file mode 100644
index 0000000..0898cf9
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_base/include/lib/fidl/walker.h
@@ -0,0 +1,949 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_WALKER_H_
+#define LIB_FIDL_WALKER_H_
+
+#include <lib/fidl/coding.h>
+#include <lib/fidl/internal.h>
+#include <lib/fidl/visitor.h>
+#include <stdalign.h>
+#include <zircon/assert.h>
+#include <zircon/compiler.h>
+
+#include <cstdint>
+#include <cstdlib>
+#include <limits>
+#include <type_traits>
+
+namespace fidl {
+
+namespace internal {
+
+// The MSB is an ownership bit in the count field of vectors.
+constexpr uint64_t kVectorOwnershipMask = uint64_t(1) << 63;
+// The LSB is an ownership bit in tracking_ptr of non-array type.
+constexpr uint64_t kNonArrayTrackingPtrOwnershipMask = uint64_t(1) << 0;
+
+// Some assumptions about data type layout.
+static_assert(offsetof(fidl_string_t, size) == 0u, "fidl_string_t layout");
+static_assert(offsetof(fidl_string_t, data) == 8u, "fidl_string_t layout");
+static_assert(sizeof(fidl_string_t) == 16u, "fidl_string_t layout");
+
+static_assert(offsetof(fidl_vector_t, count) == 0u, "fidl_vector_t layout");
+static_assert(offsetof(fidl_vector_t, data) == 8u, "fidl_vector_t layout");
+static_assert(sizeof(fidl_vector_t) == 16u, "fidl_vector_t layout");
+
+static_assert(offsetof(fidl_envelope_t, num_bytes) == 0u, "fidl_envelope_t layout");
+static_assert(offsetof(fidl_envelope_t, num_handles) == 4u, "fidl_envelope_t layout");
+static_assert(offsetof(fidl_envelope_t, data) == 8u, "fidl_envelope_t layout");
+static_assert(sizeof(fidl_envelope_t) == 16u, "fidl_envelope_t layout");
+
+static_assert(ZX_HANDLE_INVALID == FIDL_HANDLE_ABSENT, "invalid handle equals absence marker");
+
+constexpr uint32_t PrimitiveSize(const FidlCodedPrimitive primitive) {
+ switch (primitive) {
+ case kFidlCodedPrimitive_Bool:
+ case kFidlCodedPrimitive_Int8:
+ case kFidlCodedPrimitive_Uint8:
+ return 1;
+ case kFidlCodedPrimitive_Int16:
+ case kFidlCodedPrimitive_Uint16:
+ return 2;
+ case kFidlCodedPrimitive_Int32:
+ case kFidlCodedPrimitive_Uint32:
+ case kFidlCodedPrimitive_Float32:
+ return 4;
+ case kFidlCodedPrimitive_Int64:
+ case kFidlCodedPrimitive_Uint64:
+ case kFidlCodedPrimitive_Float64:
+ return 8;
+ }
+ __builtin_unreachable();
+}
+
+constexpr uint32_t TypeSize(const fidl_type_t* type) {
+ switch (type->type_tag) {
+ case kFidlTypePrimitive:
+ return PrimitiveSize(type->coded_primitive);
+ case kFidlTypeEnum:
+ return PrimitiveSize(type->coded_enum.underlying_type);
+ case kFidlTypeBits:
+ return PrimitiveSize(type->coded_bits.underlying_type);
+ case kFidlTypeStructPointer:
+ case kFidlTypeUnionPointer:
+ return sizeof(uint64_t);
+ case kFidlTypeHandle:
+ return sizeof(zx_handle_t);
+ case kFidlTypeStruct:
+ return type->coded_struct.size;
+ case kFidlTypeTable:
+ return sizeof(fidl_vector_t);
+ case kFidlTypeUnion:
+ return type->coded_union.size;
+ case kFidlTypeXUnion:
+ return sizeof(fidl_xunion_t);
+ case kFidlTypeString:
+ return sizeof(fidl_string_t);
+ case kFidlTypeArray:
+ return type->coded_array.array_size;
+ case kFidlTypeVector:
+ return sizeof(fidl_vector_t);
+ }
+ __builtin_unreachable();
+}
+
+constexpr bool IsPrimitive(const fidl_type_t* type) {
+ switch (type->type_tag) {
+ case kFidlTypePrimitive:
+ return true;
+ default:
+ return false;
+ }
+}
+
+// The Walker class traverses through a FIDL message by following its coding table and
+// calling the visitor implementation. VisitorImpl must be a concrete implementation of the
+// fidl::Visitor interface. The concrete type is used to eliminate dynamic dispatch.
+template <typename VisitorImpl>
+class Walker final {
+ private:
+ using MutationTrait = typename VisitorImpl::MutationTrait;
+
+ using StartingPoint = typename VisitorImpl::StartingPoint;
+
+ using Position = typename VisitorImpl::Position;
+
+ using VisitorSuper = Visitor<MutationTrait, StartingPoint, Position>;
+
+ using Status = typename VisitorSuper::Status;
+
+ static_assert(CheckVisitorInterface<VisitorSuper, VisitorImpl>(), "");
+
+ public:
+ Walker(const fidl_type_t* type, StartingPoint start) : type_(type), start_(start) {}
+
+ // Walk the object/buffer located at |start_|.
+ void Walk(VisitorImpl& visitor);
+
+ private:
+ // Optionally uses non-const pointers depending on if the visitor
+ // is declared as mutating or not.
+ template <typename T>
+ using Ptr = typename VisitorImpl::template Ptr<T>;
+
+ // Wrapper around Position::Get with friendlier syntax.
+ template <typename T>
+ Ptr<T> PtrTo(Position position) {
+ return position.template Get<T>(start_);
+ }
+
+ // Functions that manipulate the coding stack frames.
+ struct Frame {
+ Frame(const fidl_type_t* fidl_type, Position position) : position(position) {
+ switch (fidl_type->type_tag) {
+ case kFidlTypeEnum:
+ state = kStateEnum;
+ enum_state.underlying_type = fidl_type->coded_enum.underlying_type;
+ enum_state.validate = fidl_type->coded_enum.validate;
+ break;
+ case kFidlTypeBits:
+ state = kStateBits;
+ bits_state.underlying_type = fidl_type->coded_bits.underlying_type;
+ bits_state.mask = fidl_type->coded_bits.mask;
+ break;
+ case kFidlTypeStruct:
+ state = kStateStruct;
+ struct_state.fields = fidl_type->coded_struct.fields;
+ struct_state.field_count = fidl_type->coded_struct.field_count;
+ struct_state.field = 0;
+ struct_state.struct_size = fidl_type->coded_struct.size;
+ break;
+ case kFidlTypeStructPointer:
+ state = kStateStructPointer;
+ struct_pointer_state.struct_type = fidl_type->coded_struct_pointer.struct_type;
+ break;
+ case kFidlTypeTable:
+ state = kStateTable;
+ table_state.field = fidl_type->coded_table.fields;
+ table_state.remaining_fields = fidl_type->coded_table.field_count;
+ table_state.present_count = 0;
+ table_state.ordinal = 0;
+ break;
+ case kFidlTypeUnion:
+ state = kStateUnion;
+ union_state.fields = fidl_type->coded_union.fields;
+ union_state.field_count = fidl_type->coded_union.field_count;
+ union_state.data_offset = fidl_type->coded_union.data_offset;
+ union_state.union_size = fidl_type->coded_union.size;
+ break;
+ case kFidlTypeUnionPointer:
+ state = kStateUnionPointer;
+ union_pointer_state.union_type = fidl_type->coded_union_pointer.union_type;
+ break;
+ case kFidlTypeXUnion:
+ state = kStateXUnion;
+ xunion_state.fields = fidl_type->coded_xunion.fields;
+ xunion_state.field_count = fidl_type->coded_xunion.field_count;
+ xunion_state.inside_envelope = false;
+ xunion_state.nullable = fidl_type->coded_xunion.nullable;
+ xunion_state.strictness = fidl_type->coded_xunion.strictness;
+ break;
+ case kFidlTypeArray:
+ state = kStateArray;
+ array_state.element = fidl_type->coded_array.element;
+ array_state.array_size = fidl_type->coded_array.array_size;
+ array_state.element_size = fidl_type->coded_array.element_size;
+ array_state.element_offset = 0;
+ break;
+ case kFidlTypeString:
+ state = kStateString;
+ string_state.max_size = fidl_type->coded_string.max_size;
+ string_state.nullable = fidl_type->coded_string.nullable;
+ break;
+ case kFidlTypeHandle:
+ state = kStateHandle;
+ handle_state.handle_rights = fidl_type->coded_handle.handle_rights;
+ handle_state.handle_subtype = fidl_type->coded_handle.handle_subtype;
+ handle_state.nullable = fidl_type->coded_handle.nullable;
+ break;
+ case kFidlTypeVector:
+ state = kStateVector;
+ vector_state.element = fidl_type->coded_vector.element;
+ vector_state.max_count = fidl_type->coded_vector.max_count;
+ vector_state.element_size = fidl_type->coded_vector.element_size;
+ vector_state.nullable = fidl_type->coded_vector.nullable;
+ break;
+ case kFidlTypePrimitive:
+ state = kStatePrimitive;
+ break;
+ }
+ }
+
+ Frame(const FidlCodedStruct* coded_struct, Position position) : position(position) {
+ state = kStateStruct;
+ struct_state.fields = coded_struct->fields;
+ struct_state.field_count = coded_struct->field_count;
+ struct_state.field = 0;
+ struct_state.struct_size = coded_struct->size;
+ }
+
+ Frame(const FidlCodedTable* coded_table, Position position) : position(position) {
+ state = kStateStruct;
+ table_state.field = coded_table->fields;
+ table_state.remaining_fields = coded_table->field_count;
+ table_state.present_count = 0;
+ table_state.ordinal = 0;
+ }
+
+ Frame(const FidlCodedUnion* coded_union, Position position) : position(position) {
+ state = kStateUnion;
+ union_state.fields = coded_union->fields;
+ union_state.field_count = coded_union->field_count;
+ union_state.data_offset = coded_union->data_offset;
+ union_state.union_size = coded_union->size;
+ }
+
+ Frame(const FidlCodedXUnion* coded_xunion, Position position)
+ : state(kStateXUnion), position(position) {
+ // This initialization is done in the ctor body instead of in an
+ // initialization list since we need to set fields in unions, which
+ // is much more involved in a ctor initialization list.
+ xunion_state.fields = coded_xunion->fields;
+ xunion_state.field_count = coded_xunion->field_count;
+ xunion_state.inside_envelope = false;
+ xunion_state.nullable = coded_xunion->nullable;
+ xunion_state.strictness = coded_xunion->strictness;
+ }
+
+ Frame(const fidl_type_t* element, uint32_t array_size, uint32_t element_size, Position position)
+ : position(position) {
+ state = kStateArray;
+ array_state.element = element;
+ array_state.array_size = array_size;
+ array_state.element_size = element_size;
+ array_state.element_offset = 0;
+ }
+
+ // The default constructor does nothing when initializing the stack of frames.
+ Frame() = default;
+
+ static Frame DoneSentinel() {
+ Frame frame;
+ frame.state = kStateDone;
+ return frame;
+ }
+
+ uint32_t NextStructField() {
+ ZX_DEBUG_ASSERT(state == kStateStruct);
+
+ uint32_t current = struct_state.field;
+ struct_state.field++;
+ return current;
+ }
+
+ uint32_t NextArrayOffset() {
+ ZX_DEBUG_ASSERT(state == kStateArray);
+
+ uint32_t current = array_state.element_offset;
+ array_state.element_offset += array_state.element_size;
+ return current;
+ }
+
+ enum : int {
+ kStateEnum,
+ kStateBits,
+ kStateStruct,
+ kStateStructPointer,
+ kStateTable,
+ kStateUnion,
+ kStateUnionPointer,
+ kStateXUnion,
+ kStateArray,
+ kStateString,
+ kStateHandle,
+ kStateVector,
+ kStatePrimitive,
+
+ kStateDone,
+ } state;
+
+ // Position into the message.
+ Position position;
+
+ // This is a subset of the information recorded in the
+ // fidl_type structures needed for coding state. For
+ // example, struct sizes do not need to be present here.
+ union {
+ struct {
+ FidlCodedPrimitive underlying_type;
+ EnumValidationPredicate validate;
+ } enum_state;
+ struct {
+ FidlCodedPrimitive underlying_type;
+ uint64_t mask;
+ } bits_state;
+ struct {
+ const FidlStructField* fields;
+ uint32_t field_count;
+ // Index of the currently processing field.
+ uint32_t field;
+ // Size of the entire struct.
+ uint32_t struct_size;
+ } struct_state;
+ struct {
+ const FidlCodedStruct* struct_type;
+ } struct_pointer_state;
+ struct {
+ // Sparse (but monotonically increasing) coding table array for fields;
+ // advance the |field| pointer on every matched ordinal to save space
+ const FidlTableField* field;
+ // Number of unseen fields in the coding table
+ uint32_t remaining_fields;
+ // How many fields are stored in the message
+ uint32_t present_count;
+ // Current ordinal (valid ordinals start at 1)
+ uint32_t ordinal;
+ // When true, the walker is currently working within an envelope, or equivalently,
+ // |EnterEnvelope| was successful.
+ bool inside_envelope;
+ } table_state;
+ struct {
+ // Array of coding table corresponding to each union variant.
+ // The union tag counts upwards from 0 without breaks; hence it can be used to
+ // index into the |fields| array.
+ const FidlUnionField* fields;
+ // Size of the |fields| array. Equal to the number of tags.
+ uint32_t field_count;
+ // Offset of the payload in the wire format (size of tag + padding).
+ uint32_t data_offset;
+ // Size of the entire union.
+ uint32_t union_size;
+ } union_state;
+ struct {
+ const FidlCodedUnion* union_type;
+ } union_pointer_state;
+ struct {
+ const FidlXUnionField* fields;
+ // Number of known ordinals declared in the coding table
+ uint32_t field_count;
+ // When true, the walker is currently working within an envelope, or equivalently,
+ // |EnterEnvelope| was successful.
+ bool inside_envelope;
+ FidlNullability nullable;
+ FidlStrictness strictness;
+ } xunion_state;
+ struct {
+ const fidl_type_t* element;
+ // Size of the entire array in bytes
+ uint32_t array_size;
+ // Size of a single element in bytes
+ uint32_t element_size;
+ // Byte offset of the current element being processed
+ uint32_t element_offset;
+ } array_state;
+ struct {
+ uint32_t max_size;
+ bool nullable;
+ } string_state;
+ struct {
+ zx_rights_t handle_rights;
+ zx_obj_type_t handle_subtype;
+ bool nullable;
+ } handle_state;
+ struct {
+ const fidl_type_t* element;
+ // Upperbound on number of elements.
+ uint32_t max_count;
+ // Size of a single element in bytes
+ uint32_t element_size;
+ bool nullable;
+ } vector_state;
+ };
+ };
+
+ // Returns true on success and false on recursion overflow.
+ bool Push(Frame frame) {
+ if (depth_ == FIDL_RECURSION_DEPTH) {
+ return false;
+ }
+ coding_frames_[depth_] = frame;
+ ++depth_;
+ return true;
+ }
+
+ void Pop() {
+ ZX_DEBUG_ASSERT(depth_ != 0u);
+ --depth_;
+ }
+
+ Frame* Peek() {
+ ZX_DEBUG_ASSERT(depth_ != 0u);
+ return &coding_frames_[depth_ - 1];
+ }
+
+ const fidl_type_t* const type_;
+ const StartingPoint start_;
+
+ // Decoding stack state.
+ uint32_t depth_ = 0u;
+ Frame coding_frames_[FIDL_RECURSION_DEPTH];
+};
+
+template <typename VisitorImpl>
+void Walker<VisitorImpl>::Walk(VisitorImpl& visitor) {
+ Push(Frame::DoneSentinel());
+ Push(Frame(type_, start_.ToPosition()));
+
+// Macro to insert the relevant goop required to support two control flows here in case of error:
+// one where we keep reading after error, and another where we return immediately.
+#define FIDL_STATUS_GUARD_IMPL(status, pop) \
+ switch ((status)) { \
+ case Status::kSuccess: \
+ break; \
+ case Status::kConstraintViolationError: \
+ if (VisitorImpl::kContinueAfterConstraintViolation) { \
+ if ((pop)) { \
+ Pop(); \
+ } \
+ continue; \
+ } else { \
+ return; \
+ } \
+ case Status::kMemoryError: \
+ return; \
+ }
+
+#define FIDL_STATUS_GUARD(status) FIDL_STATUS_GUARD_IMPL(status, true)
+#define FIDL_STATUS_GUARD_NO_POP(status) FIDL_STATUS_GUARD_IMPL(status, false)
+
+ for (;;) {
+ Frame* frame = Peek();
+
+ switch (frame->state) {
+ case Frame::kStateEnum: {
+ uint64_t value;
+ switch (frame->enum_state.underlying_type) {
+ case kFidlCodedPrimitive_Uint8:
+ value = *PtrTo<uint8_t>(frame->position);
+ break;
+ case kFidlCodedPrimitive_Uint16:
+ value = *PtrTo<uint16_t>(frame->position);
+ break;
+ case kFidlCodedPrimitive_Uint32:
+ value = *PtrTo<uint32_t>(frame->position);
+ break;
+ case kFidlCodedPrimitive_Uint64:
+ value = *PtrTo<uint64_t>(frame->position);
+ break;
+ case kFidlCodedPrimitive_Int8:
+ value = static_cast<uint64_t>(*PtrTo<int8_t>(frame->position));
+ break;
+ case kFidlCodedPrimitive_Int16:
+ value = static_cast<uint64_t>(*PtrTo<int16_t>(frame->position));
+ break;
+ case kFidlCodedPrimitive_Int32:
+ value = static_cast<uint64_t>(*PtrTo<int32_t>(frame->position));
+ break;
+ case kFidlCodedPrimitive_Int64:
+ value = static_cast<uint64_t>(*PtrTo<int64_t>(frame->position));
+ break;
+ default:
+ __builtin_unreachable();
+ }
+ if (!frame->enum_state.validate(value)) {
+ // TODO(FIDL-523): Make this strictness dependent.
+ visitor.OnError("not a valid enum member");
+ FIDL_STATUS_GUARD(Status::kConstraintViolationError);
+ }
+ Pop();
+ continue;
+ }
+ case Frame::kStateBits: {
+ uint64_t value;
+ switch (frame->bits_state.underlying_type) {
+ case kFidlCodedPrimitive_Uint8:
+ value = *PtrTo<uint8_t>(frame->position);
+ break;
+ case kFidlCodedPrimitive_Uint16:
+ value = *PtrTo<uint16_t>(frame->position);
+ break;
+ case kFidlCodedPrimitive_Uint32:
+ value = *PtrTo<uint32_t>(frame->position);
+ break;
+ case kFidlCodedPrimitive_Uint64:
+ value = *PtrTo<uint64_t>(frame->position);
+ break;
+ default:
+ __builtin_unreachable();
+ }
+ if (value & ~frame->bits_state.mask) {
+ visitor.OnError("not a valid bits member");
+ FIDL_STATUS_GUARD(Status::kConstraintViolationError);
+ }
+ Pop();
+ continue;
+ }
+ case Frame::kStateStruct: {
+ const uint32_t field_index = frame->NextStructField();
+ if (field_index == frame->struct_state.field_count) {
+ Pop();
+ continue;
+ }
+ const FidlStructField& field = frame->struct_state.fields[field_index];
+ const fidl_type_t* field_type = field.type;
+ Position field_position = frame->position + field.offset;
+ if (field.padding > 0) {
+ Position padding_position;
+ if (field_type) {
+ padding_position = field_position + TypeSize(field_type);
+ } else {
+ // Current type does not have coding information. |field.offset| stores the
+ // offset of the padding.
+ padding_position = field_position;
+ }
+ auto status = visitor.VisitInternalPadding(padding_position, field.padding);
+ FIDL_STATUS_GUARD(status);
+ }
+ if (!field_type) {
+ // Skip fields that do not contain codable types.
+ // Such fields only serve to provide padding information.
+ continue;
+ }
+ if (!Push(Frame(field_type, field_position))) {
+ visitor.OnError("recursion depth exceeded processing struct");
+ FIDL_STATUS_GUARD(Status::kConstraintViolationError);
+ }
+ continue;
+ }
+ case Frame::kStateStructPointer: {
+ if (*PtrTo<Ptr<void>>(frame->position) == nullptr) {
+ Pop();
+ continue;
+ }
+ auto status = visitor.VisitPointer(
+ frame->position, VisitorImpl::PointeeType::kOther, PtrTo<Ptr<void>>(frame->position),
+ frame->struct_pointer_state.struct_type->size, &frame->position);
+ FIDL_STATUS_GUARD(status);
+ const FidlCodedStruct* coded_struct = frame->struct_pointer_state.struct_type;
+ *frame = Frame(coded_struct, frame->position);
+ continue;
+ }
+ case Frame::kStateTable: {
+ auto& table_frame = frame->table_state;
+ // Utility to locate the position of the Nth-ordinal envelope header
+ auto envelope_position = [&frame](uint32_t ordinal) -> Position {
+ return frame->position + (ordinal - 1) * static_cast<uint32_t>(sizeof(fidl_envelope_t));
+ };
+ if (table_frame.ordinal == 0) {
+ // Process the vector part of the table
+ auto envelope_vector_ptr = PtrTo<fidl_vector_t>(frame->position);
+ if (envelope_vector_ptr->data == nullptr) {
+ // The vector of envelope headers in a table is always non-nullable.
+ if (!VisitorImpl::kAllowNonNullableCollectionsToBeAbsent) {
+ visitor.OnError("Table data cannot be absent");
+ FIDL_STATUS_GUARD(Status::kConstraintViolationError);
+ }
+ if (envelope_vector_ptr->count != 0) {
+ visitor.OnError("Table envelope vector data absent but non-zero count");
+ FIDL_STATUS_GUARD(Status::kConstraintViolationError);
+ }
+ }
+ uint32_t size;
+ if (mul_overflow(envelope_vector_ptr->count, sizeof(fidl_envelope_t), &size)) {
+ visitor.OnError("integer overflow calculating table size");
+ return;
+ }
+ auto status = visitor.VisitPointer(frame->position, VisitorImpl::PointeeType::kOther,
+ &envelope_vector_ptr->data, size, &frame->position);
+ FIDL_STATUS_GUARD(status);
+ table_frame.ordinal = 1;
+ table_frame.present_count = static_cast<uint32_t>(envelope_vector_ptr->count);
+ table_frame.inside_envelope = false;
+ continue;
+ }
+ if (table_frame.inside_envelope) {
+ // Leave the envelope that was entered during the last iteration
+ uint32_t last_ordinal = table_frame.ordinal - 1;
+ ZX_DEBUG_ASSERT(last_ordinal >= 1);
+ Position envelope_pos = envelope_position(last_ordinal);
+ auto envelope_ptr = PtrTo<fidl_envelope_t>(envelope_pos);
+ table_frame.inside_envelope = false;
+ auto status = visitor.LeaveEnvelope(envelope_pos, envelope_ptr);
+ FIDL_STATUS_GUARD(status);
+ }
+ if (table_frame.ordinal > table_frame.present_count) {
+ // Processed last stored field in table. Done with this table.
+ Pop();
+ continue;
+ }
+ const FidlTableField* known_field = nullptr;
+ if (table_frame.remaining_fields > 0) {
+ const FidlTableField* field = table_frame.field;
+ if (field->ordinal == table_frame.ordinal) {
+ known_field = field;
+ table_frame.field++;
+ table_frame.remaining_fields--;
+ }
+ }
+ Position envelope_pos = envelope_position(table_frame.ordinal);
+ auto envelope_ptr = PtrTo<fidl_envelope_t>(envelope_pos);
+ // Process the next ordinal in the following state machine iteration
+ table_frame.ordinal++;
+ // Make sure we don't process a malformed envelope
+ const fidl_type_t* payload_type = known_field ? known_field->type : nullptr;
+ auto status = visitor.EnterEnvelope(envelope_pos, envelope_ptr, payload_type);
+ FIDL_STATUS_GUARD(status);
+ table_frame.inside_envelope = true;
+ // Skip empty envelopes
+ if (envelope_ptr->data == nullptr) {
+ continue;
+ }
+ uint32_t num_bytes =
+ payload_type != nullptr ? TypeSize(payload_type) : envelope_ptr->num_bytes;
+ Position position;
+ status =
+ visitor.VisitPointer(frame->position, VisitorImpl::PointeeType::kOther,
+ // casting since |envelope_ptr->data| is always void*
+ &const_cast<Ptr<void>&>(envelope_ptr->data), num_bytes, &position);
+ // Do not pop the table frame, to guarantee calling |LeaveEnvelope|
+ FIDL_STATUS_GUARD_NO_POP(status);
+ if (payload_type != nullptr && !IsPrimitive(payload_type)) {
+ if (!Push(Frame(payload_type, position))) {
+ visitor.OnError("recursion depth exceeded processing table");
+ FIDL_STATUS_GUARD_NO_POP(Status::kConstraintViolationError);
+ }
+ }
+ continue;
+ }
+ case Frame::kStateUnion: {
+ auto union_tag = *PtrTo<fidl_union_tag_t>(frame->position);
+ if (union_tag >= frame->union_state.field_count) {
+ visitor.OnError("Bad union discriminant");
+ FIDL_STATUS_GUARD(Status::kConstraintViolationError);
+ }
+ auto variant = frame->union_state.fields[union_tag];
+ if (variant.padding > 0) {
+ Position padding_position =
+ frame->position + (frame->union_state.union_size - variant.padding);
+ auto status = visitor.VisitInternalPadding(padding_position, variant.padding);
+ FIDL_STATUS_GUARD(status);
+ }
+ auto data_offset = frame->union_state.data_offset;
+ ZX_DEBUG_ASSERT(data_offset == 4 || data_offset == 8);
+ if (data_offset == 8) {
+ // There is an additional 4 byte of padding after the tag.
+ auto status = visitor.VisitInternalPadding(frame->position + 4, 4);
+ FIDL_STATUS_GUARD(status);
+ }
+ const fidl_type_t* member = variant.type;
+ if (!member) {
+ Pop();
+ continue;
+ }
+ frame->position += data_offset;
+ *frame = Frame(member, frame->position);
+ continue;
+ }
+ case Frame::kStateUnionPointer: {
+ if (*PtrTo<Ptr<fidl_union_tag_t>>(frame->position) == nullptr) {
+ Pop();
+ continue;
+ }
+ auto status = visitor.VisitPointer(
+ frame->position, VisitorImpl::PointeeType::kOther, PtrTo<Ptr<void>>(frame->position),
+ frame->union_pointer_state.union_type->size, &frame->position);
+ FIDL_STATUS_GUARD(status);
+ const FidlCodedUnion* coded_union = frame->union_pointer_state.union_type;
+ *frame = Frame(coded_union, frame->position);
+ continue;
+ }
+ case Frame::kStateXUnion: {
+ auto xunion = PtrTo<fidl_xunion_t>(frame->position);
+ const auto envelope_pos = frame->position + offsetof(fidl_xunion_t, envelope);
+ auto envelope_ptr = &xunion->envelope;
+ // |inside_envelope| is always false when first encountering an xunion.
+ if (frame->xunion_state.inside_envelope) {
+ // Finished processing the xunion field, and is in clean-up state
+ auto status = visitor.LeaveEnvelope(envelope_pos, envelope_ptr);
+ FIDL_STATUS_GUARD(status);
+ Pop();
+ continue;
+ }
+ // Validate zero-ordinal invariants
+ if (xunion->tag == 0) {
+ if (envelope_ptr->data != nullptr || envelope_ptr->num_bytes != 0 ||
+ envelope_ptr->num_handles != 0) {
+ visitor.OnError("xunion with zero as ordinal must be empty");
+ FIDL_STATUS_GUARD(Status::kConstraintViolationError);
+ }
+ if (!frame->xunion_state.nullable) {
+ visitor.OnError("non-nullable xunion is absent");
+ FIDL_STATUS_GUARD(Status::kConstraintViolationError);
+ }
+ Pop();
+ continue;
+ }
+ // Find coding table corresponding to the ordinal via linear search
+ const FidlXUnionField* known_field = nullptr;
+ for (size_t i = 0; i < frame->xunion_state.field_count; i++) {
+ const auto field = frame->xunion_state.fields + i;
+ if (field->ordinal == xunion->tag) {
+ known_field = field;
+ break;
+ }
+ }
+
+ if (!known_field && frame->xunion_state.strictness == kFidlStrictness_Strict) {
+ visitor.OnError("strict xunion has unknown ordinal");
+ FIDL_STATUS_GUARD(Status::kConstraintViolationError);
+ }
+
+ // Make sure we don't process a malformed envelope
+ const fidl_type_t* payload_type = known_field ? known_field->type : nullptr;
+ auto status = visitor.EnterEnvelope(envelope_pos, envelope_ptr, payload_type);
+ FIDL_STATUS_GUARD(status);
+ frame->xunion_state.inside_envelope = true;
+ // Skip empty envelopes
+ if (envelope_ptr->data == nullptr) {
+ if (xunion->tag != 0) {
+ visitor.OnError("empty xunion must have zero as ordinal");
+ FIDL_STATUS_GUARD_NO_POP(Status::kConstraintViolationError);
+ }
+ continue;
+ }
+ uint32_t num_bytes =
+ payload_type != nullptr ? TypeSize(payload_type) : envelope_ptr->num_bytes;
+ Position position;
+ status =
+ visitor.VisitPointer(frame->position, VisitorImpl::PointeeType::kOther,
+ &const_cast<Ptr<void>&>(envelope_ptr->data), num_bytes, &position);
+ FIDL_STATUS_GUARD_NO_POP(status);
+ if (payload_type != nullptr && !IsPrimitive(payload_type)) {
+ if (!Push(Frame(payload_type, position))) {
+ visitor.OnError("recursion depth exceeded processing xunion");
+ FIDL_STATUS_GUARD_NO_POP(Status::kConstraintViolationError);
+ }
+ }
+ continue;
+ }
+ case Frame::kStateArray: {
+ const uint32_t element_offset = frame->NextArrayOffset();
+ if (element_offset == frame->array_state.array_size) {
+ Pop();
+ continue;
+ }
+ const fidl_type_t* element_type = frame->array_state.element;
+ if (element_type) {
+ Position position = frame->position + element_offset;
+ if (!Push(Frame(element_type, position))) {
+ visitor.OnError("recursion depth exceeded processing array");
+ FIDL_STATUS_GUARD(Status::kConstraintViolationError);
+ }
+ } else {
+ // If there is no element type pointer, the array contents
+ // do not need extra processing, but the array coding table
+ // is present to provide size information when linearizing
+ // envelopes. Just continue.
+ Pop();
+ }
+ continue;
+ }
+ case Frame::kStateString: {
+ auto string_ptr = PtrTo<fidl_string_t>(frame->position);
+ // The MSB of the size is reserved for an ownership bit used by fidl::StringView.
+ // fidl::StringView's count() would be ideally used in place of the direct bit masking
+ // here, but because of build dependencies this is currently not possible.
+ const uint64_t size = string_ptr->size & ~kVectorOwnershipMask;
+ auto status = visitor.VisitVectorOrStringCount(&string_ptr->size);
+ FIDL_STATUS_GUARD(status);
+ if (string_ptr->data == nullptr) {
+ if (!frame->string_state.nullable &&
+ !VisitorImpl::kAllowNonNullableCollectionsToBeAbsent) {
+ visitor.OnError("non-nullable string is absent");
+ FIDL_STATUS_GUARD(Status::kConstraintViolationError);
+ }
+ if (size == 0) {
+ if (frame->string_state.nullable ||
+ !VisitorImpl::kAllowNonNullableCollectionsToBeAbsent) {
+ Pop();
+ continue;
+ }
+ } else {
+ visitor.OnError("string is absent but length is not zero");
+ FIDL_STATUS_GUARD(Status::kConstraintViolationError);
+ }
+ }
+ uint64_t bound = frame->string_state.max_size;
+ if (size > std::numeric_limits<uint32_t>::max()) {
+ visitor.OnError("string size overflows 32 bits");
+ FIDL_STATUS_GUARD(Status::kMemoryError);
+ }
+ if (size > bound) {
+ visitor.OnError("message tried to access too large of a bounded string");
+ FIDL_STATUS_GUARD(Status::kConstraintViolationError);
+ }
+ Position position;
+ status = visitor.VisitPointer(
+ position, VisitorImpl::PointeeType::kVectorOrString,
+ &reinterpret_cast<Ptr<void>&>(const_cast<Ptr<char>&>(string_ptr->data)),
+ static_cast<uint32_t>(size), &position);
+ FIDL_STATUS_GUARD(status);
+ Pop();
+ continue;
+ }
+ case Frame::kStateHandle: {
+ auto handle_ptr = PtrTo<zx_handle_t>(frame->position);
+ if (*handle_ptr == ZX_HANDLE_INVALID) {
+ if (!frame->handle_state.nullable) {
+ visitor.OnError("message is missing a non-nullable handle");
+ FIDL_STATUS_GUARD(Status::kConstraintViolationError);
+ }
+ Pop();
+ continue;
+ }
+ auto status =
+ visitor.VisitHandle(frame->position, handle_ptr, frame->handle_state.handle_rights,
+ frame->handle_state.handle_subtype);
+ FIDL_STATUS_GUARD(status);
+ Pop();
+ continue;
+ }
+ case Frame::kStateVector: {
+ auto vector_ptr = PtrTo<fidl_vector_t>(frame->position);
+ // The MSB of the count is reserved for an ownership bit used by fidl::VectorView.
+ // fidl::VectorView's count() would be ideally used in place of the direct bit masking
+ // here, but because of build dependencies this is currently not possible.
+ const uint64_t count = vector_ptr->count & ~kVectorOwnershipMask;
+ auto status = visitor.VisitVectorOrStringCount(&vector_ptr->count);
+ FIDL_STATUS_GUARD(status);
+ if (vector_ptr->data == nullptr) {
+ if (!frame->vector_state.nullable &&
+ !VisitorImpl::kAllowNonNullableCollectionsToBeAbsent) {
+ visitor.OnError("non-nullable vector is absent");
+ FIDL_STATUS_GUARD(Status::kConstraintViolationError);
+ }
+ if (count == 0) {
+ if (frame->vector_state.nullable ||
+ !VisitorImpl::kAllowNonNullableCollectionsToBeAbsent) {
+ Pop();
+ continue;
+ }
+ } else {
+ visitor.OnError("absent vector of non-zero elements");
+ FIDL_STATUS_GUARD(Status::kConstraintViolationError);
+ }
+ }
+ if (count > frame->vector_state.max_count) {
+ visitor.OnError("message tried to access too large of a bounded vector");
+ FIDL_STATUS_GUARD(Status::kConstraintViolationError);
+ }
+ uint32_t size;
+ if (mul_overflow(count, frame->vector_state.element_size, &size)) {
+ visitor.OnError("integer overflow calculating vector size");
+ return;
+ }
+ status = visitor.VisitPointer(frame->position, VisitorImpl::PointeeType::kVectorOrString,
+ &vector_ptr->data, size, &frame->position);
+ FIDL_STATUS_GUARD(status);
+ if (frame->vector_state.element) {
+ // Continue by visiting the vector elements as an array.
+ *frame = Frame(frame->vector_state.element, size, frame->vector_state.element_size,
+ frame->position);
+ } else {
+ // If there is no element type pointer, there is
+ // nothing to process in the vector secondary
+ // payload. So just continue.
+ Pop();
+ }
+ continue;
+ }
+ case Frame::kStatePrimitive: {
+ // Nothing to do for primitives.
+ Pop();
+ continue;
+ }
+ case Frame::kStateDone: {
+ return;
+ }
+ }
+ }
+}
+
+} // namespace internal
+
+// Walks the FIDL message, calling hooks in the concrete VisitorImpl.
+//
+// |visitor| is an implementation of the fidl::Visitor interface.
+// |type| is the coding table for the FIDL type. It cannot be null.
+// |start| is the starting point for the walk.
+template <typename VisitorImpl>
+void Walk(VisitorImpl& visitor, const fidl_type_t* type,
+ typename VisitorImpl::StartingPoint start) {
+ internal::Walker<VisitorImpl> walker(type, start);
+ walker.Walk(visitor);
+}
+
+// Infer the size of the primary object, from the coding table in |type|.
+// Ensures that the primary object is of one of the expected types.
+//
+// An error is returned if:
+// - |type| is null
+// - The primary object is neither a struct nor a table.
+zx_status_t PrimaryObjectSize(const fidl_type_t* type, size_t* out_size, const char** out_error);
+
+// Calculate the offset of the first out-of-line object, from the coding table in |type|.
+// Ensures that the primary object is of one of the expected types, and the offset falls within the
+// |buffer_size| constraints.
+//
+// An error is returned if:
+// - |type| is null
+// - The primary object is neither a struct nor a table.
+// - The offset overflows, or is larger than |buffer_size|.
+zx_status_t StartingOutOfLineOffset(const fidl_type_t* type, uint32_t buffer_size,
+ uint32_t* out_first_out_of_line, const char** out_error);
+
+} // namespace fidl
+
+#endif // LIB_FIDL_WALKER_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_base/internal.c b/third_party/fuchsia-sdk/pkg/fidl_base/internal.c
new file mode 100644
index 0000000..a954fcf
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_base/internal.c
@@ -0,0 +1,31 @@
+// 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.
+
+#include <lib/fidl/internal.h>
+
+// Coding tables for primitives are predefined and interned here.
+// This file must be a .c to guarantee that these types are stored directly in
+// .rodata, rather than requiring global ctors to have been run (fxb/39978).
+const fidl_type_t fidl_internal_kBoolTable = {.type_tag = kFidlTypePrimitive,
+ .coded_primitive = kFidlCodedPrimitive_Bool};
+const fidl_type_t fidl_internal_kInt8Table = {.type_tag = kFidlTypePrimitive,
+ .coded_primitive = kFidlCodedPrimitive_Int8};
+const fidl_type_t fidl_internal_kInt16Table = {.type_tag = kFidlTypePrimitive,
+ .coded_primitive = kFidlCodedPrimitive_Int16};
+const fidl_type_t fidl_internal_kInt32Table = {.type_tag = kFidlTypePrimitive,
+ .coded_primitive = kFidlCodedPrimitive_Int32};
+const fidl_type_t fidl_internal_kInt64Table = {.type_tag = kFidlTypePrimitive,
+ .coded_primitive = kFidlCodedPrimitive_Int64};
+const fidl_type_t fidl_internal_kUint8Table = {.type_tag = kFidlTypePrimitive,
+ .coded_primitive = kFidlCodedPrimitive_Uint8};
+const fidl_type_t fidl_internal_kUint16Table = {.type_tag = kFidlTypePrimitive,
+ .coded_primitive = kFidlCodedPrimitive_Uint16};
+const fidl_type_t fidl_internal_kUint32Table = {.type_tag = kFidlTypePrimitive,
+ .coded_primitive = kFidlCodedPrimitive_Uint32};
+const fidl_type_t fidl_internal_kUint64Table = {.type_tag = kFidlTypePrimitive,
+ .coded_primitive = kFidlCodedPrimitive_Uint64};
+const fidl_type_t fidl_internal_kFloat32Table = {.type_tag = kFidlTypePrimitive,
+ .coded_primitive = kFidlCodedPrimitive_Float32};
+const fidl_type_t fidl_internal_kFloat64Table = {.type_tag = kFidlTypePrimitive,
+ .coded_primitive = kFidlCodedPrimitive_Float64};
diff --git a/third_party/fuchsia-sdk/pkg/fidl_base/linearizing.cc b/third_party/fuchsia-sdk/pkg/fidl_base/linearizing.cc
new file mode 100644
index 0000000..acdde15
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_base/linearizing.cc
@@ -0,0 +1,270 @@
+// Copyright 2018 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.
+
+#include <lib/fidl/coding.h>
+#include <lib/fidl/envelope_frames.h>
+#include <lib/fidl/internal.h>
+#include <lib/fidl/visitor.h>
+#include <lib/fidl/walker.h>
+#include <stdalign.h>
+#include <string.h>
+#include <zircon/assert.h>
+#include <zircon/compiler.h>
+
+#include <cstdint>
+#include <cstdlib>
+#include <limits>
+
+namespace {
+
+struct Position;
+
+struct StartingPoint {
+ // The starting object of linearization
+ void* const source;
+ // The starting address of a contiguous destination buffer
+ uint8_t* const destination;
+ Position ToPosition() const;
+};
+
+struct Position {
+ // |object| points to one of the objects from the source pile
+ void* object;
+ // |offset| is an offset into the destination buffer
+ uint32_t offset;
+ Position operator+(uint32_t size) const {
+ return Position{.object = reinterpret_cast<void*>(reinterpret_cast<uint8_t*>(object) + size),
+ .offset = offset + size};
+ }
+ Position& operator+=(uint32_t size) {
+ *this = *this + size;
+ return *this;
+ }
+ // By default, return the pointer in the destination buffer
+ template <typename T>
+ constexpr T* Get(StartingPoint start) const {
+ return reinterpret_cast<T*>(start.destination + offset);
+ }
+ // Additional method to get a pointer to one of the source objects
+ template <typename T>
+ constexpr T* GetFromSource() const {
+ return reinterpret_cast<T*>(object);
+ }
+};
+
+Position StartingPoint::ToPosition() const { return Position{.object = source, .offset = 0}; }
+
+using EnvelopeState = ::fidl::EnvelopeFrames::EnvelopeState;
+
+class FidlLinearizer final
+ : public fidl::Visitor<fidl::MutatingVisitorTrait, StartingPoint, Position> {
+ public:
+ FidlLinearizer(void* bytes, uint32_t num_bytes, uint32_t next_out_of_line,
+ const char** out_error_msg)
+ : bytes_(static_cast<uint8_t*>(bytes)),
+ num_bytes_(num_bytes),
+ next_out_of_line_(next_out_of_line),
+ out_error_msg_(out_error_msg) {}
+
+ using StartingPoint = StartingPoint;
+
+ using Position = Position;
+
+ // Does not make sense to keep going after any error, since the resulting buffer
+ // would not be usable anyways.
+ static constexpr bool kContinueAfterConstraintViolation = false;
+
+ // When we encounter a non-nullable vector/string with zero count, do not check the
+ // data pointer. It is cumbersome for the caller to provide a meaningful value other than NULL
+ // in the case of an empty vector/string.
+ static constexpr bool kAllowNonNullableCollectionsToBeAbsent = true;
+
+ Status VisitPointer(Position ptr_position, PointeeType pointee_type,
+ ObjectPointerPointer object_ptr_ptr, uint32_t inline_size,
+ Position* out_position) {
+ // For pointers in types other than vectors and strings, the LSB is reserved to mark ownership
+ // and may be set to 1 if the object is heap allocated. However, the original pointer has this
+ // bit cleared. For vectors and strings, any value is accepted.
+ auto object_ptr =
+ pointee_type == PointeeType::kVectorOrString
+ ? *object_ptr_ptr
+ : reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(*object_ptr_ptr) &
+ ~fidl::internal::kNonArrayTrackingPtrOwnershipMask);
+
+ uint32_t new_offset;
+ if (!FidlAddOutOfLine(next_out_of_line_, inline_size, &new_offset)) {
+ SetError("out-of-line offset overflow trying to linearize");
+ return Status::kMemoryError;
+ }
+
+ if (new_offset > num_bytes_) {
+ SetError("object is too big to linearize into provided buffer", ZX_ERR_BUFFER_TOO_SMALL);
+ return Status::kConstraintViolationError;
+ }
+
+ // Copy the pointee to the desired location in secondary storage
+ memcpy(&bytes_[next_out_of_line_], object_ptr, inline_size);
+
+ // Instruct the walker to traverse the pointee afterwards.
+ *out_position = Position{.object = object_ptr, .offset = next_out_of_line_};
+
+ // Update the pointer within message buffer to point to the copy
+ *object_ptr_ptr = &bytes_[next_out_of_line_];
+ next_out_of_line_ = new_offset;
+ return Status::kSuccess;
+ }
+
+ Status VisitHandle(Position handle_position, HandlePointer handle_ptr, zx_rights_t handle_rights,
+ zx_obj_type_t handle_subtype) {
+ // Remember the address of the handle in the original objects,
+ // such that after the entire tree is cloned into the contiguous buffer,
+ // we can clear out the handles in the original tree in one fell swoop.
+ if (handle_idx_ == ZX_CHANNEL_MAX_MSG_HANDLES) {
+ SetError("too many handles when linearizing");
+ return Status::kConstraintViolationError;
+ }
+ original_handles_[handle_idx_] = handle_position.GetFromSource<zx_handle_t>();
+ handle_idx_ += 1;
+ return Status::kSuccess;
+ }
+
+ Status VisitVectorOrStringCount(CountPointer ptr) {
+ // Clear the MSB that is used for storing ownership information for vectors and strings.
+ // While this operationg could be considered part of encoding, it is LLCPP specific so it
+ // is done during linearization.
+ *ptr &= ~fidl::internal::kVectorOwnershipMask;
+ return Status::kSuccess;
+ }
+
+ Status VisitInternalPadding(Position padding_position, uint32_t padding_length) {
+ return Status::kSuccess;
+ }
+
+ Status EnterEnvelope(Position envelope_position, EnvelopePointer envelope,
+ const fidl_type_t* payload_type) {
+ if (envelope->data != nullptr && payload_type == nullptr) {
+ SetError("Cannot linearize envelope without a coding table");
+ return Status::kConstraintViolationError;
+ }
+ // Remember the current watermark of bytes and handles, so that after processing
+ // the envelope, we can validate that the claimed num_bytes/num_handles matches the reality.
+ if (!envelope_frames_.Push(EnvelopeState(next_out_of_line_, handle_idx_))) {
+ SetError("Overly deep nested envelopes");
+ return Status::kConstraintViolationError;
+ }
+ return Status::kSuccess;
+ }
+
+ Status LeaveEnvelope(Position envelope_position, EnvelopePointer envelope) {
+ // Now that the envelope has been consumed, go back and update the envelope header with
+ // the correct num_bytes and num_handles values
+ auto& starting_state = envelope_frames_.Pop();
+ uint32_t num_bytes = next_out_of_line_ - starting_state.bytes_so_far;
+ uint32_t num_handles = handle_idx_ - starting_state.handles_so_far;
+ envelope->num_bytes = num_bytes;
+ envelope->num_handles = num_handles;
+ return Status::kSuccess;
+ }
+
+ void OnError(const char* error) { SetError(error); }
+
+ template <typename Callback>
+ void ForEachHandle(Callback cb) {
+ for (uint32_t i = 0; i < handle_idx_; i++) {
+ cb(original_handles_[i]);
+ }
+ }
+
+ zx_status_t status() const { return status_; }
+
+ uint32_t next_out_of_line() const { return next_out_of_line_; }
+
+ private:
+ void SetError(const char* error, zx_status_t code = ZX_ERR_INVALID_ARGS) {
+ if (status_ == ZX_OK) {
+ status_ = code;
+ if (out_error_msg_ != nullptr) {
+ *out_error_msg_ = error;
+ }
+ }
+ }
+
+ // Message state passed into the constructor.
+ uint8_t* const bytes_;
+ const uint32_t num_bytes_;
+ uint32_t next_out_of_line_;
+ const char** const out_error_msg_;
+
+ // Linearizer state
+ zx_status_t status_ = ZX_OK;
+ uint32_t handle_idx_ = 0;
+ zx_handle_t* original_handles_[ZX_CHANNEL_MAX_MSG_HANDLES];
+ fidl::EnvelopeFrames envelope_frames_;
+};
+
+} // namespace
+
+zx_status_t fidl_linearize(const fidl_type_t* type, void* value, uint8_t* buffer,
+ uint32_t num_bytes, uint32_t* out_num_bytes,
+ const char** out_error_msg) {
+ auto set_error = [&out_error_msg](const char* msg) {
+ if (out_error_msg)
+ *out_error_msg = msg;
+ };
+ if (value == nullptr) {
+ set_error("Cannot linearize with null starting object");
+ return ZX_ERR_INVALID_ARGS;
+ }
+ if (buffer == nullptr) {
+ set_error("Cannot linearize with null destination buffer");
+ return ZX_ERR_INVALID_ARGS;
+ }
+ if (!FidlIsAligned(buffer)) {
+ set_error("Destination buffer must be aligned to FIDL_ALIGNMENT");
+ return ZX_ERR_INVALID_ARGS;
+ }
+
+ size_t primary_size;
+ zx_status_t status;
+ if ((status = fidl::PrimaryObjectSize(type, &primary_size, out_error_msg)) != ZX_OK) {
+ return status;
+ }
+ if (primary_size > num_bytes) {
+ set_error("Buffer is too small for first inline object");
+ return ZX_ERR_BUFFER_TOO_SMALL;
+ }
+ uint64_t next_out_of_line = FidlAlign(static_cast<uint32_t>(primary_size));
+ if (next_out_of_line > std::numeric_limits<uint32_t>::max()) {
+ set_error("Out of line starting offset overflows");
+ return ZX_ERR_INVALID_ARGS;
+ }
+
+ // Copy the primary object
+ memcpy(buffer, value, primary_size);
+
+ // Zero the padding gaps
+ memset(buffer + primary_size, 0, next_out_of_line - primary_size);
+
+ FidlLinearizer linearizer(buffer, num_bytes, static_cast<uint32_t>(next_out_of_line),
+ out_error_msg);
+ fidl::Walk(linearizer, type,
+ StartingPoint{
+ .source = value,
+ .destination = buffer,
+ });
+
+ if (linearizer.status() != ZX_OK) {
+ return linearizer.status();
+ }
+
+ // Clear out handles in the original objects
+ linearizer.ForEachHandle([](zx_handle_t* handle_ptr) { *handle_ptr = ZX_HANDLE_INVALID; });
+
+ // Return the message size, which is the starting offset of the next out-of-line object
+ if (out_num_bytes) {
+ *out_num_bytes = linearizer.next_out_of_line();
+ }
+
+ return ZX_OK;
+}
diff --git a/third_party/fuchsia-sdk/pkg/fidl_base/message.cc b/third_party/fuchsia-sdk/pkg/fidl_base/message.cc
new file mode 100644
index 0000000..b4c0394
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_base/message.cc
@@ -0,0 +1,216 @@
+// Copyright 2018 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.
+
+#include <lib/fidl/coding.h>
+#include <lib/fidl/cpp/builder.h>
+#include <lib/fidl/cpp/message.h>
+#include <lib/fidl/internal.h>
+#include <lib/fidl/transformer.h>
+#include <string.h>
+
+#ifdef __Fuchsia__
+#include <zircon/errors.h>
+#include <zircon/syscalls.h>
+#endif
+
+namespace fidl {
+
+namespace {
+
+constexpr uint32_t kMaxStackAllocSize = 256;
+
+// This is analogous to ClampedMessageSize in traits.h, but does its work at
+// runtime instead of at compile time and is only called on v1 wire format types
+// in the sending direction.
+uint32_t ClampedMessageSize(const FidlCodedStruct& type) {
+ // convert these to u64 before summing
+ auto primary = static_cast<uint64_t>(type.size);
+ auto max_out_of_line = static_cast<uint64_t>(type.max_out_of_line);
+ uint64_t total_size = primary + max_out_of_line;
+ if (total_size > ZX_CHANNEL_MAX_MSG_BYTES) {
+ return ZX_CHANNEL_MAX_MSG_BYTES;
+ } else {
+ return static_cast<uint32_t>(total_size);
+ }
+}
+
+// RAII managed heap allocated storage for raw message bytes. Used to hold
+// the temporary output of fidl_transform (see ValidateV1Bytes)
+struct HeapAllocatedMessage {
+ explicit HeapAllocatedMessage(uint32_t size) : data(static_cast<uint8_t*>(malloc(size))) {}
+ ~HeapAllocatedMessage() { free(data); }
+
+ uint8_t* data;
+};
+
+} // namespace
+
+const fidl_type_t* get_alt_type(const fidl_type_t* type) {
+ switch (type->type_tag) {
+ case kFidlTypePrimitive:
+ case kFidlTypeEnum:
+ case kFidlTypeBits:
+ case kFidlTypeString:
+ case kFidlTypeHandle:
+ return type;
+ case kFidlTypeStruct:
+ return type->coded_struct.alt_type;
+ case kFidlTypeUnion:
+ return type->coded_union.alt_type;
+ case kFidlTypeXUnion:
+ return type->coded_xunion.alt_type;
+ case kFidlTypeArray:
+ return type->coded_array.alt_type;
+ case kFidlTypeVector:
+ return type->coded_vector.alt_type;
+ default:
+ assert(false && "cannot get alt type of a type that lacks an alt type");
+ return type;
+ }
+}
+
+zx_status_t FidlTransformWithCallback(
+ fidl_transformation_t transformation, const fidl_type_t* type, const uint8_t* src_bytes,
+ uint32_t src_num_bytes, const char** out_error_msg,
+ const std::function<zx_status_t(const uint8_t* dst_bytes, uint32_t dst_num_bytes)>& callback) {
+ if (type->type_tag != kFidlTypeStruct) {
+ return ZX_ERR_INVALID_ARGS;
+ }
+ auto struct_type = type->coded_struct;
+ if (!struct_type.contains_union) {
+ return callback(src_bytes, src_num_bytes);
+ }
+
+ auto msg_size = ClampedMessageSize(get_alt_type(type)->coded_struct);
+ uint32_t dst_num_bytes;
+ if (msg_size <= kMaxStackAllocSize) {
+ auto dst_bytes = static_cast<uint8_t*>(alloca(msg_size));
+ zx_status_t status = fidl_transform(transformation, type, src_bytes, src_num_bytes, dst_bytes,
+ msg_size, &dst_num_bytes, out_error_msg);
+ if (status != ZX_OK) {
+ return status;
+ }
+ return callback(dst_bytes, dst_num_bytes);
+ } else {
+ HeapAllocatedMessage dst_bytes(msg_size);
+ zx_status_t status = fidl_transform(transformation, type, src_bytes, src_num_bytes,
+ dst_bytes.data, msg_size, &dst_num_bytes, out_error_msg);
+ if (status != ZX_OK) {
+ return status;
+ }
+ return callback(dst_bytes.data, dst_num_bytes);
+ }
+}
+
+Message::Message() = default;
+
+Message::Message(BytePart bytes, HandlePart handles)
+ : bytes_(static_cast<BytePart&&>(bytes)), handles_(static_cast<HandlePart&&>(handles)) {}
+
+Message::~Message() {
+#ifdef __Fuchsia__
+ if (handles_.actual() > 0) {
+ zx_handle_close_many(handles_.data(), handles_.actual());
+ }
+#endif
+ ClearHandlesUnsafe();
+}
+
+Message::Message(Message&& other)
+ : bytes_(static_cast<BytePart&&>(other.bytes_)),
+ handles_(static_cast<HandlePart&&>(other.handles_)) {}
+
+Message& Message::operator=(Message&& other) {
+ bytes_ = static_cast<BytePart&&>(other.bytes_);
+ handles_ = static_cast<HandlePart&&>(other.handles_);
+ return *this;
+}
+
+zx_status_t Message::Encode(const fidl_type_t* type, const char** error_msg_out) {
+ uint32_t actual_handles = 0u;
+ zx_status_t status = fidl_encode(type, bytes_.data(), bytes_.actual(), handles_.data(),
+ handles_.capacity(), &actual_handles, error_msg_out);
+ if (status == ZX_OK)
+ handles_.set_actual(actual_handles);
+
+ return status;
+}
+
+zx_status_t Message::Decode(const fidl_type_t* type, const char** error_msg_out) {
+ zx_status_t status = fidl_decode(type, bytes_.data(), bytes_.actual(), handles_.data(),
+ handles_.actual(), error_msg_out);
+ ClearHandlesUnsafe();
+ return status;
+}
+
+zx_status_t Message::Validate(const fidl_type_t* v1_type, const char** error_msg_out) const {
+ return fidl_validate(v1_type, bytes_.data(), bytes_.actual(), handles_.actual(), error_msg_out);
+}
+
+#ifdef __Fuchsia__
+zx_status_t Message::Read(zx_handle_t channel, uint32_t flags) {
+ uint32_t actual_bytes = 0u;
+ uint32_t actual_handles = 0u;
+ zx_status_t status =
+ zx_channel_read(channel, flags, bytes_.data(), handles_.data(), bytes_.capacity(),
+ handles_.capacity(), &actual_bytes, &actual_handles);
+ if (status == ZX_OK) {
+ bytes_.set_actual(actual_bytes);
+ handles_.set_actual(actual_handles);
+ }
+ if (actual_bytes < sizeof(fidl_message_header_t)) {
+ // When reading a message, the size should always greater than the header size.
+ return ZX_ERR_INVALID_ARGS;
+ }
+ return status;
+}
+
+zx_status_t Message::Write(zx_handle_t channel, uint32_t flags) {
+ zx_status_t status = zx_channel_write(channel, flags, bytes_.data(), bytes_.actual(),
+ handles_.data(), handles_.actual());
+ ClearHandlesUnsafe();
+ return status;
+}
+
+zx_status_t Message::WriteTransformV1(zx_handle_t channel, uint32_t flags,
+ const fidl_type_t* old_type) {
+ auto src_data = bytes().data();
+ auto src_num_bytes = bytes().actual();
+ auto callback = [&](const uint8_t* dst_bytes, uint32_t dst_num_bytes) -> zx_status_t {
+ zx_status_t status = zx_channel_write(channel, flags, dst_bytes, dst_num_bytes, handles_.data(),
+ handles_.actual());
+ ClearHandlesUnsafe();
+ return status;
+ };
+ return FidlTransformWithCallback(FIDL_TRANSFORMATION_OLD_TO_V1, old_type, src_data, src_num_bytes,
+ nullptr, callback);
+}
+
+zx_status_t Message::Call(zx_handle_t channel, uint32_t flags, zx_time_t deadline,
+ Message* response) {
+ zx_channel_call_args_t args;
+ args.wr_bytes = bytes_.data();
+ args.wr_handles = handles_.data();
+ args.rd_bytes = response->bytes_.data();
+ args.rd_handles = response->handles_.data();
+ args.wr_num_bytes = bytes_.actual();
+ args.wr_num_handles = handles_.actual();
+ args.rd_num_bytes = response->bytes_.capacity();
+ args.rd_num_handles = response->handles_.capacity();
+ uint32_t actual_bytes = 0u;
+ uint32_t actual_handles = 0u;
+ zx_status_t status =
+ zx_channel_call(channel, flags, deadline, &args, &actual_bytes, &actual_handles);
+ ClearHandlesUnsafe();
+ if (status == ZX_OK) {
+ response->bytes_.set_actual(actual_bytes);
+ response->handles_.set_actual(actual_handles);
+ }
+ return status;
+}
+#endif
+
+void Message::ClearHandlesUnsafe() { handles_.set_actual(0u); }
+
+} // namespace fidl
diff --git a/third_party/fuchsia-sdk/pkg/fidl_base/message_buffer.cc b/third_party/fuchsia-sdk/pkg/fidl_base/message_buffer.cc
new file mode 100644
index 0000000..ef4884a
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_base/message_buffer.cc
@@ -0,0 +1,43 @@
+// Copyright 2018 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.
+
+#include <lib/fidl/cpp/message_buffer.h>
+#include <stdlib.h>
+#include <zircon/assert.h>
+
+namespace fidl {
+namespace {
+
+uint64_t AddPadding(uint32_t offset) {
+ constexpr uint32_t kMask = alignof(zx_handle_t) - 1;
+ // Cast before addition to avoid overflow.
+ return static_cast<uint64_t>(offset) + static_cast<uint64_t>(offset & kMask);
+}
+
+size_t GetAllocSize(uint32_t bytes_capacity, uint32_t handles_capacity) {
+ return AddPadding(bytes_capacity) + sizeof(zx_handle_t) * handles_capacity;
+}
+
+} // namespace
+
+MessageBuffer::MessageBuffer(uint32_t bytes_capacity, uint32_t handles_capacity)
+ : buffer_(static_cast<uint8_t*>(malloc(GetAllocSize(bytes_capacity, handles_capacity)))),
+ bytes_capacity_(bytes_capacity),
+ handles_capacity_(handles_capacity) {
+ ZX_ASSERT_MSG(buffer_, "malloc returned NULL in MessageBuffer::MessageBuffer()");
+}
+
+MessageBuffer::~MessageBuffer() { free(buffer_); }
+
+zx_handle_t* MessageBuffer::handles() const {
+ return reinterpret_cast<zx_handle_t*>(buffer_ + AddPadding(bytes_capacity_));
+}
+
+Message MessageBuffer::CreateEmptyMessage() {
+ return Message(BytePart(bytes(), bytes_capacity()), HandlePart(handles(), handles_capacity()));
+}
+
+Builder MessageBuffer::CreateBuilder() { return Builder(bytes(), bytes_capacity()); }
+
+} // namespace fidl
diff --git a/third_party/fuchsia-sdk/pkg/fidl_base/message_builder.cc b/third_party/fuchsia-sdk/pkg/fidl_base/message_builder.cc
new file mode 100644
index 0000000..738caee
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_base/message_builder.cc
@@ -0,0 +1,29 @@
+// Copyright 2018 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.
+
+#include <lib/fidl/cpp/message_builder.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+namespace fidl {
+
+MessageBuilder::MessageBuilder(const fidl_type_t* type, uint32_t bytes_capacity,
+ uint32_t handles_capacity)
+ : type_(type), buffer_(bytes_capacity, handles_capacity) {
+ Reset();
+}
+
+MessageBuilder::~MessageBuilder() = default;
+
+zx_status_t MessageBuilder::Encode(Message* message_out, const char** error_msg_out) {
+ *message_out = Message(Finalize(), HandlePart(buffer_.handles(), buffer_.handles_capacity()));
+ return message_out->Encode(type_, error_msg_out);
+}
+
+void MessageBuilder::Reset() {
+ Builder::Reset(buffer_.bytes(), buffer_.bytes_capacity());
+ New<fidl_message_header_t>();
+}
+
+} // namespace fidl
diff --git a/third_party/fuchsia-sdk/pkg/fidl_base/meta.json b/third_party/fuchsia-sdk/pkg/fidl_base/meta.json
new file mode 100644
index 0000000..35f082b
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_base/meta.json
@@ -0,0 +1,42 @@
+{
+ "banjo_deps": [],
+ "deps": [
+ "fit"
+ ],
+ "fidl_deps": [],
+ "headers": [
+ "pkg/fidl_base/include/lib/fidl/coding.h",
+ "pkg/fidl_base/include/lib/fidl/txn_header.h",
+ "pkg/fidl_base/include/lib/fidl/cpp/builder.h",
+ "pkg/fidl_base/include/lib/fidl/cpp/message.h",
+ "pkg/fidl_base/include/lib/fidl/cpp/message_buffer.h",
+ "pkg/fidl_base/include/lib/fidl/cpp/message_builder.h",
+ "pkg/fidl_base/include/lib/fidl/cpp/message_part.h",
+ "pkg/fidl_base/include/lib/fidl/envelope_frames.h",
+ "pkg/fidl_base/include/lib/fidl/internal.h",
+ "pkg/fidl_base/include/lib/fidl/transformer.h",
+ "pkg/fidl_base/include/lib/fidl/internal_callable_traits.h",
+ "pkg/fidl_base/include/lib/fidl/visitor.h",
+ "pkg/fidl_base/include/lib/fidl/walker.h"
+ ],
+ "include_dir": "pkg/fidl_base/include",
+ "name": "fidl_base",
+ "root": "pkg/fidl_base",
+ "sources": [
+ "pkg/fidl_base/builder.cc",
+ "pkg/fidl_base/decoding.cc",
+ "pkg/fidl_base/encoding.cc",
+ "pkg/fidl_base/formatting.cc",
+ "pkg/fidl_base/internal.c",
+ "pkg/fidl_base/linearizing.cc",
+ "pkg/fidl_base/message.cc",
+ "pkg/fidl_base/message_buffer.cc",
+ "pkg/fidl_base/message_builder.cc",
+ "pkg/fidl_base/transformer.cc",
+ "pkg/fidl_base/txn_header.c",
+ "pkg/fidl_base/validate_string.cc",
+ "pkg/fidl_base/validating.cc",
+ "pkg/fidl_base/walker.cc"
+ ],
+ "type": "cc_source_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/fidl_base/transformer.cc b/third_party/fuchsia-sdk/pkg/fidl_base/transformer.cc
new file mode 100644
index 0000000..43113c4
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_base/transformer.cc
@@ -0,0 +1,1386 @@
+// 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.
+
+#include <lib/fidl/coding.h>
+#include <lib/fidl/internal.h>
+#include <lib/fidl/transformer.h>
+
+#include <cassert>
+#include <cinttypes>
+#include <cstdio>
+#include <cstring>
+#include <string>
+
+// Disable warning about implicit fallthrough, since it's intentionally used a
+// lot in this code, and the switch()es end up being harder to read without it.
+// Note that "#pragma GCC" works for both GCC & Clang.
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+
+namespace {
+
+// This is an array of 32-bit ordinals that's intended to help debugging. The
+// array is normally empty, but you can add an ordinal to this array in your
+// local tree if you encounter a message in-the-field that the transformer is
+// having issues with.
+constexpr uint64_t kDebugOrdinals[] = {
+ // 0x61f19458'00000000, // example ordinal
+};
+
+enum struct WireFormat {
+ kOld,
+ kV1,
+};
+
+// Call this macro instead of assert() when inside a TransformerBase method: it
+// will print out useful debugging information. This macro inlines the code in
+// order to get precise line number information, and to know the assertion being
+// evaluated.
+#define TRANSFORMER_ASSERT(assertion, position) \
+ { \
+ const auto ok = static_cast<bool>(assertion); \
+ if (!ok) { \
+ debug_info_->RecordFailure(__LINE__, (#assertion), (position)); \
+ assert(assertion); \
+ } \
+ }
+
+// Call this macro instead of the TransformerBase::Fail() method. This is a simple wrapper to pass
+// the current __LINE__ number to Fail().
+#define TRANSFORMER_FAIL(status, position, error_message) \
+ Fail(status, position, __LINE__, error_message);
+
+// Every Transform() method outputs a TraversalResult, which indicates how many out-of-line bytes
+// that transform method consumed, and the actual (not max) number of handles that were encountered
+// during the transformation. This is needed for writing the correct size and handle information in
+// an envelope. (This isn't a great name. A better name would be welcome!)
+struct TraversalResult {
+ uint32_t src_out_of_line_size = 0u;
+ uint32_t dst_out_of_line_size = 0u;
+ uint32_t handle_count = 0u;
+
+ TraversalResult& operator+=(const TraversalResult rhs) {
+ src_out_of_line_size += rhs.src_out_of_line_size;
+ dst_out_of_line_size += rhs.dst_out_of_line_size;
+ handle_count += rhs.handle_count;
+
+ return *this;
+ }
+};
+
+constexpr uint32_t PrimitiveSize(const FidlCodedPrimitive primitive) {
+ switch (primitive) {
+ case kFidlCodedPrimitive_Bool:
+ case kFidlCodedPrimitive_Int8:
+ case kFidlCodedPrimitive_Uint8:
+ return 1;
+ case kFidlCodedPrimitive_Int16:
+ case kFidlCodedPrimitive_Uint16:
+ return 2;
+ case kFidlCodedPrimitive_Int32:
+ case kFidlCodedPrimitive_Uint32:
+ case kFidlCodedPrimitive_Float32:
+ return 4;
+ case kFidlCodedPrimitive_Int64:
+ case kFidlCodedPrimitive_Uint64:
+ case kFidlCodedPrimitive_Float64:
+ return 8;
+ }
+ __builtin_unreachable();
+}
+
+// This function is named UnsafeInlineSize since it assumes that |type| will be
+// non-null. Don't call this function directly; instead, call
+// TransformerBase::InlineSize().
+uint32_t UnsafeInlineSize(const fidl_type_t* type, WireFormat wire_format) {
+ assert(type);
+
+ switch (type->type_tag) {
+ case kFidlTypePrimitive:
+ return PrimitiveSize(type->coded_primitive);
+ case kFidlTypeEnum:
+ return PrimitiveSize(type->coded_enum.underlying_type);
+ case kFidlTypeBits:
+ return PrimitiveSize(type->coded_bits.underlying_type);
+ case kFidlTypeStructPointer:
+ return 8;
+ case kFidlTypeUnionPointer:
+ assert(wire_format == WireFormat::kOld);
+ return 8;
+ case kFidlTypeVector:
+ case kFidlTypeString:
+ return 16;
+ case kFidlTypeStruct:
+ return type->coded_struct.size;
+ case kFidlTypeUnion:
+ assert(wire_format == WireFormat::kOld);
+ return type->coded_union.size;
+ case kFidlTypeArray:
+ return type->coded_array.array_size;
+ case kFidlTypeXUnion:
+ return 24;
+ case kFidlTypeHandle:
+ return 4;
+ case kFidlTypeTable:
+ return 16;
+ }
+
+ // This is needed to suppress a GCC warning "control reaches end of non-void function", since GCC
+ // treats switch() on enums as non-exhaustive without a default case.
+ assert(false && "unexpected non-exhaustive switch on FidlTypeTag");
+ return 0;
+}
+
+struct Position {
+ uint32_t src_inline_offset = 0;
+ uint32_t src_out_of_line_offset = 0;
+ uint32_t dst_inline_offset = 0;
+ uint32_t dst_out_of_line_offset = 0;
+
+ Position(uint32_t src_inline_offset, uint32_t src_out_of_line_offset, uint32_t dst_inline_offset,
+ uint32_t dst_out_of_line_offset)
+ : src_inline_offset(src_inline_offset),
+ src_out_of_line_offset(src_out_of_line_offset),
+ dst_inline_offset(dst_inline_offset),
+ dst_out_of_line_offset(dst_out_of_line_offset) {}
+
+ Position(const Position&) = default;
+ Position& operator=(const Position&) = default;
+
+ inline Position IncreaseInlineOffset(uint32_t increase) const
+ __attribute__((warn_unused_result)) {
+ return IncreaseSrcInlineOffset(increase).IncreaseDstInlineOffset(increase);
+ }
+
+ inline Position IncreaseSrcInlineOffset(uint32_t increase) const
+ __attribute__((warn_unused_result)) {
+ return Position(src_inline_offset + increase, src_out_of_line_offset, dst_inline_offset,
+ dst_out_of_line_offset);
+ }
+
+ inline Position IncreaseSrcOutOfLineOffset(uint32_t increase) const
+ __attribute__((warn_unused_result)) {
+ return Position(src_inline_offset, src_out_of_line_offset + increase, dst_inline_offset,
+ dst_out_of_line_offset);
+ }
+
+ inline Position IncreaseDstInlineOffset(uint32_t increase) const
+ __attribute__((warn_unused_result)) {
+ return Position(src_inline_offset, src_out_of_line_offset, dst_inline_offset + increase,
+ dst_out_of_line_offset);
+ }
+
+ inline Position IncreaseDstOutOfLineOffset(uint32_t increase) const
+ __attribute__((warn_unused_result)) {
+ return Position(src_inline_offset, src_out_of_line_offset, dst_inline_offset,
+ dst_out_of_line_offset + increase);
+ }
+
+ std::string ToString() const {
+ char buffer[32];
+
+ snprintf(buffer, sizeof(buffer), "{0x%02x, 0x%02x, 0x%02x, 0x%02x}", src_inline_offset,
+ src_out_of_line_offset, dst_inline_offset, dst_out_of_line_offset);
+ return std::string(buffer);
+ }
+};
+
+class SrcDst final {
+ public:
+ SrcDst(const uint8_t* src_bytes, const uint32_t src_num_bytes, uint8_t* dst_bytes,
+ uint32_t dst_num_bytes_capacity)
+ : src_bytes_(src_bytes),
+ src_max_offset_(src_num_bytes),
+ dst_bytes_(dst_bytes),
+ dst_max_offset_(dst_num_bytes_capacity) {}
+ SrcDst(const SrcDst&) = delete;
+
+ // Reads |T| from |src_bytes|.
+ // This may update the max src read offset if needed.
+ template <typename T>
+ const T* __attribute__((warn_unused_result)) Read(const Position& position) {
+ return Read<T>(position, sizeof(T));
+ }
+
+ // Reads |size| bytes from |src_bytes|, but only returns a pointer to |T|
+ // which may be smaller, i.e. |sizeof(T)| can be smaller than |size|.
+ // This may update the max src read offset if needed.
+ template <typename T>
+ const T* __attribute__((warn_unused_result)) Read(const Position& position, uint32_t size) {
+ assert(sizeof(T) <= size);
+ const auto status = src_max_offset_.Update(position.src_inline_offset + size);
+ if (status != ZX_OK) {
+ return nullptr;
+ }
+
+ return reinterpret_cast<const T*>(src_bytes_ + position.src_inline_offset);
+ }
+
+ // Copies |size| bytes from |src_bytes| to |dst_bytes|.
+ // This may update the max src read offset if needed.
+ // This may update the max dst written offset if needed.
+ zx_status_t __attribute__((warn_unused_result)) Copy(const Position& position, uint32_t size) {
+ const auto src_status = src_max_offset_.Update(position.src_inline_offset + size);
+ if (src_status != ZX_OK) {
+ return src_status;
+ }
+ const auto dst_status = dst_max_offset_.Update(position.dst_inline_offset + size);
+ if (dst_status != ZX_OK) {
+ return dst_status;
+ }
+
+ memcpy(dst_bytes_ + position.dst_inline_offset, src_bytes_ + position.src_inline_offset, size);
+ return ZX_OK;
+ }
+
+ // Pads |size| bytes in |dst_bytes|.
+ // This may update the max dst written offset if needed.
+ zx_status_t __attribute__((warn_unused_result)) Pad(const Position& position, uint32_t size) {
+ const auto status = dst_max_offset_.Update(position.dst_inline_offset + size);
+ if (status != ZX_OK) {
+ return status;
+ }
+ memset(dst_bytes_ + position.dst_inline_offset, 0, size);
+ return ZX_OK;
+ }
+
+ // Writes |value| in |dst_bytes|.
+ // This may update the max dst written offset if needed.
+ template <typename T>
+ zx_status_t __attribute__((warn_unused_result)) Write(const Position& position, T value) {
+ const auto size = static_cast<uint32_t>(sizeof(value));
+ const auto status = dst_max_offset_.Update(position.dst_inline_offset + size);
+ if (status != ZX_OK) {
+ return status;
+ }
+ auto ptr = reinterpret_cast<T*>(dst_bytes_ + position.dst_inline_offset);
+ *ptr = value;
+ return ZX_OK;
+ }
+
+ const uint8_t* src_bytes() const { return src_bytes_; }
+ uint32_t src_num_bytes() const { return src_max_offset_.capacity_; }
+ uint32_t src_max_offset_read() const { return src_max_offset_.max_offset_; }
+
+ uint8_t* dst_bytes() const { return dst_bytes_; }
+ uint32_t dst_num_bytes_capacity() const { return dst_max_offset_.capacity_; }
+ uint32_t dst_max_offset_written() const { return dst_max_offset_.max_offset_; }
+
+ private:
+ struct MaxOffset {
+ MaxOffset(uint32_t capacity) : capacity_(capacity) {}
+ const uint32_t capacity_;
+ uint32_t max_offset_ = 0;
+
+ zx_status_t __attribute__((warn_unused_result)) Update(uint32_t offset) {
+ if (offset > capacity_) {
+ return ZX_ERR_BAD_STATE;
+ }
+ if (offset > max_offset_) {
+ max_offset_ = offset;
+ }
+ return ZX_OK;
+ }
+ };
+
+ const uint8_t* src_bytes_;
+ MaxOffset src_max_offset_;
+ uint8_t* dst_bytes_;
+ MaxOffset dst_max_offset_;
+};
+
+// Debug related information, which is set both on construction, and as we
+// transform. On destruction, this object writes any collected error message
+// if an |out_error_msg| is provided.
+class DebugInfo final {
+ public:
+ DebugInfo(fidl_transformation_t transformation, const fidl_type_t* type, const SrcDst& src_dst,
+ const char** out_error_msg)
+ : transformation_(transformation),
+ type_(type),
+ src_dst_(src_dst),
+ out_error_msg_(out_error_msg) {}
+ DebugInfo(const DebugInfo&) = delete;
+
+ ~DebugInfo() {
+ if (has_failed_) {
+ Print("ERROR");
+ }
+ if (out_error_msg_) {
+ *out_error_msg_ = error_msg_;
+ }
+ }
+
+ void RecordFailure(int line_number, const char* error_msg) {
+ has_failed_ = true;
+ error_msg_ = error_msg;
+ line_number_ = line_number;
+ }
+
+ void RecordFailure(int line_number, const char* error_msg, const Position& position) {
+ RecordFailure(line_number, error_msg);
+ position_ = position;
+ }
+
+ void DebugPrint(int line_number, const char* error_msg, const Position& position) const {
+ DebugInfo dup(transformation_, type_, src_dst_, nullptr);
+ dup.RecordFailure(line_number, error_msg, position);
+ dup.Print("INFO");
+ // Avoid printing twice.
+ dup.has_failed_ = false;
+ }
+
+ private:
+ void Print(const std::string& failure_type) const {
+ printf("=== TRANSFORMER %s ===\n", failure_type.c_str());
+
+ char type_desc[256] = {};
+ fidl_format_type_name(type_, type_desc, sizeof(type_desc));
+
+ printf("src: " __FILE__ "\n");
+ printf("direction: %s\n", direction().c_str());
+ printf("transformer.cc:%d: %s\n", line_number_, error_msg_);
+ printf("top level type: %s\n", type_desc);
+ printf("position: %s\n", position_.ToString().c_str());
+
+ auto print_bytes = [&](const uint8_t* buffer, uint32_t size, uint32_t out_of_line_offset) {
+ for (uint32_t i = 0; i < size; i++) {
+ if (i == out_of_line_offset) {
+ printf(" // out-of-line\n");
+ }
+
+ if (i % 8 == 0) {
+ printf(" ");
+ }
+
+ printf("0x%02x, ", buffer[i]);
+
+ if (i % 0x10 == 0x07) {
+ printf(" // 0x%02x\n", i - 7);
+ } else if (i % 0x08 == 0x07) {
+ printf("\n");
+ }
+ }
+ };
+
+ printf("uint8_t src_bytes[0x%02x] = {\n", src_dst_.src_num_bytes());
+ print_bytes(src_dst_.src_bytes(), src_dst_.src_num_bytes(), position_.src_out_of_line_offset);
+ printf("}\n");
+
+ printf("uint8_t dst_bytes[0x%02x] = { // capacity = 0x%02x\n",
+ src_dst_.dst_max_offset_written(), src_dst_.dst_num_bytes_capacity());
+ print_bytes(src_dst_.dst_bytes(), src_dst_.dst_max_offset_written(),
+ position_.dst_out_of_line_offset);
+ printf("}\n");
+
+ printf("=== END TRANSFORMER %s ===\n", failure_type.c_str());
+ }
+
+ std::string direction() const {
+ switch (transformation_) {
+ case FIDL_TRANSFORMATION_NONE:
+ return "none";
+ case FIDL_TRANSFORMATION_V1_TO_OLD:
+ return "v1 to old";
+ case FIDL_TRANSFORMATION_OLD_TO_V1:
+ return "old to v1";
+ default:
+ return "unknown";
+ }
+ }
+
+ // Set on construction, and duplicated.
+ const fidl_transformation_t transformation_;
+ const fidl_type_t* type_;
+ const SrcDst& src_dst_;
+
+ // Set on construction, never duplicated.
+ const char** out_error_msg_;
+
+ // Set post construction, never duplicated.
+ bool has_failed_ = false;
+ const char* error_msg_ = nullptr;
+ int line_number_ = -1;
+ Position position_{0, 0, 0, 0};
+};
+
+class TransformerBase {
+ public:
+ TransformerBase(SrcDst* src_dst, const fidl_type_t* top_level_src_type, DebugInfo* debug_info)
+ : src_dst(src_dst), debug_info_(debug_info), top_level_src_type_(top_level_src_type) {}
+ virtual ~TransformerBase() = default;
+
+ uint32_t InlineSize(const fidl_type_t* type, WireFormat wire_format, const Position& position) {
+ TRANSFORMER_ASSERT(type, position);
+
+ return UnsafeInlineSize(type, wire_format);
+ }
+
+ uint32_t AltInlineSize(const fidl_type_t* type, const Position& position) {
+ TRANSFORMER_ASSERT(type, position);
+
+ switch (type->type_tag) {
+ case kFidlTypeStruct:
+ return InlineSize(type->coded_struct.alt_type, To(), position);
+ case kFidlTypeUnion:
+ return InlineSize(type->coded_union.alt_type, To(), position);
+ case kFidlTypeArray:
+ return InlineSize(type->coded_array.alt_type, To(), position);
+ case kFidlTypeXUnion:
+ return InlineSize(type->coded_xunion.alt_type, To(), position);
+ case kFidlTypePrimitive:
+ case kFidlTypeEnum:
+ case kFidlTypeBits:
+ case kFidlTypeStructPointer:
+ case kFidlTypeUnionPointer:
+ case kFidlTypeVector:
+ case kFidlTypeString:
+ case kFidlTypeHandle:
+ case kFidlTypeTable:
+ return InlineSize(type, To(), position);
+ }
+
+ TRANSFORMER_ASSERT(false && "unexpected non-exhaustive switch on FidlTypeTag", position);
+ return 0;
+ }
+
+ void MaybeDebugPrintTopLevelStruct(const Position& position) {
+ if (sizeof(kDebugOrdinals) == 0) {
+ return;
+ }
+
+ auto maybe_ordinal = src_dst->Read<uint64_t>(
+ position.IncreaseSrcInlineOffset(offsetof(fidl_message_header_t, ordinal)));
+ if (!maybe_ordinal) {
+ return;
+ }
+
+ for (uint64_t debug_ordinal : kDebugOrdinals) {
+ if (debug_ordinal != *maybe_ordinal) {
+ continue;
+ }
+
+ char buffer[16];
+ snprintf(buffer, sizeof(buffer), "0x%016" PRIx64, debug_ordinal);
+
+ debug_info_->DebugPrint(__LINE__, buffer, position);
+ }
+ }
+
+ zx_status_t TransformTopLevelStruct() {
+ if (top_level_src_type_->type_tag != kFidlTypeStruct) {
+ return TRANSFORMER_FAIL(ZX_ERR_INVALID_ARGS, (Position{0, 0, 0, 0}),
+ "only top-level structs supported");
+ }
+
+ const auto& src_coded_struct = top_level_src_type_->coded_struct;
+ const auto& dst_coded_struct = src_coded_struct.alt_type->coded_struct;
+ // Since this is the top-level struct, the first secondary object (i.e.
+ // out-of-line offset) is exactly placed after this struct, i.e. the
+ // struct's inline size.
+ const auto start_position = Position(0, src_coded_struct.size, 0, dst_coded_struct.size);
+
+ TraversalResult discarded_traversal_result;
+ const zx_status_t status =
+ TransformStruct(src_coded_struct, dst_coded_struct, start_position,
+ FIDL_ALIGN(dst_coded_struct.size), &discarded_traversal_result);
+ MaybeDebugPrintTopLevelStruct(start_position);
+ return status;
+ }
+
+ protected:
+ zx_status_t Transform(const fidl_type_t* type, const Position& position, const uint32_t dst_size,
+ TraversalResult* out_traversal_result) {
+ if (!type) {
+ return src_dst->Copy(position, dst_size);
+ }
+ switch (type->type_tag) {
+ case kFidlTypeHandle:
+ return TransformHandle(position, dst_size, out_traversal_result);
+ case kFidlTypePrimitive:
+ case kFidlTypeEnum:
+ case kFidlTypeBits:
+ return src_dst->Copy(position, dst_size);
+ case kFidlTypeStructPointer: {
+ const auto& src_coded_struct = *type->coded_struct_pointer.struct_type;
+ const auto& dst_coded_struct = src_coded_struct.alt_type->coded_struct;
+ return TransformStructPointer(src_coded_struct, dst_coded_struct, position,
+ out_traversal_result);
+ }
+ case kFidlTypeUnionPointer: {
+ const auto& src_coded_union = *type->coded_union_pointer.union_type;
+ const auto& dst_coded_xunion = src_coded_union.alt_type->coded_xunion;
+ return TransformUnionPointerToOptionalXUnion(src_coded_union, dst_coded_xunion, position,
+ out_traversal_result);
+ }
+ case kFidlTypeStruct: {
+ const auto& src_coded_struct = type->coded_struct;
+ const auto& dst_coded_struct = src_coded_struct.alt_type->coded_struct;
+ return TransformStruct(src_coded_struct, dst_coded_struct, position, dst_size,
+ out_traversal_result);
+ }
+ case kFidlTypeUnion: {
+ const auto& src_coded_union = type->coded_union;
+ const auto& dst_coded_union = src_coded_union.alt_type->coded_xunion;
+ return TransformUnionToXUnion(src_coded_union, dst_coded_union, position, dst_size,
+ out_traversal_result);
+ }
+ case kFidlTypeArray: {
+ const auto convert = [](const FidlCodedArray& coded_array) {
+ FidlCodedArrayNew result = {
+ .element = coded_array.element,
+ .element_count = coded_array.array_size / coded_array.element_size,
+ .element_size = coded_array.element_size,
+ .element_padding = 0,
+ .alt_type = nullptr /* alt_type unused, we provide both src and dst */};
+ return result;
+ };
+ auto src_coded_array = convert(type->coded_array);
+ auto dst_coded_array = convert(type->coded_array.alt_type->coded_array);
+ return TransformArray(src_coded_array, dst_coded_array, position, dst_size,
+ out_traversal_result);
+ }
+ case kFidlTypeString:
+ return TransformString(position, out_traversal_result);
+ case kFidlTypeVector: {
+ const auto& src_coded_vector = type->coded_vector;
+ const auto& dst_coded_vector = src_coded_vector.alt_type->coded_vector;
+ return TransformVector(src_coded_vector, dst_coded_vector, position, out_traversal_result);
+ }
+ case kFidlTypeTable:
+ return TransformTable(type->coded_table, position, out_traversal_result);
+ case kFidlTypeXUnion:
+ TRANSFORMER_ASSERT(type->coded_xunion.alt_type, position);
+
+ switch (type->coded_xunion.alt_type->type_tag) {
+ case kFidlTypeUnion:
+ return TransformXUnionToUnion(type->coded_xunion,
+ type->coded_xunion.alt_type->coded_union, position,
+ dst_size, out_traversal_result);
+ case kFidlTypeUnionPointer:
+ return TransformOptionalXUnionToUnionPointer(
+ type->coded_xunion, *type->coded_xunion.alt_type->coded_union_pointer.union_type,
+ position, out_traversal_result);
+ case kFidlTypeXUnion:
+ // NOTE: after https://fuchsia-review.googlesource.com/c/fuchsia/+/365937,
+ // the alt type of a xunion should always be a union, so this path should
+ // never be exercised
+ return TransformXUnion(type->coded_xunion, position, out_traversal_result);
+ case kFidlTypePrimitive:
+ case kFidlTypeEnum:
+ case kFidlTypeBits:
+ case kFidlTypeStruct:
+ case kFidlTypeStructPointer:
+ case kFidlTypeArray:
+ case kFidlTypeString:
+ case kFidlTypeHandle:
+ case kFidlTypeVector:
+ case kFidlTypeTable:
+ TRANSFORMER_ASSERT(false && "Invalid src_xunion alt_type->type_tag", position);
+ __builtin_unreachable();
+ }
+ }
+
+ return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "unknown type tag");
+ }
+
+ zx_status_t TransformHandle(const Position& position, uint32_t dst_size,
+ TraversalResult* out_traversal_result) {
+ auto presence = src_dst->Read<uint32_t>(position);
+ if (!presence) {
+ return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "handle presence missing");
+ }
+ switch (*presence) {
+ case FIDL_HANDLE_ABSENT:
+ // Ok
+ break;
+ case FIDL_HANDLE_PRESENT:
+ out_traversal_result->handle_count++;
+ break;
+ default:
+ return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "handle presence invalid");
+ }
+ return src_dst->Copy(position, dst_size);
+ }
+
+ zx_status_t TransformStructPointer(const FidlCodedStruct& src_coded_struct,
+ const FidlCodedStruct& dst_coded_struct,
+ const Position& position,
+ TraversalResult* out_traversal_result) {
+ auto presence = src_dst->Read<uint64_t>(position);
+ if (!presence) {
+ return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "struct pointer missing");
+ }
+
+ auto status_copy_struct_pointer = src_dst->Copy(position, sizeof(uint64_t));
+ if (status_copy_struct_pointer != ZX_OK) {
+ return status_copy_struct_pointer;
+ }
+
+ switch (*presence) {
+ case FIDL_ALLOC_ABSENT:
+ // Early exit on absent struct.
+ return ZX_OK;
+ case FIDL_ALLOC_PRESENT:
+ // Ok
+ break;
+ default:
+ return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "struct pointer invalid");
+ }
+
+ uint32_t src_aligned_size = FIDL_ALIGN(src_coded_struct.size);
+ uint32_t dst_aligned_size = FIDL_ALIGN(dst_coded_struct.size);
+ const auto struct_position = Position{
+ position.src_out_of_line_offset,
+ position.src_out_of_line_offset + src_aligned_size,
+ position.dst_out_of_line_offset,
+ position.dst_out_of_line_offset + dst_aligned_size,
+ };
+
+ out_traversal_result->src_out_of_line_size += src_aligned_size;
+ out_traversal_result->dst_out_of_line_size += dst_aligned_size;
+
+ return TransformStruct(src_coded_struct, dst_coded_struct, struct_position, dst_aligned_size,
+ out_traversal_result);
+ }
+
+ zx_status_t TransformStruct(const FidlCodedStruct& src_coded_struct,
+ const FidlCodedStruct& dst_coded_struct, const Position& position,
+ uint32_t dst_size, TraversalResult* out_traversal_result) {
+ TRANSFORMER_ASSERT(src_coded_struct.field_count == dst_coded_struct.field_count, position);
+ // Note: we cannot use dst_coded_struct.size, and must instead rely on
+ // the provided dst_size since this struct could be placed in an alignment
+ // context that is larger than its inherent size.
+
+ // Copy structs without any coded fields, and done.
+ if (src_coded_struct.field_count == 0) {
+ return src_dst->Copy(position, dst_size);
+ }
+
+ const uint32_t src_start_of_struct = position.src_inline_offset;
+ const uint32_t dst_start_of_struct = position.dst_inline_offset;
+
+ auto current_position = position;
+ for (uint32_t field_index = 0; field_index < src_coded_struct.field_count; field_index++) {
+ const auto& src_field = src_coded_struct.fields[field_index];
+ const auto& dst_field = dst_coded_struct.fields[field_index];
+
+ if (!src_field.type) {
+ const uint32_t dst_field_size =
+ src_start_of_struct + src_field.padding_offset - current_position.src_inline_offset;
+ const auto status_copy_field = src_dst->Copy(current_position, dst_field_size);
+ if (status_copy_field != ZX_OK) {
+ return status_copy_field;
+ }
+ current_position = current_position.IncreaseInlineOffset(dst_field_size);
+ } else {
+ // The only case where the amount we've written shouldn't match the specified offset is
+ // for request/response structs, where the txn header is not specified in the coding table.
+ if (current_position.src_inline_offset != src_start_of_struct + src_field.offset) {
+ TRANSFORMER_ASSERT(src_field.offset == dst_field.offset, current_position);
+ const auto status_copy_field = src_dst->Copy(current_position, src_field.offset);
+ if (status_copy_field != ZX_OK) {
+ return status_copy_field;
+ }
+ current_position = current_position.IncreaseInlineOffset(src_field.offset);
+ }
+
+ TRANSFORMER_ASSERT(
+ current_position.src_inline_offset == src_start_of_struct + src_field.offset,
+ current_position);
+ TRANSFORMER_ASSERT(
+ current_position.dst_inline_offset == dst_start_of_struct + dst_field.offset,
+ current_position);
+
+ // Transform field.
+ uint32_t src_next_field_offset = current_position.src_inline_offset +
+ InlineSize(src_field.type, From(), current_position);
+ uint32_t dst_next_field_offset =
+ current_position.dst_inline_offset + InlineSize(dst_field.type, To(), current_position);
+ uint32_t dst_field_size = dst_next_field_offset - (dst_start_of_struct + dst_field.offset);
+
+ TraversalResult field_traversal_result;
+ const zx_status_t status =
+ Transform(src_field.type, current_position, dst_field_size, &field_traversal_result);
+ if (status != ZX_OK) {
+ return status;
+ }
+
+ *out_traversal_result += field_traversal_result;
+
+ // Update current position for next iteration.
+ current_position.src_inline_offset = src_next_field_offset;
+ current_position.dst_inline_offset = dst_next_field_offset;
+ current_position.src_out_of_line_offset += field_traversal_result.src_out_of_line_size;
+ current_position.dst_out_of_line_offset += field_traversal_result.dst_out_of_line_size;
+ }
+
+ // Pad (possibly with 0 bytes).
+ const auto status_pad = src_dst->Pad(current_position, dst_field.padding);
+ if (status_pad != ZX_OK) {
+ return TRANSFORMER_FAIL(status_pad, current_position,
+ "unable to pad end of struct element");
+ }
+ current_position = current_position.IncreaseDstInlineOffset(dst_field.padding);
+ current_position = current_position.IncreaseSrcInlineOffset(src_field.padding);
+ }
+
+ // Pad (possibly with 0 bytes).
+ const uint32_t dst_end_of_struct = position.dst_inline_offset + dst_size;
+ const auto status_pad =
+ src_dst->Pad(current_position, dst_end_of_struct - current_position.dst_inline_offset);
+ if (status_pad != ZX_OK) {
+ return TRANSFORMER_FAIL(status_pad, current_position, "unable to pad end of struct");
+ }
+
+ return ZX_OK;
+ }
+
+ zx_status_t TransformVector(const FidlCodedVector& src_coded_vector,
+ const FidlCodedVector& dst_coded_vector, const Position& position,
+ TraversalResult* out_traversal_result) {
+ const auto src_vector = src_dst->Read<fidl_vector_t>(position);
+ if (!src_vector) {
+ return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "vector missing");
+ }
+
+ // Copy vector header.
+ const auto status_copy_vector_hdr = src_dst->Copy(position, sizeof(fidl_vector_t));
+ if (status_copy_vector_hdr != ZX_OK) {
+ return status_copy_vector_hdr;
+ }
+
+ const auto presence = reinterpret_cast<uint64_t>(src_vector->data);
+ switch (presence) {
+ case FIDL_ALLOC_ABSENT:
+ // Early exit on nullable vectors.
+ return ZX_OK;
+ case FIDL_ALLOC_PRESENT:
+ // OK
+ break;
+ default:
+ return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "vector presence invalid");
+ }
+
+ const auto convert = [&](const FidlCodedVector& coded_vector) {
+ FidlCodedArrayNew result = {
+ .element = coded_vector.element,
+ .element_count = static_cast<uint32_t>(src_vector->count),
+ .element_size = coded_vector.element_size,
+ .element_padding = 0,
+ .alt_type = nullptr /* alt_type unused, we provide both src and dst */};
+ return result;
+ };
+ const auto src_vector_data_as_coded_array = convert(src_coded_vector);
+ const auto dst_vector_data_as_coded_array = convert(dst_coded_vector);
+
+ // Calculate vector size. They fit in uint32_t due to automatic bounds.
+ uint32_t src_vector_size =
+ FIDL_ALIGN(static_cast<uint32_t>(src_vector->count * (src_coded_vector.element_size)));
+ uint32_t dst_vector_size =
+ FIDL_ALIGN(static_cast<uint32_t>(src_vector->count * (dst_coded_vector.element_size)));
+
+ // Transform elements.
+ auto vector_data_position = Position{
+ position.src_out_of_line_offset, position.src_out_of_line_offset + src_vector_size,
+ position.dst_out_of_line_offset, position.dst_out_of_line_offset + dst_vector_size};
+
+ const zx_status_t status =
+ TransformArray(src_vector_data_as_coded_array, dst_vector_data_as_coded_array,
+ vector_data_position, dst_vector_size, out_traversal_result);
+ if (status != ZX_OK) {
+ return status;
+ }
+
+ out_traversal_result->src_out_of_line_size += src_vector_size;
+ out_traversal_result->dst_out_of_line_size += dst_vector_size;
+
+ return ZX_OK;
+ }
+
+ zx_status_t TransformString(const Position& position, TraversalResult* out_traversal_result) {
+ FidlCodedVector string_as_coded_vector = {
+ .element = nullptr,
+ .max_count = 0 /*unused*/,
+ .element_size = 1,
+ .nullable = kFidlNullability_Nullable, /* constraints are not checked, i.e. unused */
+ .alt_type = nullptr /* alt_type unused, we provide both src and dst */};
+ return TransformVector(string_as_coded_vector, string_as_coded_vector, position,
+ out_traversal_result);
+ }
+
+ zx_status_t TransformEnvelope(bool known_type, const fidl_type_t* type, const Position& position,
+ TraversalResult* out_traversal_result) {
+ auto src_envelope = src_dst->Read<const fidl_envelope_t>(position);
+ if (!src_envelope) {
+ return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "envelope missing");
+ }
+
+ switch (src_envelope->presence) {
+ case FIDL_ALLOC_ABSENT: {
+ const auto status = src_dst->Copy(position, sizeof(fidl_envelope_t));
+ if (status != ZX_OK) {
+ return TRANSFORMER_FAIL(status, position, "unable to copy envelope header");
+ }
+ return ZX_OK;
+ }
+ case FIDL_ALLOC_PRESENT:
+ // We write the transformed envelope after the transformation, since
+ // the num_bytes may be different in the dst.
+ break;
+ default:
+ return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "envelope presence invalid");
+ }
+
+ if (!known_type) {
+ // When we encounter an unknown type, the best we can do is to copy the
+ // envelope header (which includes the num_bytes and num_handles), and
+ // copy the envelope's data. While it's possible that transformation was
+ // needed, since we do not have the type, we cannot perform it.
+
+ const auto status_copy_hdr = src_dst->Copy(position, sizeof(fidl_envelope_t));
+ if (status_copy_hdr != ZX_OK) {
+ return TRANSFORMER_FAIL(status_copy_hdr, position,
+ "unable to copy envelope header (unknown type)");
+ }
+
+ const auto data_position =
+ Position{position.src_out_of_line_offset,
+ position.src_out_of_line_offset + src_envelope->num_bytes,
+ position.dst_out_of_line_offset,
+ position.dst_out_of_line_offset + src_envelope->num_bytes};
+ const auto status_copy_data = src_dst->Copy(data_position, src_envelope->num_bytes);
+ if (status_copy_data != ZX_OK) {
+ return TRANSFORMER_FAIL(status_copy_data, data_position,
+ "unable to copy envelope data (unknown type)");
+ }
+
+ out_traversal_result->src_out_of_line_size += src_envelope->num_bytes;
+ out_traversal_result->dst_out_of_line_size += src_envelope->num_bytes;
+ out_traversal_result->handle_count += src_envelope->num_handles;
+
+ return ZX_OK;
+ }
+
+ const uint32_t src_contents_inline_size = [&] {
+ if (!type) {
+ // The envelope contents are either a primitive or an array of primitives,
+ // because |type| is nullptr. There's no size information
+ // available for the type in the coding tables, but since the data is a
+ // primitive or array of primitives, there can never be any out-of-line
+ // data, so it's safe to use the envelope's num_bytes to determine the
+ // content's inline size.
+ return src_envelope->num_bytes;
+ }
+
+ return InlineSize(type, From(), position);
+ }();
+
+ const uint32_t dst_contents_inline_size = FIDL_ALIGN(AltInlineSize(type, position));
+ Position data_position = Position{position.src_out_of_line_offset,
+ position.src_out_of_line_offset + src_contents_inline_size,
+ position.dst_out_of_line_offset,
+ position.dst_out_of_line_offset + dst_contents_inline_size};
+ TraversalResult contents_traversal_result;
+ zx_status_t result =
+ Transform(type, data_position, dst_contents_inline_size, &contents_traversal_result);
+ if (result != ZX_OK) {
+ return result;
+ }
+
+ const uint32_t src_contents_size =
+ FIDL_ALIGN(src_contents_inline_size) + contents_traversal_result.src_out_of_line_size;
+ const uint32_t dst_contents_size =
+ dst_contents_inline_size + contents_traversal_result.dst_out_of_line_size;
+
+ fidl_envelope_t dst_envelope = *src_envelope;
+ dst_envelope.num_bytes = dst_contents_size;
+ const auto status_write = src_dst->Write(position, dst_envelope);
+ if (status_write != ZX_OK) {
+ return TRANSFORMER_FAIL(status_write, position, "unable to write envelope");
+ }
+
+ out_traversal_result->src_out_of_line_size += src_contents_size;
+ out_traversal_result->dst_out_of_line_size += dst_contents_size;
+ out_traversal_result->handle_count += src_envelope->num_handles;
+
+ return ZX_OK;
+ }
+
+ zx_status_t TransformXUnion(const FidlCodedXUnion& coded_xunion, const Position& position,
+ TraversalResult* out_traversal_result) {
+ auto xunion = src_dst->Read<const fidl_xunion_t>(position);
+ if (!xunion) {
+ return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "xunion missing");
+ }
+
+ const auto status_copy_xunion_hdr = src_dst->Copy(position, sizeof(fidl_xunion_t));
+ if (status_copy_xunion_hdr != ZX_OK) {
+ return status_copy_xunion_hdr;
+ }
+
+ const FidlXUnionField* field = nullptr;
+ for (uint32_t i = 0; i < coded_xunion.field_count; i++) {
+ const FidlXUnionField* candidate_field = coded_xunion.fields + i;
+ if (candidate_field->ordinal == xunion->tag) {
+ field = candidate_field;
+ break;
+ }
+ }
+
+ const Position envelope_position = {
+ position.src_inline_offset + static_cast<uint32_t>(offsetof(fidl_xunion_t, envelope)),
+ position.src_out_of_line_offset,
+ position.dst_inline_offset + static_cast<uint32_t>(offsetof(fidl_xunion_t, envelope)),
+ position.dst_out_of_line_offset,
+ };
+
+ return TransformEnvelope(field != nullptr, field ? field->type : nullptr, envelope_position,
+ out_traversal_result);
+ }
+
+ zx_status_t TransformTable(const FidlCodedTable& coded_table, const Position& position,
+ TraversalResult* out_traversal_result) {
+ auto table = src_dst->Read<const fidl_table_t>(position);
+ if (!table) {
+ return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "table header missing");
+ }
+
+ const auto status_copy_table_hdr = src_dst->Copy(position, sizeof(fidl_table_t));
+ if (status_copy_table_hdr != ZX_OK) {
+ return TRANSFORMER_FAIL(status_copy_table_hdr, position, "unable to copy table header");
+ }
+
+ const uint32_t envelopes_vector_size =
+ static_cast<uint32_t>(table->envelopes.count * sizeof(fidl_envelope_t));
+ out_traversal_result->src_out_of_line_size += envelopes_vector_size;
+ out_traversal_result->dst_out_of_line_size += envelopes_vector_size;
+
+ auto current_envelope_position = Position{
+ position.src_out_of_line_offset,
+ position.src_out_of_line_offset + envelopes_vector_size,
+ position.dst_out_of_line_offset,
+ position.dst_out_of_line_offset + envelopes_vector_size,
+ };
+ const auto max_field_index = coded_table.field_count - 1;
+ for (uint32_t ordinal = 1, field_index = 0; ordinal <= table->envelopes.count; ordinal++) {
+ const FidlTableField& field = coded_table.fields[field_index];
+
+ const bool known_field = (ordinal == field.ordinal);
+ if (known_field) {
+ if (field_index < max_field_index)
+ field_index++;
+ }
+
+ TraversalResult envelope_traversal_result;
+ zx_status_t status = TransformEnvelope(known_field, known_field ? field.type : nullptr,
+ current_envelope_position, &envelope_traversal_result);
+ if (status != ZX_OK) {
+ return status;
+ }
+
+ current_envelope_position.src_inline_offset += static_cast<uint32_t>(sizeof(fidl_envelope_t));
+ current_envelope_position.dst_inline_offset += static_cast<uint32_t>(sizeof(fidl_envelope_t));
+ current_envelope_position.src_out_of_line_offset +=
+ envelope_traversal_result.src_out_of_line_size;
+ current_envelope_position.dst_out_of_line_offset +=
+ envelope_traversal_result.dst_out_of_line_size;
+
+ *out_traversal_result += envelope_traversal_result;
+ }
+
+ return ZX_OK;
+ }
+
+ zx_status_t TransformArray(const FidlCodedArrayNew& src_coded_array,
+ const FidlCodedArrayNew& dst_coded_array, const Position& position,
+ uint32_t dst_array_size, TraversalResult* out_traversal_result) {
+ TRANSFORMER_ASSERT(src_coded_array.element_count == dst_coded_array.element_count, position);
+
+ // Fast path for elements without coding tables (e.g. strings).
+ if (!src_coded_array.element) {
+ return src_dst->Copy(position, dst_array_size);
+ }
+
+ // Slow path otherwise.
+ auto current_element_position = position;
+ for (uint32_t i = 0; i < src_coded_array.element_count; i++) {
+ TraversalResult element_traversal_result;
+ const zx_status_t status = Transform(src_coded_array.element, current_element_position,
+ dst_coded_array.element_size, &element_traversal_result);
+
+ if (status != ZX_OK) {
+ return status;
+ }
+
+ // Pad end of an element.
+ auto padding_position =
+ current_element_position.IncreaseSrcInlineOffset(src_coded_array.element_size)
+ .IncreaseDstInlineOffset(dst_coded_array.element_size);
+ const auto status_pad = src_dst->Pad(padding_position, dst_coded_array.element_padding);
+ if (status_pad != ZX_OK) {
+ return TRANSFORMER_FAIL(status_pad, padding_position, "unable to pad array element");
+ }
+
+ current_element_position =
+ padding_position.IncreaseSrcInlineOffset(src_coded_array.element_padding)
+ .IncreaseDstInlineOffset(dst_coded_array.element_padding)
+ .IncreaseSrcOutOfLineOffset(element_traversal_result.src_out_of_line_size)
+ .IncreaseDstOutOfLineOffset(element_traversal_result.dst_out_of_line_size);
+
+ *out_traversal_result += element_traversal_result;
+ }
+
+ // Pad end of elements.
+ uint32_t padding =
+ dst_array_size + position.dst_inline_offset - current_element_position.dst_inline_offset;
+ const auto status_pad = src_dst->Pad(current_element_position, padding);
+ if (status_pad != ZX_OK) {
+ return TRANSFORMER_FAIL(status_pad, current_element_position, "unable to pad end of array");
+ }
+
+ return ZX_OK;
+ }
+
+ zx_status_t TransformUnionPointerToOptionalXUnion(const FidlCodedUnion& src_coded_union,
+ const FidlCodedXUnion& dst_coded_xunion,
+ const Position& position,
+ TraversalResult* out_traversal_result) {
+ auto presence = src_dst->Read<uint64_t>(position);
+ if (!presence) {
+ return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "union pointer missing");
+ }
+
+ switch (*presence) {
+ case FIDL_ALLOC_ABSENT: {
+ fidl_xunion_t absent = {};
+ const auto status = src_dst->Write(position, absent);
+ if (status != ZX_OK) {
+ return TRANSFORMER_FAIL(status, position, "unable to write union pointer absense");
+ }
+ return ZX_OK;
+ }
+ case FIDL_ALLOC_PRESENT:
+ // Ok
+ break;
+ default:
+ return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "union pointer invalid");
+ }
+
+ uint32_t src_aligned_size = FIDL_ALIGN(src_coded_union.size);
+ const auto union_position = Position{
+ position.src_out_of_line_offset,
+ position.src_out_of_line_offset + src_aligned_size,
+ position.dst_inline_offset,
+ position.dst_out_of_line_offset,
+ };
+
+ out_traversal_result->src_out_of_line_size += src_aligned_size;
+ return TransformUnionToXUnion(src_coded_union, dst_coded_xunion, union_position,
+ 0 /* unused: xunions are FIDL_ALIGNed */, out_traversal_result);
+ }
+
+ zx_status_t TransformUnionToXUnion(const FidlCodedUnion& src_coded_union,
+ const FidlCodedXUnion& dst_coded_xunion,
+ const Position& position, uint32_t /* unused: dst_size */,
+ TraversalResult* out_traversal_result) {
+ TRANSFORMER_ASSERT(src_coded_union.field_count == dst_coded_xunion.field_count, position);
+
+ // Read: union tag.
+ const auto union_tag_ptr =
+ src_dst->Read<const fidl_union_tag_t>(position, src_coded_union.size);
+ if (!union_tag_ptr) {
+ return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "union tag missing");
+ }
+ const auto union_tag = *union_tag_ptr;
+
+ // Retrieve: union field/variant.
+ if (union_tag >= src_coded_union.field_count) {
+ return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "invalid union tag");
+ }
+
+ const FidlUnionField& src_field = src_coded_union.fields[union_tag];
+ const FidlXUnionField& dst_field = dst_coded_xunion.fields[union_tag];
+
+ // Write: xunion tag & envelope.
+ const uint32_t dst_inline_field_size = [&] {
+ if (src_field.type) {
+ return AltInlineSize(src_field.type, position);
+ } else {
+ return src_coded_union.size - src_coded_union.data_offset - src_field.padding;
+ }
+ }();
+
+ // Transform: static-union field to xunion field.
+ auto field_position = Position{
+ position.src_inline_offset + src_coded_union.data_offset,
+ position.src_out_of_line_offset,
+ position.dst_out_of_line_offset,
+ position.dst_out_of_line_offset + FIDL_ALIGN(dst_inline_field_size),
+ };
+ TraversalResult field_traversal_result;
+ zx_status_t status =
+ Transform(src_field.type, field_position, dst_inline_field_size, &field_traversal_result);
+ if (status != ZX_OK) {
+ return status;
+ }
+
+ // Pad field (if needed).
+ const uint32_t dst_field_size =
+ dst_inline_field_size + field_traversal_result.dst_out_of_line_size;
+ const uint32_t dst_padding = FIDL_ALIGN(dst_field_size) - dst_field_size;
+ const auto status_pad_field =
+ src_dst->Pad(field_position.IncreaseDstInlineOffset(dst_field_size), dst_padding);
+ if (status_pad_field != ZX_OK) {
+ return TRANSFORMER_FAIL(status_pad_field, field_position,
+ "unable to pad union-as-xunion variant");
+ }
+
+ // Write envelope header.
+ fidl_xunion_t xunion;
+ xunion.tag = dst_field.ordinal;
+ xunion.envelope.num_bytes = FIDL_ALIGN(dst_field_size);
+ xunion.envelope.num_handles = field_traversal_result.handle_count;
+ xunion.envelope.presence = FIDL_ALLOC_PRESENT;
+ const auto status_write_xunion = src_dst->Write(position, xunion);
+ if (status_write_xunion != ZX_OK) {
+ return TRANSFORMER_FAIL(status_write_xunion, position,
+ "unable to write union-as-xunion header");
+ }
+
+ out_traversal_result->src_out_of_line_size += field_traversal_result.src_out_of_line_size;
+ out_traversal_result->dst_out_of_line_size += FIDL_ALIGN(dst_field_size);
+ out_traversal_result->handle_count += field_traversal_result.handle_count;
+
+ return ZX_OK;
+ }
+
+ zx_status_t TransformOptionalXUnionToUnionPointer(const FidlCodedXUnion& src_coded_xunion,
+ const FidlCodedUnion& dst_coded_union,
+ const Position& position,
+ TraversalResult* out_traversal_result) {
+ auto src_xunion = src_dst->Read<const fidl_xunion_t>(position);
+ if (!src_xunion) {
+ return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "union-as-xunion missing");
+ }
+
+ switch (src_xunion->envelope.presence) {
+ case FIDL_ALLOC_ABSENT:
+ case FIDL_ALLOC_PRESENT: {
+ const auto status = src_dst->Write(position, src_xunion->envelope.presence);
+ if (status != ZX_OK) {
+ return TRANSFORMER_FAIL(status, position, "unable to write union pointer absence");
+ }
+ if (src_xunion->envelope.presence == FIDL_ALLOC_ABSENT) {
+ return ZX_OK;
+ }
+ break;
+ }
+ default:
+ return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position,
+ "union-as-xunion envelope presence invalid");
+ }
+
+ const uint32_t dst_aligned_size = FIDL_ALIGN(dst_coded_union.size);
+ const auto union_position = Position{
+ position.src_inline_offset,
+ position.src_out_of_line_offset,
+ position.dst_out_of_line_offset,
+ position.dst_out_of_line_offset + dst_aligned_size,
+ };
+
+ out_traversal_result->dst_out_of_line_size += dst_aligned_size;
+
+ return TransformXUnionToUnion(src_coded_xunion, dst_coded_union, union_position,
+ FIDL_ALIGN(dst_coded_union.size), out_traversal_result);
+ }
+
+ zx_status_t TransformXUnionToUnion(const FidlCodedXUnion& src_coded_xunion,
+ const FidlCodedUnion& dst_coded_union,
+ const Position& position, uint32_t dst_size,
+ TraversalResult* out_traversal_result) {
+ TRANSFORMER_ASSERT(src_coded_xunion.field_count == dst_coded_union.field_count, position);
+
+ // Read: extensible-union ordinal.
+ const auto src_xunion = src_dst->Read<const fidl_xunion_t>(position);
+ if (!src_xunion) {
+ return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "union-as-xunion missing");
+ }
+
+ switch (src_xunion->envelope.presence) {
+ case FIDL_ALLOC_PRESENT:
+ // OK
+ break;
+ case FIDL_ALLOC_ABSENT:
+ return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position,
+ "union-as-xunion envelope is invalid FIDL_ALLOC_ABSENT");
+ default:
+ return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position,
+ "union-as-xunion envelope presence invalid");
+ }
+
+ // Retrieve: flexible-union field (or variant).
+ bool src_field_found = false;
+ uint32_t src_field_index = 0;
+ const FidlXUnionField* src_field = nullptr;
+ for (/* src_field_index needed after the loop */;
+ src_field_index < src_coded_xunion.field_count; src_field_index++) {
+ const FidlXUnionField* candidate_src_field = &src_coded_xunion.fields[src_field_index];
+ if (candidate_src_field->ordinal == src_xunion->tag) {
+ src_field_found = true;
+ src_field = candidate_src_field;
+ break;
+ }
+ }
+ if (!src_field_found) {
+ return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "ordinal has no corresponding variant");
+ }
+
+ const FidlUnionField& dst_field = dst_coded_union.fields[src_field_index];
+
+ // Write: static-union tag, and pad (if needed).
+ switch (dst_coded_union.data_offset) {
+ case 4: {
+ const auto status = src_dst->Write(position, src_field_index);
+ if (status != ZX_OK) {
+ return TRANSFORMER_FAIL(status, position, "unable to write union tag");
+ }
+ break;
+ }
+ case 8: {
+ const auto status = src_dst->Write(position, static_cast<uint64_t>(src_field_index));
+ if (status != ZX_OK) {
+ return TRANSFORMER_FAIL(status, position, "unable to write union tag");
+ }
+ break;
+ }
+ default:
+ TRANSFORMER_ASSERT(false && "static-union data offset can only be 4 or 8", position);
+ }
+
+ const uint32_t src_field_inline_size = [&] {
+ if (!src_field->type) {
+ // src_field's type is either a primitive or an array of primitives,
+ // because src_field->type is nullptr. There's no size information
+ // available for the field in the coding tables, but since the data is a
+ // primitive or array of primitives, there can never be any out-of-line
+ // data, so it's safe to use the envelope's num_bytes to determine the
+ // field's inline size.
+ return src_xunion->envelope.num_bytes;
+ }
+
+ return FIDL_ALIGN(InlineSize(src_field->type, From(), position));
+ }();
+
+ // Transform: xunion field to static-union field (or variant).
+ auto field_position = Position{
+ position.src_out_of_line_offset,
+ position.src_out_of_line_offset + src_field_inline_size,
+ position.dst_inline_offset + dst_coded_union.data_offset,
+ position.dst_out_of_line_offset,
+ };
+ uint32_t dst_field_unpadded_size =
+ dst_coded_union.size - dst_coded_union.data_offset - dst_field.padding;
+
+ zx_status_t status =
+ Transform(src_field->type, field_position, dst_field_unpadded_size, out_traversal_result);
+ if (status != ZX_OK) {
+ return status;
+ }
+
+ // Pad after static-union data.
+ auto field_padding_position = field_position.IncreaseDstInlineOffset(dst_field_unpadded_size);
+ const auto dst_padding = (dst_size - dst_coded_union.size) + dst_field.padding;
+ const auto status_pad_field = src_dst->Pad(field_padding_position, dst_padding);
+ if (status_pad_field != ZX_OK) {
+ return TRANSFORMER_FAIL(status_pad_field, field_padding_position,
+ "unable to pad union variant");
+ }
+
+ out_traversal_result->src_out_of_line_size += src_field_inline_size;
+ return ZX_OK;
+ }
+
+ virtual WireFormat From() const = 0;
+ virtual WireFormat To() const = 0;
+
+ inline zx_status_t Fail(zx_status_t status, const Position& position, const int line_number,
+ const char* error_msg) {
+ debug_info_->RecordFailure(line_number, error_msg, position);
+ return status;
+ }
+
+ SrcDst* src_dst;
+ DebugInfo* const debug_info_;
+
+ private:
+ const fidl_type_t* top_level_src_type_;
+};
+
+class V1ToOld final : public TransformerBase {
+ public:
+ V1ToOld(SrcDst* src_dst, const fidl_type_t* top_level_src_type, DebugInfo* debug_info)
+ : TransformerBase(src_dst, top_level_src_type, debug_info) {}
+
+ WireFormat From() const override { return WireFormat::kV1; }
+ WireFormat To() const override { return WireFormat::kOld; }
+};
+
+class OldToV1 final : public TransformerBase {
+ public:
+ OldToV1(SrcDst* src_dst, const fidl_type_t* top_level_src_type, DebugInfo* debug_info)
+ : TransformerBase(src_dst, top_level_src_type, debug_info) {}
+
+ private:
+ WireFormat From() const override { return WireFormat::kOld; }
+ WireFormat To() const override { return WireFormat::kV1; }
+};
+
+} // namespace
+
+zx_status_t fidl_transform(fidl_transformation_t transformation, const fidl_type_t* src_type,
+ const uint8_t* src_bytes, uint32_t src_num_bytes, uint8_t* dst_bytes,
+ uint32_t dst_num_bytes_capacity, uint32_t* out_dst_num_bytes,
+ const char** out_error_msg) {
+ if (!src_type || !src_bytes || !dst_bytes || !out_dst_num_bytes || !FidlIsAligned(src_bytes) ||
+ !FidlIsAligned(dst_bytes)) {
+ return ZX_ERR_INVALID_ARGS;
+ }
+
+ SrcDst src_dst(src_bytes, src_num_bytes, dst_bytes, dst_num_bytes_capacity);
+ DebugInfo debug_info(transformation, src_type, src_dst, out_error_msg);
+
+ const zx_status_t status = [&] {
+ switch (transformation) {
+ case FIDL_TRANSFORMATION_NONE: {
+ const auto start = Position{
+ 0, UINT16_MAX, /* unused: src_out_of_line_offset */
+ 0, UINT16_MAX, /* unused: dst_out_of_line_offset */
+ };
+ return src_dst.Copy(start, src_num_bytes);
+ }
+ case FIDL_TRANSFORMATION_V1_TO_OLD:
+ return V1ToOld(&src_dst, src_type, &debug_info).TransformTopLevelStruct();
+ case FIDL_TRANSFORMATION_OLD_TO_V1:
+ return OldToV1(&src_dst, src_type, &debug_info).TransformTopLevelStruct();
+ default:
+ debug_info.RecordFailure(__LINE__, "unsupported transformation");
+ return ZX_ERR_INVALID_ARGS;
+ }
+ }();
+
+ if (status != ZX_OK) {
+ return status;
+ }
+
+ if (FIDL_ALIGN(src_dst.src_max_offset_read()) != src_num_bytes) {
+ debug_info.RecordFailure(__LINE__, "did not read all provided bytes during transformation");
+ return ZX_ERR_INVALID_ARGS;
+ }
+
+ *out_dst_num_bytes = src_dst.dst_max_offset_written();
+ return ZX_OK;
+}
+
+#pragma GCC diagnostic pop // "-Wimplicit-fallthrough"
diff --git a/third_party/fuchsia-sdk/pkg/fidl_base/txn_header.c b/third_party/fuchsia-sdk/pkg/fidl_base/txn_header.c
new file mode 100644
index 0000000..8a43a5b
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_base/txn_header.c
@@ -0,0 +1,21 @@
+// 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.
+
+#include <lib/fidl/txn_header.h>
+#include <zircon/errors.h>
+#include <zircon/fidl.h>
+
+void fidl_init_txn_header(fidl_message_header_t* out_hdr, zx_txid_t txid, uint64_t ordinal) {
+ out_hdr->txid = txid;
+ out_hdr->flags[0] = 0;
+ out_hdr->flags[1] = 0;
+ out_hdr->flags[2] = 0;
+ out_hdr->magic_number = kFidlWireFormatMagicNumberInitial;
+ out_hdr->ordinal = ordinal;
+}
+
+zx_status_t fidl_validate_txn_header(const fidl_message_header_t* hdr) {
+ return hdr->magic_number == kFidlWireFormatMagicNumberInitial ? ZX_OK
+ : ZX_ERR_PROTOCOL_NOT_SUPPORTED;
+}
diff --git a/third_party/fuchsia-sdk/pkg/fidl_base/validate_string.cc b/third_party/fuchsia-sdk/pkg/fidl_base/validate_string.cc
new file mode 100644
index 0000000..44186c2
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_base/validate_string.cc
@@ -0,0 +1,87 @@
+// Copyright 2020 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.
+
+#include <lib/fidl/coding.h>
+
+zx_status_t fidl_validate_string(const char* data, uint64_t size) {
+ if (!data) {
+ return ZX_ERR_INVALID_ARGS;
+ }
+ if (size > FIDL_MAX_SIZE) {
+ return ZX_ERR_INVALID_ARGS;
+ }
+
+ uint64_t pos = 0;
+ uint64_t next_pos = 0;
+ uint32_t code_point = 0;
+ while (pos < size) {
+ // The following comparison relies on treating the byte as if it was an
+ // unsigned 8-bit value. However, both signed and unsigned char are allowed
+ // in the C++ spec, with x64 choosing signed, and arm64 choosing unsigned.
+ // We therefore force the byte to be treated as unsigned, since we cannot
+ // rely on the default.
+ unsigned char byte = data[pos];
+ if (byte < 0b10000000) {
+ pos++;
+ continue;
+ } else if ((byte & 0b11100000) == 0b11000000) {
+ next_pos = pos + 2;
+ if (next_pos > size) {
+ return ZX_ERR_INVALID_ARGS;
+ }
+ if ((data[pos + 1] & 0b11000000) != 0b10000000) {
+ return ZX_ERR_INVALID_ARGS;
+ }
+ // range check
+ code_point = (byte & 0b00011111) << 6 |
+ (data[pos + 1] & 0b00111111);
+ if (code_point < 0x80 || 0x7ff < code_point) {
+ return ZX_ERR_INVALID_ARGS;
+ }
+ } else if ((byte & 0b11110000) == 0b11100000) {
+ next_pos = pos + 3;
+ if (next_pos > size) {
+ return ZX_ERR_INVALID_ARGS;
+ }
+ if ((data[pos + 1] & 0b11000000) != 0b10000000) {
+ return ZX_ERR_INVALID_ARGS;
+ }
+ if ((data[pos + 2] & 0b11000000) != 0b10000000) {
+ return ZX_ERR_INVALID_ARGS;
+ }
+ // range check
+ code_point = (byte & 0b00001111) << 12 |
+ (data[pos + 1] & 0b00111111) << 6 |
+ (data[pos + 2] & 0b00111111);
+ if (code_point < 0x800 || 0xffff < code_point ||
+ (0xd7ff < code_point && code_point < 0xe000)) {
+ return ZX_ERR_INVALID_ARGS;
+ }
+ } else { // 0b11110000
+ next_pos = pos + 4;
+ if (next_pos > size) {
+ return ZX_ERR_INVALID_ARGS;
+ }
+ if ((data[pos + 1] & 0b11000000) != 0b10000000) {
+ return ZX_ERR_INVALID_ARGS;
+ }
+ if ((data[pos + 2] & 0b11000000) != 0b10000000) {
+ return ZX_ERR_INVALID_ARGS;
+ }
+ if ((data[pos + 3] & 0b11000000) != 0b10000000) {
+ return ZX_ERR_INVALID_ARGS;
+ }
+ // range check
+ code_point = (byte & 0b00000111) << 18 |
+ (data[pos + 1] & 0b00111111) << 12 |
+ (data[pos + 2] & 0b00111111) << 6 |
+ (data[pos + 3] & 0b00111111);
+ if (code_point < 0xffff || 0x10ffff < code_point) {
+ return ZX_ERR_INVALID_ARGS;
+ }
+ }
+ pos = next_pos;
+ }
+ return ZX_OK;
+}
diff --git a/third_party/fuchsia-sdk/pkg/fidl_base/validating.cc b/third_party/fuchsia-sdk/pkg/fidl_base/validating.cc
new file mode 100644
index 0000000..f6784c9
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_base/validating.cc
@@ -0,0 +1,241 @@
+// Copyright 2017 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.
+
+#include <lib/fidl/coding.h>
+#include <lib/fidl/envelope_frames.h>
+#include <lib/fidl/internal.h>
+#include <lib/fidl/visitor.h>
+#include <lib/fidl/walker.h>
+#include <stdalign.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <zircon/assert.h>
+#include <zircon/compiler.h>
+
+// TODO(kulakowski) Design zx_status_t error values.
+
+namespace {
+
+struct Position;
+
+struct StartingPoint {
+ const uint8_t* const addr;
+ Position ToPosition() const;
+};
+
+struct Position {
+ uint32_t offset;
+ Position operator+(uint32_t size) const { return Position{offset + size}; }
+ Position& operator+=(uint32_t size) {
+ offset += size;
+ return *this;
+ }
+ template <typename T>
+ constexpr const T* Get(StartingPoint start) const {
+ return reinterpret_cast<const T*>(start.addr + offset);
+ }
+};
+
+Position StartingPoint::ToPosition() const { return Position{0}; }
+
+constexpr uintptr_t kAllocPresenceMarker = FIDL_ALLOC_PRESENT;
+constexpr uintptr_t kAllocAbsenceMarker = FIDL_ALLOC_ABSENT;
+
+using EnvelopeState = ::fidl::EnvelopeFrames::EnvelopeState;
+
+class FidlValidator final
+ : public fidl::Visitor<fidl::NonMutatingVisitorTrait, StartingPoint, Position> {
+ public:
+ FidlValidator(const void* bytes, uint32_t num_bytes, uint32_t num_handles,
+ uint32_t next_out_of_line, const char** out_error_msg)
+ : bytes_(static_cast<const uint8_t*>(bytes)),
+ num_bytes_(num_bytes),
+ num_handles_(num_handles),
+ next_out_of_line_(next_out_of_line),
+ out_error_msg_(out_error_msg) {}
+
+ using StartingPoint = StartingPoint;
+
+ using Position = Position;
+
+ static constexpr bool kContinueAfterConstraintViolation = true;
+
+ static constexpr bool kAllowNonNullableCollectionsToBeAbsent = false;
+
+ Status VisitPointer(Position ptr_position, PointeeType pointee_type,
+ ObjectPointerPointer object_ptr_ptr, uint32_t inline_size,
+ Position* out_position) {
+ if (reinterpret_cast<uintptr_t>(*object_ptr_ptr) != kAllocPresenceMarker) {
+ SetError("validator encountered invalid pointer");
+ return Status::kConstraintViolationError;
+ }
+ uint32_t new_offset;
+ if (!FidlAddOutOfLine(next_out_of_line_, inline_size, &new_offset)) {
+ SetError("overflow updating out-of-line offset");
+ return Status::kMemoryError;
+ }
+ if (new_offset > num_bytes_) {
+ SetError("message tried to access more than provided number of bytes");
+ return Status::kMemoryError;
+ }
+ auto status = ValidatePadding(&bytes_[next_out_of_line_ + inline_size],
+ new_offset - next_out_of_line_ - inline_size);
+ if (status != Status::kSuccess) {
+ return status;
+ }
+ *out_position = Position{next_out_of_line_};
+ next_out_of_line_ = new_offset;
+ return Status::kSuccess;
+ }
+
+ Status VisitHandle(Position handle_position, HandlePointer handle, zx_rights_t handle_rights,
+ zx_obj_type_t handle_subtype) {
+ if (*handle != FIDL_HANDLE_PRESENT) {
+ SetError("message contains a garbage handle");
+ return Status::kConstraintViolationError;
+ }
+ if (handle_idx_ == num_handles_) {
+ SetError("message has too many handles");
+ return Status::kConstraintViolationError;
+ }
+ handle_idx_++;
+ return Status::kSuccess;
+ }
+
+ Status VisitVectorOrStringCount(CountPointer ptr) { return Status::kSuccess; }
+
+ Status VisitInternalPadding(Position padding_position, uint32_t padding_length) {
+ auto padding_ptr = padding_position.template Get<const uint8_t>(StartingPoint{bytes_});
+ return ValidatePadding(padding_ptr, padding_length);
+ }
+
+ Status EnterEnvelope(Position envelope_position, EnvelopePointer envelope,
+ const fidl_type_t* payload_type) {
+ if (envelope->presence == kAllocAbsenceMarker &&
+ (envelope->num_bytes != 0 || envelope->num_handles != 0)) {
+ SetError("Envelope has absent data pointer, yet has data and/or handles");
+ return Status::kConstraintViolationError;
+ }
+ if (envelope->presence != kAllocAbsenceMarker && envelope->num_bytes == 0) {
+ SetError("Envelope has present data pointer, but zero byte count");
+ return Status::kConstraintViolationError;
+ }
+ uint32_t expected_handle_count;
+ if (add_overflow(handle_idx_, envelope->num_handles, &expected_handle_count) ||
+ expected_handle_count > num_handles_) {
+ SetError("Envelope has more handles than expected");
+ return Status::kConstraintViolationError;
+ }
+ // Remember the current watermark of bytes and handles, so that after processing
+ // the envelope, we can validate that the claimed num_bytes/num_handles matches the reality.
+ if (!envelope_frames_.Push(EnvelopeState(next_out_of_line_, handle_idx_))) {
+ SetError("Overly deep nested envelopes");
+ return Status::kConstraintViolationError;
+ }
+ // If we do not have the coding table for this payload,
+ // treat it as unknown and add its contained handles
+ if (envelope->presence != kAllocAbsenceMarker && payload_type == nullptr) {
+ handle_idx_ += envelope->num_handles;
+ }
+ return Status::kSuccess;
+ }
+
+ Status LeaveEnvelope(Position envelope_position, EnvelopePointer envelope) {
+ // Now that the envelope has been consumed, check the correctness of the envelope header.
+ auto& starting_state = envelope_frames_.Pop();
+ uint32_t num_bytes = next_out_of_line_ - starting_state.bytes_so_far;
+ uint32_t num_handles = handle_idx_ - starting_state.handles_so_far;
+ if (envelope->num_bytes != num_bytes) {
+ SetError("Envelope num_bytes was mis-sized");
+ return Status::kConstraintViolationError;
+ }
+ if (envelope->num_handles != num_handles) {
+ SetError("Envelope num_handles was mis-sized");
+ return Status::kConstraintViolationError;
+ }
+ return Status::kSuccess;
+ }
+
+ void OnError(const char* error) { SetError(error); }
+
+ zx_status_t status() const { return status_; }
+
+ bool DidConsumeAllBytes() const { return next_out_of_line_ == num_bytes_; }
+
+ bool DidConsumeAllHandles() const { return handle_idx_ == num_handles_; }
+
+ private:
+ void SetError(const char* error) {
+ if (status_ == ZX_OK) {
+ status_ = ZX_ERR_INVALID_ARGS;
+ if (out_error_msg_ != nullptr) {
+ *out_error_msg_ = error;
+ }
+ }
+ }
+
+ Status ValidatePadding(const uint8_t* padding_ptr, uint32_t padding_length) {
+ for (uint32_t i = 0; i < padding_length; i++) {
+ if (padding_ptr[i] != 0) {
+ SetError("non-zero padding bytes detected");
+ return Status::kConstraintViolationError;
+ }
+ }
+ return Status::kSuccess;
+ }
+
+ // Message state passed in to the constructor.
+ const uint8_t* bytes_;
+ const uint32_t num_bytes_;
+ const uint32_t num_handles_;
+ uint32_t next_out_of_line_;
+ const char** const out_error_msg_;
+
+ // Validator state
+ zx_status_t status_ = ZX_OK;
+ uint32_t handle_idx_ = 0;
+ fidl::EnvelopeFrames envelope_frames_;
+};
+
+} // namespace
+
+zx_status_t fidl_validate(const fidl_type_t* type, const void* bytes, uint32_t num_bytes,
+ uint32_t num_handles, const char** out_error_msg) {
+ auto set_error = [&out_error_msg](const char* msg) {
+ if (out_error_msg)
+ *out_error_msg = msg;
+ };
+ if (bytes == nullptr) {
+ set_error("Cannot validate null bytes");
+ return ZX_ERR_INVALID_ARGS;
+ }
+
+ uint32_t next_out_of_line;
+ zx_status_t status;
+ if ((status = fidl::StartingOutOfLineOffset(type, num_bytes, &next_out_of_line, out_error_msg)) !=
+ ZX_OK) {
+ return status;
+ }
+
+ FidlValidator validator(bytes, num_bytes, num_handles, next_out_of_line, out_error_msg);
+ fidl::Walk(validator, type, StartingPoint{reinterpret_cast<const uint8_t*>(bytes)});
+
+ if (validator.status() == ZX_OK) {
+ if (!validator.DidConsumeAllBytes()) {
+ set_error("message did not consume all provided bytes");
+ return ZX_ERR_INVALID_ARGS;
+ }
+ if (!validator.DidConsumeAllHandles()) {
+ set_error("message did not reference all provided handles");
+ return ZX_ERR_INVALID_ARGS;
+ }
+ }
+
+ return validator.status();
+}
+
+zx_status_t fidl_validate_msg(const fidl_type_t* type, const fidl_msg_t* msg,
+ const char** out_error_msg) {
+ return fidl_validate(type, msg->bytes, msg->num_bytes, msg->num_handles, out_error_msg);
+}
diff --git a/third_party/fuchsia-sdk/pkg/fidl_base/walker.cc b/third_party/fuchsia-sdk/pkg/fidl_base/walker.cc
new file mode 100644
index 0000000..8676800
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_base/walker.cc
@@ -0,0 +1,58 @@
+// Copyright 2018 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.
+
+#include <lib/fidl/walker.h>
+
+#include <cstdint>
+#include <limits>
+
+namespace fidl {
+
+zx_status_t PrimaryObjectSize(const fidl_type_t* type, size_t* out_size, const char** out_error) {
+ auto set_error = [&out_error](const char* msg) {
+ if (out_error)
+ *out_error = msg;
+ };
+ if (type == nullptr) {
+ set_error("fidl type cannot be null");
+ return ZX_ERR_INVALID_ARGS;
+ }
+ switch (type->type_tag) {
+ case kFidlTypeStruct:
+ *out_size = type->coded_struct.size;
+ return ZX_OK;
+ case kFidlTypeTable:
+ *out_size = sizeof(fidl_vector_t);
+ return ZX_OK;
+ default:
+ set_error("Message must be a struct or a table");
+ return ZX_ERR_INVALID_ARGS;
+ }
+}
+
+zx_status_t StartingOutOfLineOffset(const fidl_type_t* type, uint32_t buffer_size,
+ uint32_t* out_first_out_of_line, const char** out_error) {
+ auto set_error = [&out_error](const char* msg) {
+ if (out_error)
+ *out_error = msg;
+ };
+ size_t primary_size;
+ zx_status_t status;
+ if ((status = PrimaryObjectSize(type, &primary_size, out_error)) != ZX_OK) {
+ return status;
+ }
+ if (primary_size > buffer_size) {
+ set_error("Buffer is too small for first inline object");
+ return ZX_ERR_INVALID_ARGS;
+ }
+ uint64_t first_out_of_line = FidlAlign(static_cast<uint32_t>(primary_size));
+ if (first_out_of_line > std::numeric_limits<uint32_t>::max()) {
+ set_error("Out of line starting offset overflows");
+ return ZX_ERR_INVALID_ARGS;
+ }
+ *out_first_out_of_line = static_cast<uint32_t>(first_out_of_line);
+ return ZX_OK;
+}
+
+} // namespace fidl
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/BUILD.gn b/third_party/fuchsia-sdk/pkg/fidl_cpp/BUILD.gn
new file mode 100644
index 0000000..c7c769c
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/BUILD.gn
@@ -0,0 +1,60 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("fidl_cpp") {
+ sources = [
+ "internal/message_handler.cc",
+ "internal/message_reader.cc",
+ "internal/pending_response.cc",
+ "internal/proxy.cc",
+ "internal/proxy_controller.cc",
+ "internal/stub.cc",
+ "internal/stub_controller.cc",
+ "internal/weak_stub_controller.cc",
+ "include/lib/fidl/cpp/binding.h",
+ "include/lib/fidl/cpp/binding_set.h",
+ "include/lib/fidl/cpp/enum.h",
+ "include/lib/fidl/cpp/event_sender.h",
+ "include/lib/fidl/cpp/interface_ptr.h",
+ "include/lib/fidl/cpp/interface_ptr_set.h",
+ "include/lib/fidl/cpp/internal/header.h",
+ "include/lib/fidl/cpp/internal/implementation.h",
+ "include/lib/fidl/cpp/internal/message_handler.h",
+ "include/lib/fidl/cpp/internal/message_reader.h",
+ "include/lib/fidl/cpp/internal/pending_response.h",
+ "include/lib/fidl/cpp/internal/proxy.h",
+ "include/lib/fidl/cpp/internal/proxy_controller.h",
+ "include/lib/fidl/cpp/internal/stub.h",
+ "include/lib/fidl/cpp/internal/stub_controller.h",
+ "include/lib/fidl/cpp/internal/weak_stub_controller.h",
+ "include/lib/fidl/cpp/member_connector.h",
+ "include/lib/fidl/cpp/optional.h",
+ "include/lib/fidl/cpp/service_connector.h",
+ "include/lib/fidl/cpp/service_handler_base.h",
+ "include/lib/fidl/cpp/thread_safe_binding_set.h",
+ "include/lib/fidl/cpp/type_converter.h",
+ ]
+ include_dirs = [ "include" ]
+ public_deps = [
+ "../async",
+ "../async-default",
+ "../fidl",
+ "../fidl-async",
+ "../fidl_cpp_sync",
+ "../fit",
+ "../zx",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fidl_cpp",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/binding.h b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/binding.h
new file mode 100644
index 0000000..7267f1c
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/binding.h
@@ -0,0 +1,252 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_BINDING_H_
+#define LIB_FIDL_CPP_BINDING_H_
+
+#include <lib/async/dispatcher.h>
+#include <lib/fidl/cpp/interface_handle.h>
+#include <lib/fidl/cpp/interface_ptr.h>
+#include <lib/fidl/cpp/interface_request.h>
+#include <lib/fidl/cpp/internal/stub_controller.h>
+#include <lib/fit/function.h>
+#include <lib/zx/channel.h>
+#include <zircon/assert.h>
+
+#include <memory>
+#include <utility>
+
+namespace fidl {
+
+// Binds the implementation of |Interface| to a channel.
+//
+// The |Binding| listens for incoming messages on the channel, decodes them, and
+// calls the appropriate method on the bound implementation. If the message
+// expects a reply, the |Binding| creates callbacks that encode and send
+// reply messages when called.
+//
+// When the |Binding| object is destroyed, the binding between the channel
+// and the interface is torn down and the channel is closed, leaving the
+// |Binding| in an unbound state.
+//
+// The implementation pointer type of the binding is also parameterized,
+// allowing the use of smart pointer types such as |std::unique_ptr| to
+// reference the implementation.
+//
+// Example:
+//
+// #include "foo.fidl.h"
+//
+// class FooImpl : public Foo {
+// public:
+// explicit FooImpl(InterfaceRequest<Foo> request)
+// : binding_(this, std::move(request)) {}
+//
+// // Foo implementation here.
+//
+// private:
+// Binding<Foo> binding_;
+// };
+//
+// After the |Binding| has been bound to an implementation, the implementation
+// will receive methods calls from the remote endpoint of the channel on the
+// async_dispatcher_t to which the |InterfaceRequest| was bound. By default this
+// is the thread on which the binding occurred.
+//
+// See also:
+//
+// * |InterfacePtr|, which is the client analog of a |Binding|.
+// * |EventSender|, which can send messages from multiple threads safely.
+template <typename Interface, typename ImplPtr = Interface*>
+class Binding final {
+ private:
+ template <class T>
+ struct is_unique_ptr : std::false_type {};
+
+ template <class T, class D>
+ struct is_unique_ptr<std::unique_ptr<T, D>> : std::true_type {};
+
+ template <class T>
+ struct is_shared_ptr : std::false_type {};
+
+ template <class T>
+ struct is_shared_ptr<std::shared_ptr<T>> : std::true_type {};
+
+ static_assert(std::is_pointer<ImplPtr>::value || is_unique_ptr<ImplPtr>::value ||
+ is_shared_ptr<ImplPtr>::value,
+ "Binding only supports ImplPtr which are pointers");
+
+ public:
+ // Constructs an incomplete binding that will use the implementation |impl|.
+ //
+ // The binding may be completed with a subsequent call to the |Bind| method.
+ // Does not take ownership of |impl|, which must outlive the binding.
+ explicit Binding(ImplPtr impl) : impl_(std::forward<ImplPtr>(impl)), stub_(&*this->impl()) {
+ controller_.set_stub(&stub_);
+ stub_.set_sender(&controller_);
+ }
+
+ // Constructs a completed binding of |channel| to implementation |impl|.
+ //
+ // Does not take ownership of |impl|, which must outlive the binding.
+ //
+ // If the |Binding| cannot be bound to the given |channel| (e.g., because
+ // the |channel| lacks |ZX_RIGHT_WAIT|), the |Binding| will be constructed
+ // in an unbound state.
+ //
+ // Uses the given async_dispatcher_t (e.g., a message loop) in order to read
+ // messages from the channel and to monitor the channel for
+ // |ZX_CHANNEL_PEER_CLOSED|. If |dispatcher| is null, the current thread must
+ // have a default async_dispatcher_t.
+ Binding(ImplPtr impl, zx::channel channel, async_dispatcher_t* dispatcher = nullptr)
+ : Binding(std::forward<ImplPtr>(impl)) {
+ Bind(std::move(channel), dispatcher);
+ }
+
+ // Constructs a completed binding of |impl| to the channel in |request|.
+ //
+ // Does not take ownership of |impl|, which must outlive the binding.
+ //
+ // If the |Binding| cannot be bound to the given |channel| (e.g., because
+ // the |channel| lacks |ZX_RIGHT_WAIT|), the |Binding| will be constructed
+ // in an unbound state.
+ //
+ // Uses the given async_dispatcher_t (e.g., a message loop) in order to read
+ // messages from the channel and to monitor the channel for
+ // |ZX_CHANNEL_PEER_CLOSED|. If |dispatcher| is null, the current thread must
+ // have a default async_dispatcher_t.
+ Binding(ImplPtr impl, InterfaceRequest<Interface> request,
+ async_dispatcher_t* dispatcher = nullptr)
+ : Binding(std::forward<ImplPtr>(impl)) {
+ Bind(request.TakeChannel(), dispatcher);
+ }
+
+ Binding(const Binding&) = delete;
+ Binding& operator=(const Binding&) = delete;
+
+ // The implementation of this class provides external references to class members via pointers.
+ // As a result, instances cannot be move-constructed or move-assigned.
+ Binding(Binding&&) = delete;
+ Binding& operator=(Binding&&) = delete;
+
+ // Completes a binding by creating a new channel, binding one endpoint to
+ // the previously specified implementation and returning the other endpoint.
+ //
+ // If |NewBinding| fails to create the underlying channel, the returned
+ // |InterfaceHandle| will return false from |is_valid()|.
+ //
+ // Uses the given async_dispatcher_t (e.g., a message loop) in order to read
+ // messages from the channel and to monitor the channel for
+ // |ZX_CHANNEL_PEER_CLOSED|. If |dispatcher| is null, the current thread must
+ // have a default async_dispatcher_t.
+ InterfaceHandle<Interface> NewBinding(async_dispatcher_t* dispatcher = nullptr) {
+ InterfaceHandle<Interface> client;
+ Bind(client.NewRequest().TakeChannel(), dispatcher);
+ return client;
+ }
+
+ // Binds the previously specified implementation to the given |channel|.
+ //
+ // If the |Binding| was prevously bound to another channel, that channel is
+ // closed.
+ //
+ // Uses the given async_dispatcher_t (e.g., a message loop) in order to read
+ // messages from the channel and to monitor the channel for
+ // |ZX_CHANNEL_PEER_CLOSED|. If |dispatcher| is null, the current thread must
+ // have a default async_dispatcher_t.
+ //
+ // Returns an error if the binding was not able to be created (e.g., because
+ // the |channel| lacks |ZX_RIGHT_WAIT|).
+ zx_status_t Bind(zx::channel channel, async_dispatcher_t* dispatcher = nullptr) {
+ return controller_.reader().Bind(std::move(channel), dispatcher);
+ }
+
+ // Binds the previously specified implementation to the given
+ // |InterfaceRequest|.
+ //
+ // If the |Binding| was prevously bound to another channel, that channel is
+ // closed.
+ //
+ // Uses the given async_dispatcher_t (e.g., a message loop) in order to read
+ // messages from the channel and to monitor the channel for
+ // |ZX_CHANNEL_PEER_CLOSED|. If |dispatcher| is null, the current thread must
+ // have a default async_dispatcher_t.
+ //
+ // Returns an error if the binding was not able to be created (e.g., because
+ // the |channel| lacks |ZX_RIGHT_WAIT|).
+ zx_status_t Bind(InterfaceRequest<Interface> request, async_dispatcher_t* dispatcher = nullptr) {
+ return Bind(request.TakeChannel(), dispatcher);
+ }
+
+ // Unbinds the underlying channel from this binding and returns it so it can
+ // be used in another context, such as on another thread or with a different
+ // implementation.
+ //
+ // After this function returns, the |Binding| is ready to be bound to another
+ // channel.
+ InterfaceRequest<Interface> Unbind() {
+ return InterfaceRequest<Interface>(controller_.reader().Unbind());
+ }
+
+ // Sends an Epitaph over the bound channel corresponding to the error passed
+ // as a parameter, closes the channel, and unbinds it. An Epitaph is the last
+ // message sent over a channel before a close operation; for the purposes of
+ // this function, it can be thought of as a return code. See the FIDL
+ // language spec for more information about Epitaphs.
+ //
+ // The return value can be any of the return values of zx_channel_write.
+ zx_status_t Close(zx_status_t epitaph_value) { return controller_.reader().Close(epitaph_value); }
+
+ // Blocks the calling thread until either a message arrives on the previously
+ // bound channel or an error occurs.
+ //
+ // Returns an error if waiting for the message, reading the message, or
+ // processing the message fails. If the error results in the channel being
+ // closed, the error handler will be called synchronously before this
+ // method returns.
+ //
+ // This method can be called only if this |Binding| is currently bound to a
+ // channel.
+ zx_status_t WaitForMessage() {
+ return controller_.reader().WaitAndDispatchOneMessageUntil(zx::time::infinite());
+ }
+
+ // Sets an error handler that will be called if an error causes the underlying
+ // channel to be closed.
+ //
+ // If the error is being reported because an error occurred on the local side
+ // of the channel, the zx_status_t of that error will be passed as the
+ // parameter to the handler.
+ //
+ // For example, the error handler will be called if the remote side of the
+ // channel sends an invalid message. When the error handler is called, the
+ // |Binding| will no longer be bound to the channel.
+ void set_error_handler(fit::function<void(zx_status_t)> error_handler) {
+ controller_.reader().set_error_handler(std::move(error_handler));
+ }
+
+ // The implementation used by this |Binding| to process incoming messages.
+ const ImplPtr& impl() const { return impl_; }
+
+ // The interface for sending events back to the client.
+ typename Interface::EventSender_& events() { return stub_; }
+
+ // Whether this |Binding| is currently listening to a channel.
+ bool is_bound() const { return controller_.reader().is_bound(); }
+
+ // The underlying channel.
+ const zx::channel& channel() const { return controller_.reader().channel(); }
+
+ // The |async_dispatcher_t| to which this binding is bound, if any.
+ async_dispatcher_t* dispatcher() const { return controller_.reader().dispatcher(); }
+
+ private:
+ const ImplPtr impl_;
+ typename Interface::Stub_ stub_;
+ internal::StubController controller_;
+};
+
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_BINDING_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/binding_set.h b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/binding_set.h
new file mode 100644
index 0000000..5c05917
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/binding_set.h
@@ -0,0 +1,245 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_BINDING_SET_H_
+#define LIB_FIDL_CPP_BINDING_SET_H_
+
+#include <lib/fit/function.h>
+
+#include <algorithm>
+#include <iostream>
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "lib/fidl/cpp/binding.h"
+
+namespace fidl {
+
+// Manages a set of bindings to implementations owned by the bound channels.
+//
+// The implementation pointer type of the binding is also parameterized,
+// allowing the use of smart pointer types such as |std::unique_ptr<>| to
+// reference the implementation.
+//
+// See also:
+//
+// * |InterfacePtrSet|, which is the client analog of |BindingSet|.
+template <typename Interface, typename ImplPtr = Interface*>
+class BindingSet final {
+ public:
+ using Binding = ::fidl::Binding<Interface, ImplPtr>;
+ using StorageType = std::vector<std::unique_ptr<Binding>>;
+ // TODO(FIDL-761) Use fit::function here instead of std::function.
+ using ErrorHandler = std::function<void(zx_status_t)>;
+
+ using iterator = typename StorageType::iterator;
+
+ BindingSet() = default;
+
+ BindingSet(const BindingSet&) = delete;
+ BindingSet& operator=(const BindingSet&) = delete;
+
+ // The implementation of this class provides external references to class members via pointers.
+ // As a result, instances cannot be move-constructed or move-assigned.
+ BindingSet(BindingSet&&) = delete;
+ BindingSet& operator=(BindingSet&&) = delete;
+
+ // Adds a binding to the set.
+ //
+ // The given |ImplPtr| is bound to the channel underlying the
+ // |InterfaceRequest|. The binding is removed (and the |~ImplPtr| called)
+ // when the created binding has an error (e.g., if the remote endpoint of
+ // the channel sends an invalid message). The binding can also be removed
+ // by calling |RemoveBinding()|.
+ //
+ // Whether this method takes ownership of |impl| depends on |ImplPtr|. If
+ // |ImplPtr| is a raw pointer, then this method does not take ownership of
+ // |impl|. If |ImplPtr| is a |unique_ptr|, then running |~ImplPtr| when the
+ // binding generates an error will delete |impl| because |~ImplPtr| is
+ // |~unique_ptr|, which deletes |impl|.
+ void AddBinding(ImplPtr impl, InterfaceRequest<Interface> request,
+ async_dispatcher_t* dispatcher = nullptr, ErrorHandler handler = nullptr) {
+ bindings_.push_back(
+ std::make_unique<Binding>(std::forward<ImplPtr>(impl), std::move(request), dispatcher));
+ auto* binding = bindings_.back().get();
+ // Set the connection error handler for the newly added Binding to be a
+ // function that will erase it from the vector.
+ binding->set_error_handler(
+ [binding, capture_handler = std::move(handler), this](zx_status_t status) {
+ // Subtle behavior: it is necessary to std::move into a local
+ // variable because the closure is deleted when RemoveOnError
+ // is called.
+ ErrorHandler handler(std::move(capture_handler));
+ this->RemoveOnError(binding);
+ if (handler) {
+ handler(status);
+ }
+ });
+ }
+
+ // Adds a binding to the set for the given implementation.
+ //
+ // Creates a channel for the binding and returns the client endpoint of
+ // the channel as an |InterfaceHandle|. If |AddBinding| fails to create the
+ // underlying channel, the returned |InterfaceHandle| will return false from
+ // |is_valid()|.
+ //
+ // The given |ImplPtr| is bound to the newly created channel. The binding is
+ // removed (and the |~ImplPtr| called) when the created binding has an error
+ // (e.g., if the remote endpoint of the channel sends an invalid message).
+ //
+ // Whether this method takes ownership of |impl| depends on |ImplPtr|. If
+ // |ImplPtr| is a raw pointer, then this method does not take ownership of
+ // |impl|. If |ImplPtr| is a |unique_ptr|, then running |~ImplPtr| when the
+ // binding generates an error will delete |impl| because |~ImplPtr| is
+ // |~unique_ptr|, which deletes |impl|.
+ InterfaceHandle<Interface> AddBinding(ImplPtr impl, async_dispatcher_t* dispatcher = nullptr,
+ ErrorHandler handler = nullptr) {
+ InterfaceHandle<Interface> handle;
+ InterfaceRequest<Interface> request = handle.NewRequest();
+ if (!request)
+ return nullptr;
+ AddBinding(std::forward<ImplPtr>(impl), std::move(request), dispatcher, std::move(handler));
+ return handle;
+ }
+
+ // Removes a binding from the set.
+ //
+ // Returns true iff the binding was successfully found and removed.
+ // Upon removal, the server endpoint of the channel is closed without sending an epitaph.
+ template <class T>
+ bool RemoveBinding(const T& impl) {
+ return RemoveMatchedBinding([&impl](const std::unique_ptr<Binding>& b) {
+ return ResolvePtr(impl) == ResolvePtr(b->impl());
+ });
+ }
+
+ // Removes a binding from the set.
+ //
+ // Returns true iff the binding was successfully found and removed.
+ // Upon removal, the server endpoint of the channel is closed and the epitaph provided is sent.
+
+ template <class T>
+ bool CloseBinding(const T& impl, zx_status_t epitaph_value) {
+ auto binding = ExtractMatchedBinding([&impl](const std::unique_ptr<Binding>& b) {
+ return ResolvePtr(impl) == ResolvePtr(b->impl());
+ });
+
+ if (binding == nullptr)
+ return false;
+
+ binding->Close(epitaph_value);
+
+ CheckIfEmpty();
+ return true;
+ }
+
+ // Returns an InterfaceRequestHandler that binds the incoming
+ // InterfaceRequests this object.
+ InterfaceRequestHandler<Interface> GetHandler(ImplPtr impl,
+ async_dispatcher_t* dispatcher = nullptr) {
+ return [this, impl, dispatcher](InterfaceRequest<Interface> request) {
+ AddBinding(impl, std::move(request), dispatcher);
+ };
+ }
+
+ // Removes all the bindings from the set.
+ //
+ // Closes all the channels associated with this |BindingSet|.
+ // Bindings are destroyed AFTER it is removed from the bindings set. An
+ // example of when this is useful is if an error handler on a binding has
+ // some behavior where it needs to read from the binding set; the set would
+ // then properly reflect that the binding is not present in the set.
+ void CloseAll() {
+ auto bindings_local = std::move(bindings_);
+ bindings_.clear();
+ }
+
+ // Removes all the bindings from the set using the provided epitaph.
+ //
+ // Closes all the channels associated with this |BindingSet| after sending
+ // an epitaph. As with CloseAll(void) above, bindings are destroyed after they
+ // are removed from the bindings set.
+ void CloseAll(zx_status_t epitaph_value) {
+ auto bindings_local = std::move(bindings_);
+ bindings_.clear();
+ for (const auto& binding : bindings_local) {
+ binding->Close(epitaph_value);
+ }
+ }
+
+ // The number of bindings in this |BindingSet|.
+ size_t size() const { return bindings_.size(); }
+
+ // Called when the last binding has been removed from this |BindingSet|.
+ //
+ // This function is not called by |CloseAll| or by |~BindingSet|.
+ void set_empty_set_handler(fit::closure empty_set_handler) {
+ empty_set_handler_ = std::move(empty_set_handler);
+ }
+
+ // The bindings stored in this set.
+ //
+ // This collection of bindings can be invalidated when a |Binding| in the
+ // set encounters a connection error because connection errors causes the
+ // |BindingSet| to remove the |Binding| from the set.
+ const StorageType& bindings() const { return bindings_; }
+
+ private:
+ // Resolve smart pointers with get methods (e.g. shared_ptr, unique_ptr, etc).
+ template <class T, std::enable_if_t<!std::is_pointer<T>::value>* = nullptr>
+ static void* ResolvePtr(T& p) {
+ return reinterpret_cast<void*>(p.get());
+ }
+
+ // Resolve raw pointers.
+ template <class T, std::enable_if_t<std::is_pointer<T>::value>* = nullptr>
+ static void* ResolvePtr(T p) {
+ return reinterpret_cast<void*>(p);
+ }
+
+ // Called when a binding has an error to remove the binding from the set.
+ void RemoveOnError(Binding* binding) {
+ bool found = RemoveMatchedBinding(
+ [binding](const std::unique_ptr<Binding>& b) { return b.get() == binding; });
+ ZX_DEBUG_ASSERT(found);
+ }
+
+ bool RemoveMatchedBinding(std::function<bool(const std::unique_ptr<Binding>&)> binding_matcher) {
+ {
+ auto matching_binding = ExtractMatchedBinding(binding_matcher);
+ if (matching_binding == nullptr)
+ return false;
+ }
+
+ CheckIfEmpty();
+ return true;
+ }
+
+ std::unique_ptr<Binding> ExtractMatchedBinding(
+ std::function<bool(const std::unique_ptr<Binding>&)> binding_matcher) {
+ auto it = std::find_if(bindings_.begin(), bindings_.end(), binding_matcher);
+ if (it == bindings_.end())
+ return nullptr;
+
+ auto binding_local = std::move(*it);
+ binding_local->set_error_handler(nullptr);
+ bindings_.erase(it);
+
+ return binding_local;
+ }
+
+ void CheckIfEmpty() {
+ if (bindings_.empty() && empty_set_handler_)
+ empty_set_handler_();
+ }
+
+ StorageType bindings_;
+ fit::closure empty_set_handler_;
+};
+
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_BINDING_SET_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/enum.h b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/enum.h
new file mode 100644
index 0000000..08bea9d
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/enum.h
@@ -0,0 +1,20 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_ENUM_H_
+#define LIB_FIDL_CPP_ENUM_H_
+
+#include <type_traits>
+
+namespace fidl {
+
+// Converts an enum value to its underlying type.
+template <typename TEnum>
+constexpr auto ToUnderlying(TEnum value) -> typename std::underlying_type<TEnum>::type {
+ return static_cast<typename std::underlying_type<TEnum>::type>(value);
+}
+
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_ENUM_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/event_sender.h b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/event_sender.h
new file mode 100644
index 0000000..53ff654
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/event_sender.h
@@ -0,0 +1,61 @@
+// 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.
+
+#ifndef LIB_FIDL_CPP_EVENT_SENDER_H_
+#define LIB_FIDL_CPP_EVENT_SENDER_H_
+
+#include <lib/fidl/cpp/interface_request.h>
+#include <lib/fidl/cpp/internal/message_sender.h>
+#include <lib/zx/channel.h>
+
+#include <utility>
+
+namespace fidl {
+
+// Sends events for |Interface| on a given channel.
+//
+// An |EventSender| lets its client send events on a given channel. This class
+// differs from |Binding| in that |EventSender| does not listen for incoming
+// messages on the channel, which allows |EventSender| to send messages from
+// multiple threads safely.
+//
+// See also:
+//
+// * |Binding|, which can receive messages as well as send events.
+template <typename Interface>
+class EventSender final : public fidl::internal::MessageSender {
+ public:
+ // Constructs an event sender that sends events through |channel|.
+ explicit EventSender(zx::channel channel) : channel_(std::move(channel)), stub_(nullptr) {
+ stub_.set_sender(this);
+ }
+
+ // Constructs an event sender that sends events through the underlying channel
+ // in |request|.
+ explicit EventSender(InterfaceRequest<Interface> request) : EventSender(request.TakeChannel()) {}
+
+ EventSender(const EventSender&) = delete;
+ EventSender& operator=(const EventSender&) = delete;
+
+ // The interface for sending events back to the client.
+ typename Interface::EventSender_& events() { return stub_; }
+
+ // The underlying channel.
+ const zx::channel& channel() const { return channel_; }
+
+ // Transfers ownership of the underlying channel to the caller.
+ zx::channel TakeChannel() { return std::move(channel_); }
+
+ private:
+ zx_status_t Send(const fidl_type_t* type, Message message) final {
+ return fidl::internal::SendMessage(channel_, type, std::move(message));
+ }
+
+ zx::channel channel_;
+ typename Interface::Stub_ stub_;
+};
+
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_EVENT_SENDER_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/interface_ptr.h b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/interface_ptr.h
new file mode 100644
index 0000000..7b06f6e
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/interface_ptr.h
@@ -0,0 +1,264 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_INTERFACE_PTR_H_
+#define LIB_FIDL_CPP_INTERFACE_PTR_H_
+
+#include <lib/fit/function.h>
+#include <lib/zx/channel.h>
+#include <zircon/assert.h>
+
+#include <algorithm>
+#include <cstddef>
+#include <utility>
+
+#include "lib/fidl/cpp/interface_handle.h"
+#include "lib/fidl/cpp/interface_request.h"
+#include "lib/fidl/cpp/internal/proxy_controller.h"
+
+namespace fidl {
+
+// A client interface to a remote implementation of |Interface|.
+//
+// An |InterfacePtr| implements |Interface| by proxying calls through a
+// |channel| to a remote implementation of |Interface|. Method calls on the
+// |Interface| proxy are encoded and sent through the bound channel to the
+// remote endpoint, which processes them. If the remote endpoint has not yet
+// been bound to an implementation, messages sent on the channel are buffered
+// by the channel, allowing for *pipelined* operation.
+//
+// The |InterfacePtr| also keeps state about the connection and about
+// outstanding request transactions that are expecting replies. When the
+// |InterfacePtr| receives a reply to an outstanding transaction, the
+// |InterfacePtr| decodes the reply and calls the appropriate callback on the
+// thread to which the |InterfacePtr| was bound.
+//
+// You need to bind the |InterfacePtr| before calling any |Interface| methods.
+// There are a number of ways to bind the |InterfacePtr|. See |NewRequest|,
+// |Bind|, and the |Bind| method on |InterfaceHandle|.
+//
+// If the underlying channel experiences an error, the |InterfacePtr| will
+// unbind from the channel and call its error handler.
+//
+// This class is thread-hostile, as is the local proxy it manages. All calls to
+// this class or the proxy should be from the thread to which the
+// |InterfacePtr| was bound. If you need to move the proxy to a different
+// thread, extract the |InterfaceHandle| by calling |Unbind|, and pass the
+// |InterfaceHandle| to a different thread, which the |InterfaceHandle| can be
+// bound to an |InterfacePtr| again. This operation destroys the state about
+// outstanding request transactions that are expecting replies.
+//
+// See also:
+//
+// * |Binding|, which is the server analog of an |InterfacePtr|.
+// * |SynchronousInterfacePtr|, which is a synchronous client interface to a
+// remote implementation.
+template <typename Interface>
+class InterfacePtr final {
+ public:
+ using Proxy = typename Interface::Proxy_;
+
+ // Creates an unbound |InterfacePtr|.
+ InterfacePtr() : impl_(new Impl) {}
+ InterfacePtr(std::nullptr_t) : InterfacePtr() {}
+
+ InterfacePtr(const InterfacePtr& other) = delete;
+ InterfacePtr& operator=(const InterfacePtr& other) = delete;
+
+ InterfacePtr(InterfacePtr&& other) : impl_(std::move(other.impl_)) {
+ other.impl_.reset(new Impl);
+ }
+
+ InterfacePtr& operator=(InterfacePtr&& other) {
+ if (this != &other) {
+ impl_ = std::move(other.impl_);
+ other.impl_.reset(new Impl);
+ }
+ return *this;
+ }
+
+ // Bind the |InterfacePtr| to one endpoint of a newly created channel and
+ // return the other endpoint as an |InterfaceRequest|.
+ //
+ // Typically, the returned |InterfaceRequest| will be sent to a remote process
+ // to be bound to an implementation of |Interface| using a |Binding| object.
+ //
+ // After calling this method, clients can start calling methods on this
+ // |InterfacePtr|. The methods will write messages into the underlying
+ // channel created by |NewRequest|, where they will be buffered by the
+ // underlying channel until the |InterfaceRequest| is bound to an
+ // implementation of |Interface|, potentially in a remote process.
+ //
+ // Uses the given async_dispatcher_t in order to read messages from the
+ // channel and to monitor the channel for |ZX_CHANNEL_PEER_CLOSED|. If
+ // |dispatcher| is null, the current thread must have a default
+ // async_dispatcher_t.
+ //
+ // # Example
+ //
+ // Given the following interface:
+ //
+ // interface Database {
+ // OpenTable(request<Table> table);
+ // };
+ //
+ // The client can use the |NewRequest| method to create the |InterfaceRequest|
+ // object needed by the |OpenTable| method:
+ //
+ // DatabasePtr database = ...; // Connect to database.
+ // TablePtr table;
+ // database->OpenTable(table.NewRequest());
+ //
+ // The client can call methods on |table| immediately.
+ InterfaceRequest<Interface> NewRequest(async_dispatcher_t* dispatcher = nullptr) {
+ zx::channel h1;
+ zx::channel h2;
+ if (zx::channel::create(0, &h1, &h2) != ZX_OK || Bind(std::move(h1), dispatcher) != ZX_OK)
+ return nullptr;
+ return InterfaceRequest<Interface>(std::move(h2));
+ }
+
+ // Binds the |InterfacePtr| to the given |channel|.
+ //
+ // The |InterfacePtr| expects the remote end of the |channel| to speak the
+ // protocol defined by |Interface|. Unlike the |Bind| overload that takes a
+ // |InterfaceHandle| parameter, this |Bind| overload lacks type safety.
+ //
+ // If the |InterfacePtr| was prevously bound to another channel, that channel
+ // is closed. If the |channel| is invalid, then this method will effectively
+ // unbind the |InterfacePtr|. A more direct way to have that effect is to call
+ // |Unbind|.
+ //
+ // Uses the given async_dispatcher_t in order to read messages from the
+ // channel and to monitor the channel for |ZX_CHANNEL_PEER_CLOSED|. If
+ // |dispatcher| is null, the current thread must have a default
+ // async_dispatcher_t.
+ //
+ // Returns an error if the binding was not able to be created (e.g., because
+ // the |channel| lacks |ZX_RIGHT_WAIT|).
+ zx_status_t Bind(zx::channel channel, async_dispatcher_t* dispatcher = nullptr) {
+ return impl_->controller.reader().Bind(std::move(channel), dispatcher);
+ }
+
+ // Binds the |InterfacePtr| to the given |InterfaceHandle|.
+ //
+ // The |InterfacePtr| expects the remote end of the |channel| to speak the
+ // protocol defined by |Interface|. Unlike the |Bind| overload that takes a
+ // |channel| parameter, this |Bind| overload provides type safety.
+ //
+ // If the |InterfacePtr| was prevously bound to another channel, that channel
+ // is closed. If the |InterfaceHandle| is invalid, then this method will
+ // effectively unbind the |InterfacePtr|. A more direct way to have that
+ // effect is to call |Unbind|.
+ //
+ // Uses the given async_dispatcher_t in order to read messages from the
+ // channel and to monitor the channel for |ZX_CHANNEL_PEER_CLOSED|. If
+ // |dispatcher| is null, the current thread must have a default
+ // async_dispatcher_t.
+ //
+ // Returns an error if the binding was not able to be created (e.g., because
+ // the |channel| lacks |ZX_RIGHT_WAIT|).
+ zx_status_t Bind(InterfaceHandle<Interface> handle, async_dispatcher_t* dispatcher = nullptr) {
+ return Bind(handle.TakeChannel(), dispatcher);
+ }
+
+ // Unbinds the underlying channel from the |InterfacePtr|.
+ //
+ // The underlying channel is returned as an |InterfaceHandle|, which is safe
+ // to transport to another thread or process. Any callbacks waiting for
+ // replies from the remote endpoint are discarded and any outstanding
+ // transaction state is erased.
+ //
+ // After this method returns, a subsequent call to |Bind| is required before
+ // calling any additional |Interface| methods.
+ InterfaceHandle<Interface> Unbind() {
+ return InterfaceHandle<Interface>(impl_->controller.reader().Unbind());
+ }
+
+ // Whether this |InterfacePtr| is currently bound to a channel.
+ //
+ // If the |InterfacePtr| is bound to a channel, the |InterfacePtr| has
+ // affinity for the thread to which it was bound and calls to |Interface|
+ // methods are proxied to the remote endpoint of the channel.
+ //
+ // See also:
+ //
+ // * |Bind|, which binds a channel to this |InterfacePtr|.
+ // * |Unbind|, which unbinds a channel from this |InterfacePtr|.
+ bool is_bound() const { return impl_->controller.reader().is_bound(); }
+
+ // Whether this |InterfacePtr| is currently bound to a channel.
+ //
+ // See |is_bound| for details.
+ explicit operator bool() const { return is_bound(); }
+
+ // The |Interface| proxy associated with this |InterfacePtr|.
+ //
+ // When this |InterfacePtr| is bound, method calls on this |Interface| will
+ // be proxied to the remote endpoint of the connection. Methods that expect
+ // replies will retain the supplied callbacks until the |InterfacePtr| either
+ // receives a reply to that transaction or the |InterfacePtr| is unbound from
+ // the channel.
+ //
+ // When this |InterfacePtr| is not bound, calling methods on the returned
+ // |Interface| simply discards the arguments and closes any handles contained
+ // in those arguments.
+ //
+ // The returned |Interface| is thread-hostile and can be used only on the
+ // thread to which the |InterfacePtr| was bound.
+ Interface* get() const { return &impl_->proxy; }
+ Interface* operator->() const { return get(); }
+ Interface& operator*() const { return *get(); }
+
+ // An object on which to register for FIDL events.
+ //
+ // Arriving events are dispatched to the callbacks stored on this object.
+ // Events for unbound callbacks are ignored.
+ Proxy& events() const { return impl_->proxy; }
+
+ // Sets an error handler that will be called if an error causes the underlying
+ // channel to be closed.
+ //
+ // If the error is being reported because an error occurred on the local side
+ // of the channel, the zx_status_t of that error will be passed as the
+ // parameter to the handler.
+ //
+ // If an Epitaph was present on the channel, its error value will be passed as
+ // the parameter. See the FIDL language specification for more detail on
+ // Epitaphs.
+ //
+ // For example, the error handler will be called if the remote side of the
+ // channel sends an invalid message. When the error handler is called, the
+ // |Binding| will no longer be bound to the channel.
+ //
+ // WARNING: The |error_handler| is often called from the thread to which the
+ // |InterfacePtr| was bound, but the function can also be called from another
+ // thread if the |InterfacePtr| is still bound to the thread when the
+ // |async::Loop| for the thread is shutdown.
+ void set_error_handler(fit::function<void(zx_status_t)> error_handler) {
+ impl_->controller.reader().set_error_handler(std::move(error_handler));
+ }
+
+ // The underlying channel.
+ const zx::channel& channel() const { return impl_->controller.reader().channel(); }
+
+ // The |async_dispatcher_t| to which this interface is bound, if any.
+ async_dispatcher_t* dispatcher() const { return impl_->controller.reader().dispatcher(); }
+
+ private:
+ struct Impl;
+
+ std::unique_ptr<Impl> impl_;
+};
+
+template <typename T>
+struct InterfacePtr<T>::Impl {
+ Impl() : proxy(&controller) { controller.set_proxy(&proxy); }
+ internal::ProxyController controller;
+ mutable Proxy proxy;
+};
+
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_INTERFACE_PTR_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/interface_ptr_set.h b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/interface_ptr_set.h
new file mode 100644
index 0000000..7ea3438
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/interface_ptr_set.h
@@ -0,0 +1,94 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_INTERFACE_PTR_SET_H_
+#define LIB_FIDL_CPP_INTERFACE_PTR_SET_H_
+
+#include <zircon/assert.h>
+
+#include <vector>
+
+#include "lib/fidl/cpp/interface_ptr.h"
+
+namespace fidl {
+
+// Contains a set of |InterfacePtr| objects, each with their own channels.
+//
+// An |InterfacePtr| is removed from the set and destroyed when its underlying
+// channel experiences an error. When the set is destroyed, all the underlying
+// channels are closed.
+//
+// An |InterfacePtrSet| is useful for broadcasting messages to a set of clients,
+// each with their own implementation of |Interface|.
+//
+// See also:
+//
+// * |BindingSet|, which is the server analog of an |InterfacePtrSet|.
+template <typename Interface>
+class InterfacePtrSet final {
+ public:
+ using StorageType = std::vector<std::unique_ptr<InterfacePtr<Interface>>>;
+ using Ptr = InterfacePtr<Interface>;
+
+ // Creates an empty |InterfacePtrSet|.
+ InterfacePtrSet() = default;
+
+ InterfacePtrSet(const InterfacePtrSet& other) = delete;
+ InterfacePtrSet& operator=(const InterfacePtrSet& other) = delete;
+
+ // Adds the given |InterfacePtr| to the set.
+ //
+ // The |InterfacePtr| must already be bound to a channel. The |InterfacePtr|
+ // will be removed from the set when its underlying channel experiences an
+ // error.
+ void AddInterfacePtr(InterfacePtr<Interface> ptr) {
+ ZX_DEBUG_ASSERT(ptr.is_bound());
+ // Allocated a new |InterfacePtr| so that we can have a unique value to use
+ // as a key for removing the InterfacePtr. Otherwise, we'll lose track of
+ // the InterfacePtr when the vector resizes.
+ ptrs_.push_back(std::make_unique<Ptr>(std::move(ptr)));
+ auto* pointer = ptrs_.back().get();
+ pointer->set_error_handler(
+ [pointer, this](zx_status_t status) { this->RemoveOnError(pointer); });
+ }
+
+ // The |InterfacePtr| objects stored in this set.
+ //
+ // This collection of bindings can be invalidated when an |InterfacePtr| in
+ // the set encounters a connection error because connection errors causes the
+ // |InterfacePtrSet| to remove the |InterfacePtr| from the set.
+ const StorageType& ptrs() const { return ptrs_; }
+
+ // Closes all channels associated with |InterfacePtr| objects in the set.
+ //
+ // After this method returns, the set is empty.
+ void CloseAll() { ptrs_.clear(); }
+
+ // The number of |InterfacePtr| objects in the set.
+ //
+ // This number might be smaller than the number of |InterfacePtr| objects
+ // added to the set if some of the underlying channels have experienced an
+ // error.
+ size_t size() const { return ptrs_.size(); }
+
+ private:
+ // Removes the given |pointer| from the set.
+ //
+ // Called from the error handler callback for |pointer|.
+ void RemoveOnError(Ptr* pointer) {
+ auto it = std::find_if(ptrs_.begin(), ptrs_.end(),
+ [pointer](const std::unique_ptr<Ptr>& p) { return p.get() == pointer; });
+ ZX_DEBUG_ASSERT(it != ptrs_.end());
+ ptrs_.erase(it);
+ }
+
+ // We use |unique_ptr| rather than just |InterfacePtr| so that we can keep
+ // track of the |InterfacePtr| objects after the |vector| resizes and moves
+ // its contents to its new buffer.
+ StorageType ptrs_;
+};
+
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_INTERFACE_PTR_SET_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/internal/header.h b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/internal/header.h
new file mode 100644
index 0000000..d3e5acb
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/internal/header.h
@@ -0,0 +1,71 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_INTERNAL_HEADER_H_
+#define LIB_FIDL_CPP_INTERNAL_HEADER_H_
+
+#include <lib/fit/function.h>
+#include <lib/fit/result.h>
+#include <lib/fit/variant.h>
+
+#include <array>
+#include <functional>
+#include <ostream>
+
+#ifdef __Fuchsia__
+#include <lib/zx/bti.h>
+#include <lib/zx/channel.h>
+#include <lib/zx/clock.h>
+#include <lib/zx/debuglog.h>
+#include <lib/zx/event.h>
+#include <lib/zx/eventpair.h>
+#include <lib/zx/exception.h>
+#include <lib/zx/fifo.h>
+#include <lib/zx/guest.h>
+#include <lib/zx/handle.h>
+#include <lib/zx/interrupt.h>
+#include <lib/zx/job.h>
+#include <lib/zx/object.h>
+#include <lib/zx/pmt.h>
+#include <lib/zx/port.h>
+#include <lib/zx/process.h>
+#include <lib/zx/profile.h>
+#include <lib/zx/resource.h>
+#include <lib/zx/socket.h>
+#include <lib/zx/stream.h>
+#include <lib/zx/suspend_token.h>
+#include <lib/zx/task.h>
+#include <lib/zx/thread.h>
+#include <lib/zx/time.h>
+#include <lib/zx/timer.h>
+#include <lib/zx/vcpu.h>
+#include <lib/zx/vmar.h>
+#include <lib/zx/vmo.h>
+#endif
+
+#include "lib/fidl/cpp/coding_traits.h"
+#include "lib/fidl/cpp/enum.h"
+#include "lib/fidl/cpp/internal/logging.h"
+
+#ifdef __Fuchsia__
+#include "lib/fidl/cpp/interface_handle.h"
+#include "lib/fidl/cpp/interface_ptr.h"
+#include "lib/fidl/cpp/internal/proxy_controller.h"
+#include "lib/fidl/cpp/internal/stub_controller.h"
+#include "lib/fidl/cpp/internal/synchronous_proxy.h"
+#include "lib/fidl/cpp/member_connector.h"
+#include "lib/fidl/cpp/service_handler_base.h"
+#include "lib/fidl/cpp/synchronous_interface_ptr.h"
+#endif
+
+#include "lib/fidl/cpp/comparison.h"
+#include "lib/fidl/cpp/string.h"
+#include "lib/fidl/cpp/vector.h"
+
+// clone.h must be imported before any of the generated Clone methods are
+// defined, so that calls to Clone in clone.h are referencing the ADL
+// implementation and are not ambiguous.
+#include "lib/fidl/cpp/clone.h"
+
+#endif // LIB_FIDL_CPP_INTERNAL_HEADER_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/internal/implementation.h b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/internal/implementation.h
new file mode 100644
index 0000000..37a3bec
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/internal/implementation.h
@@ -0,0 +1,21 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_INTERNAL_IMPLEMENTATION_H_
+#define LIB_FIDL_CPP_INTERNAL_IMPLEMENTATION_H_
+
+#include <lib/fidl/internal.h>
+#include <stdint.h>
+#include <zircon/assert.h>
+
+#include <limits>
+#include <memory>
+
+#include "lib/fidl/cpp/clone.h"
+#include "lib/fidl/cpp/comparison.h"
+#include "lib/fidl/cpp/encoder.h"
+#include "lib/fidl/cpp/internal/logging.h"
+#include "lib/fidl/cpp/traits.h"
+
+#endif // LIB_FIDL_CPP_INTERNAL_IMPLEMENTATION_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/internal/message_handler.h b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/internal/message_handler.h
new file mode 100644
index 0000000..13660ad
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/internal/message_handler.h
@@ -0,0 +1,39 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_INTERNAL_MESSAGE_HANDLER_H_
+#define LIB_FIDL_CPP_INTERNAL_MESSAGE_HANDLER_H_
+
+#include <lib/fidl/cpp/message.h>
+#include <zircon/types.h>
+
+namespace fidl {
+namespace internal {
+
+// An interface for receiving FIDL messages.
+//
+// Used by |MessageReader| to call back into its client whenever it reads a
+// message from the channel.
+class MessageHandler {
+ public:
+ virtual ~MessageHandler();
+
+ // A new message has arrived.
+ //
+ // The memory backing the message will remain valid until this method returns,
+ // at which point the memory might or might not be deallocated.
+ virtual zx_status_t OnMessage(Message message) = 0;
+
+ // The channel from which the messages were being read is gone.
+ //
+ // The channel's peer might have been closed or the |MessageReader| might have
+ // unbound from the channel. In either case, implementations that keep
+ // per-channel state should reset their state when this method is called.
+ virtual void OnChannelGone();
+};
+
+} // namespace internal
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_INTERNAL_MESSAGE_HANDLER_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/internal/message_reader.h b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/internal/message_reader.h
new file mode 100644
index 0000000..9066789
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/internal/message_reader.h
@@ -0,0 +1,149 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_INTERNAL_MESSAGE_READER_H_
+#define LIB_FIDL_CPP_INTERNAL_MESSAGE_READER_H_
+
+#include <lib/async/wait.h>
+#include <lib/fidl/cpp/message.h>
+#include <lib/fidl/cpp/message_buffer.h>
+#include <lib/fit/function.h>
+#include <lib/zx/channel.h>
+
+#include <functional>
+#include <memory>
+#include <utility>
+
+#include "lib/fidl/cpp/internal/message_handler.h"
+
+namespace fidl {
+namespace internal {
+
+class MessageReader final {
+ public:
+ explicit MessageReader(MessageHandler* message_handler = nullptr);
+ ~MessageReader();
+
+ MessageReader(const MessageReader&) = delete;
+ MessageReader& operator=(const MessageReader&) = delete;
+
+ // Binds the given channel to this |MessageReader|.
+ //
+ // The |MessageReader| will wait asynchronously for messages on this channel
+ // and dispatch them to the message handler using |dispatcher|. After this
+ // method returns, the |MessageReader| will be waiting for incomming messages.
+ //
+ // If the |MessageReader| is already bound, the |MessageReader| will first
+ // be unbound.
+ //
+ // If |dispatcher| is null, the current thread must have a default
+ // async_dispatcher_t.
+ zx_status_t Bind(zx::channel channel, async_dispatcher_t* dispatcher = nullptr);
+
+ // Unbinds the channel from this |MessageReader|.
+ //
+ // The |MessageReader| will stop waiting for the messages on this channel.
+ //
+ // Returns the channel to which this |MessageReader| was previously bound, if
+ // any.
+ zx::channel Unbind();
+
+ // Unbinds the channel from this |MessageReader| and clears the error handler.
+ void Reset();
+
+ // Unbinds the channel from |other| and bindings it to this |MessageReader|.
+ //
+ // Also moves the error handler from |other| to this |MessageReader|.
+ //
+ // Useful for implementing move semantics for objects that have a
+ // |MessageReader|.
+ zx_status_t TakeChannelAndErrorHandlerFrom(MessageReader* other);
+
+ // Sends an epitaph with the given value, unbinds, and then closes the channel
+ // associated with this |MessageReader|.
+ //
+ // The |MessageReader| will send an Epitaph with the given error, unbind
+ // the channel, and then close it.
+ //
+ // The return value can be any of the return values of zx_channel_write.
+ zx_status_t Close(zx_status_t epitaph_value);
+
+ // Whether the |MessageReader| is currently bound.
+ //
+ // See |Bind()| and |Unbind()|.
+ bool is_bound() const { return channel_.is_valid(); }
+
+ // The channel to which this |MessageReader| is bound, if any.
+ const zx::channel& channel() const { return channel_; }
+
+ // The |async_dispatcher_t| to which this |MessageReader| is bound, if any.
+ async_dispatcher_t* dispatcher() const { return dispatcher_; }
+
+ // Synchronously waits on |channel()| until either a message is available or
+ // the peer closes. If the channel is readable, reads a single message from
+ // the channel and dispatches it to the message handler.
+ //
+ // Returns |ZX_ERR_BAD_STATE| if this |MessageReader| is not bound, or if it
+ // receives a malformed Epitaph.
+ zx_status_t WaitAndDispatchOneMessageUntil(zx::time deadline);
+
+ // The given message handler is called whenever the |MessageReader| reads a
+ // message from the channel.
+ //
+ // The |Message| given to the message handler will be valid until the message
+ // handler returns.
+ //
+ // The handler should return ZX_OK if the message was handled and an error
+ // otherwise. If the handler returns ZX_OK, the |MessageReader| will continue
+ // to wait for messages.
+ //
+ // The handler can destroy the |MessageReader|, in which case the
+ // handler MUST return |ZX_ERR_STOP|. If the handler returns
+ // |ZX_ERR_SHOULD_WAIT|, the |MessageReader| will continue waiting. Other
+ // errors cause the |MessageReader| to unbind from the channel and call the
+ // error handler.
+ void set_message_handler(MessageHandler* message_handler) { message_handler_ = message_handler; }
+
+ // The given error handler is called whenever the |MessageReader| encounters
+ // an error on the channel.
+ //
+ // If the error is being reported because an error occurred on the local side
+ // of the channel, the zx_status_t of that error will be passed as the
+ // parameter to the handler.
+ //
+ // If an Epitaph was present on the channel, its error value will be passed as
+ // the parameter. See the FIDL language specification for more detail on
+ // Epitaphs.
+ //
+ // For example, the error handler will be called if the remote side of the
+ // channel sends an invalid message. When the error handler is called, the
+ // |Binding| will no longer be bound to the channel.
+ //
+ // The handler can destroy the |MessageReader|.
+ void set_error_handler(fit::function<void(zx_status_t)> error_handler) {
+ error_handler_ = std::move(error_handler);
+ }
+
+ private:
+ static void CallHandler(async_dispatcher_t* dispatcher, async_wait_t* wait, zx_status_t status,
+ const zx_packet_signal_t* signal);
+ void OnHandleReady(async_dispatcher_t* dispatcher, zx_status_t status,
+ const zx_packet_signal_t* signal);
+ zx_status_t ReadAndDispatchMessage(MessageBuffer* buffer);
+ void NotifyError(zx_status_t epitaph_value);
+ void Stop();
+
+ async_wait_t wait_; // Must be first.
+ zx::channel channel_;
+ async_dispatcher_t* dispatcher_;
+ bool* should_stop_; // See |Canary| in message_reader.cc.
+ bool* destroyed_; // See |Canary| in message_reader.cc.
+ MessageHandler* message_handler_;
+ fit::function<void(zx_status_t)> error_handler_;
+};
+
+} // namespace internal
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_INTERNAL_MESSAGE_READER_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/internal/pending_response.h b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/internal/pending_response.h
new file mode 100644
index 0000000..8a9b499
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/internal/pending_response.h
@@ -0,0 +1,90 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_INTERNAL_PENDING_RESPONSE_H_
+#define LIB_FIDL_CPP_INTERNAL_PENDING_RESPONSE_H_
+
+#include <lib/fidl/cpp/internal/message_sender.h>
+#include <lib/fidl/cpp/message_builder.h>
+#include <zircon/types.h>
+
+namespace fidl {
+namespace internal {
+class WeakStubController;
+
+// A response to a FIDL message.
+//
+// When a server receives a message that expects a response, the stub receives a
+// |PendingResponse| object that the implementation can use to reply to the
+// message. A given |PendingResponse| object can be used to send a reply at
+// most once.
+//
+// If the |StubController| that processed the original message is destroyed or
+// unbound from the underlying channel (e.g., due to an error), the stub can
+// still safely call |Send|, but the response will not actually be sent to the
+// client.
+class PendingResponse final : public MessageSender {
+ public:
+ // Creates a |PendingResponse| that does not need a response.
+ //
+ // The |needs_response()| method will return false.
+ PendingResponse();
+
+ // Creates a |PendingResponse| for a message with the given transaction ID.
+ //
+ // The |PendingResponse| object will take a reference to |weak_controller|,
+ // which it releases in its destructor.
+ PendingResponse(zx_txid_t txid, WeakStubController* weak_controller);
+
+ ~PendingResponse();
+
+ // |PendingResponse| objects are copiable.
+ //
+ // Each copy refers to the same logical reponse, which means |Send| should be
+ // called at most once among all the copies.
+ //
+ // The reason |PendingResponse| objects are copiable is so that they can be
+ // held by an fit::function, which is also copyable. Typically, a
+ // |PendingResponse| object is held as a member of another object that
+ // implements operator(), which can be wrapped by fit::function.
+ PendingResponse(const PendingResponse& other);
+ PendingResponse& operator=(const PendingResponse& other);
+
+ // |PendingResponse| objects are movable.
+ //
+ // Moving a |PendingResponse| object is more efficient that copying it because
+ // moving avoid churning the reference count of the associated
+ // |WeakStubController|.
+ PendingResponse(PendingResponse&& other);
+ PendingResponse& operator=(PendingResponse&& other);
+
+ // Whether the message that caused this |PendingResponse| object to be created
+ // expects a response.
+ //
+ // This method does not indiciate whether a response has or has not already
+ // been sent. That state is difficult to track because |PendingResponse| is
+ // copiable.
+ bool needs_response() const { return txid_; }
+
+ // Send a response.
+ //
+ // This function should be called at most once among all the copies of a given
+ // |PendingResponse| object.
+ //
+ // If the associated |WeakStubController| is no longer available (e.g., if it
+ // has been destroyed), this function will return |ZX_ERR_BAD_STATE|.
+ zx_status_t Send(const fidl_type_t* type, Message message) final;
+
+ private:
+ // This class should be small enough to fit into the inline storage for an
+ // fit::function to avoid allocating additional storage when processing
+ // messages. Currently, fit::function has space for three pointers.
+ zx_txid_t txid_ = {};
+ WeakStubController* weak_controller_ = {};
+};
+
+} // namespace internal
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_INTERNAL_PENDING_RESPONSE_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/internal/proxy.h b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/internal/proxy.h
new file mode 100644
index 0000000..cc72783
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/internal/proxy.h
@@ -0,0 +1,29 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_INTERNAL_PROXY_H_
+#define LIB_FIDL_CPP_INTERNAL_PROXY_H_
+
+#include <lib/fidl/cpp/message.h>
+#include <zircon/types.h>
+
+namespace fidl {
+namespace internal {
+
+// An interface for sending FIDL messages to a remote implementation.
+class Proxy {
+ public:
+ virtual ~Proxy();
+
+ // A new message has arrived.
+ //
+ // The memory backing the message will remain valid until this method returns,
+ // at which point the memory might or might not be deallocated.
+ virtual zx_status_t Dispatch_(Message message) = 0;
+};
+
+} // namespace internal
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_INTERNAL_PROXY_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/internal/proxy_controller.h b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/internal/proxy_controller.h
new file mode 100644
index 0000000..54acd9c
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/internal/proxy_controller.h
@@ -0,0 +1,96 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_INTERNAL_PROXY_CONTROLLER_H_
+#define LIB_FIDL_CPP_INTERNAL_PROXY_CONTROLLER_H_
+
+#include <lib/fidl/cpp/message.h>
+#include <lib/fidl/cpp/message_builder.h>
+
+#include <map>
+#include <memory>
+
+#include "lib/fidl/cpp/internal/message_handler.h"
+#include "lib/fidl/cpp/internal/message_reader.h"
+#include "lib/fidl/cpp/internal/proxy.h"
+
+namespace fidl {
+namespace internal {
+
+// Controls the client endpoint of a FIDL channel.
+//
+// A |ProxyController| controls the protocol-specific "proxy" object. Proxy
+// objects are used on the client endpoint of a FIDL channel to encode messages
+// into the channel and send them to the server endpoint, whose "stub" object
+// decodes them and dispatches them to an implementation of the protocol.
+class ProxyController : public MessageHandler {
+ public:
+ ProxyController();
+ ~ProxyController() override;
+
+ ProxyController(const ProxyController&) = delete;
+ ProxyController& operator=(const ProxyController&) = delete;
+
+ ProxyController(ProxyController&&);
+ ProxyController& operator=(ProxyController&&);
+
+ // The |MessageReader| that is listening for responses to messages sent by
+ // this object.
+ MessageReader& reader() { return reader_; }
+ const MessageReader& reader() const { return reader_; }
+
+ // The protocol-specific object that decodes messages and dispatches them to
+ // an implementation of the protocol.
+ //
+ // The proxy must be set to a non-null value before messages are read from the
+ // underlying channel. Typically, the caller will set a non-null proxy before
+ // binding a channel to the |MessageReader|.
+ Proxy* proxy() const { return proxy_; }
+ void set_proxy(Proxy* proxy) { proxy_ = proxy; }
+
+ // Send a message over the channel.
+ //
+ // If |response_handler| is non-null, the message will be assigned a
+ // transaction identifier before being encoded and sent over the channel. The
+ // |response_handler| will be retained by the |ProxyController| until the
+ // |ProxyController| recieves a response to the message, at which time the
+ // |ProxyController| will call the |OnMessage| method of the
+ // |response_handler|.
+ //
+ // Returns an error if the message fails to encode properly or if the message
+ // cannot be written to the channel.
+ zx_status_t Send(const fidl_type_t* type, Message message,
+ std::unique_ptr<MessageHandler> response_handler);
+
+ // Clears all the state associated with this |ProxyController|.
+ //
+ // After this method returns, the |ProxyController| is in the same state it
+ // would have been in if freshly constructed.
+ void Reset();
+
+ private:
+ // Called by the |MessageReader| when a message arrives on the channel from
+ // the server.
+ //
+ // The message might be a response to a previously sent message or an
+ // unsolicited event.
+ zx_status_t OnMessage(Message message) final;
+
+ // Causes the |ProxyController| to |ClearPendingHandlers()|.
+ void OnChannelGone() final;
+
+ // Causes the |ProxyController| to destroy all pending response handlers and
+ // reset its transition identifiers.
+ void ClearPendingHandlers();
+
+ MessageReader reader_;
+ Proxy* proxy_ = nullptr;
+ std::map<zx_txid_t, std::unique_ptr<MessageHandler>> handlers_;
+ zx_txid_t next_txid_;
+};
+
+} // namespace internal
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_INTERNAL_PROXY_CONTROLLER_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/internal/stub.h b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/internal/stub.h
new file mode 100644
index 0000000..cf1f41c
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/internal/stub.h
@@ -0,0 +1,50 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_INTERNAL_STUB_H_
+#define LIB_FIDL_CPP_INTERNAL_STUB_H_
+
+#include <lib/fidl/cpp/internal/pending_response.h>
+#include <lib/fidl/cpp/message.h>
+#include <zircon/types.h>
+
+namespace fidl {
+namespace internal {
+class MessageSender;
+
+// An interface for dispatching FIDL messages to a protocol implementation.
+//
+// Used by |StubController| to supply both a |Message| and a |PendingResponse|
+// object to protocol implementations.
+class Stub {
+ public:
+ virtual ~Stub();
+
+ // A new message has arrived.
+ //
+ // If the message expects a response, the |PendingResponse| object's
+ // |needs_response()| method will return true.
+ //
+ // The memory backing the message will remain valid until this method returns,
+ // at which point the memory might or might not be deallocated.
+ //
+ // The |PendingResponse| object has affinity for the current thread and is not
+ // safe to transport to another thread.
+ virtual zx_status_t Dispatch_(Message message, PendingResponse response) = 0;
+
+ // The protocol-agnostic object that can send messages.
+ //
+ // The sender must be set to a non-null value before sending events
+ // through this stub.
+ MessageSender* sender_() const { return message_sender_; }
+ void set_sender(MessageSender* sender) { message_sender_ = sender; }
+
+ private:
+ MessageSender* message_sender_ = nullptr;
+};
+
+} // namespace internal
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_INTERNAL_STUB_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/internal/stub_controller.h b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/internal/stub_controller.h
new file mode 100644
index 0000000..7f560f8
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/internal/stub_controller.h
@@ -0,0 +1,80 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_INTERNAL_STUB_CONTROLLER_H_
+#define LIB_FIDL_CPP_INTERNAL_STUB_CONTROLLER_H_
+
+#include <lib/fidl/cpp/internal/message_handler.h>
+#include <lib/fidl/cpp/internal/message_reader.h>
+#include <lib/fidl/cpp/internal/message_sender.h>
+#include <lib/fidl/cpp/internal/stub.h>
+#include <lib/fidl/cpp/message.h>
+#include <lib/zx/channel.h>
+
+#include <memory>
+
+namespace fidl {
+namespace internal {
+class WeakStubController;
+
+// Controls the server endpoint of a FIDL channel.
+//
+// A |StubController| controls the protocol-specific "stub" object. Stub
+// objects are used on the server endpoint of a FIDL channel to decode messages
+// received over the channel and dispatch them to an implementation of the
+// protocol.
+class StubController final : public MessageHandler, public MessageSender {
+ public:
+ StubController();
+ ~StubController() override;
+
+ StubController(const StubController&) = delete;
+ StubController& operator=(const StubController&) = delete;
+
+ // The |MessageReader| that is listening for messages sent by the client.
+ MessageReader& reader() { return reader_; }
+ const MessageReader& reader() const { return reader_; }
+
+ // The protocol-specific object that decodes messages and dispatches them to
+ // an implementation of the protocol.
+ //
+ // The stub must be set to a non-null value before messages are read from the
+ // underlying channel. Typically, the caller will set a non-null stub before
+ // binding a channel to the |MessageReader|.
+ Stub* stub() const { return stub_; }
+ void set_stub(Stub* stub) { stub_ = stub; }
+
+ // Send a message over the channel.
+ //
+ // Returns an error if the message fails to encode properly or if the message
+ // cannot be written to the channel.
+ zx_status_t Send(const fidl_type_t* type, Message message) final;
+
+ private:
+ // Called by the |MessageReader| when a message arrives on the channel from
+ // the client.
+ //
+ // The message will be dispatched using the |stub()|. If the message expects a
+ // response, the |stub()| will also be given a |PendingResponse| object that
+ // can be used to send a reply to the message.
+ zx_status_t OnMessage(Message message) final;
+
+ // Causes the |StubController| to invalidate all outstanding weak pointers,
+ // preventing outstanding |PendingResponse| objects from sending messages on
+ // the channel that has gone away.
+ void OnChannelGone() final;
+
+ // Invalidate all outstanding weak pointers, preventing outstanding
+ // |PendingResponse| objects from sending messages.
+ void InvalidateWeakIfNeeded();
+
+ WeakStubController* weak_;
+ MessageReader reader_;
+ Stub* stub_;
+};
+
+} // namespace internal
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_INTERNAL_STUB_CONTROLLER_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/internal/weak_stub_controller.h b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/internal/weak_stub_controller.h
new file mode 100644
index 0000000..c7dcea9
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/internal/weak_stub_controller.h
@@ -0,0 +1,74 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_INTERNAL_WEAK_STUB_CONTROLLER_H_
+#define LIB_FIDL_CPP_INTERNAL_WEAK_STUB_CONTROLLER_H_
+
+#include <stdint.h>
+
+#include <zircon/assert.h>
+#include <threads.h>
+
+namespace fidl {
+namespace internal {
+class StubController;
+
+// A weak reference to a |StubController|.
+//
+// Used to link a |PendingResponse| object with a |StubController|. When the
+// |StubController| is destroyed (or unbound from the underling channel), the
+// weak reference is invalidated, preventing outstanding |PendingResponse|
+// objects from referencing the |StubController|.
+class WeakStubController final {
+ public:
+ // Creates a weak reference to a |StubController|.
+ //
+ // The created |WeakStubController| has a reference count of one, which means
+ // the creator is responsible for calling |Release| exactly once.
+ explicit WeakStubController(StubController* controller);
+
+ // Increment the refernence count for this object.
+ //
+ // Each call to this method imposes a requirement to eventually call |Release|
+ // exactly once.
+ void AddRef();
+
+ // Decrements the reference count for this object.
+ //
+ // When the reference count reaches zero, the object is destroyed.
+ void Release();
+
+ // Break the connection between this object and the |StubController|.
+ //
+ // After calling this method, |controller()| will return nullptr.
+ void Invalidate();
+
+ // The |StubController| to which this weak reference refers.
+ //
+ // After the weak reference has been invalidated, this method returns nullptr.
+ StubController* controller() const;
+
+ private:
+ ~WeakStubController();
+
+ uint32_t ref_count_; // starts at one
+ StubController* controller_;
+#if ZX_DEBUG_ASSERT_IMPLEMENTED
+ // thrd_current() needs to match the thread on which this instance was
+ // created, so that non-atomic ref_count_ updates work as intended.
+ bool IsCurrentThreadOk() const;
+#endif
+ // If the WeakStubController constructor is release build, this field will be initialized to
+ // thrd_t{} by the constructor and stay that value until destruction. If debug build, this field
+ // remembers the construction thread. In a debug build, many of the methods will ZX_PANIC() if
+ // run on a thread other than the construction thread AND thread != thrd_t{}. By checking vs.
+ // thrd_t{}, a WeakStubController constructed by release code, but passed to a debug method, will
+ // avoid asserting.
+ thrd_t thread_;
+};
+
+} // namespace internal
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_INTERNAL_WEAK_STUB_CONTROLLER_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/member_connector.h b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/member_connector.h
new file mode 100644
index 0000000..7d2b92b
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/member_connector.h
@@ -0,0 +1,48 @@
+// 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.
+
+#ifndef LIB_FIDL_CPP_MEMBER_CONNECTOR_H_
+#define LIB_FIDL_CPP_MEMBER_CONNECTOR_H_
+
+#include <lib/fidl/cpp/interface_handle.h>
+#include <lib/fidl/cpp/service_connector.h>
+
+namespace fidl {
+
+// A connector for a member of a service instance.
+template <typename Protocol>
+class MemberConnector final {
+ public:
+ // Constructs a connector for a member of a service instance.
+ //
+ // As |dir| is not owned by the connector, it must outlive it.
+ MemberConnector(const ServiceConnector* service, std::string name)
+ : service_(service), name_(std::move(name)) {}
+
+ // Connects to the member using |request|.
+ zx_status_t Connect(InterfaceRequest<Protocol> request) const {
+ return service_->Connect(name_, request.TakeChannel());
+ }
+
+ // Connects to the member and returns a new handle.
+ InterfaceHandle<Protocol> Connect() const {
+ InterfaceHandle<Protocol> handle;
+ zx_status_t status = service_->Connect(name_, handle.NewRequest().TakeChannel());
+ if (status != ZX_OK) {
+ return nullptr;
+ }
+ return handle;
+ }
+
+ // Returns the name of this member.
+ const std::string& name() const { return name_; }
+
+ private:
+ const ServiceConnector* const service_;
+ const std::string name_;
+};
+
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_MEMBER_CONNECTOR_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/optional.h b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/optional.h
new file mode 100644
index 0000000..4dc6219
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/optional.h
@@ -0,0 +1,20 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_OPTIONAL_H_
+#define LIB_FIDL_CPP_OPTIONAL_H_
+
+#include <memory>
+#include <utility>
+
+namespace fidl {
+
+template <typename T>
+std::unique_ptr<T> MakeOptional(T value) {
+ return std::make_unique<T>(std::move(value));
+}
+
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_OPTIONAL_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/service_connector.h b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/service_connector.h
new file mode 100644
index 0000000..b08178d
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/service_connector.h
@@ -0,0 +1,21 @@
+// 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.
+
+#ifndef LIB_FIDL_CPP_SERVICE_CONNECTOR_H_
+#define LIB_FIDL_CPP_SERVICE_CONNECTOR_H_
+
+namespace fidl {
+
+// A connector for service instances.
+class ServiceConnector {
+ public:
+ virtual ~ServiceConnector() = default;
+
+ // Connect to a |path| within a serviec instance, using |channel|.
+ virtual zx_status_t Connect(const std::string& path, zx::channel channel) const = 0;
+};
+
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_SERVICE_CONNECTOR_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/service_handler_base.h b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/service_handler_base.h
new file mode 100644
index 0000000..02e0671
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/service_handler_base.h
@@ -0,0 +1,39 @@
+// 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.
+
+#ifndef LIB_FIDL_CPP_SERVICE_HANDLER_BASE_H_
+#define LIB_FIDL_CPP_SERVICE_HANDLER_BASE_H_
+
+#include <lib/async/dispatcher.h>
+#include <lib/fidl/cpp/interface_request.h>
+
+namespace fidl {
+
+// A base class for service handlers.
+//
+// This base class is used to reduce the number of libraries that generated code
+// needs to depend upon.
+class ServiceHandlerBase {
+ public:
+ virtual ~ServiceHandlerBase() = default;
+
+ // A callback to be invoked when binding a channel to a protocol.
+ using MemberHandler = fit::function<void(zx::channel channel, async_dispatcher_t* dispatcher)>;
+
+ // Add a |member| to the instance, which will be handled by |handler|.
+ virtual zx_status_t AddMember(std::string member, MemberHandler handler) const = 0;
+
+ // Add a |member| to the instance, which will be handled by |handler|.
+ template <typename Protocol>
+ zx_status_t AddMember(std::string member, fidl::InterfaceRequestHandler<Protocol> handler) {
+ return AddMember(std::move(member), [handler = std::move(handler)](
+ zx::channel channel, async_dispatcher_t* dispatcher) {
+ handler(fidl::InterfaceRequest<Protocol>(std::move(channel)));
+ });
+ }
+};
+
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_SERVICE_HANDLER_BASE_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/thread_safe_binding_set.h b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/thread_safe_binding_set.h
new file mode 100644
index 0000000..fc54be5
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/thread_safe_binding_set.h
@@ -0,0 +1,125 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_THREAD_SAFE_BINDING_SET_H_
+#define LIB_FIDL_CPP_THREAD_SAFE_BINDING_SET_H_
+
+#include <lib/async/dispatcher.h>
+#include <zircon/compiler.h>
+
+#include <algorithm>
+#include <memory>
+#include <mutex>
+#include <utility>
+#include <vector>
+
+#include "lib/fidl/cpp/binding.h"
+
+namespace fidl {
+
+// Manages a set of bindings to implemenations owned by the bound channels.
+//
+// The implementation pointer type of the binding is also parameterized,
+// allowing the use of smart pointer types such as |std::unique_ptr<>| to
+// reference the implementation.
+//
+// This class is thread-safe; bindings may be added or cleared from any thread.
+//
+// See also:
+//
+// * |BindingSet|, which is the thread-hostile analog that offers more
+// functionality.
+// * |InterfacePtrSet|, which is the client analog of |BindingSet|.
+template <typename Interface, typename ImplPtr = Interface*>
+class DeprecatedBrokenBindingSet final {
+ public:
+ using Binding = ::fidl::Binding<Interface, ImplPtr>;
+ using StorageType = std::vector<std::unique_ptr<Binding>>;
+
+ DeprecatedBrokenBindingSet() = default;
+
+ DeprecatedBrokenBindingSet(const DeprecatedBrokenBindingSet&) = delete;
+ DeprecatedBrokenBindingSet& operator=(const DeprecatedBrokenBindingSet&) = delete;
+
+ // Adds a binding to the set.
+ //
+ // The given |ImplPtr| is bound to the channel underlying the
+ // |InterfaceRequest|. The binding is removed (and the |~ImplPtr| called)
+ // when the created binding has an error (e.g., if the remote endpoint of
+ // the channel sends an invalid message).
+ //
+ // Whether this method takes ownership of |impl| depends on |ImplPtr|. If
+ // |ImplPtr| is a raw pointer, then this method does not take ownership of
+ // |impl|. If |ImplPtr| is a |unique_ptr|, then running |~ImplPtr| when the
+ // binding generates an error will delete |impl| because |~ImplPtr| is
+ // |~unique_ptr|, which deletes |impl|.
+ //
+ // The impl will use the given async_dispatcher_t in order to read messages
+ // from the channel and to monitor the channel for |ZX_CHANNEL_PEER_CLOSED|.
+ // It is not necessary to use the same async_dispatcher_t for each binding
+ // added.
+ void AddBinding(ImplPtr impl, InterfaceRequest<Interface> request,
+ async_dispatcher_t* dispatcher) {
+ std::lock_guard<std::mutex> guard(lock_);
+ bindings_.push_back(
+ std::make_unique<Binding>(std::forward<ImplPtr>(impl), std::move(request), dispatcher));
+ auto* binding = bindings_.back().get();
+ // Set the connection error handler for the newly added Binding to be a
+ // function that will erase it from the vector.
+ binding->set_error_handler(
+ [binding, this](zx_status_t status) { this->RemoveOnError(binding); });
+ }
+
+ // Adds a binding to the set for the given implementation.
+ //
+ // Creates a channel for the binding and returns the client endpoint of
+ // the channel as an |InterfaceHandle|. If |AddBinding| fails to create the
+ // underlying channel, the returned |InterfaceHandle| will return false from
+ // |is_valid()|.
+ //
+ // The given |ImplPtr| is bound to the newly created channel. The binding is
+ // removed (and the |~ImplPtr| called) when the created binding has an error
+ // (e.g., if the remote endpoint of the channel sends an invalid message).
+ //
+ // Whether this method takes ownership of |impl| depends on |ImplPtr|. If
+ // |ImplPtr| is a raw pointer, then this method does not take ownership of
+ // |impl|. If |ImplPtr| is a |unique_ptr|, then running |~ImplPtr| when the
+ // binding generates an error will delete |impl| because |~ImplPtr| is
+ // |~unique_ptr|, which deletes |impl|.
+ InterfaceHandle<Interface> AddBinding(ImplPtr impl, async_dispatcher_t* dispatcher) {
+ InterfaceHandle<Interface> handle;
+ InterfaceRequest<Interface> request = handle.NewRequest();
+ if (!request)
+ return nullptr;
+ AddBinding(std::forward<ImplPtr>(impl), std::move(request), dispatcher);
+ return handle;
+ }
+
+ // Removes all the bindings from the set.
+ //
+ // Closes all the channels associated with this |BindingSet|.
+ void CloseAll() {
+ std::lock_guard<std::mutex> guard(lock_);
+ bindings_.clear();
+ }
+
+ private:
+ // Called when a binding has an error to remove the binding from the set.
+ void RemoveOnError(Binding* binding) {
+ std::lock_guard<std::mutex> guard(lock_);
+ auto it =
+ std::find_if(bindings_.begin(), bindings_.end(),
+ [binding](const std::unique_ptr<Binding>& b) { return b.get() == binding; });
+ ZX_DEBUG_ASSERT(it != bindings_.end());
+ (*it)->set_error_handler(nullptr);
+ bindings_.erase(it);
+ }
+
+ std::mutex lock_;
+ StorageType bindings_ __TA_GUARDED(lock_);
+};
+
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_THREAD_SAFE_BINDING_SET_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/type_converter.h b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/type_converter.h
new file mode 100644
index 0000000..c7083e2
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/include/lib/fidl/cpp/type_converter.h
@@ -0,0 +1,43 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_TYPE_CONVERTER_H_
+#define LIB_FIDL_CPP_TYPE_CONVERTER_H_
+
+namespace fidl {
+
+// Specialize the following class:
+// template <typename T, typename U> struct TypeConverter;
+// to perform desired type conversions. Here, T is the target type; U is the
+// input type.
+//
+// To convert from type Y to type X, create a specialization of TypeConverter
+// like this:
+//
+// namespace fidl {
+//
+// template <>
+// struct TypeConverter<X, Y> {
+// static X Convert(const Y& input);
+// };
+//
+// } // namespace fidl
+//
+// With this specialization, it's possible to write code like this:
+//
+// Y y;
+// X x = fidl::To<X>(y);
+//
+
+template <typename T, typename U>
+struct TypeConverter;
+
+template <typename T, typename U>
+inline T To(const U& obj) {
+ return TypeConverter<T, U>::Convert(obj);
+}
+
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_TYPE_CONVERTER_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/internal/message_handler.cc b/third_party/fuchsia-sdk/pkg/fidl_cpp/internal/message_handler.cc
new file mode 100644
index 0000000..fbcaa5a
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/internal/message_handler.cc
@@ -0,0 +1,15 @@
+// Copyright 2018 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.
+
+#include "lib/fidl/cpp/internal/message_handler.h"
+
+namespace fidl {
+namespace internal {
+
+MessageHandler::~MessageHandler() = default;
+
+void MessageHandler::OnChannelGone() {}
+
+} // namespace internal
+} // namespace fidl
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/internal/message_reader.cc b/third_party/fuchsia-sdk/pkg/fidl_cpp/internal/message_reader.cc
new file mode 100644
index 0000000..836e655
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/internal/message_reader.cc
@@ -0,0 +1,275 @@
+// Copyright 2018 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.
+
+#include "lib/fidl/cpp/internal/message_reader.h"
+
+#include <lib/async/default.h>
+#include <lib/fidl/cpp/message_buffer.h>
+#include <lib/fidl/epitaph.h>
+#include <zircon/assert.h>
+#include <zircon/errors.h>
+#include <zircon/fidl.h>
+
+namespace fidl {
+namespace internal {
+namespace {
+
+constexpr zx_signals_t kSignals = ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED;
+
+// |Canary| is a stack-allocated object that observes when a |MessageReader| is
+// destroyed or unbound from the current channel.
+//
+// Because |WaitAndDispatchOneMessageUntil| can be called re-entrantly, we can
+// be in a state where there are N nested calls to |ReadAndDispatchMessage| on
+// the stack. While dispatching any of those messages, the client can destroy
+// the |MessageReader| or unbind it from the current channel. When that happens
+// we need to stop reading messages from the channel and unwind the stack
+// safely.
+//
+// The |Canary| works by storing a pointer to its |should_stop_| field in the
+// |MessageReader|. Upon destruction or unbinding, the |MessageReader| writes
+// |true| into |should_stop_|. When we unwind the stack, the |Canary| forwards
+// that value to the next |Canary| on the stack.
+class Canary {
+ public:
+ explicit Canary(bool** should_stop_slot)
+ : should_stop_slot_(should_stop_slot),
+ previous_should_stop_(*should_stop_slot_),
+ should_stop_(false) {
+ *should_stop_slot_ = &should_stop_;
+ }
+
+ ~Canary() {
+ if (should_stop_) {
+ // If we should stop, we need to propagate that information to the
+ // |Canary| higher up the stack, if any. We also cannot touch
+ // |*should_stop_slot_| because the |MessageReader| might have been
+ // destroyed (or bound to another channel).
+ if (previous_should_stop_)
+ *previous_should_stop_ = should_stop_;
+ } else {
+ // Otherwise, the |MessageReader| was not destroyed and is still bound to
+ // the same channel. We need to restore the previous |should_stop_|
+ // pointer so that a |Canary| further up the stack can still be informed
+ // about whether to stop.
+ *should_stop_slot_ = previous_should_stop_;
+ }
+ }
+
+ // Whether the |ReadAndDispatchMessage| that created the |Canary| should stop
+ // after dispatching the current message.
+ bool should_stop() const { return should_stop_; }
+
+ private:
+ bool** should_stop_slot_;
+ bool* previous_should_stop_;
+ bool should_stop_;
+};
+
+} // namespace
+
+static_assert(std::is_standard_layout<MessageReader>::value, "We need offsetof to work");
+
+MessageReader::MessageReader(MessageHandler* message_handler)
+ : wait_{{ASYNC_STATE_INIT}, &MessageReader::CallHandler, ZX_HANDLE_INVALID, kSignals, 0},
+ dispatcher_(nullptr),
+ should_stop_(nullptr),
+ destroyed_(nullptr),
+ message_handler_(message_handler),
+ error_handler_(nullptr) {}
+
+MessageReader::~MessageReader() {
+ Stop();
+ if (destroyed_) {
+ *destroyed_ = true;
+ destroyed_ = nullptr;
+ }
+ if (dispatcher_)
+ async_cancel_wait(dispatcher_, &wait_);
+}
+
+zx_status_t MessageReader::Bind(zx::channel channel, async_dispatcher_t* dispatcher) {
+ if (is_bound())
+ Unbind();
+ if (!channel)
+ return ZX_OK;
+ channel_ = std::move(channel);
+ if (dispatcher) {
+ dispatcher_ = dispatcher;
+ } else {
+ dispatcher_ = async_get_default_dispatcher();
+ }
+ ZX_ASSERT_MSG(dispatcher_ != nullptr,
+ "either |dispatcher| must be non-null, or "
+ "|async_get_default_dispatcher| must "
+ "be configured to return a non-null value");
+ wait_.object = channel_.get();
+ zx_status_t status = async_begin_wait(dispatcher_, &wait_);
+ if (status != ZX_OK)
+ Unbind();
+ return status;
+}
+
+zx::channel MessageReader::Unbind() {
+ if (!is_bound())
+ return zx::channel();
+ Stop();
+ async_cancel_wait(dispatcher_, &wait_);
+ wait_.object = ZX_HANDLE_INVALID;
+ dispatcher_ = nullptr;
+ zx::channel channel = std::move(channel_);
+ if (message_handler_)
+ message_handler_->OnChannelGone();
+ return channel;
+}
+
+void MessageReader::Reset() {
+ Unbind();
+ error_handler_ = nullptr;
+}
+
+zx_status_t MessageReader::TakeChannelAndErrorHandlerFrom(MessageReader* other) {
+ zx_status_t status = Bind(other->Unbind(), other->dispatcher_);
+ if (status != ZX_OK)
+ return status;
+ error_handler_ = std::move(other->error_handler_);
+ return ZX_OK;
+}
+
+zx_status_t MessageReader::WaitAndDispatchOneMessageUntil(zx::time deadline) {
+ if (!is_bound())
+ return ZX_ERR_BAD_STATE;
+ zx_signals_t pending = ZX_SIGNAL_NONE;
+ zx_status_t status = channel_.wait_one(kSignals, deadline, &pending);
+ if (status == ZX_ERR_TIMED_OUT)
+ return status;
+ if (status != ZX_OK) {
+ NotifyError(status);
+ return status;
+ }
+
+ if (pending & ZX_CHANNEL_READABLE) {
+ MessageBuffer buffer;
+ return ReadAndDispatchMessage(&buffer);
+ }
+
+ ZX_DEBUG_ASSERT(pending & ZX_CHANNEL_PEER_CLOSED);
+ NotifyError(ZX_ERR_PEER_CLOSED);
+ return ZX_ERR_PEER_CLOSED;
+}
+
+void MessageReader::CallHandler(async_dispatcher_t* dispatcher, async_wait_t* wait,
+ zx_status_t status, const zx_packet_signal_t* signal) {
+ static_assert(offsetof(MessageReader, wait_) == 0,
+ "The wait must be the first member for this cast to be valid.");
+ reinterpret_cast<MessageReader*>(wait)->OnHandleReady(dispatcher, status, signal);
+}
+
+void MessageReader::OnHandleReady(async_dispatcher_t* dispatcher, zx_status_t status,
+ const zx_packet_signal_t* signal) {
+ if (status != ZX_OK) {
+ NotifyError(status);
+ return;
+ }
+
+ if (signal->observed & ZX_CHANNEL_READABLE) {
+ MessageBuffer buffer;
+ for (uint64_t i = 0; i < signal->count; i++) {
+ status = ReadAndDispatchMessage(&buffer);
+ // If ReadAndDispatchMessage returns ZX_ERR_STOP, that means the message
+ // handler has destroyed this object and we need to unwind without
+ // touching |this|.
+ if (status == ZX_ERR_SHOULD_WAIT)
+ break;
+ if (status != ZX_OK)
+ return;
+ }
+ status = async_begin_wait(dispatcher, &wait_);
+ if (status != ZX_OK) {
+ NotifyError(status);
+ }
+ return;
+ }
+
+ ZX_DEBUG_ASSERT(signal->observed & ZX_CHANNEL_PEER_CLOSED);
+ // Notice that we don't notify an error until we've drained all the messages
+ // out of the channel.
+ NotifyError(ZX_ERR_PEER_CLOSED);
+}
+
+zx_status_t MessageReader::ReadAndDispatchMessage(MessageBuffer* buffer) {
+ Message message = buffer->CreateEmptyMessage();
+ zx_status_t status = message.Read(channel_.get(), 0);
+ if (status == ZX_ERR_SHOULD_WAIT)
+ return status;
+ if (status != ZX_OK) {
+ NotifyError(status);
+ return status;
+ }
+
+ if (!message.is_supported_version()) {
+ NotifyError(ZX_ERR_PROTOCOL_NOT_SUPPORTED);
+ return ZX_ERR_PROTOCOL_NOT_SUPPORTED;
+ }
+
+ if (message.ordinal() == kFidlOrdinalEpitaph) {
+ // This indicates the message is an epitaph, and that any epitaph-friendly
+ // error handlers should be invoked. Note the epitaph error is stored as a
+ // struct{int32} in the message payload
+
+ // TODO(FIDL-322): Use a different error code to distinguish remote encoding
+ // errors from local ones.
+ if (message.bytes().actual() != sizeof(fidl_epitaph_t)) {
+ NotifyError(ZX_ERR_INVALID_ARGS);
+ return ZX_ERR_INVALID_ARGS;
+ }
+ fidl_epitaph_t* epitaph = message.GetBytesAs<fidl_epitaph_t>();
+ NotifyError(epitaph->error);
+ return ZX_ERR_PEER_CLOSED;
+ }
+
+ if (!message_handler_)
+ return ZX_OK;
+ Canary canary(&should_stop_);
+ status = message_handler_->OnMessage(std::move(message));
+ if (canary.should_stop())
+ return ZX_ERR_STOP;
+ if (status != ZX_OK)
+ NotifyError(status);
+ return status;
+}
+
+zx_status_t MessageReader::Close(zx_status_t epitaph_value) {
+ if (!is_bound()) {
+ return ZX_ERR_BAD_STATE;
+ }
+
+ zx_status_t status = fidl_epitaph_write(channel_.get(), epitaph_value);
+ if (status != ZX_OK) {
+ return status;
+ }
+ Unbind();
+ return ZX_OK;
+}
+
+void MessageReader::NotifyError(zx_status_t epitaph_value) {
+ Canary canary(&destroyed_);
+ Unbind();
+ if (canary.should_stop()) {
+ return;
+ }
+ if (error_handler_) {
+ error_handler_(epitaph_value);
+ }
+}
+
+void MessageReader::Stop() {
+ if (should_stop_) {
+ *should_stop_ = true;
+ should_stop_ = nullptr;
+ }
+}
+
+} // namespace internal
+} // namespace fidl
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/internal/pending_response.cc b/third_party/fuchsia-sdk/pkg/fidl_cpp/internal/pending_response.cc
new file mode 100644
index 0000000..c552524
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/internal/pending_response.cc
@@ -0,0 +1,69 @@
+// Copyright 2018 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.
+
+#include "lib/fidl/cpp/internal/pending_response.h"
+
+#include "lib/fidl/cpp/internal/logging.h"
+#include "lib/fidl/cpp/internal/stub_controller.h"
+#include "lib/fidl/cpp/internal/weak_stub_controller.h"
+
+namespace fidl {
+namespace internal {
+
+PendingResponse::PendingResponse() : txid_(0), weak_controller_(nullptr) {}
+
+PendingResponse::PendingResponse(zx_txid_t txid, WeakStubController* weak_controller)
+ : txid_(txid), weak_controller_(weak_controller) {
+ if (weak_controller_)
+ weak_controller_->AddRef();
+}
+
+PendingResponse::~PendingResponse() {
+ if (weak_controller_)
+ weak_controller_->Release();
+}
+
+PendingResponse::PendingResponse(const PendingResponse& other)
+ : PendingResponse(other.txid_, other.weak_controller_) {}
+
+PendingResponse& PendingResponse::operator=(const PendingResponse& other) {
+ if (this == &other)
+ return *this;
+ txid_ = other.txid_;
+ if (weak_controller_)
+ weak_controller_->Release();
+ weak_controller_ = other.weak_controller_;
+ if (weak_controller_)
+ weak_controller_->AddRef();
+ return *this;
+}
+
+PendingResponse::PendingResponse(PendingResponse&& other)
+ : txid_(other.txid_), weak_controller_(other.weak_controller_) {
+ other.weak_controller_ = nullptr;
+}
+
+PendingResponse& PendingResponse::operator=(PendingResponse&& other) {
+ if (this == &other)
+ return *this;
+ txid_ = other.txid_;
+ if (weak_controller_)
+ weak_controller_->Release();
+ weak_controller_ = other.weak_controller_;
+ other.weak_controller_ = nullptr;
+ return *this;
+}
+
+zx_status_t PendingResponse::Send(const fidl_type_t* type, Message message) {
+ if (!weak_controller_)
+ return ZX_ERR_BAD_STATE;
+ StubController* controller = weak_controller_->controller();
+ if (!controller)
+ return ZX_ERR_BAD_STATE;
+ message.set_txid(txid_);
+ return fidl::internal::SendMessage(controller->reader().channel(), type, std::move(message));
+}
+
+} // namespace internal
+} // namespace fidl
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/internal/proxy.cc b/third_party/fuchsia-sdk/pkg/fidl_cpp/internal/proxy.cc
new file mode 100644
index 0000000..412aff7
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/internal/proxy.cc
@@ -0,0 +1,13 @@
+// Copyright 2018 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.
+
+#include "lib/fidl/cpp/internal/proxy.h"
+
+namespace fidl {
+namespace internal {
+
+Proxy::~Proxy() = default;
+
+} // namespace internal
+} // namespace fidl
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/internal/proxy_controller.cc b/third_party/fuchsia-sdk/pkg/fidl_cpp/internal/proxy_controller.cc
new file mode 100644
index 0000000..6face80
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/internal/proxy_controller.cc
@@ -0,0 +1,94 @@
+// Copyright 2018 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.
+
+#include "lib/fidl/cpp/internal/proxy_controller.h"
+
+#include <utility>
+
+#include "lib/fidl/cpp/internal/logging.h"
+
+namespace fidl {
+namespace internal {
+namespace {
+
+constexpr uint32_t kUserspaceTxidMask = 0x7FFFFFFF;
+
+} // namespace
+
+ProxyController::ProxyController() : reader_(this), next_txid_(1) {}
+
+ProxyController::~ProxyController() = default;
+
+ProxyController::ProxyController(ProxyController&& other)
+ : reader_(this), handlers_(std::move(other.handlers_)), next_txid_(other.next_txid_) {
+ reader_.TakeChannelAndErrorHandlerFrom(&other.reader());
+ other.Reset();
+}
+
+ProxyController& ProxyController::operator=(ProxyController&& other) {
+ if (this != &other) {
+ reader_.TakeChannelAndErrorHandlerFrom(&other.reader());
+ handlers_ = std::move(other.handlers_);
+ next_txid_ = other.next_txid_;
+ other.Reset();
+ }
+ return *this;
+}
+
+zx_status_t ProxyController::Send(const fidl_type_t* type, Message message,
+ std::unique_ptr<MessageHandler> response_handler) {
+ zx_txid_t txid = 0;
+ if (response_handler) {
+ txid = next_txid_++ & kUserspaceTxidMask;
+ while (!txid || handlers_.find(txid) != handlers_.end())
+ txid = next_txid_++ & kUserspaceTxidMask;
+ message.set_txid(txid);
+ }
+ const char* error_msg = nullptr;
+ zx_status_t status = message.Validate(type, &error_msg);
+ if (status != ZX_OK) {
+ FIDL_REPORT_ENCODING_ERROR(message, type, error_msg);
+ return status;
+ }
+ status = message.Write(reader_.channel().get(), 0);
+ if (status != ZX_OK) {
+ FIDL_REPORT_CHANNEL_WRITING_ERROR(message, type, status);
+ return status;
+ }
+ if (response_handler)
+ handlers_.emplace(txid, std::move(response_handler));
+ return ZX_OK;
+}
+
+void ProxyController::Reset() {
+ reader_.Reset();
+ ClearPendingHandlers();
+}
+
+zx_status_t ProxyController::OnMessage(Message message) {
+ zx_txid_t txid = message.txid();
+ if (!txid) {
+ if (!proxy_)
+ return ZX_ERR_NOT_SUPPORTED;
+ return proxy_->Dispatch_(std::move(message));
+ }
+ auto it = handlers_.find(txid);
+ if (it == handlers_.end())
+ return ZX_ERR_NOT_FOUND;
+ std::unique_ptr<MessageHandler> handler = std::move(it->second);
+ handlers_.erase(it);
+ return handler->OnMessage(std::move(message));
+}
+
+void ProxyController::OnChannelGone() { ClearPendingHandlers(); }
+
+void ProxyController::ClearPendingHandlers() {
+ // Avoid reentrancy problems by first copying the handlers map.
+ auto doomed = std::move(handlers_);
+ next_txid_ = 1;
+ doomed.clear();
+}
+
+} // namespace internal
+} // namespace fidl
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/internal/stub.cc b/third_party/fuchsia-sdk/pkg/fidl_cpp/internal/stub.cc
new file mode 100644
index 0000000..0ddec10
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/internal/stub.cc
@@ -0,0 +1,13 @@
+// Copyright 2018 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.
+
+#include "lib/fidl/cpp/internal/stub.h"
+
+namespace fidl {
+namespace internal {
+
+Stub::~Stub() = default;
+
+} // namespace internal
+} // namespace fidl
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/internal/stub_controller.cc b/third_party/fuchsia-sdk/pkg/fidl_cpp/internal/stub_controller.cc
new file mode 100644
index 0000000..ce91ffc
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/internal/stub_controller.cc
@@ -0,0 +1,44 @@
+// Copyright 2018 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.
+
+#include "lib/fidl/cpp/internal/stub_controller.h"
+
+#include "lib/fidl/cpp/internal/logging.h"
+#include "lib/fidl/cpp/internal/pending_response.h"
+#include "lib/fidl/cpp/internal/weak_stub_controller.h"
+
+namespace fidl {
+namespace internal {
+
+StubController::StubController() : weak_(nullptr), reader_(this) {}
+
+StubController::~StubController() { InvalidateWeakIfNeeded(); }
+
+zx_status_t StubController::Send(const fidl_type_t* type, Message message) {
+ return fidl::internal::SendMessage(reader_.channel(), type, std::move(message));
+}
+
+zx_status_t StubController::OnMessage(Message message) {
+ zx_txid_t txid = message.txid();
+ WeakStubController* weak = nullptr;
+ if (txid) {
+ if (!weak_)
+ weak_ = new WeakStubController(this);
+ weak = weak_;
+ }
+ return stub_->Dispatch_(std::move(message), PendingResponse(txid, weak));
+}
+
+void StubController::OnChannelGone() { InvalidateWeakIfNeeded(); }
+
+void StubController::InvalidateWeakIfNeeded() {
+ if (!weak_)
+ return;
+ weak_->Invalidate();
+ weak_->Release();
+ weak_ = nullptr;
+}
+
+} // namespace internal
+} // namespace fidl
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/internal/weak_stub_controller.cc b/third_party/fuchsia-sdk/pkg/fidl_cpp/internal/weak_stub_controller.cc
new file mode 100644
index 0000000..9b3d6c6
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/internal/weak_stub_controller.cc
@@ -0,0 +1,68 @@
+// Copyright 2018 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.
+
+#include "lib/fidl/cpp/internal/weak_stub_controller.h"
+
+namespace fidl {
+namespace internal {
+
+WeakStubController::WeakStubController(StubController* controller)
+ : ref_count_(1u),
+ controller_(controller),
+#if ZX_DEBUG_ASSERT_IMPLEMENTED
+ thread_(thrd_current())
+#else
+ thread_(thrd_t{})
+#endif
+{
+#if !ZX_DEBUG_ASSERT_IMPLEMENTED
+ // convince the compiler that thread_ is "used" in release
+ (void)thread_;
+#endif
+}
+
+WeakStubController::~WeakStubController() = default;
+
+void WeakStubController::AddRef() {
+ ZX_DEBUG_ASSERT_COND(IsCurrentThreadOk());
+ ZX_DEBUG_ASSERT(ref_count_ != 0);
+ ++ref_count_;
+}
+
+void WeakStubController::Release() {
+ // We have to allow !controller_ here, due to async::Loop::Shutdown() calling Invalidate(),
+ // Release() from a thread other than async::Loop::StartThread(), after the
+ // async::Loop::StartThread() thread has been joined.
+ ZX_DEBUG_ASSERT_COND(IsCurrentThreadOk() || !controller_);
+ ZX_DEBUG_ASSERT(ref_count_ > 0);
+ if (--ref_count_ == 0)
+ delete this;
+}
+
+void WeakStubController::Invalidate() {
+ // This call can occur during async::Loop::Shutdown(), from a thread other than the thread created
+ // by async::Loop::StartThread(). In that usage path, it's typically ok, and in this method we
+ // don't attempt to detect cases that are not ok. In correct usage, the
+ // async::Loop::StartThread() thread has been joined, so that thread can't be touching
+ // WeakStubController.
+ controller_ = nullptr;
+}
+
+StubController* WeakStubController::controller() const {
+ ZX_DEBUG_ASSERT_COND(IsCurrentThreadOk());
+ return controller_;
+}
+
+#if ZX_DEBUG_ASSERT_IMPLEMENTED
+bool WeakStubController::IsCurrentThreadOk() const {
+ // The check for thrd_t{} will always be false, unless the release build constructor ran somehow
+ // despite the present method being debug-only. The extra check is to avoid asserting if the
+ // release constructor was used followed by debug methods. That's not expected to be common, but
+ // avoid asserting in mixed debug/release builds like that, just in case.
+ return (thrd_current() == thread_) || (thread_ == thrd_t{});
+}
+#endif
+
+} // namespace internal
+} // namespace fidl
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp/meta.json b/third_party/fuchsia-sdk/pkg/fidl_cpp/meta.json
new file mode 100644
index 0000000..548e6c0
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp/meta.json
@@ -0,0 +1,51 @@
+{
+ "banjo_deps": [],
+ "deps": [
+ "fidl_cpp_sync",
+ "async",
+ "async-default",
+ "fidl",
+ "fidl-async",
+ "fit",
+ "zx"
+ ],
+ "fidl_deps": [],
+ "headers": [
+ "pkg/fidl_cpp/include/lib/fidl/cpp/binding.h",
+ "pkg/fidl_cpp/include/lib/fidl/cpp/binding_set.h",
+ "pkg/fidl_cpp/include/lib/fidl/cpp/enum.h",
+ "pkg/fidl_cpp/include/lib/fidl/cpp/event_sender.h",
+ "pkg/fidl_cpp/include/lib/fidl/cpp/interface_ptr.h",
+ "pkg/fidl_cpp/include/lib/fidl/cpp/interface_ptr_set.h",
+ "pkg/fidl_cpp/include/lib/fidl/cpp/internal/header.h",
+ "pkg/fidl_cpp/include/lib/fidl/cpp/internal/implementation.h",
+ "pkg/fidl_cpp/include/lib/fidl/cpp/internal/message_handler.h",
+ "pkg/fidl_cpp/include/lib/fidl/cpp/internal/message_reader.h",
+ "pkg/fidl_cpp/include/lib/fidl/cpp/internal/pending_response.h",
+ "pkg/fidl_cpp/include/lib/fidl/cpp/internal/proxy.h",
+ "pkg/fidl_cpp/include/lib/fidl/cpp/internal/proxy_controller.h",
+ "pkg/fidl_cpp/include/lib/fidl/cpp/internal/stub.h",
+ "pkg/fidl_cpp/include/lib/fidl/cpp/internal/stub_controller.h",
+ "pkg/fidl_cpp/include/lib/fidl/cpp/internal/weak_stub_controller.h",
+ "pkg/fidl_cpp/include/lib/fidl/cpp/member_connector.h",
+ "pkg/fidl_cpp/include/lib/fidl/cpp/optional.h",
+ "pkg/fidl_cpp/include/lib/fidl/cpp/service_connector.h",
+ "pkg/fidl_cpp/include/lib/fidl/cpp/service_handler_base.h",
+ "pkg/fidl_cpp/include/lib/fidl/cpp/thread_safe_binding_set.h",
+ "pkg/fidl_cpp/include/lib/fidl/cpp/type_converter.h"
+ ],
+ "include_dir": "pkg/fidl_cpp/include",
+ "name": "fidl_cpp",
+ "root": "pkg/fidl_cpp",
+ "sources": [
+ "pkg/fidl_cpp/internal/message_handler.cc",
+ "pkg/fidl_cpp/internal/message_reader.cc",
+ "pkg/fidl_cpp/internal/pending_response.cc",
+ "pkg/fidl_cpp/internal/proxy.cc",
+ "pkg/fidl_cpp/internal/proxy_controller.cc",
+ "pkg/fidl_cpp/internal/stub.cc",
+ "pkg/fidl_cpp/internal/stub_controller.cc",
+ "pkg/fidl_cpp/internal/weak_stub_controller.cc"
+ ],
+ "type": "cc_source_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp_base/BUILD.gn b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/BUILD.gn
new file mode 100644
index 0000000..ac87cea
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/BUILD.gn
@@ -0,0 +1,42 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("fidl_cpp_base") {
+ sources = [
+ "clone.cc",
+ "decoder.cc",
+ "encoder.cc",
+ "internal/logging.cc",
+ "include/lib/fidl/cpp/clone.h",
+ "include/lib/fidl/cpp/coding_traits.h",
+ "include/lib/fidl/cpp/comparison.h",
+ "include/lib/fidl/cpp/decoder.h",
+ "include/lib/fidl/cpp/encoder.h",
+ "include/lib/fidl/cpp/internal/logging.h",
+ "include/lib/fidl/cpp/object_coding.h",
+ "include/lib/fidl/cpp/string.h",
+ "include/lib/fidl/cpp/traits.h",
+ "include/lib/fidl/cpp/transition.h",
+ "include/lib/fidl/cpp/vector.h",
+ ]
+ include_dirs = [ "include" ]
+ public_deps = [
+ "../fidl-async",
+ "../fidl_base",
+ "../fit",
+ "../zx",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fidl_cpp_base",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp_base/clone.cc b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/clone.cc
new file mode 100644
index 0000000..396974d
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/clone.cc
@@ -0,0 +1,23 @@
+// Copyright 2018 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.
+
+#include "lib/fidl/cpp/clone.h"
+
+namespace fidl {
+
+zx_status_t Clone(const StringPtr& value, StringPtr* result) {
+ if (!value) {
+ *result = StringPtr();
+ } else {
+ *result = value.value();
+ }
+ return ZX_OK;
+}
+
+zx_status_t Clone(const ::std::string& value, std::string* result) {
+ *result = value;
+ return ZX_OK;
+}
+
+} // namespace fidl
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp_base/decoder.cc b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/decoder.cc
new file mode 100644
index 0000000..fb25688
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/decoder.cc
@@ -0,0 +1,34 @@
+// Copyright 2018 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.
+
+#include "lib/fidl/cpp/decoder.h"
+
+#include <utility>
+
+namespace fidl {
+
+Decoder::Decoder(Message message) : message_(std::move(message)) {}
+
+Decoder::~Decoder() = default;
+
+size_t Decoder::GetOffset(void* ptr) { return GetOffset(reinterpret_cast<uintptr_t>(ptr)); }
+
+size_t Decoder::GetOffset(uintptr_t ptr) {
+ // The |ptr| value comes from the message buffer, which we've already
+ // validated. That means it should coorespond to a valid offset within the
+ // message.
+ return ptr - reinterpret_cast<uintptr_t>(message_.bytes().data());
+}
+
+#ifdef __Fuchsia__
+void Decoder::DecodeHandle(zx::object_base* value, size_t offset) {
+ zx_handle_t* handle = GetPtr<zx_handle_t>(offset);
+ value->reset(*handle);
+ *handle = ZX_HANDLE_INVALID;
+}
+#endif
+
+uint8_t* Decoder::InternalGetPtr(size_t offset) { return message_.bytes().data() + offset; }
+
+} // namespace fidl
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp_base/encoder.cc b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/encoder.cc
new file mode 100644
index 0000000..e7e8367
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/encoder.cc
@@ -0,0 +1,62 @@
+// Copyright 2018 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.
+
+#include "lib/fidl/cpp/encoder.h"
+
+#include <lib/fidl/txn_header.h>
+#include <zircon/assert.h>
+#include <zircon/fidl.h>
+
+namespace fidl {
+namespace {
+
+size_t Align(size_t size) {
+ constexpr size_t alignment_mask = FIDL_ALIGNMENT - 1;
+ return (size + alignment_mask) & ~alignment_mask;
+}
+
+} // namespace
+
+Encoder::Encoder(uint64_t ordinal) { EncodeMessageHeader(ordinal); }
+
+Encoder::~Encoder() = default;
+
+size_t Encoder::Alloc(size_t size) {
+ size_t offset = bytes_.size();
+ size_t new_size = bytes_.size() + Align(size);
+ ZX_ASSERT(new_size >= offset);
+ bytes_.resize(new_size);
+ return offset;
+}
+
+#ifdef __Fuchsia__
+void Encoder::EncodeHandle(zx::object_base* value, size_t offset) {
+ if (value->is_valid()) {
+ *GetPtr<zx_handle_t>(offset) = FIDL_HANDLE_PRESENT;
+ handles_.push_back(value->release());
+ } else {
+ *GetPtr<zx_handle_t>(offset) = FIDL_HANDLE_ABSENT;
+ }
+}
+#endif
+
+Message Encoder::GetMessage() {
+ return Message(BytePart(bytes_.data(), bytes_.size(), bytes_.size()),
+ HandlePart(handles_.data(), handles_.size(), handles_.size()));
+}
+
+void Encoder::Reset(uint64_t ordinal) {
+ bytes_.clear();
+ handles_.clear();
+ EncodeMessageHeader(ordinal);
+}
+
+void Encoder::EncodeMessageHeader(uint64_t ordinal) {
+ size_t offset = Alloc(sizeof(fidl_message_header_t));
+ fidl_message_header_t* header = GetPtr<fidl_message_header_t>(offset);
+ fidl_init_txn_header(header, 0, ordinal);
+ header->flags[0] |= FIDL_TXN_HEADER_UNION_FROM_XUNION_FLAG;
+}
+
+} // namespace fidl
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/clone.h b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/clone.h
new file mode 100644
index 0000000..f51599a
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/clone.h
@@ -0,0 +1,179 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_CLONE_H_
+#define LIB_FIDL_CPP_CLONE_H_
+
+#include <zircon/assert.h>
+
+#include <array>
+#include <memory>
+
+#include "lib/fidl/cpp/string.h"
+#include "lib/fidl/cpp/traits.h"
+#include "lib/fidl/cpp/vector.h"
+
+namespace fidl {
+
+#ifdef __Fuchsia__
+namespace internal {
+
+template <typename T>
+inline typename std::enable_if<zx::object_traits<T>::supports_duplication, zx_status_t>::type
+CloneKernelObject(const zx::object<T>& object, zx::object<T>* result) {
+ return object.duplicate(ZX_RIGHT_SAME_RIGHTS, result);
+}
+
+template <typename T>
+inline typename std::enable_if<!zx::object_traits<T>::supports_duplication, zx_status_t>::type
+CloneKernelObject(const zx::object<T>& object, zx::object<T>* result) {
+ return ZX_ERR_ACCESS_DENIED;
+}
+
+} // namespace internal
+#endif // __Fuchsia__
+
+// Deep copies the contents of |value| into |result|.
+// This operation also attempts to duplicate any handles the value contains.
+//
+// Returns an error if the value could not be cloned, perhaps because a
+// handle was not duplicable.
+//
+// There are many overloads of this function with the following signature:
+// zx_status_t Clone(const T& value, T* result);
+template <typename T>
+inline typename std::enable_if<IsPrimitive<T>::value, zx_status_t>::type Clone(const T& value,
+ T* result) {
+ *result = value;
+ return ZX_OK;
+}
+
+// Forward-declare some templates:
+template <typename T, size_t N>
+inline typename std::enable_if<IsPrimitive<T>::value || IsStdString<T>::value, zx_status_t>::type
+Clone(const std::array<T, N>& value, std::array<T, N>* result);
+template <typename T, size_t N>
+inline typename std::enable_if<!IsPrimitive<T>::value && !IsStdString<T>::value, zx_status_t>::type
+Clone(const std::array<T, N>& value, std::array<T, N>* result);
+
+template <typename T>
+inline
+#ifdef __Fuchsia__
+ typename std::enable_if<!IsPrimitive<T>::value && !std::is_base_of<zx::object_base, T>::value &&
+ !IsStdVector<T>::value && !IsStdArray<T>::value,
+ zx_status_t>::type
+#else // __Fuchsia__
+ typename std::enable_if<!IsPrimitive<T>::value && !IsStdVector<T>::value &&
+ !IsStdArray<T>::value,
+ zx_status_t>::type
+#endif // __Fuchsia__
+ Clone(const T& value, T* result) {
+ return value.Clone(result);
+}
+
+#ifdef __Fuchsia__
+template <typename T>
+zx_status_t Clone(const zx::object<T>& value, zx::object<T>* result) {
+ if (!value) {
+ result->reset();
+ return ZX_OK;
+ }
+ return internal::CloneKernelObject(value, result);
+}
+#endif // __Fuchsia__
+
+zx_status_t Clone(const StringPtr& value, StringPtr* result);
+zx_status_t Clone(const ::std::string& value, std::string* result);
+
+template <typename T>
+inline zx_status_t Clone(const std::unique_ptr<T>& value, std::unique_ptr<T>* result) {
+ if (!value) {
+ result->reset();
+ return ZX_OK;
+ }
+ *result = std::make_unique<T>();
+ return Clone(*value, result->get());
+}
+
+template <typename T>
+inline typename std::enable_if<IsPrimitive<T>::value || IsStdString<T>::value, zx_status_t>::type
+Clone(const VectorPtr<T>& value, VectorPtr<T>* result) {
+ if (!value.has_value()) {
+ result->reset();
+ return ZX_OK;
+ }
+ *result = *value;
+ return ZX_OK;
+}
+
+template <typename T>
+inline typename std::enable_if<IsPrimitive<T>::value || IsStdString<T>::value, zx_status_t>::type
+Clone(const ::std::vector<T>& value, ::std::vector<T>* result) {
+ *result = value;
+ return ZX_OK;
+}
+
+template <typename T>
+inline typename std::enable_if<!IsPrimitive<T>::value && !IsStdString<T>::value, zx_status_t>::type
+Clone(const ::std::vector<T>& value, ::std::vector<T>* result) {
+ result->resize(value.size());
+ for (size_t i = 0; i < value.size(); ++i) {
+ zx_status_t status = Clone(value.at(i), &result->at(i));
+ if (status != ZX_OK)
+ return status;
+ }
+ return ZX_OK;
+}
+
+template <typename T>
+inline typename std::enable_if<!IsPrimitive<T>::value && !IsStdString<T>::value, zx_status_t>::type
+Clone(const VectorPtr<T>& value, VectorPtr<T>* result) {
+ if (!value.has_value()) {
+ result->reset();
+ return ZX_OK;
+ }
+ result->emplace();
+ (*result)->resize(value->size());
+ for (size_t i = 0; i < value->size(); ++i) {
+ zx_status_t status = Clone(value->at(i), &(*result)->at(i));
+ if (status != ZX_OK)
+ return status;
+ }
+ return ZX_OK;
+}
+
+template <typename T, size_t N>
+inline typename std::enable_if<IsPrimitive<T>::value || IsStdString<T>::value, zx_status_t>::type
+Clone(const ::std::array<T, N>& value, ::std::array<T, N>* result) {
+ *result = value;
+ return ZX_OK;
+}
+
+template <typename T, size_t N>
+inline typename std::enable_if<!IsPrimitive<T>::value && !IsStdString<T>::value, zx_status_t>::type
+Clone(const std::array<T, N>& value, std::array<T, N>* result) {
+ for (size_t i = 0; i < N; ++i) {
+ zx_status_t status = Clone(value[i], &result->at(i));
+ if (status != ZX_OK)
+ return status;
+ }
+ return ZX_OK;
+}
+
+// Returns a deep copy of |value|.
+// This operation also attempts to duplicate any handles the value contains.
+//
+// Crashes the program if the value could not be cloned, perhaps because a
+// handle was not duplicable.
+template <typename T>
+inline T Clone(const T& value) {
+ T clone;
+ zx_status_t status = Clone(value, &clone);
+ ZX_ASSERT(status == ZX_OK);
+ return clone;
+}
+
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_CLONE_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/coding_traits.h b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/coding_traits.h
new file mode 100644
index 0000000..59df778
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/coding_traits.h
@@ -0,0 +1,212 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_CODING_TRAITS_H_
+#define LIB_FIDL_CPP_CODING_TRAITS_H_
+
+#include <array>
+#include <memory>
+
+#include "lib/fidl/cpp/decoder.h"
+#include "lib/fidl/cpp/encoder.h"
+#include "lib/fidl/cpp/traits.h"
+#include "lib/fidl/cpp/vector.h"
+
+namespace fidl {
+
+template <typename T, class Enable = void>
+struct CodingTraits;
+
+template <typename T>
+struct CodingTraits<T, typename std::enable_if<IsPrimitive<T>::value>::type> {
+ static constexpr size_t inline_size_v1_no_ee = sizeof(T);
+ template <class EncoderImpl>
+ static void Encode(EncoderImpl* encoder, T* value, size_t offset) {
+ *encoder->template GetPtr<T>(offset) = *value;
+ }
+ template <class DecoderImpl>
+ static void Decode(DecoderImpl* decoder, T* value, size_t offset) {
+ *value = *decoder->template GetPtr<T>(offset);
+ }
+};
+
+template <>
+struct CodingTraits<bool> {
+ static constexpr size_t inline_size_v1_no_ee = sizeof(bool);
+ template <class EncoderImpl>
+ static void Encode(EncoderImpl* encoder, bool* value, size_t offset) {
+ *encoder->template GetPtr<bool>(offset) = *value;
+ }
+ template <class EncoderImpl>
+ static void Encode(EncoderImpl* encoder, std::vector<bool>::iterator value, size_t offset) {
+ *encoder->template GetPtr<bool>(offset) = *value;
+ }
+ template <class DecoderImpl>
+ static void Decode(DecoderImpl* decoder, bool* value, size_t offset) {
+ *value = *decoder->template GetPtr<bool>(offset);
+ }
+ template <class DecoderImpl>
+ static void Decode(DecoderImpl* decoder, std::vector<bool>::iterator value, size_t offset) {
+ *value = *decoder->template GetPtr<bool>(offset);
+ }
+};
+
+#ifdef __Fuchsia__
+template <typename T>
+struct CodingTraits<T, typename std::enable_if<std::is_base_of<zx::object_base, T>::value>::type> {
+ static constexpr size_t inline_size_v1_no_ee = sizeof(zx_handle_t);
+ static void Encode(Encoder* encoder, zx::object_base* value, size_t offset) {
+ encoder->EncodeHandle(value, offset);
+ }
+ static void Decode(Decoder* decoder, zx::object_base* value, size_t offset) {
+ decoder->DecodeHandle(value, offset);
+ }
+};
+#endif
+
+template <typename T>
+struct CodingTraits<std::unique_ptr<T>, typename std::enable_if<!IsFidlXUnion<T>::value>::type> {
+ static constexpr size_t inline_size_v1_no_ee = sizeof(uintptr_t);
+ template <class EncoderImpl>
+ static void Encode(EncoderImpl* encoder, std::unique_ptr<T>* value, size_t offset) {
+ if (value->get()) {
+ *encoder->template GetPtr<uintptr_t>(offset) = FIDL_ALLOC_PRESENT;
+ CodingTraits<T>::Encode(encoder, value->get(),
+ encoder->Alloc(CodingTraits<T>::inline_size_v1_no_ee));
+ } else {
+ *encoder->template GetPtr<uintptr_t>(offset) = FIDL_ALLOC_ABSENT;
+ }
+ }
+ template <class DecoderImpl>
+ static void Decode(DecoderImpl* decoder, std::unique_ptr<T>* value, size_t offset) {
+ uintptr_t ptr = *decoder->template GetPtr<uintptr_t>(offset);
+ if (!ptr)
+ return value->reset();
+ *value = std::make_unique<T>();
+ CodingTraits<T>::Decode(decoder, value->get(), decoder->GetOffset(ptr));
+ }
+};
+
+template <class EncoderImpl>
+void EncodeNullVector(EncoderImpl* encoder, size_t offset) {
+ fidl_vector_t* vector = encoder->template GetPtr<fidl_vector_t>(offset);
+ vector->count = 0u;
+ vector->data = reinterpret_cast<void*>(FIDL_ALLOC_ABSENT);
+}
+
+template <class EncoderImpl>
+void EncodeVectorPointer(EncoderImpl* encoder, size_t count, size_t offset) {
+ fidl_vector_t* vector = encoder->template GetPtr<fidl_vector_t>(offset);
+ vector->count = count;
+ vector->data = reinterpret_cast<void*>(FIDL_ALLOC_PRESENT);
+}
+
+template <typename T>
+struct CodingTraits<VectorPtr<T>> {
+ static constexpr size_t inline_size_v1_no_ee = sizeof(fidl_vector_t);
+ template <class EncoderImpl>
+ static void Encode(EncoderImpl* encoder, VectorPtr<T>* value, size_t offset) {
+ if (!value->has_value())
+ return EncodeNullVector(encoder, offset);
+ std::vector<T>& vector = **value;
+ CodingTraits<::std::vector<T>>::Encode(encoder, &vector, offset);
+ }
+ template <class DecoderImpl>
+ static void Decode(DecoderImpl* decoder, VectorPtr<T>* value, size_t offset) {
+ fidl_vector_t* encoded = decoder->template GetPtr<fidl_vector_t>(offset);
+ if (!encoded->data) {
+ *value = VectorPtr<T>();
+ return;
+ }
+ std::vector<T> vector;
+ CodingTraits<std::vector<T>>::Decode(decoder, &vector, offset);
+ (*value) = std::move(vector);
+ }
+};
+
+template <typename T>
+struct CodingTraits<::std::vector<T>> {
+ static constexpr size_t inline_size_v1_no_ee = sizeof(fidl_vector_t);
+ template <class EncoderImpl>
+ static void Encode(EncoderImpl* encoder, ::std::vector<T>* value, size_t offset) {
+ size_t count = value->size();
+ EncodeVectorPointer(encoder, count, offset);
+ size_t stride = CodingTraits<T>::inline_size_v1_no_ee;
+ size_t base = encoder->Alloc(count * stride);
+ for (size_t i = 0; i < count; ++i)
+ CodingTraits<T>::Encode(encoder, &value->at(i), base + i * stride);
+ }
+ template <class DecoderImpl>
+ static void Decode(DecoderImpl* decoder, ::std::vector<T>* value, size_t offset) {
+ fidl_vector_t* encoded = decoder->template GetPtr<fidl_vector_t>(offset);
+ value->resize(encoded->count);
+ size_t stride = CodingTraits<T>::inline_size_v1_no_ee;
+ size_t base = decoder->GetOffset(encoded->data);
+ size_t count = encoded->count;
+ for (size_t i = 0; i < count; ++i)
+ CodingTraits<T>::Decode(decoder, &value->at(i), base + i * stride);
+ }
+};
+
+template <typename T, size_t N>
+struct CodingTraits<::std::array<T, N>> {
+ static constexpr size_t inline_size_v1_no_ee = CodingTraits<T>::inline_size_v1_no_ee * N;
+ template <class EncoderImpl>
+ static void Encode(EncoderImpl* encoder, std::array<T, N>* value, size_t offset) {
+ size_t stride;
+ stride = CodingTraits<T>::inline_size_v1_no_ee;
+ for (size_t i = 0; i < N; ++i)
+ CodingTraits<T>::Encode(encoder, &value->at(i), offset + i * stride);
+ }
+ template <class DecoderImpl>
+ static void Decode(DecoderImpl* decoder, std::array<T, N>* value, size_t offset) {
+ size_t stride = CodingTraits<T>::inline_size_v1_no_ee;
+ for (size_t i = 0; i < N; ++i)
+ CodingTraits<T>::Decode(decoder, &value->at(i), offset + i * stride);
+ }
+};
+
+template <typename T, size_t InlineSizeV1NoEE>
+struct EncodableCodingTraits {
+ static constexpr size_t inline_size_v1_no_ee = InlineSizeV1NoEE;
+ template <class EncoderImpl>
+ static void Encode(EncoderImpl* encoder, T* value, size_t offset) {
+ value->Encode(encoder, offset);
+ }
+ template <class DecoderImpl>
+ static void Decode(DecoderImpl* decoder, T* value, size_t offset) {
+ T::Decode(decoder, value, offset);
+ }
+};
+
+template <typename T, class EncoderImpl = Encoder>
+size_t EncodingInlineSize(EncoderImpl* encoder) {
+ return CodingTraits<T>::inline_size_v1_no_ee;
+}
+
+template <typename T, class DecoderImpl = Decoder>
+size_t DecodingInlineSize(DecoderImpl* decoder) {
+ return CodingTraits<T>::inline_size_v1_no_ee;
+}
+
+template <typename T, class EncoderImpl>
+void Encode(EncoderImpl* encoder, T* value, size_t offset) {
+ CodingTraits<T>::Encode(encoder, value, offset);
+}
+
+template <typename T, class DecoderImpl>
+void Decode(DecoderImpl* decoder, T* value, size_t offset) {
+ CodingTraits<T>::Decode(decoder, value, offset);
+}
+
+template <typename T, class DecoderImpl>
+T DecodeAs(DecoderImpl* decoder, size_t offset) {
+ T value;
+ Decode(decoder, &value, offset);
+ return value;
+}
+
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_CODING_TRAITS_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/comparison.h b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/comparison.h
new file mode 100644
index 0000000..ec58825
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/comparison.h
@@ -0,0 +1,90 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_COMPARISON_H_
+#define LIB_FIDL_CPP_COMPARISON_H_
+
+#include <array>
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <type_traits>
+#include <vector>
+
+#ifdef __Fuchsia__
+#include <lib/zx/object.h>
+#endif
+
+// Comparisons that uses structure equality on on std::unique_ptr instead of
+// pointer equality.
+namespace fidl {
+
+template <class T>
+bool Equals(const T& lhs, const T& rhs);
+
+template <typename T, typename = void>
+struct Equality {};
+
+template <class T>
+struct Equality<T, typename std::enable_if_t<std::is_integral<T>::value>> {
+ constexpr bool operator()(const T& lhs, const T& rhs) const { return lhs == rhs; }
+};
+
+template <class T>
+struct Equality<T, typename std::enable_if_t<std::is_floating_point<T>::value>> {
+ constexpr bool operator()(const T& lhs, const T& rhs) const {
+ // TODO(ianloic): do something better for floating point comparison?
+ return lhs == rhs;
+ }
+};
+
+#ifdef __Fuchsia__
+template <class T>
+struct Equality<T, typename std::enable_if_t<std::is_base_of<zx::object_base, T>::value>> {
+ bool operator()(const T& lhs, const T& rhs) const { return lhs.get() == rhs.get(); }
+};
+#endif // __Fuchsia__
+
+template <typename T, size_t N>
+struct Equality<std::array<T, N>> {
+ // N.B.: This may be constexpr-able in C++20.
+ bool operator()(const std::array<T, N>& lhs, const std::array<T, N>& rhs) const {
+ return std::equal(lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend(), ::fidl::Equality<T>{});
+ }
+};
+
+template <>
+struct Equality<std::string> {
+ bool operator()(const std::string& lhs, const std::string& rhs) const { return lhs == rhs; }
+};
+
+template <class T>
+struct Equality<std::vector<T>> {
+ bool operator()(const std::vector<T>& lhs, const std::vector<T>& rhs) const {
+ if (lhs.size() != rhs.size()) {
+ return false;
+ }
+
+ return std::equal(lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend(), ::fidl::Equality<T>{});
+ }
+};
+
+template <class T>
+struct Equality<std::unique_ptr<T>> {
+ constexpr bool operator()(const std::unique_ptr<T>& lhs, const std::unique_ptr<T>& rhs) const {
+ if (lhs == nullptr || rhs == nullptr) {
+ return rhs == lhs;
+ }
+ return ::fidl::Equality<T>{}(*lhs, *rhs);
+ }
+};
+
+template <class T>
+bool Equals(const T& lhs, const T& rhs) {
+ return ::fidl::Equality<T>{}(lhs, rhs);
+}
+
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_COMPARISON_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/decoder.h b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/decoder.h
new file mode 100644
index 0000000..3c68cda
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/decoder.h
@@ -0,0 +1,42 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_DECODER_H_
+#define LIB_FIDL_CPP_DECODER_H_
+
+#include <lib/fidl/cpp/message.h>
+#include <zircon/fidl.h>
+
+#ifdef __Fuchsia__
+#include <lib/zx/object.h>
+#endif
+
+namespace fidl {
+
+class Decoder final {
+ public:
+ explicit Decoder(Message message);
+ ~Decoder();
+
+ template <typename T>
+ T* GetPtr(size_t offset) {
+ return reinterpret_cast<T*>(InternalGetPtr(offset));
+ }
+
+ size_t GetOffset(void* ptr);
+ size_t GetOffset(uintptr_t ptr);
+
+#ifdef __Fuchsia__
+ void DecodeHandle(zx::object_base* value, size_t offset);
+#endif
+
+ private:
+ uint8_t* InternalGetPtr(size_t offset);
+
+ Message message_;
+};
+
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_DECODER_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/encoder.h b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/encoder.h
new file mode 100644
index 0000000..6f97061
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/encoder.h
@@ -0,0 +1,59 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_ENCODER_H_
+#define LIB_FIDL_CPP_ENCODER_H_
+
+#include <lib/fidl/cpp/message.h>
+
+#ifdef __Fuchsia__
+#include <lib/zx/object.h>
+#endif
+
+#include <zircon/fidl.h>
+
+#include <vector>
+
+namespace fidl {
+
+class Encoder final {
+ public:
+ enum NoHeader { NO_HEADER };
+
+ explicit Encoder(uint64_t ordinal);
+ explicit Encoder(NoHeader marker) {}
+
+ ~Encoder();
+
+ size_t Alloc(size_t size);
+
+ template <typename T>
+ T* GetPtr(size_t offset) {
+ return reinterpret_cast<T*>(bytes_.data() + offset);
+ }
+
+#ifdef __Fuchsia__
+ void EncodeHandle(zx::object_base* value, size_t offset);
+#endif
+
+ Message GetMessage();
+
+ void Reset(uint64_t ordinal);
+
+ size_t CurrentLength() const { return bytes_.size(); }
+
+ size_t CurrentHandleCount() const { return handles_.size(); }
+
+ std::vector<uint8_t> TakeBytes() { return std::move(bytes_); }
+
+ private:
+ void EncodeMessageHeader(uint64_t ordinal);
+
+ std::vector<uint8_t> bytes_;
+ std::vector<zx_handle_t> handles_;
+};
+
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_ENCODER_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/internal/logging.h b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/internal/logging.h
new file mode 100644
index 0000000..8d69660
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/internal/logging.h
@@ -0,0 +1,34 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_INTERNAL_LOGGING_H_
+#define LIB_FIDL_CPP_INTERNAL_LOGGING_H_
+
+#include <lib/fidl/cpp/message.h>
+
+namespace fidl {
+namespace internal {
+
+void ReportEncodingError(const Message& message, const fidl_type_t* type, const char* error_msg,
+ const char* file, int line);
+
+void ReportDecodingError(const Message& message, const fidl_type_t* type, const char* error_msg,
+ const char* file, int line);
+
+void ReportChannelWritingError(const Message& message, const fidl_type_t* type, zx_status_t status,
+ const char* file, int line);
+
+#define FIDL_REPORT_ENCODING_ERROR(message, type, error_msg) \
+ ::fidl::internal::ReportEncodingError((message), (type), (error_msg), __FILE__, __LINE__)
+
+#define FIDL_REPORT_DECODING_ERROR(message, type, error_msg) \
+ ::fidl::internal::ReportDecodingError((message), (type), (error_msg), __FILE__, __LINE__)
+
+#define FIDL_REPORT_CHANNEL_WRITING_ERROR(message, type, status) \
+ ::fidl::internal::ReportChannelWritingError((message), (type), (status), __FILE__, __LINE__)
+
+} // namespace internal
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_INTERNAL_LOGGING_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/object_coding.h b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/object_coding.h
new file mode 100644
index 0000000..328c6ed
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/object_coding.h
@@ -0,0 +1,44 @@
+// Copyright 2018 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.
+
+#include "coding_traits.h"
+#include "encoder.h"
+
+namespace fidl {
+
+template <class T>
+zx_status_t EncodeObject(T* object, std::vector<uint8_t>* output, const char** error_msg_out) {
+ Encoder encoder(Encoder::NO_HEADER);
+ object->Encode(&encoder, encoder.Alloc(EncodingInlineSize<T, fidl::Encoder>(&encoder)));
+ if (encoder.CurrentHandleCount() != 0) {
+ if (error_msg_out != nullptr) {
+ *error_msg_out = "Cannot encode handles with object encoding";
+ }
+ return ZX_ERR_INVALID_ARGS;
+ }
+ *output = encoder.TakeBytes();
+ return ZX_OK;
+}
+
+template <class T>
+zx_status_t DecodeObject(uint8_t* bytes, size_t bytes_length, T* object,
+ const char** error_msg_out) {
+ Message msg(BytePart(bytes, bytes_length, bytes_length), HandlePart());
+ zx_status_t status = msg.Decode(T::FidlType, error_msg_out);
+ if (status != ZX_OK) {
+ return status;
+ }
+ Decoder decoder(std::move(msg));
+ T::Decode(&decoder, object, 0);
+ return ZX_OK;
+}
+
+template <class T>
+zx_status_t ValidateObject(uint8_t* bytes, size_t bytes_length, T* object,
+ const char** error_msg_out) {
+ return Message(BytePart(bytes, bytes_length, bytes_length), HandlePart())
+ .Validate(T::FidlType, error_msg_out);
+}
+
+} // namespace fidl
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/string.h b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/string.h
new file mode 100644
index 0000000..dac3e36
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/string.h
@@ -0,0 +1,337 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_STRING_H_
+#define LIB_FIDL_CPP_STRING_H_
+
+#include <lib/fidl/cpp/builder.h>
+#include <lib/fit/optional.h>
+#include <zircon/assert.h>
+
+#include <iosfwd>
+#include <string>
+#include <utility>
+
+#include "lib/fidl/cpp/coding_traits.h"
+#include "lib/fidl/cpp/traits.h"
+#include "lib/fidl/cpp/transition.h"
+
+namespace fidl {
+
+#if defined(FIDL_USE_FIT_OPTIONAL)
+
+class StringPtr final : public fit::optional<std::string> {
+ public:
+ constexpr StringPtr() = default;
+
+ constexpr StringPtr(fit::nullopt_t) noexcept {}
+ FIDL_FIT_OPTIONAL_DEPRECATED("Use fit::nullopt instead of nullptr")
+ constexpr StringPtr(std::nullptr_t) noexcept {}
+
+ StringPtr(const StringPtr&) = default;
+ StringPtr& operator=(const StringPtr&) = default;
+
+ StringPtr(StringPtr&&) = default;
+ StringPtr& operator=(StringPtr&&) = default;
+
+ // Move construct and move assignment from the value type
+ constexpr StringPtr(std::string&& value) : fit::optional<std::string>(std::move(value)) {}
+ constexpr StringPtr& operator=(std::string&& value) {
+ fit::optional<std::string>::operator=(std::move(value));
+ return *this;
+ }
+
+ // Copy construct and copy assignment from the value type
+ constexpr StringPtr(const std::string& value) : fit::optional<std::string>(value) {}
+ constexpr StringPtr& operator=(const std::string& value) {
+ fit::optional<std::string>::operator=(value);
+ return *this;
+ }
+
+ // Construct from string literals
+ template <size_t N>
+ constexpr StringPtr(const char (&literal)[N]) : fit::optional<std::string>(literal) {}
+ template <size_t N>
+ constexpr StringPtr& operator=(const char (&literal)[N]) {
+ fit::optional<std::string>::operator=(literal);
+ return *this;
+ }
+
+ // Construct from string pointers
+ StringPtr(const char* value) : fit::optional<std::string>(value) {}
+ StringPtr& operator=(const char* value) {
+ fit::optional<std::string>::operator=(value);
+ return *this;
+ }
+
+ // Override unchecked accessors with versions that check.
+ constexpr std::string* operator->() {
+ if (!fit::optional<std::string>::has_value()) {
+ __builtin_trap();
+ }
+ return fit::optional<std::string>::operator->();
+ }
+ constexpr const std::string* operator->() const {
+ if (!fit::optional<std::string>::has_value()) {
+ __builtin_trap();
+ }
+ return fit::optional<std::string>::operator->();
+ }
+
+ // Destructor.
+ ~StringPtr() = default;
+};
+
+#else
+
+// A representation of a FIDL string that owns the memory for the string.
+//
+// A StringPtr has three states: (1) null, (2) empty, (3) contains a string. In
+// the second state, operations that return an std::string return the empty
+// std::string. The null and empty states can be distinguished using the
+// |is_null| and |operator bool| methods.
+class StringPtr final {
+ public:
+ StringPtr() = default;
+ StringPtr(const StringPtr& other) = default;
+ StringPtr(StringPtr&& other) noexcept = default;
+ ~StringPtr() = default;
+
+ StringPtr& operator=(const StringPtr&) = default;
+ StringPtr& operator=(StringPtr&& other) = default;
+
+ StringPtr(std::string str) : str_(std::move(str)), is_null_if_empty_(false) {}
+ StringPtr(const char* str)
+ : str_(str ? std::string(str) : std::string()), is_null_if_empty_(!str) {}
+ FIDL_FIT_OPTIONAL_DEPRECATED("use StringPtr(std::string(bytes, length))")
+ StringPtr(const char* str, size_t length)
+ : str_(str ? std::string(str, length) : std::string()), is_null_if_empty_(!str) {}
+
+ // Accesses the underlying std::string object.
+ FIDL_FIT_OPTIONAL_DEPRECATED("use value_or(\"\")")
+ const std::string& get() const { return str_; }
+
+ // Accesses the underlying std::string object.
+ const std::string& value() const { return str_; }
+ std::string& value() { return str_; }
+
+ std::string value_or(std::string&& default_value) const& {
+ if (has_value()) {
+ return str_;
+ } else {
+ return std::move(default_value);
+ }
+ }
+
+ std::string value_or(std::string&& default_value) && {
+ if (has_value()) {
+ return std::move(str_);
+ } else {
+ return std::move(default_value);
+ }
+ }
+
+ // Stores the given std::string in this StringPtr.
+ //
+ // After this method returns, the StringPtr is non-null.
+ FIDL_FIT_OPTIONAL_DEPRECATED("use assignment")
+ void reset(std::string str) {
+ str_ = std::move(str);
+ is_null_if_empty_ = false;
+ }
+
+ // Causes this StringPtr to become null.
+ void reset() {
+ str_.clear();
+ is_null_if_empty_ = true;
+ }
+
+ void swap(StringPtr& other) {
+ using std::swap;
+ swap(str_, other.str_);
+ swap(is_null_if_empty_, other.is_null_if_empty_);
+ }
+
+ // Whether this StringPtr is null.
+ //
+ // The null state is separate from the empty state.
+ FIDL_FIT_OPTIONAL_DEPRECATED("use !has_value()")
+ bool is_null() const { return is_null_if_empty_ && str_.empty(); }
+
+ bool has_value() const { return !(is_null_if_empty_ && str_.empty()); }
+
+ // Tests as true if non-null, false if null.
+ explicit operator bool() const { return has_value(); }
+
+ // Provides access to the underlying std::string.
+ std::string* operator->() { return &str_; }
+ const std::string* operator->() const { return &str_; }
+
+ // Provides access to the underlying std::string.
+ const std::string& operator*() const { return str_; }
+
+ FIDL_FIT_OPTIONAL_DEPRECATED("use value_or(\"\")")
+ operator const std::string &() const { return str_; }
+
+ private:
+ std::string str_;
+ bool is_null_if_empty_ = true;
+};
+
+#endif
+
+template <>
+struct Equality<StringPtr> {
+ bool operator()(const StringPtr& lhs, const StringPtr& rhs) const {
+ if (!lhs.has_value()) {
+ return !rhs.has_value();
+ }
+ return rhs.has_value() && lhs.value() == rhs.value();
+ }
+};
+
+inline bool operator==(const StringPtr& lhs, const StringPtr& rhs) {
+ return ::fidl::Equality<StringPtr>{}(lhs, rhs);
+}
+
+inline bool operator==(const char* lhs, const StringPtr& rhs) {
+ if (lhs == nullptr) {
+ return !rhs.has_value();
+ }
+ return rhs.has_value() && lhs == rhs.value();
+}
+
+inline bool operator==(const StringPtr& lhs, const char* rhs) {
+ if (!lhs.has_value()) {
+ return rhs == nullptr;
+ }
+ return rhs != nullptr && lhs.value() == rhs;
+}
+
+inline bool operator!=(const StringPtr& lhs, const StringPtr& rhs) { return !(lhs == rhs); }
+
+inline bool operator!=(const char* lhs, const StringPtr& rhs) { return !(lhs == rhs); }
+
+inline bool operator!=(const StringPtr& lhs, const char* rhs) { return !(lhs == rhs); }
+
+inline bool operator<(const StringPtr& lhs, const StringPtr& rhs) {
+ if (!lhs.has_value() || !rhs.has_value()) {
+ return rhs.has_value();
+ }
+ return *lhs < *rhs;
+}
+
+inline bool operator<(const char* lhs, const StringPtr& rhs) {
+ if (lhs == nullptr || !rhs.has_value()) {
+ return rhs.has_value();
+ }
+ return lhs < *rhs;
+}
+
+inline bool operator<(const StringPtr& lhs, const char* rhs) {
+ if (!lhs.has_value() || rhs == nullptr) {
+ return rhs != nullptr;
+ }
+ return *lhs < rhs;
+}
+
+inline bool operator>(const StringPtr& lhs, const StringPtr& rhs) {
+ if (!lhs.has_value() || !rhs.has_value()) {
+ return !!lhs.has_value();
+ }
+ return *lhs > *rhs;
+}
+
+inline bool operator>(const char* lhs, const StringPtr& rhs) {
+ if (lhs == nullptr || !rhs.has_value()) {
+ return lhs != nullptr;
+ }
+ return lhs > *rhs;
+}
+
+inline bool operator>(const StringPtr& lhs, const char* rhs) {
+ if (!lhs.has_value() || rhs == nullptr) {
+ return lhs != nullptr;
+ }
+ return *lhs > rhs;
+}
+
+inline bool operator<=(const StringPtr& lhs, const StringPtr& rhs) { return !(lhs > rhs); }
+
+inline bool operator<=(const char* lhs, const StringPtr& rhs) { return !(lhs > rhs); }
+
+inline bool operator<=(const StringPtr& lhs, const char* rhs) { return !(lhs > rhs); }
+
+inline bool operator>=(const StringPtr& lhs, const StringPtr& rhs) { return !(lhs < rhs); }
+
+inline bool operator>=(const char* lhs, const StringPtr& rhs) { return !(lhs < rhs); }
+
+inline bool operator>=(const StringPtr& lhs, const char* rhs) { return !(lhs < rhs); }
+
+#if defined(FIDL_USE_FIT_OPTIONAL)
+FIDL_FIT_OPTIONAL_DEPRECATED("Use value_or(\"\")")
+#endif
+inline std::ostream& operator<<(std::ostream& out, const StringPtr& str) {
+ return out << str.value_or("");
+}
+
+template <>
+struct CodingTraits<::std::string> {
+ static constexpr size_t inline_size_old = sizeof(fidl_string_t);
+ static constexpr size_t inline_size_v1_no_ee = sizeof(fidl_string_t);
+ template <class EncoderImpl>
+ static void Encode(EncoderImpl* encoder, std::string* value, size_t offset) {
+ fidl_string_t* string = encoder->template GetPtr<fidl_string_t>(offset);
+ string->size = value->size();
+ string->data = reinterpret_cast<char*>(FIDL_ALLOC_PRESENT);
+ size_t base = encoder->Alloc(value->size());
+ char* payload = encoder->template GetPtr<char>(base);
+ memcpy(payload, value->data(), value->size());
+ }
+ template <class DecoderImpl>
+ static void Decode(DecoderImpl* decoder, std::string* value, size_t offset) {
+ fidl_string_t* string = decoder->template GetPtr<fidl_string_t>(offset);
+ ZX_ASSERT(string->data != nullptr);
+ *value = std::string(string->data, string->size);
+ }
+};
+
+template <>
+struct CodingTraits<StringPtr> {
+ static constexpr size_t inline_size_old = sizeof(fidl_string_t);
+ static constexpr size_t inline_size_v1_no_ee = sizeof(fidl_string_t);
+ template <class EncoderImpl>
+ static void Encode(EncoderImpl* encoder, StringPtr* value, size_t offset) {
+ if (value->has_value()) {
+ ::fidl::CodingTraits<std::string>::Encode(encoder, &value->value(), offset);
+ } else {
+ fidl_string_t* string = encoder->template GetPtr<fidl_string_t>(offset);
+ string->size = 0u;
+ string->data = reinterpret_cast<char*>(FIDL_ALLOC_ABSENT);
+ }
+ }
+ template <class DecoderImpl>
+ static void Decode(DecoderImpl* decoder, StringPtr* value, size_t offset) {
+ fidl_string_t* string = decoder->template GetPtr<fidl_string_t>(offset);
+ if (string->data) {
+ std::string string_value;
+ ::fidl::CodingTraits<std::string>::Decode(decoder, &string_value, offset);
+ (*value) = std::move(string_value);
+ } else {
+ value->reset();
+ }
+ }
+};
+
+} // namespace fidl
+
+namespace fit {
+
+inline std::ostream& operator<<(std::ostream& out, const fit::optional<std::string>& str) {
+ return out << str.value_or("");
+}
+
+} // namespace fit
+
+#endif // LIB_FIDL_CPP_STRING_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/traits.h b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/traits.h
new file mode 100644
index 0000000..1e879c4
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/traits.h
@@ -0,0 +1,59 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_TRAITS_H_
+#define LIB_FIDL_CPP_TRAITS_H_
+
+#include <array>
+#include <cstdint>
+#include <type_traits>
+#include <vector>
+
+namespace fidl {
+
+// A type trait that indicates whether the given type is a primitive FIDL type.
+template <typename T>
+struct IsPrimitive : public std::false_type {};
+
+// clang-format off
+template <> struct IsPrimitive<bool> : public std::true_type {};
+template <> struct IsPrimitive<uint8_t> : public std::true_type {};
+template <> struct IsPrimitive<uint16_t> : public std::true_type {};
+template <> struct IsPrimitive<uint32_t> : public std::true_type {};
+template <> struct IsPrimitive<uint64_t> : public std::true_type {};
+template <> struct IsPrimitive<int8_t> : public std::true_type {};
+template <> struct IsPrimitive<int16_t> : public std::true_type {};
+template <> struct IsPrimitive<int32_t> : public std::true_type {};
+template <> struct IsPrimitive<int64_t> : public std::true_type {};
+template <> struct IsPrimitive<float> : public std::true_type {};
+template <> struct IsPrimitive<double> : public std::true_type {};
+// clang-format on
+
+template <typename T>
+struct IsFidlUnion : public std::false_type {};
+
+template <typename T>
+struct IsFidlXUnion : public std::false_type {};
+
+template <typename T>
+struct IsStdArray : public std::false_type {};
+
+template <typename T, size_t N>
+struct IsStdArray<std::array<T, N>> : public std::true_type {};
+
+template <typename T>
+struct IsStdVector : public std::false_type {};
+
+template <typename V, typename A>
+struct IsStdVector<std::vector<V, A>> : public std::true_type {};
+
+template <typename T>
+struct IsStdString : public std::false_type {};
+
+template <>
+struct IsStdString<std::string> : public std::true_type {};
+
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_TRAITS_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/transition.h b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/transition.h
new file mode 100644
index 0000000..59a9d6e
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/transition.h
@@ -0,0 +1,20 @@
+// 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.
+
+#ifndef LIB_FIDL_CPP_TRANSITION_H_
+#define LIB_FIDL_CPP_TRANSITION_H_
+
+// Define this to use fit::optional in StringPtr and VectorPtr definitions
+#define FIDL_USE_FIT_OPTIONAL
+// Enable deprecation warnings for methods going away after the fit::optional transition
+// #define FIDL_FIT_OPTIONAL_DEPRECATION
+
+// A macro for (optional) deprecation warnings
+#if defined(FIDL_FIT_OPTIONAL_DEPRECATION)
+#define FIDL_FIT_OPTIONAL_DEPRECATED(M) [[deprecated(M)]]
+#else
+#define FIDL_FIT_OPTIONAL_DEPRECATED(M) [[]]
+#endif
+
+#endif // LIB_FIDL_CPP_TRANSITION_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/vector.h b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/vector.h
new file mode 100644
index 0000000..73e9d1e
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/include/lib/fidl/cpp/vector.h
@@ -0,0 +1,268 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_VECTOR_H_
+#define LIB_FIDL_CPP_VECTOR_H_
+
+#include <lib/fidl/cpp/builder.h>
+#include <lib/fidl/cpp/comparison.h>
+#include <lib/fit/optional.h>
+#include <zircon/assert.h>
+
+#include <utility>
+#include <vector>
+
+#include "lib/fidl/cpp/traits.h"
+#include "lib/fidl/cpp/transition.h"
+
+namespace fidl {
+
+#if defined(FIDL_USE_FIT_OPTIONAL)
+
+template <typename T>
+class VectorPtr : public fit::optional<std::vector<T>> {
+ public:
+ constexpr VectorPtr() = default;
+
+ constexpr VectorPtr(fit::nullopt_t) noexcept {}
+ FIDL_FIT_OPTIONAL_DEPRECATED("Use fit::nullopt instead of nullptr")
+ constexpr VectorPtr(std::nullptr_t) noexcept {}
+
+ VectorPtr(const VectorPtr&) = default;
+ VectorPtr& operator=(const VectorPtr&) = default;
+
+ VectorPtr(VectorPtr&&) noexcept = default;
+ VectorPtr& operator=(VectorPtr&&) noexcept = default;
+
+ // Move construct and move assignment from the value type
+ constexpr VectorPtr(std::vector<T>&& value) : fit::optional<std::vector<T>>(std::move(value)) {}
+ constexpr VectorPtr& operator=(std::vector<T>&& value) {
+ fit::optional<std::vector<T>>::operator=(std::move(value));
+ return *this;
+ }
+
+ // Copy construct and copy assignment from the value type
+ constexpr VectorPtr(const std::vector<T>& value) : fit::optional<std::vector<T>>(value) {}
+ constexpr VectorPtr& operator=(const std::vector<T>& value) {
+ fit::optional<std::vector<T>>::operator=(value);
+ return *this;
+ }
+
+ explicit VectorPtr(size_t size) : fit::optional<std::vector<T>>(size) {}
+
+ // Override unchecked accessors with versions that check.
+ constexpr std::vector<T>* operator->() {
+ if (!fit::optional<std::vector<T>>::has_value()) {
+ __builtin_trap();
+ }
+ return fit::optional<std::vector<T>>::operator->();
+ }
+ constexpr const std::vector<T>* operator->() const {
+ if (!fit::optional<std::vector<T>>::has_value()) {
+ __builtin_trap();
+ }
+ return fit::optional<std::vector<T>>::operator->();
+ }
+
+ FIDL_FIT_OPTIONAL_DEPRECATED("Assign an empty std::vector")
+ VectorPtr& emplace() {
+ *this = std::move(std::vector<T>());
+ return *this;
+ }
+
+ FIDL_FIT_OPTIONAL_DEPRECATED("Assign an std::vector")
+ VectorPtr& emplace(std::initializer_list<std::vector<T>>&& ilist) {
+ *this = (std::move(std::vector<T>(ilist)));
+ return *this;
+ }
+
+ FIDL_FIT_OPTIONAL_DEPRECATED("Assign an std::vector")
+ VectorPtr& emplace(std::vector<T>&& value) {
+ *this = std::move(value);
+ return *this;
+ }
+};
+
+#else
+
+// A representation of a FIDL vector that owns the memory for the vector.
+//
+// A VectorPtr has three states: (1) null, (2) empty, (3) contains data. You
+// can check for the null state using the |is_null| method.
+template <typename T>
+class VectorPtr {
+ public:
+ VectorPtr() : is_null_if_empty_(true) {}
+ ~VectorPtr() = default;
+ VectorPtr(std::nullptr_t) : is_null_if_empty_(true) {}
+ explicit VectorPtr(size_t size) : vec_(std::vector<T>(size)), is_null_if_empty_(false) {}
+ VectorPtr(std::vector<T>&& vec) : vec_(std::move(vec)), is_null_if_empty_(false) {}
+
+ VectorPtr(VectorPtr&& other) = default;
+ VectorPtr& operator=(VectorPtr&& other) = default;
+
+ // Copy construct and assignment from a const std::vector<T>&
+ VectorPtr(const std::vector<T>& other) : vec_(other), is_null_if_empty_(false) {}
+ VectorPtr& operator=(const std::vector<T>& other) {
+ vec_ = other;
+ is_null_if_empty_ = false;
+ return *this;
+ }
+
+ // Creates a VectorPtr of the given size.
+ //
+ // Equivalent to using the |VectorPtr(size_t)| constructor.
+ FIDL_FIT_OPTIONAL_DEPRECATED("use constructor")
+ static VectorPtr New(size_t size) { return VectorPtr(size); }
+
+ // Accesses the underlying std::vector object.
+ FIDL_FIT_OPTIONAL_DEPRECATED("use value_or")
+ const std::vector<T>& get() const { return vec_; }
+
+ // Takes the std::vector from the VectorPtr.
+ //
+ // After this method returns, the VectorPtr is null.
+ FIDL_FIT_OPTIONAL_DEPRECATED("use std::move(vecptr).value();vecptr.reset();")
+ std::vector<T> take() {
+ is_null_if_empty_ = true;
+ return std::move(vec_);
+ }
+
+ // Stores the given std::vector in this VectorPtr.
+ //
+ // After this method returns, the VectorPtr is non-null.
+ FIDL_FIT_OPTIONAL_DEPRECATED("use assignment or emplace()")
+ void reset(std::vector<T> vec) {
+ vec_ = std::move(vec);
+ is_null_if_empty_ = false;
+ }
+
+ VectorPtr& emplace() {
+ vec_.clear();
+ is_null_if_empty_ = false;
+ return *this;
+ }
+
+ VectorPtr& emplace(std::vector<T>&& vec) {
+ vec_ = std::move(vec);
+ is_null_if_empty_ = false;
+ return *this;
+ }
+
+ VectorPtr& emplace(std::initializer_list<T>&& ilist) {
+ vec_ = std::vector<T>(ilist);
+ is_null_if_empty_ = false;
+ return *this;
+ }
+
+ VectorPtr& operator=(std::vector<T>&& vec) {
+ vec_ = std::move(vec);
+ is_null_if_empty_ = false;
+ return *this;
+ }
+
+ void reset() {
+ vec_.clear();
+ is_null_if_empty_ = true;
+ }
+
+ // Resizes the underlying std::vector in this VectorPtr to the given size.
+ //
+ // After this method returns, the VectorPtr is non-null.
+ FIDL_FIT_OPTIONAL_DEPRECATED("initialize and use operator->")
+ void resize(size_t size) {
+ vec_.resize(size);
+ is_null_if_empty_ = false;
+ }
+
+ // Pushes |value| onto the back of this VectorPtr.
+ //
+ // If this vector was null, it will become non-null with a size of 1.
+ FIDL_FIT_OPTIONAL_DEPRECATED("initialize and use operator->")
+ void push_back(const T& value) {
+ vec_.push_back(value);
+ is_null_if_empty_ = false;
+ }
+
+ // Pushes |value| onto the back of this VectorPtr.
+ //
+ // If this vector was null, it will become non-null with a size of 1.
+ FIDL_FIT_OPTIONAL_DEPRECATED("initialize and use operator->")
+ void push_back(T&& value) {
+ vec_.push_back(std::forward<T>(value));
+ is_null_if_empty_ = false;
+ }
+
+ void swap(VectorPtr& other) {
+ using std::swap;
+ swap(vec_, other.vec_);
+ swap(is_null_if_empty_, other.is_null_if_empty_);
+ }
+
+ // Returns a copy of this VectorPtr.
+ //
+ // Unlike fidl::Clone, this function can never fail. However, this function
+ // works only if T is copiable.
+ FIDL_FIT_OPTIONAL_DEPRECATED("use fidl::Clone()")
+ VectorPtr Clone() const {
+ if (is_null())
+ return VectorPtr();
+ return VectorPtr(vec_);
+ }
+
+ // Whether this VectorPtr is null.
+ //
+ // The null state is separate from the empty state.
+ FIDL_FIT_OPTIONAL_DEPRECATED("use !has_value()")
+ bool is_null() const { return is_null_if_empty_ && vec_.empty(); }
+
+ bool has_value() const { return !is_null_if_empty_ || !vec_.empty(); }
+
+ // Tests as true if non-null, false if null.
+ explicit operator bool() const { return has_value(); }
+
+ // Provides access to the underlying std::vector.
+ std::vector<T>* operator->() { return &vec_; }
+ const std::vector<T>* operator->() const { return &vec_; }
+
+ // Provides access to the underlying std::vector.
+ std::vector<T>& operator*() { return vec_; }
+ const std::vector<T>& operator*() const { return vec_; }
+
+ std::vector<T>& value() & { return vec_; }
+ const std::vector<T>& value() const& { return vec_; }
+
+ std::vector<T>& value_or(std::vector<T>& default_value) & {
+ return has_value() ? vec_ : default_value;
+ }
+ const std::vector<T>& value_or(const std::vector<T>& default_value) const& {
+ return has_value() ? vec_ : default_value;
+ }
+
+ // Provides implicit conversion for accessing the underlying std::vector.
+ // To mutate the vector, use operator* or operator-> or one of the mutation
+ // functions.
+ FIDL_FIT_OPTIONAL_DEPRECATED("use value_or()")
+ operator const std::vector<T> &() const { return vec_; }
+
+ private:
+ std::vector<T> vec_;
+ bool is_null_if_empty_;
+};
+
+#endif
+
+template <class T>
+struct Equality<VectorPtr<T>> {
+ bool operator()(const VectorPtr<T>& lhs, const VectorPtr<T>& rhs) const {
+ if (!lhs.has_value() || !rhs.has_value()) {
+ return !lhs.has_value() == !rhs.has_value();
+ }
+ return ::fidl::Equality<std::vector<T>>{}(lhs.value(), rhs.value());
+ }
+};
+
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_VECTOR_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp_base/internal/logging.cc b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/internal/logging.cc
new file mode 100644
index 0000000..0386bae
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/internal/logging.cc
@@ -0,0 +1,67 @@
+// Copyright 2018 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.
+
+#include "lib/fidl/cpp/internal/logging.h"
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef __Fuchsia__
+
+#include <zircon/status.h>
+
+#endif
+
+namespace fidl {
+namespace internal {
+
+void ReportEncodingError(const Message& message, const fidl_type_t* type, const char* error_msg,
+ const char* file, int line) {
+ char type_name[1024];
+ size_t type_name_length = fidl_format_type_name(type, type_name, sizeof(type_name));
+ fprintf(stderr,
+ "fidl encoding error at %s:%d: %s, "
+ "type %.*s, %" PRIu32 " bytes, %" PRIu32 " handles\n",
+ file, line, error_msg, static_cast<int>(type_name_length), type_name,
+ message.bytes().actual(), message.handles().actual());
+}
+
+void ReportDecodingError(const Message& message, const fidl_type_t* type, const char* error_msg,
+ const char* file, int line) {
+ char type_name[1024];
+ size_t type_name_length = fidl_format_type_name(type, type_name, sizeof(type_name));
+ fprintf(stderr,
+ "fidl decoding error at %s:%d: %s, "
+ "type %.*s, %" PRIu32 " bytes, %" PRIu32 " handles\n",
+ file, line, error_msg, static_cast<int>(type_name_length), type_name,
+ message.bytes().actual(), message.handles().actual());
+}
+
+void ReportChannelWritingError(const Message& message, const fidl_type_t* type, zx_status_t status,
+ const char* file, int line) {
+ char type_name[1024];
+ size_t type_name_length = fidl_format_type_name(type, type_name, sizeof(type_name));
+
+#ifdef __Fuchsia__
+
+ fprintf(stderr,
+ "fidl channel writing error at %s:%d: zx_status_t %d (%s), "
+ "type %.*s, %" PRIu32 " bytes, %" PRIu32 " handles\n",
+ file, line, status, zx_status_get_string(status), static_cast<int>(type_name_length),
+ type_name, message.bytes().actual(), message.handles().actual());
+
+#else
+
+ fprintf(stderr,
+ "fidl channel writing error at %s:%d: zx_status_t %d, "
+ "type %.*s, %" PRIu32 " bytes, %" PRIu32 " handles\n",
+ file, line, status, static_cast<int>(type_name_length), type_name,
+ message.bytes().actual(), message.handles().actual());
+
+#endif
+}
+
+} // namespace internal
+} // namespace fidl
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp_base/meta.json b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/meta.json
new file mode 100644
index 0000000..0b0746a
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp_base/meta.json
@@ -0,0 +1,33 @@
+{
+ "banjo_deps": [],
+ "deps": [
+ "fidl_base",
+ "fit",
+ "fidl-async",
+ "zx"
+ ],
+ "fidl_deps": [],
+ "headers": [
+ "pkg/fidl_cpp_base/include/lib/fidl/cpp/clone.h",
+ "pkg/fidl_cpp_base/include/lib/fidl/cpp/coding_traits.h",
+ "pkg/fidl_cpp_base/include/lib/fidl/cpp/comparison.h",
+ "pkg/fidl_cpp_base/include/lib/fidl/cpp/decoder.h",
+ "pkg/fidl_cpp_base/include/lib/fidl/cpp/encoder.h",
+ "pkg/fidl_cpp_base/include/lib/fidl/cpp/internal/logging.h",
+ "pkg/fidl_cpp_base/include/lib/fidl/cpp/object_coding.h",
+ "pkg/fidl_cpp_base/include/lib/fidl/cpp/string.h",
+ "pkg/fidl_cpp_base/include/lib/fidl/cpp/traits.h",
+ "pkg/fidl_cpp_base/include/lib/fidl/cpp/transition.h",
+ "pkg/fidl_cpp_base/include/lib/fidl/cpp/vector.h"
+ ],
+ "include_dir": "pkg/fidl_cpp_base/include",
+ "name": "fidl_cpp_base",
+ "root": "pkg/fidl_cpp_base",
+ "sources": [
+ "pkg/fidl_cpp_base/clone.cc",
+ "pkg/fidl_cpp_base/decoder.cc",
+ "pkg/fidl_cpp_base/encoder.cc",
+ "pkg/fidl_cpp_base/internal/logging.cc"
+ ],
+ "type": "cc_source_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp_sync/BUILD.gn b/third_party/fuchsia-sdk/pkg/fidl_cpp_sync/BUILD.gn
new file mode 100644
index 0000000..7b416bd
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp_sync/BUILD.gn
@@ -0,0 +1,35 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("fidl_cpp_sync") {
+ sources = [
+ "internal/message_sender.cc",
+ "internal/synchronous_proxy.cc",
+ "include/lib/fidl/cpp/interface_handle.h",
+ "include/lib/fidl/cpp/interface_request.h",
+ "include/lib/fidl/cpp/internal/message_sender.h",
+ "include/lib/fidl/cpp/internal/synchronous_proxy.h",
+ "include/lib/fidl/cpp/synchronous_interface_ptr.h",
+ ]
+ include_dirs = [ "include" ]
+ public_deps = [
+ "../fidl",
+ "../fidl-async",
+ "../fidl_cpp_base",
+ "../fit",
+ "../zx",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fidl_cpp_sync",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp_sync/include/lib/fidl/cpp/interface_handle.h b/third_party/fuchsia-sdk/pkg/fidl_cpp_sync/include/lib/fidl/cpp/interface_handle.h
new file mode 100644
index 0000000..f33ffe1
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp_sync/include/lib/fidl/cpp/interface_handle.h
@@ -0,0 +1,186 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_INTERFACE_HANDLE_H_
+#define LIB_FIDL_CPP_INTERFACE_HANDLE_H_
+
+#include <lib/zx/channel.h>
+#include <zircon/assert.h>
+
+#include <cstddef>
+#include <utility>
+
+#include "lib/fidl/cpp/clone.h"
+#include "lib/fidl/cpp/coding_traits.h"
+#include "lib/fidl/cpp/interface_request.h"
+
+namespace fidl {
+class Builder;
+template <typename Interface>
+class InterfacePtr;
+template <typename Interface>
+class SynchronousInterfacePtr;
+
+// The client endpoint of a FIDL channel.
+//
+// The remote end of the channel expects this end of the channel to speak the
+// protocol associated with |Interface|. This type is the dual of
+// |InterfaceRequest|.
+//
+// Unlike an |InterfacePtr|, an |InterfaceHandle| does not have thread affinity
+// and can therefore be transferred to another thread or another process. To
+// create an |InterfacePtr| to send messages on this channel, call the |Bind()|
+// method, either on the |InterfaceHandle| or the |InterfacePtr| object.
+//
+// See also:
+//
+// * |InterfaceRequest|, which is the server analog of an |InterfaceHandle|.
+template <typename Interface>
+class InterfaceHandle final {
+ public:
+ // Creates an |InterfaceHandle| whose underlying channel is invalid.
+ InterfaceHandle() = default;
+
+ // Creates an |InterfaceHandle| that wraps the given |channel|.
+ explicit InterfaceHandle(zx::channel channel) : channel_(std::move(channel)) {}
+
+ InterfaceHandle(const InterfaceHandle& other) = delete;
+ InterfaceHandle& operator=(const InterfaceHandle& other) = delete;
+
+ InterfaceHandle(InterfaceHandle&& other) : channel_(std::move(other.channel_)) {}
+
+ InterfaceHandle& operator=(InterfaceHandle&& other) {
+ channel_ = std::move(other.channel_);
+ return *this;
+ }
+
+ // Implicit conversion from nullptr to an |InterfaceHandle| without a valid
+ // |channel|.
+ InterfaceHandle(std::nullptr_t) {}
+
+ // Implicit conversion from |InterfacePtr| unbinds the channel from the
+ // |InterfacePtr|.
+ //
+ // This requires the caller to provide an rvalue reference, as the caller's
+ // InterfacePtr is effectively moved out of.
+ //
+ // Making this constructor templated ensures that it is not type-instantiated
+ // unless it is used, making the InterfacePtr<->InterfaceHandle codependency
+ // less fragile.
+ //
+ // The std::enable_if_t avoids creation of unintended implicit type
+ // conversions (especially from anything else that has an "Unbind()"),
+ // presumably due to InterfacePtrType being inferred to be something other
+ // than InterfacePtr<Interface>. However, if a caller is trying to use a type
+ // that's only incorrect due to not being an rvalue reference, we do permit
+ // this constructor to be selected, but then static_assert() with a message
+ // suggesting std::move().
+ template <typename InterfacePtrType = InterfacePtr<Interface>,
+ typename std::enable_if_t<
+ std::is_same<InterfacePtr<Interface>,
+ typename std::remove_reference<InterfacePtrType>::type>::value ||
+ std::is_same<SynchronousInterfacePtr<Interface>,
+ typename std::remove_reference<InterfacePtrType>::type>::value,
+ int>
+ zero_not_used = 0>
+ InterfaceHandle(InterfacePtrType&& ptr) {
+ static_assert(std::is_same<InterfacePtr<Interface>&&, decltype(ptr)>::value ||
+ std::is_same<SynchronousInterfacePtr<Interface>&&, decltype(ptr)>::value,
+ "Implicit conversion from InterfacePtr<> (or "
+ "SynchronousInterfacePtr<>) to InterfaceHandle<> requires an rvalue "
+ "reference. Maybe there's a missing std::move(), or consider "
+ "using/providing an InterfaceHandle<> directly instead (particularly "
+ "if the usage prior to this conversion doesn't need to send or receive "
+ "messages).");
+ *this = ptr.Unbind();
+ }
+
+ // Creates a new channel, retains one endpoint in this |InterfaceHandle| and
+ // returns the other as an |InterfaceRequest|.
+ //
+ // Typically, the returned |InterfaceRequest| is passed to another process,
+ // which will implement the server endpoint for the |Interface| protocol.
+ //
+ // If |NewRequest| fails to create the underlying channel, the returned
+ // |InterfaceRequest| will return false from |is_valid()|.
+ InterfaceRequest<Interface> NewRequest() {
+ zx::channel h1, h2;
+ if (zx::channel::create(0, &h1, &h2) != ZX_OK)
+ return nullptr;
+ channel_ = std::move(h1);
+ return InterfaceRequest<Interface>(std::move(h2));
+ }
+
+ // Creates an |InterfacePtr| bound to the channel in this |InterfaceHandle|.
+ //
+ // This function transfers ownership of the underlying channel to the
+ // returned |InterfacePtr|, which means the |is_valid()| method will return
+ // false after this method returns.
+ //
+ // Requires the current thread to have a default async_dispatcher_t (e.g., a
+ // message loop) in order to read messages from the channel and to monitor the
+ // channel for |ZX_CHANNEL_PEER_CLOSED|.
+ //
+ // Making this method templated ensures that it is not type-instantiated
+ // unless it is used, making the InterfacePtr<->InterfaceHandle codependency
+ // less fragile.
+ template <typename InterfacePtr = InterfacePtr<Interface>>
+ inline InterfacePtr Bind() {
+ InterfacePtr ptr;
+ ptr.Bind(std::move(channel_));
+ return ptr;
+ }
+
+ template <typename SyncInterfacePtr = SynchronousInterfacePtr<Interface>>
+ inline SyncInterfacePtr BindSync() {
+ SyncInterfacePtr ptr;
+ ptr.Bind(std::move(channel_));
+ return ptr;
+ }
+
+ // Whether the underlying channel is valid.
+ bool is_valid() const { return !!channel_; }
+ explicit operator bool() const { return is_valid(); }
+
+ // Transfers ownership of the underlying channel to the caller.
+ zx::channel TakeChannel() { return std::move(channel_); }
+
+ // The underlying channel.
+ const zx::channel& channel() const { return channel_; }
+ void set_channel(zx::channel channel) { channel_ = std::move(channel); }
+
+ void Encode(Encoder* encoder, size_t offset) { encoder->EncodeHandle(&channel_, offset); }
+
+ static void Decode(Decoder* decoder, InterfaceHandle<Interface>* value, size_t offset) {
+ decoder->DecodeHandle(&value->channel_, offset);
+ }
+
+ private:
+ zx::channel channel_;
+};
+
+// Equality.
+template <typename T>
+struct Equality<InterfaceHandle<T>> {
+ bool operator()(const InterfaceHandle<T>& lhs, const InterfaceHandle<T>& rhs) const {
+ return lhs.channel() == rhs.channel();
+ }
+};
+
+template <typename T>
+struct CodingTraits<InterfaceHandle<T>>
+ : public EncodableCodingTraits<InterfaceHandle<T>, sizeof(zx_handle_t)> {};
+
+template <typename T>
+inline zx_status_t Clone(const InterfaceHandle<T>& value, InterfaceHandle<T>* result) {
+ if (!value) {
+ *result = InterfaceHandle<T>();
+ return ZX_OK;
+ }
+ return ZX_ERR_ACCESS_DENIED;
+}
+
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_INTERFACE_HANDLE_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp_sync/include/lib/fidl/cpp/interface_request.h b/third_party/fuchsia-sdk/pkg/fidl_cpp_sync/include/lib/fidl/cpp/interface_request.h
new file mode 100644
index 0000000..7db775a
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp_sync/include/lib/fidl/cpp/interface_request.h
@@ -0,0 +1,152 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_INTERFACE_REQUEST_H_
+#define LIB_FIDL_CPP_INTERFACE_REQUEST_H_
+
+#include <lib/fidl/epitaph.h>
+#include <lib/fit/function.h>
+#include <lib/zx/channel.h>
+
+#include <cstddef>
+#include <utility>
+
+#include "lib/fidl/cpp/clone.h"
+#include "lib/fidl/cpp/coding_traits.h"
+
+namespace fidl {
+class Builder;
+
+// The server endpoint of a FIDL channel.
+//
+// The remote end of the channel expects this end of the channel to speak the
+// protocol associated with |Interface|. This type is the dual of
+// |InterfaceHandle|.
+//
+// An |InterfaceRequest| does not have thread affinity and can therefore be
+// transferred to another thread or another process. To bind an implementation
+// of |Interface| to this |InterfaceRequest|, use a |Binding| object.
+//
+// Typically, |InterfaceRequest| objects are created by a prospective client of
+// |Interface|, which then sends the |InterfaceRequest| to another process to
+// request that the remote process implement the |Interface|. This pattern
+// enables *pipelined* operation, in which the client can start calling methods
+// on an associated |InterfacePtr| immediately, before the |InterfaceRequest|
+// has reached the remote process and been bound to an implementation. These
+// method calls are buffered by the underlying channel until they are read by
+// the remote process.
+//
+// Example:
+//
+// #include "foo.fidl.h"
+//
+// class FooImpl : public Foo {
+// public:
+// explicit FooImpl(InterfaceRequest<Foo> request)
+// : binding_(this, std::move(request)) {}
+//
+// // Foo implementation here.
+//
+// private:
+// Binding<Foo> binding_;
+// };
+//
+// After the |InterfaceRequest| has been bound to an implementation, the
+// implementation will receive method calls from the remote endpoint of the
+// channel on the thread to which the |InterfaceRequest| was bound.
+//
+// See also:
+//
+// * |InterfaceHandle|, which is the client analog of an |InterfaceRequest|.
+template <typename Interface>
+class InterfaceRequest final {
+ public:
+ // Creates an |InterfaceHandle| whose underlying channel is invalid.
+ //
+ // Some protocols contain messages that permit such |InterfaceRequest|
+ // objects, which indicate that the client is not interested in the server
+ // providing an implementation of |Interface|.
+ InterfaceRequest() = default;
+
+ // Creates an |InterfaceHandle| that wraps the given |channel|.
+ explicit InterfaceRequest(zx::channel channel) : channel_(std::move(channel)) {}
+
+ InterfaceRequest(const InterfaceRequest& other) = delete;
+ InterfaceRequest& operator=(const InterfaceRequest& other) = delete;
+
+ InterfaceRequest(InterfaceRequest&& other) : channel_(std::move(other.channel_)) {}
+
+ InterfaceRequest& operator=(InterfaceRequest&& other) {
+ channel_ = std::move(other.channel_);
+ return *this;
+ }
+
+ // Implicit conversion from nullptr to an |InterfaceRequest| with an
+ // invalid |channel|.
+ InterfaceRequest(std::nullptr_t) {}
+
+ // Whether the underlying channel is valid.
+ bool is_valid() const { return !!channel_; }
+ explicit operator bool() const { return is_valid(); }
+
+ // Transfers ownership of the underlying channel to the caller.
+ zx::channel TakeChannel() { return std::move(channel_); }
+
+ // The underlying channel.
+ const zx::channel& channel() const { return channel_; }
+ void set_channel(zx::channel channel) { channel_ = std::move(channel); }
+
+ void Encode(Encoder* encoder, size_t offset) { encoder->EncodeHandle(&channel_, offset); }
+
+ static void Decode(Decoder* decoder, InterfaceRequest<Interface>* value, size_t offset) {
+ decoder->DecodeHandle(&value->channel_, offset);
+ }
+
+ // Sends an Epitaph over the bound channel corresponding to the error passed
+ // as a parameter, closes the channel, and unbinds it. An Epitaph is the last
+ // message sent over a channel before a close operation; for the purposes of
+ // this function, it can be thought of as a return code. See the FIDL
+ // language spec for more information about Epitaphs.
+ //
+ // The return value can be any of the return values of zx_channel_write.
+ zx_status_t Close(zx_status_t epitaph_value) {
+ return is_valid() ? fidl_epitaph_write(TakeChannel().get(), epitaph_value) : ZX_ERR_BAD_STATE;
+ }
+
+ private:
+ zx::channel channel_;
+};
+
+// A |InterfaceRequestHandler<Interface>| is simply a function that
+// handles an interface request for |Interface|. If it determines that the
+// request should be "accepted", then it should "connect" ("take ownership
+// of") request. Otherwise, it can simply drop |request| (as implied by the
+// interface).
+template <typename Interface>
+using InterfaceRequestHandler = fit::function<void(fidl::InterfaceRequest<Interface> request)>;
+
+// Equality.
+template <typename T>
+struct Equality<InterfaceRequest<T>> {
+ bool operator()(const InterfaceRequest<T>& lhs, const InterfaceRequest<T>& rhs) const {
+ return lhs.channel() == rhs.channel();
+ }
+};
+
+template <typename T>
+struct CodingTraits<InterfaceRequest<T>>
+ : public EncodableCodingTraits<InterfaceRequest<T>, sizeof(zx_handle_t)> {};
+
+template <typename T>
+inline zx_status_t Clone(const InterfaceRequest<T>& value, InterfaceRequest<T>* result) {
+ if (!value) {
+ *result = InterfaceRequest<T>();
+ return ZX_OK;
+ }
+ return ZX_ERR_ACCESS_DENIED;
+}
+
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_INTERFACE_REQUEST_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp_sync/include/lib/fidl/cpp/internal/message_sender.h b/third_party/fuchsia-sdk/pkg/fidl_cpp_sync/include/lib/fidl/cpp/internal/message_sender.h
new file mode 100644
index 0000000..2fa1073
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp_sync/include/lib/fidl/cpp/internal/message_sender.h
@@ -0,0 +1,36 @@
+// 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.
+
+#ifndef LIB_FIDL_CPP_INTERNAL_MESSAGE_SENDER_H_
+#define LIB_FIDL_CPP_INTERNAL_MESSAGE_SENDER_H_
+
+#include <lib/fidl/cpp/message.h>
+#include <lib/zx/channel.h>
+#include <zircon/types.h>
+
+namespace fidl {
+namespace internal {
+
+// An interface for sending FIDL messages.
+class MessageSender {
+ public:
+ virtual ~MessageSender();
+
+ // Send a message over the channel.
+ //
+ // Returns an error if the message fails to encode properly or if the message
+ // cannot be written to the channel.
+ virtual zx_status_t Send(const fidl_type_t* type, Message message) = 0;
+};
+
+// Send a message over the channel.
+//
+// Returns an error if the message fails to encode properly or if the message
+// cannot be written to the channel.
+zx_status_t SendMessage(const zx::channel& channel, const fidl_type_t* type, Message message);
+
+} // namespace internal
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_INTERNAL_MESSAGE_SENDER_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp_sync/include/lib/fidl/cpp/internal/synchronous_proxy.h b/third_party/fuchsia-sdk/pkg/fidl_cpp_sync/include/lib/fidl/cpp/internal/synchronous_proxy.h
new file mode 100644
index 0000000..4ab12cd
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp_sync/include/lib/fidl/cpp/internal/synchronous_proxy.h
@@ -0,0 +1,61 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_INTERNAL_SYNCHRONOUS_PROXY_H_
+#define LIB_FIDL_CPP_INTERNAL_SYNCHRONOUS_PROXY_H_
+
+#include <lib/fidl/cpp/internal/message_sender.h>
+#include <lib/fidl/cpp/message.h>
+#include <lib/zx/channel.h>
+#include <zircon/fidl.h>
+
+namespace fidl {
+namespace internal {
+
+// Manages the client state for a synchronous interface.
+//
+// A |SynchronousProxy| manages the client state for a sychronous interface.
+// This object validates messages before sending them to the remote endpoint,
+// and (optionally) blocks until it receives a reply.
+//
+// Instances of this class are thread-safe.
+class SynchronousProxy final : public MessageSender {
+ public:
+ // Creates a |SynchronousProxy| that wraps the given channel.
+ explicit SynchronousProxy(zx::channel channel);
+ ~SynchronousProxy();
+
+ // Returns the underlying channel from this object.
+ //
+ // The |SynchronousProxy| does not attempt to synchronize this operation with
+ // |Send| or |Call|.
+ zx::channel TakeChannel();
+
+ // Validates that |message| matches the given |type| and sends the message
+ // through the underlying channel.
+ //
+ // Does not block.
+ //
+ // Returns an error if validation or writing fails.
+ zx_status_t Send(const fidl_type_t* type, Message message) final;
+
+ // Validate that |request| matches the given |request_type| and sends
+ // |request| through the underlying channel. Blocks until it receives a
+ // response, which is then decoded according to |response_type| and returned
+ // in |response_type|.
+ //
+ // Blocks until the remote endpoint replied.
+ //
+ // Returns an error if validation, writing, reading, or decoding fails.
+ zx_status_t Call(const fidl_type_t* request_type, const fidl_type_t* response_type,
+ Message request, Message* response);
+
+ private:
+ zx::channel channel_;
+};
+
+} // namespace internal
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_INTERNAL_SYNCHRONOUS_PROXY_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp_sync/include/lib/fidl/cpp/synchronous_interface_ptr.h b/third_party/fuchsia-sdk/pkg/fidl_cpp_sync/include/lib/fidl/cpp/synchronous_interface_ptr.h
new file mode 100644
index 0000000..cb775f9
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp_sync/include/lib/fidl/cpp/synchronous_interface_ptr.h
@@ -0,0 +1,182 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIDL_CPP_SYNCHRONOUS_INTERFACE_PTR_H_
+#define LIB_FIDL_CPP_SYNCHRONOUS_INTERFACE_PTR_H_
+
+#include <stddef.h>
+
+#include <memory>
+#include <utility>
+
+#include "lib/fidl/cpp/interface_handle.h"
+
+namespace fidl {
+
+// A synchronous client interface to a remote implementation of |Interface|.
+//
+// An |SynchronousInterfacePtr| implements |Interface| by proxying calls through
+// a |channel| to a remote implementation of |Interface|. Method calls on the
+// |Interface| proxy are encoded and sent through the bound channel to the
+// remote endpoint, which processes them. If the method has a reply (including
+// any empty reply), the client blocks and waits for the remote endpoint to
+// reply.
+//
+// You need to bind the |SynchronousInterfacePtr| before calling any |Interface|
+// methods. There are a number of ways to bind the |SynchronousInterfacePtr|.
+// See |NewRequest|, |Bind|, and the |BindSync| method on |InterfaceHandle|.
+//
+// This class is thread-compatible. Once bound, the |SynchronousInterfacePtr|
+// can be used from multiple threads simultaneously. However, the
+// |SynchronousInterfacePtr| does not attempt to synchronize mutating operatios,
+// such as |Bind| or |Unbind|.
+//
+// |SynchronousInterfacePtr| does not require a |async_dispatcher_t|
+// implementation and does not bind to the default |async_dispatcher_t*| for the
+// current thread, unlike |InterfacePtr|.
+//
+// See also:
+//
+// * |Binding|, which is the server analog of an |SynchronousInterfacePtr|.
+// * |InterfacePtr|, which is an asynchronous interface to a remote
+// implementation.
+template <typename Interface>
+class SynchronousInterfacePtr final {
+ public:
+ using InterfaceSync = typename Interface::Sync_;
+
+ // Creates an unbound |SynchronousInterfacePtr|.
+ SynchronousInterfacePtr() {}
+ SynchronousInterfacePtr(std::nullptr_t) {}
+
+ SynchronousInterfacePtr(const SynchronousInterfacePtr& other) = delete;
+ SynchronousInterfacePtr& operator=(const SynchronousInterfacePtr& other) = delete;
+
+ SynchronousInterfacePtr(SynchronousInterfacePtr&& other) = default;
+ SynchronousInterfacePtr& operator=(SynchronousInterfacePtr&& other) = default;
+
+ // Bind the |SynchronousInterfacePtr| to one endpoint of a newly created
+ // channel and return the other endpoint as an |InterfaceRequest|.
+ //
+ // Typically, the returned |InterfaceRequest| will be sent to a remote process
+ // to be bound to an implementation of |Interface| using a |Binding| object.
+ //
+ // After calling this method, clients can start calling methods on this
+ // |SynchronousInterfacePtr|. However, methods that have replies will block
+ // until the remote implementation binds the |InterfaceRequest| and replies.
+ //
+ // # Example
+ //
+ // Given the following interface:
+ //
+ // interface Database {
+ // OpenTable(request<Table> table);
+ // };
+ //
+ // The client can use the |NewRequest| method to create the |InterfaceRequest|
+ // object needed by the |OpenTable| method:
+ //
+ // DatabasePtr database = ...; // Connect to database.
+ // TableSyncPtr table;
+ // database->OpenTable(table.NewRequest());
+ //
+ // The client can call methods on |table| immediately. Messages that have
+ // replies will block until the Database implementation binds a Table
+ // implementation and replies.
+ InterfaceRequest<Interface> NewRequest() {
+ zx::channel h1;
+ zx::channel h2;
+ if (zx::channel::create(0, &h1, &h2) != ZX_OK)
+ return nullptr;
+ Bind(std::move(h1));
+ return InterfaceRequest<Interface>(std::move(h2));
+ }
+
+ // Binds the |SynchronousInterfacePtr| to the given |channel|.
+ //
+ // The |SynchronousInterfacePtr| expects the remote end of the |channel| to
+ // speak the protocol defined by |Interface|. Unlike the |Bind| overload that
+ // takes a |InterfaceHandle| parameter, this |Bind| overload lacks type
+ // safety.
+ //
+ // If the |SynchronousInterfacePtr| was prevously bound to another channel,
+ // that channel is closed. If the |channel| is invalid, then this method will
+ // effectively unbind the |SynchronousInterfacePtr|. A more direct way to have
+ // that effect is to call |Unbind|.
+ //
+ // Does not require the current thread to have a default async_dispatcher_t.
+ void Bind(zx::channel channel) {
+ if (!channel) {
+ proxy_.reset();
+ return;
+ }
+ proxy_.reset(new typename InterfaceSync::Proxy_(std::move(channel)));
+ }
+
+ // Binds the |SynchronousInterfacePtr| to the given |InterfaceHandle|.
+ //
+ // The |SynchronousInterfacePtr| expects the remote end of the |channel| to
+ // speak the protocol defined by |Interface|. Unlike the |Bind| overload that
+ // takes a |channel| parameter, this |Bind| overload provides type safety.
+ //
+ // If the |SynchronousInterfacePtr| was prevously bound to another channel,
+ // that channel is closed. If the |InterfaceHandle| is invalid, then this
+ // method will effectively unbind the |SynchronousInterfacePtr|. A more direct
+ // way to have that effect is to call |Unbind|.
+ //
+ // Does not require the current thread to have a default async_dispatcher_t.
+ void Bind(InterfaceHandle<Interface> handle) { return Bind(handle.TakeChannel()); }
+
+ // Unbinds the underlying channel from the |SynchronousInterfacePtr|.
+ //
+ // The underlying channel is returned as an |InterfaceHandle|, which is safe
+ // to transport to another thread or process.
+ //
+ // After this method returns, a subsequent call to |Bind| is required before
+ // calling any additional |Interface| methods.
+ InterfaceHandle<Interface> Unbind() {
+ InterfaceHandle<Interface> handle(proxy_->proxy_.TakeChannel());
+ proxy_.reset();
+ return handle;
+ }
+
+ // Whether this |SynchronousInterfacePtr| is currently bound to a channel.
+ //
+ // If the |SynchronousInterfacePtr| is bound to a channel, calls to
+ // |Interface| methods are proxied to the remote endpoint of the channel.
+ //
+ // See also:
+ //
+ // * |Bind|, which binds a channel to this |SynchronousInterfacePtr|.
+ // * |Unbind|, which unbinds a channel from this |SynchronousInterfacePtr|.
+ bool is_bound() const { return static_cast<bool>(proxy_); }
+
+ // Whether this |SynchronousInterfacePtr| is currently bound to a channel.
+ //
+ // See |is_bound| for details.
+ explicit operator bool() const { return is_bound(); }
+
+ // The |Interface| proxy associated with this |SynchronousInterfacePtr|.
+ //
+ // When this |SynchronousInterfacePtr| is bound, method calls on this
+ // |Interface| will be proxied to the remote endpoint of the connection.
+ // Methods that expect replies will block until the
+ // |SynchronousInterfacePtr| either receives a reply to that transaction.
+ //
+ // When this |SynchronousInterfacePtr| is not bound, this method returns
+ // nullptr.
+ //
+ // The returned |Interface| is thread-compatible and can be used from any
+ // thread.
+ InterfaceSync* get() const { return proxy_.get(); }
+ InterfaceSync* operator->() const { return get(); }
+ InterfaceSync& operator*() const { return *get(); }
+
+ private:
+ std::unique_ptr<typename InterfaceSync::Proxy_> proxy_;
+};
+
+} // namespace fidl
+
+#endif // LIB_FIDL_CPP_SYNCHRONOUS_INTERFACE_PTR_H_
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp_sync/internal/message_sender.cc b/third_party/fuchsia-sdk/pkg/fidl_cpp_sync/internal/message_sender.cc
new file mode 100644
index 0000000..ce609ff
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp_sync/internal/message_sender.cc
@@ -0,0 +1,32 @@
+// 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.
+
+#include <lib/fidl/cpp/internal/logging.h>
+#include <lib/fidl/cpp/internal/message_sender.h>
+#include <zircon/fidl.h>
+
+namespace fidl {
+namespace internal {
+
+MessageSender::~MessageSender() = default;
+
+zx_status_t SendMessage(const zx::channel& channel, const fidl_type_t* type, Message message) {
+ const char* error_msg = nullptr;
+ zx_status_t status = message.Validate(type, &error_msg);
+ if (status != ZX_OK) {
+ FIDL_REPORT_ENCODING_ERROR(message, type, error_msg);
+ return status;
+ }
+
+ status = message.Write(channel.get(), 0);
+ if (status != ZX_OK) {
+ FIDL_REPORT_CHANNEL_WRITING_ERROR(message, type, status);
+ return status;
+ }
+
+ return ZX_OK;
+}
+
+} // namespace internal
+} // namespace fidl
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp_sync/internal/synchronous_proxy.cc b/third_party/fuchsia-sdk/pkg/fidl_cpp_sync/internal/synchronous_proxy.cc
new file mode 100644
index 0000000..c24a84d
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp_sync/internal/synchronous_proxy.cc
@@ -0,0 +1,46 @@
+// Copyright 2018 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.
+
+#include "lib/fidl/cpp/internal/synchronous_proxy.h"
+
+#include <memory>
+#include <utility>
+
+#include "lib/fidl/cpp/internal/logging.h"
+
+namespace fidl {
+namespace internal {
+
+SynchronousProxy::SynchronousProxy(zx::channel channel) : channel_(std::move(channel)) {}
+
+SynchronousProxy::~SynchronousProxy() = default;
+
+zx::channel SynchronousProxy::TakeChannel() { return std::move(channel_); }
+
+zx_status_t SynchronousProxy::Send(const fidl_type_t* type, Message message) {
+ return fidl::internal::SendMessage(channel_, type, std::move(message));
+}
+
+zx_status_t SynchronousProxy::Call(const fidl_type_t* request_type,
+ const fidl_type_t* response_type, Message request,
+ Message* response) {
+ const char* error_msg = nullptr;
+ zx_status_t status = request.Validate(request_type, &error_msg);
+ if (status != ZX_OK) {
+ FIDL_REPORT_ENCODING_ERROR(request, request_type, error_msg);
+ return status;
+ }
+ status = request.Call(channel_.get(), 0, ZX_TIME_INFINITE, response);
+ if (status != ZX_OK)
+ return status;
+ status = response->Decode(response_type, &error_msg);
+ if (status != ZX_OK) {
+ FIDL_REPORT_DECODING_ERROR(*response, response_type, error_msg);
+ return status;
+ }
+ return ZX_OK;
+}
+
+} // namespace internal
+} // namespace fidl
diff --git a/third_party/fuchsia-sdk/pkg/fidl_cpp_sync/meta.json b/third_party/fuchsia-sdk/pkg/fidl_cpp_sync/meta.json
new file mode 100644
index 0000000..d47c0be
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fidl_cpp_sync/meta.json
@@ -0,0 +1,26 @@
+{
+ "banjo_deps": [],
+ "deps": [
+ "fidl_cpp_base",
+ "fidl",
+ "fidl-async",
+ "fit",
+ "zx"
+ ],
+ "fidl_deps": [],
+ "headers": [
+ "pkg/fidl_cpp_sync/include/lib/fidl/cpp/interface_handle.h",
+ "pkg/fidl_cpp_sync/include/lib/fidl/cpp/interface_request.h",
+ "pkg/fidl_cpp_sync/include/lib/fidl/cpp/internal/message_sender.h",
+ "pkg/fidl_cpp_sync/include/lib/fidl/cpp/internal/synchronous_proxy.h",
+ "pkg/fidl_cpp_sync/include/lib/fidl/cpp/synchronous_interface_ptr.h"
+ ],
+ "include_dir": "pkg/fidl_cpp_sync/include",
+ "name": "fidl_cpp_sync",
+ "root": "pkg/fidl_cpp_sync",
+ "sources": [
+ "pkg/fidl_cpp_sync/internal/message_sender.cc",
+ "pkg/fidl_cpp_sync/internal/synchronous_proxy.cc"
+ ],
+ "type": "cc_source_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/fit/BUILD.gn b/third_party/fuchsia-sdk/pkg/fit/BUILD.gn
new file mode 100644
index 0000000..436765d
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/BUILD.gn
@@ -0,0 +1,53 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("fit") {
+ sources = [
+ "barrier.cc",
+ "promise.cc",
+ "scheduler.cc",
+ "scope.cc",
+ "sequencer.cc",
+ "single_threaded_executor.cc",
+ "include/lib/fit/barrier.h",
+ "include/lib/fit/bridge.h",
+ "include/lib/fit/bridge_internal.h",
+ "include/lib/fit/constructors_internal.h",
+ "include/lib/fit/defer.h",
+ "include/lib/fit/function.h",
+ "include/lib/fit/function_internal.h",
+ "include/lib/fit/function_traits.h",
+ "include/lib/fit/in_place_internal.h",
+ "include/lib/fit/nullable.h",
+ "include/lib/fit/optional.h",
+ "include/lib/fit/promise.h",
+ "include/lib/fit/promise_internal.h",
+ "include/lib/fit/result.h",
+ "include/lib/fit/scheduler.h",
+ "include/lib/fit/scope.h",
+ "include/lib/fit/sequencer.h",
+ "include/lib/fit/single_threaded_executor.h",
+ "include/lib/fit/storage_internal.h",
+ "include/lib/fit/string_view.h",
+ "include/lib/fit/thread_safety.h",
+ "include/lib/fit/traits.h",
+ "include/lib/fit/utility_internal.h",
+ "include/lib/fit/variant.h",
+ ]
+ include_dirs = [ "include" ]
+ public_deps = [
+ ]
+}
+
+group("all"){
+ deps = [
+ ":fit",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/fit/barrier.cc b/third_party/fuchsia-sdk/pkg/fit/barrier.cc
new file mode 100644
index 0000000..76a8a71
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/barrier.cc
@@ -0,0 +1,26 @@
+// 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.
+
+#include <lib/fit/barrier.h>
+
+namespace fit {
+
+barrier::barrier() {
+ // Capture a new consumer and intentionally abandon its associated
+ // completer so that a promise chained onto the consumer using
+ // |promise_or()| will become immediately runnable.
+ fit::bridge<> bridge;
+ prior_ = std::move(bridge.consumer);
+}
+
+barrier::~barrier() = default;
+
+fit::consumer<> barrier::swap_prior(fit::consumer<> new_prior) {
+ std::lock_guard<std::mutex> lock(mutex_);
+ fit::consumer<> old_prior = std::move(prior_);
+ prior_ = std::move(new_prior);
+ return old_prior;
+}
+
+} // namespace fit
diff --git a/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/barrier.h b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/barrier.h
new file mode 100644
index 0000000..59c3459
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/barrier.h
@@ -0,0 +1,106 @@
+// 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.
+
+#ifndef LIB_FIT_BARRIER_H_
+#define LIB_FIT_BARRIER_H_
+
+#include <assert.h>
+
+#include <atomic>
+#include <mutex>
+
+#include "bridge.h"
+#include "promise.h"
+#include "thread_safety.h"
+
+namespace fit {
+
+// A barrier is utility class for monitoring pending promises and ensuring they have completed when
+// |barrier.sync| completes. This class is used to mark promises with |barrier.wrap|, without
+// changing their order, but allowing a caller to later invoke |sync| and ensure they have
+// completed.
+//
+// EXAMPLE
+//
+// // Issue tracked work, wrapped by the barrier.
+// fit::barrier barrier;
+// auto work = fit::make_promise([] { do_work(); });
+// executor.schedule_task(work.wrap_with(barrier));
+//
+// auto more_work = fit::make_promise([] { do_work_but_more(); });
+// executor.schedule_task(more_work.wrap_with(barrier));
+//
+// // Ensure that all prior work completes, using the same barrier.
+// barrier.sync().and_then([] {
+// // |work| and |more_work| have been completed.
+// });
+//
+// See documentation of |fit::promise| for more information.
+class barrier final {
+ public:
+ barrier();
+ ~barrier();
+
+ barrier(const barrier&) = delete;
+ barrier(barrier&&) = delete;
+ barrier& operator=(const barrier&) = delete;
+ barrier& operator=(barrier&&) = delete;
+
+ // Returns a new promise which, after invoking the original |promise|, may update sync() callers
+ // if they are waiting for all prior work to complete.
+ //
+ // This method is thread-safe.
+ template <typename Promise>
+ decltype(auto) wrap(Promise promise) {
+ assert(promise);
+
+ fit::bridge<> bridge;
+ auto prior = swap_prior(std::move(bridge.consumer));
+
+ // First, execute the originally provided promise.
+ //
+ // Note that execution of this original promise is not gated behind any interactions
+ // between other calls to |sync()| or |wrap()|.
+ return promise.then([prior = std::move(prior), completer = std::move(bridge.completer)](
+ fit::context& context, typename Promise::result_type& result) mutable {
+ // Wait for all prior work to either terminate or be abandoned before terminating the
+ // completer.
+ //
+ // This means that when |sync()| invokes |swap_prior()|, that caller receives a chain
+ // of these promise-bound completer objects from all prior invocations of |wrap()|.
+ // When this chain completes, the sync promise can complete too, since it implies
+ // that all prior access to the barrier has completed.
+ context.executor()->schedule_task(prior.promise_or(fit::ok()).then(
+ [completer = std::move(completer)](const fit::result<>&) mutable { return; }));
+
+ return result;
+ });
+ }
+
+ // Returns a promise which completes after all previously wrapped work has completed.
+ //
+ // This method is thread-safe.
+ fit::promise<void, void> sync() {
+ // Swap the latest pending work with our own consumer; a subsequent request
+ // to sync should wait on this one.
+ fit::bridge<> bridge;
+ fit::consumer<> prior = swap_prior(std::move(bridge.consumer));
+ return prior.promise_or(fit::ok()).then(
+ [completer = std::move(bridge.completer)](const fit::result<>&) mutable {
+ return fit::make_ok_promise();
+ });
+ }
+
+ private:
+ fit::consumer<> swap_prior(fit::consumer<> new_prior);
+
+ std::mutex mutex_;
+
+ // Holds the consumption capability of the most recently wrapped promise.
+ fit::consumer<> prior_ FIT_GUARDED(mutex_);
+};
+
+} // namespace fit
+
+#endif // LIB_FIT_BARRIER_H_
diff --git a/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/bridge.h b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/bridge.h
new file mode 100644
index 0000000..08e0ddc
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/bridge.h
@@ -0,0 +1,462 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIT_BRIDGE_H_
+#define LIB_FIT_BRIDGE_H_
+
+#include "bridge_internal.h"
+
+namespace fit {
+
+// A bridge is a building block for asynchronous control flow that is formed
+// by the association of two distinct participants: a completer and a consumer.
+//
+// - The completer is responsible for reporting completion of an asynchronous
+// task and providing its result. See |completer| and |fit::completer|.
+// - The consumer is responsible for consuming the result of the asynchronous
+// task. See |consumer| and |fit::consumer|.
+//
+// This class is often used for binding a |fit::promise| to a callback,
+// facilitating interoperation of promises with functions that asynchronously
+// report their result via a callback function. It can also be used more
+// generally anytime it is necessary to decouple completion of an asynchronous
+// task from consumption of its result (possibly on different threads).
+//
+// The completer and consumer each possesses a unique capability that can
+// be exercised at most once during their association: the asynchronous
+// task represented by a bridge can be completed at most once and its
+// result can be consumed at most once. This property is enforced by
+// a single-ownership model for completers and consumers.
+//
+// The completion capability has a single owner represented by |fit::completer|.
+// Its owner may exercise the capability to complete the task (provide its result),
+// it may transfer the capability by moving it to another completer instance,
+// or it may cause the asynchronous task to be "abandoned" by discarding the
+// capability, implying that the task can never produce a result. When this
+// occurs, the associated consumer's |fit::consumer::was_abandoned()| method
+// will return true and the consumer will not obtain any result from the task.
+// See |fit::consumer::promise()| and |fit::consumer::promise_or()| for
+// details on how abandonment of the task can be handled by the consumer.
+//
+// The consumption capability has a single owner represented by |fit::consumer|.
+// Its owner may exercise the capability to consume the task's result (as a
+// promise), it may transfer the capability by moving it to another consumer
+// instance, or it may cause the asynchronous task to be "canceled" by
+// discarding the capability, implying that the task's result can never be
+// consumed. When this occurs, the associated completer's
+// |fit::completer::was_canceled()| method will return true and the task's
+// eventual result (if any) will be silently discarded.
+//
+// DECOUPLING
+//
+// See |fit::schedule_for_consumer| for a helper which uses a bridge to
+// decouple completion and consumption of a task's result so they can be
+// performed on different executors.
+//
+// SYNOPSIS
+//
+// |V| is the type of value produced when the task completes successfully.
+// Use |std::tuple<Args...>| if the task produces multiple values, such as
+// when you intend to bind the task's completer to a callback with multiple
+// arguments using |fit::completer::bind_tuple()|.
+// Defaults to |void|.
+//
+// |E| is the type of error produced when the task completes with an error.
+// Defaults to |void|.
+//
+// EXAMPLE
+//
+// Imagine a File I/O library offers a callback-based asynchronous reading
+// function. We suppose that the read handling code will invoke the
+// callback upon completion. The library's API might look a bit like this:
+//
+// using read_callback = fit::function<void(size_t bytes_read)>;
+// void read_async(size_t num_bytes, uint8_t* buffer, read_callback cb);
+//
+// Here's how we can adapt the library's "read_async" function to a
+// |fit::promise| by binding its callback to a bridge:
+//
+// fit::promise<size_t> promise_read(uint8_t* buffer, size_t num_bytes) {
+// fit::bridge<size_t> bridge;
+// read_async(num_bytes, buffer, bridge.completer.bind());
+// return bridge.consumer.promise_or(::fit::error());
+// }
+//
+// Finally we can chain additional asynchronous tasks to be performed upon
+// completion of the promised read:
+//
+// uint8_t buffer[4096];
+// void my_program(fit::executor* executor) {
+// auto promise = promise_read(buffer, sizeof(buffer))
+// .and_then([] (const size_t& bytes_read) {
+// // consume contents of buffer
+// })
+// .or_else() {
+// // handle error case
+// });
+// executor->schedule_task(std::move(promise));
+// }
+//
+// Similarly, suppose the File I/O library offers a callback-based asynchronous
+// writing function that can return a variety of errors encoded as negative
+// sizes. Here's how we might decode those errors uniformly into |fit::result|
+// allowing them to be handled using combinators such as |or_else|.
+//
+// using write_callback = fit::function<void(size_t bytes_written, int error)>;
+// void write_async(size_t num_bytes, uint8_t* buffer, write_callback cb);
+//
+// fit::promise<size_t, int> promise_write(uint8_t* buffer, size_t num_bytes) {
+// fit::bridge<size_t, int> bridge;
+// write_async(num_bytes, buffer,
+// [completer = std::move(bridge.completer)](size_t bytes_written, int error) {
+// if (bytes_written == 0) {
+// completer.complete_error(error);
+// return;
+// }
+// completer.complete_ok(bytes_written);
+// });
+// return bridge.consumer.promise_or(::fit::error(ERR_ABANDONED));
+// }
+//
+// uint8_t buffer[4096];
+// void my_program(fit::executor* executor) {
+// auto promise = promise_write(buffer, sizeof(buffer))
+// .and_then([] (const size_t& bytes_written) {
+// // consume contents of buffer
+// })
+// .or_else(const int& error) {
+// // handle error case
+// });
+// executor->schedule_task(std::move(promise));
+// }
+//
+// See documentation of |fit::promise| for more information.
+template <typename V, typename E>
+class bridge final {
+ public:
+ using value_type = V;
+ using error_type = E;
+ using result_type = result<value_type, error_type>;
+ using completer_type = ::fit::completer<V, E>;
+ using consumer_type = ::fit::consumer<V, E>;
+
+ // Creates a bridge representing a new asynchronous task formed by the
+ // association of a completer and consumer.
+ bridge() {
+ ::fit::internal::bridge_state<V, E>::create(&completer.completion_ref_,
+ &consumer.consumption_ref_);
+ }
+ bridge(bridge&& other) = default;
+ bridge(const bridge& other) = delete;
+ ~bridge() = default;
+
+ bridge& operator=(bridge&& other) = default;
+ bridge& operator=(const bridge& other) = delete;
+
+ // The bridge's completer capability.
+ completer_type completer;
+
+ // The bridge's consumer capability.
+ consumer_type consumer;
+};
+
+// Provides a result upon completion of an asynchronous task.
+//
+// Instances of this class have single-ownership of a unique capability for
+// completing the task. This capability can be exercised at most once.
+// Ownership of the capability is implicitly transferred away when the
+// completer is abandoned, completed, or bound to a callback.
+//
+// See also |fit::bridge|.
+// See documentation of |fit::promise| for more information.
+//
+// SYNOPSIS
+//
+// |V| is the type of value produced when the task completes successfully.
+// Use |std::tuple<Args...>| if the task produces multiple values, such as
+// when you intend to bind the task's completer to a callback with multiple
+// arguments using |fit::completer::bind_tuple()|.
+// Defaults to |void|.
+//
+// |E| is the type of error produced when the task completes with an error.
+// Defaults to |void|.
+template <typename V, typename E>
+class completer final {
+ using bridge_state = ::fit::internal::bridge_state<V, E>;
+ using completion_ref = typename bridge_state::completion_ref;
+
+ public:
+ using value_type = V;
+ using error_type = E;
+ using result_type = ::fit::result<V, E>;
+
+ completer() = default;
+ completer(completer&& other) = default;
+ ~completer() = default;
+
+ completer& operator=(completer&& other) = default;
+
+ // Returns true if this instance currently owns the unique capability for
+ // reporting completion of the task.
+ explicit operator bool() const { return !!completion_ref_; }
+
+ // Returns true if the associated |consumer| has canceled the task.
+ // This method returns a snapshot of the current cancellation state.
+ // Note that the task may be canceled concurrently at any time.
+ bool was_canceled() const {
+ assert(completion_ref_);
+ return completion_ref_.get()->was_canceled();
+ }
+
+ // Explicitly abandons the task, meaning that it will never be completed.
+ // See |fit::bridge| for details about abandonment.
+ void abandon() {
+ assert(completion_ref_);
+ completion_ref_ = completion_ref();
+ }
+
+ // Reports that the task has completed successfully.
+ // This method takes no arguments if |value_type| is void, otherwise it
+ // takes one argument which must be assignable to |value_type|.
+ template <typename VV = value_type, typename = std::enable_if_t<std::is_void<VV>::value>>
+ void complete_ok() {
+ assert(completion_ref_);
+ bridge_state* state = completion_ref_.get();
+ state->complete_or_abandon(std::move(completion_ref_), ::fit::ok());
+ }
+ template <typename VV = value_type, typename = std::enable_if_t<!std::is_void<VV>::value>>
+ void complete_ok(VV value) {
+ assert(completion_ref_);
+ bridge_state* state = completion_ref_.get();
+ state->complete_or_abandon(std::move(completion_ref_),
+ ::fit::ok<value_type>(std::forward<VV>(value)));
+ }
+
+ // Reports that the task has completed with an error.
+ // This method takes no arguments if |error_type| is void, otherwise it
+ // takes one argument which must be assignable to |error_type|.
+ template <typename EE = error_type, typename = std::enable_if_t<std::is_void<EE>::value>>
+ void complete_error() {
+ assert(completion_ref_);
+ bridge_state* state = completion_ref_.get();
+ state->complete_or_abandon(std::move(completion_ref_), ::fit::error());
+ }
+ template <typename EE = error_type, typename = std::enable_if_t<!std::is_void<EE>::value>>
+ void complete_error(EE error) {
+ assert(completion_ref_);
+ bridge_state* state = completion_ref_.get();
+ state->complete_or_abandon(std::move(completion_ref_),
+ ::fit::error<error_type>(std::forward<EE>(error)));
+ }
+
+ // Reports that the task has completed or been abandoned.
+ // See |fit::bridge| for details about abandonment.
+ //
+ // The result state determines the task's final disposition.
+ // - |fit::result_state::ok|: The task completed successfully.
+ // - |fit::result_state::error|: The task completed with an error.
+ // - |fit::result_state::pending|: The task was abandoned.
+ void complete_or_abandon(result_type result) {
+ assert(completion_ref_);
+ bridge_state* state = completion_ref_.get();
+ state->complete_or_abandon(std::move(completion_ref_), std::move(result));
+ }
+
+ // Returns a callback that reports completion of the asynchronous task along
+ // with its result when invoked. This method is typically used to bind
+ // completion of a task to a callback that has zero or one argument.
+ //
+ // If |value_type| is void, the returned callback's signature is: void(void)
+ // Otherwise, the returned callback's signature is: void(value_type).
+ //
+ // The returned callback is thread-safe and move-only.
+ ::fit::internal::bridge_bind_callback<V, E> bind() {
+ assert(completion_ref_);
+ return ::fit::internal::bridge_bind_callback<V, E>(std::move(completion_ref_));
+ }
+
+ // A variant of |bind()| that can be used to bind a completion of a task
+ // to a callback that has zero or more arguments by wrapping the callback's
+ // arguments into a tuple when producing the task's result.
+ //
+ // The |value_type| must be a tuple type.
+ // Given a |value_type| of std::tuple<Args...>, the returned callback's
+ // signature is: void(Args...). Note that the tuple's fields are
+ // unpacked as individual arguments of the callback.
+ //
+ // The returned callback is thread-safe and move-only.
+ ::fit::internal::bridge_bind_tuple_callback<V, E> bind_tuple() {
+ assert(completion_ref_);
+ return ::fit::internal::bridge_bind_tuple_callback<V, E>(std::move(completion_ref_));
+ }
+
+ completer(const completer& other) = delete;
+ completer& operator=(const completer& other) = delete;
+
+ private:
+ friend class bridge<V, E>;
+
+ completion_ref completion_ref_;
+};
+
+// Consumes the result of an asynchronous task.
+//
+// Instances of this class have single-ownership of a unique capability for
+// consuming the task's result. This capability can be exercised at most once.
+// Ownership of the capability is implicitly transferred away when the
+// task is canceled or converted to a promise.
+//
+// See also |fit::bridge|.
+// See documentation of |fit::promise| for more information.
+//
+// SYNOPSIS
+//
+// |V| is the type of value produced when the task completes successfully.
+// Use |std::tuple<Args...>| if the task produces multiple values, such as
+// when you intend to bind the task's completer to a callback with multiple
+// arguments using |fit::completer::bind_tuple()|.
+// Defaults to |void|.
+//
+// |E| is the type of error produced when the task completes with an error.
+// Defaults to |void|.
+template <typename V, typename E>
+class consumer final {
+ using bridge_state = ::fit::internal::bridge_state<V, E>;
+ using consumption_ref = typename bridge_state::consumption_ref;
+
+ public:
+ using value_type = V;
+ using error_type = E;
+ using result_type = ::fit::result<V, E>;
+
+ consumer() = default;
+ consumer(consumer&& other) = default;
+ ~consumer() = default;
+
+ consumer& operator=(consumer&& other) = default;
+
+ // Returns true if this instance currently owns the unique capability for
+ // consuming the result of the task upon its completion.
+ explicit operator bool() const { return !!consumption_ref_; }
+
+ // Explicitly cancels the task, meaning that its result will never be consumed.
+ // See |fit::bridge| for details about cancellation.
+ void cancel() {
+ assert(consumption_ref_);
+ consumption_ref_ = consumption_ref();
+ }
+
+ // Returns true if the associated |completer| has abandoned the task.
+ // This method returns a snapshot of the current abandonment state.
+ // Note that the task may be abandoned concurrently at any time.
+ bool was_abandoned() const {
+ assert(consumption_ref_);
+ return consumption_ref_.get()->was_abandoned();
+ }
+
+ // Returns an unboxed promise which resumes execution once this task has
+ // completed. If the task is abandoned by its completer, the promise
+ // will not produce a result, thereby causing subsequent tasks associated
+ // with the promise to also be abandoned and eventually destroyed if
+ // they cannot make progress without the promised result.
+ promise_impl<typename bridge_state::promise_continuation> promise() {
+ assert(consumption_ref_);
+ return make_promise_with_continuation(
+ typename bridge_state::promise_continuation(std::move(consumption_ref_)));
+ }
+
+ // A variant of |promise()| that allows a default result to be provided when
+ // the task is abandoned by its completer. Typically this is used to cause
+ // the promise to return an error when the task is abandoned instead of
+ // causing subsequent tasks associated with the promise to also be abandoned.
+ //
+ // The state of |result_if_abandoned| determines the promise's behavior
+ // in case of abandonment.
+ //
+ // - |fit::result_state::ok|: Reports a successful result.
+ // - |fit::result_state::error|: Reports a failure result.
+ // - |fit::result_state::pending|: Does not report a result, thereby
+ // causing subsequent tasks associated with the promise to also be
+ // abandoned and eventually destroyed if they cannot make progress
+ // without the promised result.
+ promise_impl<typename bridge_state::promise_continuation> promise_or(
+ result_type result_if_abandoned) {
+ assert(consumption_ref_);
+ return make_promise_with_continuation(typename bridge_state::promise_continuation(
+ std::move(consumption_ref_), std::move(result_if_abandoned)));
+ }
+
+ consumer(const consumer& other) = delete;
+ consumer& operator=(const consumer& other) = delete;
+
+ private:
+ friend class bridge<V, E>;
+
+ consumption_ref consumption_ref_;
+};
+
+// Schedules |promise| to run on |executor| and returns a |consumer| which
+// receives the result of the promise upon its completion.
+//
+// This method has the effect of decoupling the evaluation of a promise from
+// the consumption of its result such that they can be performed on different
+// executors (possibly on different threads).
+//
+// |executor| must be non-null.
+// |promise| must be non-empty.
+//
+// EXAMPLE
+//
+// This example shows an object that encapsulates its own executor which it
+// manages independently from that of its clients. This enables the object
+// to obtain certain assurances such as a guarantee of single-threaded
+// execution for its internal operations even if its clients happen to be
+// multi-threaded (or vice-versa as desired).
+//
+// // This model has specialized internal threading requirements so it
+// // manages its own executor.
+// class model {
+// public:
+// fit::consumer<int> perform_calculation(int parameter) {
+// return fit::schedule_for_consumer(&executor_,
+// fit::make_promise([parameter] {
+// // In reality, this would likely be a much more
+// // complex expression.
+// return fit::ok(parameter * parameter);
+// });
+// }
+//
+// private:
+// // The model is responsible for initializing and running its own
+// // executor (perhaps on its own thread).
+// fit::single_threaded_executor executor_;
+// };
+//
+// // Asks the model to perform a calculation, awaits a result on the
+// // provided executor (which is different from the one internally used
+// // by the model), then prints the result.
+// void print_output(fit::executor* executor, model* m) {
+// executor->schedule_task(
+// m->perform_calculation(16)
+// .promise_or(fit::error())
+// .and_then([] (const int& result) { printf("done: %d\n", result); })
+// .or_else([] { puts("failed or abandoned"); }));
+// }
+//
+template <typename Promise>
+inline consumer<typename Promise::value_type, typename Promise::error_type> schedule_for_consumer(
+ fit::executor* executor, Promise promise) {
+ assert(executor);
+ assert(promise);
+ fit::bridge<typename Promise::value_type, typename Promise::error_type> bridge;
+ executor->schedule_task(promise.then(
+ [completer = std::move(bridge.completer)](typename Promise::result_type& result) mutable {
+ completer.complete_or_abandon(std::move(result));
+ }));
+ return std::move(bridge.consumer);
+}
+
+} // namespace fit
+
+#endif // LIB_FIT_BRIDGE_H_
diff --git a/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/bridge_internal.h b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/bridge_internal.h
new file mode 100644
index 0000000..4d19510
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/bridge_internal.h
@@ -0,0 +1,397 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIT_BRIDGE_INTERNAL_H_
+#define LIB_FIT_BRIDGE_INTERNAL_H_
+
+#include <atomic>
+#include <mutex>
+#include <tuple>
+#include <type_traits>
+#include <utility>
+
+#include "promise.h"
+#include "result.h"
+#include "thread_safety.h"
+
+namespace fit {
+namespace internal {
+
+// State shared between one completer and one consumer.
+// This object is somewhat unusual in that it has dual-ownership represented
+// by a pair of single-ownership references: a |completion_ref| and a
+// |consumption_ref|.
+//
+// The bridge's state evolves as follows:
+// - Initially the bridge's disposition is "pending".
+// - When the completer produces a result, the bridge's disposition
+// becomes "completed".
+// - When the completer drops its ref without producing a result,
+// the bridge's disposition becomes "abandoned".
+// - When the consumer drops its ref without consuming the result,
+// the bridge's disposition becomes "canceled".
+// - When a full rendezvous between completer and consumer takes place,
+// the bridge's disposition becomes "returned".
+// - When both refs are dropped, the bridge state is destroyed.
+template <typename V, typename E>
+class bridge_state final {
+ public:
+ class completion_ref;
+ class consumption_ref;
+ class promise_continuation;
+
+ using result_type = result<V, E>;
+
+ ~bridge_state() = default;
+
+ static void create(completion_ref* out_completion_ref, consumption_ref* out_consumption_ref);
+
+ bool was_canceled() const;
+ bool was_abandoned() const;
+ void complete_or_abandon(completion_ref ref, result_type result);
+
+ bridge_state(const bridge_state&) = delete;
+ bridge_state(bridge_state&&) = delete;
+ bridge_state& operator=(const bridge_state&) = delete;
+ bridge_state& operator=(bridge_state&&) = delete;
+
+ private:
+ enum class disposition { pending, abandoned, completed, canceled, returned };
+
+ bridge_state() = default;
+
+ void drop_completion_ref(bool was_completed);
+ void drop_consumption_ref(bool was_consumed);
+ void drop_ref_and_maybe_delete_self();
+ void set_result_if_abandoned(result_type result_if_abandoned);
+ result_type await_result(consumption_ref* ref, ::fit::context& context);
+
+ mutable std::mutex mutex_;
+
+ // Ref-count for completion and consumption.
+ // There can only be one of each ref type so the initial count is 2.
+ std::atomic<uint32_t> ref_count_{2};
+
+ // The disposition of the bridge.
+ // TODO(CF-246): It should be possible to implement a lock-free algorithm
+ // so as to eliminate the re-entrance hazards by introducing additional
+ // intermediate dispositions such that |task_| and |result| could be
+ // safely accessed while in those states.
+ disposition disposition_ FIT_GUARDED(mutex_) = {disposition::pending};
+
+ // The suspended task.
+ // Invariant: Only valid when disposition is |pending|.
+ suspended_task task_ FIT_GUARDED(mutex_);
+
+ // The result in flight.
+ // Invariant: Only valid when disposition is |pending|, |completed|,
+ // or |abandoned|.
+ result_type result_ FIT_GUARDED(mutex_);
+};
+
+// The unique capability held by a bridge's completer.
+template <typename V, typename E>
+class bridge_state<V, E>::completion_ref final {
+ public:
+ completion_ref() : state_(nullptr) {}
+
+ explicit completion_ref(bridge_state* state) : state_(state) {} // adopts existing reference
+
+ completion_ref(completion_ref&& other) : state_(other.state_) { other.state_ = nullptr; }
+
+ ~completion_ref() {
+ if (state_)
+ state_->drop_completion_ref(false /*was_completed*/);
+ }
+
+ completion_ref& operator=(completion_ref&& other) {
+ if (&other == this)
+ return *this;
+ if (state_)
+ state_->drop_completion_ref(false /*was_completed*/);
+ state_ = other.state_;
+ other.state_ = nullptr;
+ return *this;
+ }
+
+ explicit operator bool() const { return !!state_; }
+
+ bridge_state* get() const { return state_; }
+
+ void drop_after_completion() {
+ state_->drop_completion_ref(true /*was_completed*/);
+ state_ = nullptr;
+ }
+
+ completion_ref(const completion_ref& other) = delete;
+ completion_ref& operator=(const completion_ref& other) = delete;
+
+ private:
+ bridge_state* state_;
+};
+
+// The unique capability held by a bridge's consumer.
+template <typename V, typename E>
+class bridge_state<V, E>::consumption_ref final {
+ public:
+ consumption_ref() : state_(nullptr) {}
+
+ explicit consumption_ref(bridge_state* state) : state_(state) {} // adopts existing reference
+
+ consumption_ref(consumption_ref&& other) : state_(other.state_) { other.state_ = nullptr; }
+
+ ~consumption_ref() {
+ if (state_)
+ state_->drop_consumption_ref(false /*was_consumed*/);
+ }
+
+ consumption_ref& operator=(consumption_ref&& other) {
+ if (&other == this)
+ return *this;
+ if (state_)
+ state_->drop_consumption_ref(false /*was_consumed*/);
+ state_ = other.state_;
+ other.state_ = nullptr;
+ return *this;
+ }
+
+ explicit operator bool() const { return !!state_; }
+
+ bridge_state* get() const { return state_; }
+
+ void drop_after_consumption() {
+ state_->drop_consumption_ref(true /*was_consumed*/);
+ state_ = nullptr;
+ }
+
+ consumption_ref(const consumption_ref& other) = delete;
+ consumption_ref& operator=(const consumption_ref& other) = delete;
+
+ private:
+ bridge_state* state_;
+};
+
+// The continuation produced by |consumer::promise()| and company.
+template <typename V, typename E>
+class bridge_state<V, E>::promise_continuation final {
+ public:
+ explicit promise_continuation(consumption_ref ref) : ref_(std::move(ref)) {}
+
+ promise_continuation(consumption_ref ref, result_type result_if_abandoned)
+ : ref_(std::move(ref)) {
+ ref_.get()->set_result_if_abandoned(std::move(result_if_abandoned));
+ }
+
+ result_type operator()(::fit::context& context) {
+ return ref_.get()->await_result(&ref_, context);
+ }
+
+ private:
+ consumption_ref ref_;
+};
+
+// The callback produced by |completer::bind()|.
+template <typename V, typename E>
+class bridge_bind_callback final {
+ using callback_bridge_state = bridge_state<V, E>;
+
+ public:
+ explicit bridge_bind_callback(typename callback_bridge_state::completion_ref ref)
+ : ref_(std::move(ref)) {}
+
+ template <typename VV = V, typename = std::enable_if_t<std::is_void<VV>::value>>
+ void operator()() {
+ callback_bridge_state* state = ref_.get();
+ state->complete_or_abandon(std::move(ref_), ::fit::ok());
+ }
+
+ template <typename VV = V, typename = std::enable_if_t<!std::is_void<VV>::value>>
+ void operator()(VV value) {
+ callback_bridge_state* state = ref_.get();
+ state->complete_or_abandon(std::move(ref_), ::fit::ok<V>(std::forward<VV>(value)));
+ }
+
+ private:
+ typename callback_bridge_state::completion_ref ref_;
+};
+
+// The callback produced by |completer::bind_tuple()|.
+template <typename V, typename E>
+class bridge_bind_tuple_callback;
+template <typename... Args, typename E>
+class bridge_bind_tuple_callback<std::tuple<Args...>, E> final {
+ using tuple_callback_bridge_state = bridge_state<std::tuple<Args...>, E>;
+
+ public:
+ explicit bridge_bind_tuple_callback(typename tuple_callback_bridge_state::completion_ref ref)
+ : ref_(std::move(ref)) {}
+
+ void operator()(Args... args) {
+ tuple_callback_bridge_state* state = ref_.get();
+ state->complete_or_abandon(std::move(ref_),
+ ::fit::ok(std::make_tuple<Args...>(std::forward<Args>(args)...)));
+ }
+
+ private:
+ typename tuple_callback_bridge_state::completion_ref ref_;
+};
+
+template <typename V, typename E>
+void bridge_state<V, E>::create(completion_ref* out_completion_ref,
+ consumption_ref* out_consumption_ref) {
+ bridge_state* state = new bridge_state();
+ *out_completion_ref = completion_ref(state);
+ *out_consumption_ref = consumption_ref(state);
+}
+
+template <typename V, typename E>
+bool bridge_state<V, E>::was_canceled() const {
+ std::lock_guard<std::mutex> lock(mutex_);
+ return disposition_ == disposition::canceled;
+}
+
+template <typename V, typename E>
+bool bridge_state<V, E>::was_abandoned() const {
+ std::lock_guard<std::mutex> lock(mutex_);
+ return disposition_ == disposition::abandoned;
+}
+
+template <typename V, typename E>
+void bridge_state<V, E>::drop_completion_ref(bool was_completed) {
+ suspended_task task_to_notify;
+ bool should_resume_task = false;
+ if (!was_completed) {
+ // The task was abandoned.
+ std::lock_guard<std::mutex> lock(mutex_);
+ assert(disposition_ == disposition::pending || disposition_ == disposition::canceled);
+ if (disposition_ == disposition::pending) {
+ disposition_ = disposition::abandoned;
+ task_to_notify.swap(task_);
+ should_resume_task = !result_.is_pending();
+ }
+ }
+
+ // Drop or resume |task_to_notify| and drop the ref outside of the lock.
+ // This guards against re-entrance in case the consumption ref is
+ // dropped as a side-effect of these operations.
+ if (task_to_notify && should_resume_task) {
+ task_to_notify.resume_task();
+ }
+ drop_ref_and_maybe_delete_self();
+}
+
+template <typename V, typename E>
+void bridge_state<V, E>::drop_consumption_ref(bool was_consumed) {
+ suspended_task task_to_drop;
+ result_type result_to_drop;
+ if (!was_consumed) {
+ // The task was canceled.
+ std::lock_guard<std::mutex> lock(mutex_);
+ assert(disposition_ == disposition::pending || disposition_ == disposition::completed ||
+ disposition_ == disposition::abandoned);
+ if (disposition_ == disposition::pending) {
+ disposition_ = disposition::canceled;
+ task_to_drop.swap(task_);
+ result_to_drop.swap(result_);
+ }
+ }
+
+ // Drop |task_to_drop|, drop |result_to_drop|, and drop the ref
+ // outside of the lock.
+ // This guards against re-entrance in case the completion ref is
+ // dropped as a side-effect of these operations.
+ drop_ref_and_maybe_delete_self();
+}
+
+template <typename V, typename E>
+void bridge_state<V, E>::drop_ref_and_maybe_delete_self() {
+ uint32_t count = ref_count_.fetch_sub(1u, std::memory_order_release) - 1u;
+ assert(count >= 0);
+ if (count == 0) {
+ std::atomic_thread_fence(std::memory_order_acquire);
+ delete this;
+ }
+}
+
+template <typename V, typename E>
+void bridge_state<V, E>::complete_or_abandon(completion_ref ref, result_type result) {
+ assert(ref.get() == this);
+ if (result.is_pending())
+ return; // let the ref go out of scope to abandon the task
+
+ suspended_task task_to_notify;
+ bool should_resume_task = false;
+ {
+ std::lock_guard<std::mutex> lock(mutex_);
+ assert(disposition_ == disposition::pending || disposition_ == disposition::canceled);
+ if (disposition_ == disposition::pending) {
+ disposition_ = disposition::completed;
+ result.swap(result_);
+ task_to_notify.swap(task_);
+ should_resume_task = !result_.is_pending();
+ }
+ }
+
+ // Drop or resume |task_to_notify|, drop any prior result that
+ // was swapped into |result|, and drop the ref outside of the lock.
+ // This guards against re-entrance in case the consumption ref is
+ // dropped as a side-effect of these operations.
+ if (task_to_notify && should_resume_task) {
+ task_to_notify.resume_task();
+ }
+ ref.drop_after_completion();
+}
+
+template <typename V, typename E>
+void bridge_state<V, E>::set_result_if_abandoned(result_type result_if_abandoned) {
+ if (result_if_abandoned.is_pending())
+ return; // nothing to do
+
+ std::lock_guard<std::mutex> lock(mutex_);
+ assert(disposition_ == disposition::pending || disposition_ == disposition::completed ||
+ disposition_ == disposition::abandoned);
+ if (disposition_ == disposition::pending || disposition_ == disposition::abandoned) {
+ result_if_abandoned.swap(result_);
+ }
+
+ // Drop any prior value that was swapped into |result_if_abandoned|
+ // outside of the lock.
+}
+
+template <typename V, typename E>
+typename bridge_state<V, E>::result_type bridge_state<V, E>::await_result(consumption_ref* ref,
+ ::fit::context& context) {
+ assert(ref->get() == this);
+ suspended_task task_to_drop;
+ result_type result;
+ {
+ std::lock_guard<std::mutex> lock(mutex_);
+ assert(disposition_ == disposition::pending || disposition_ == disposition::completed ||
+ disposition_ == disposition::abandoned);
+ if (disposition_ == disposition::pending) {
+ task_to_drop.swap(task_);
+ task_ = context.suspend_task(); // assuming this isn't re-entrant
+ return ::fit::pending();
+ }
+ disposition_ = disposition::returned;
+ result = std::move(result_);
+ }
+
+ // Drop |task_to_drop| and the ref outside of the lock.
+ ref->drop_after_consumption();
+ return result;
+}
+
+} // namespace internal
+
+template <typename V = void, typename E = void>
+class bridge;
+template <typename V = void, typename E = void>
+class completer;
+template <typename V = void, typename E = void>
+class consumer;
+
+} // namespace fit
+
+#endif // LIB_FIT_BRIDGE_INTERNAL_H_
diff --git a/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/constructors_internal.h b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/constructors_internal.h
new file mode 100644
index 0000000..e11fbce
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/constructors_internal.h
@@ -0,0 +1,101 @@
+// 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.
+
+#ifndef LIB_FIT_CONSTRUCTORS_INTERNAL_H_
+#define LIB_FIT_CONSTRUCTORS_INTERNAL_H_
+
+#include <type_traits>
+#include <utility>
+
+#include "utility_internal.h"
+
+namespace fit {
+namespace internal {
+
+// Mixin that implicitly deletes the subclass default constructor when type T
+// is not default constructible.
+template <typename T, bool = std::is_default_constructible<T>::value>
+struct modulate_default_constructor {};
+template <typename T>
+struct modulate_default_constructor<T, false> {
+ constexpr modulate_default_constructor() = delete;
+};
+
+// Mixin that implicitly deletes the subclass copy constructor when type T is
+// not copy constructible.
+template <size_t Index, typename T, bool = std::is_copy_constructible<T>::value>
+struct modulate_copy_constructor {};
+template <size_t Index, typename T>
+struct modulate_copy_constructor<Index, T, false> {
+ constexpr modulate_copy_constructor() = default;
+ constexpr modulate_copy_constructor(const modulate_copy_constructor&) = delete;
+ constexpr modulate_copy_constructor& operator=(const modulate_copy_constructor&) = default;
+ constexpr modulate_copy_constructor(modulate_copy_constructor&&) = default;
+ constexpr modulate_copy_constructor& operator=(modulate_copy_constructor&&) = default;
+};
+
+// Mixin that implicitly deletes the subclass copy assignment operator when type
+// T is not copy assignable.
+template <size_t Index, typename T, bool = std::is_copy_assignable<T>::value>
+struct modulate_copy_assignment {};
+template <size_t Index, typename T>
+struct modulate_copy_assignment<Index, T, false> {
+ constexpr modulate_copy_assignment() = default;
+ constexpr modulate_copy_assignment(const modulate_copy_assignment&) = default;
+ constexpr modulate_copy_assignment& operator=(const modulate_copy_assignment&) = delete;
+ constexpr modulate_copy_assignment(modulate_copy_assignment&&) = default;
+ constexpr modulate_copy_assignment& operator=(modulate_copy_assignment&&) = default;
+};
+
+// Mixin that implicitly deletes the subclass move constructor when type T is
+// not move constructible.
+template <size_t Index, typename T, bool = std::is_move_constructible<T>::value>
+struct modulate_move_constructor {};
+template <size_t Index, typename T>
+struct modulate_move_constructor<Index, T, false> {
+ constexpr modulate_move_constructor() = default;
+ constexpr modulate_move_constructor(const modulate_move_constructor&) = default;
+ constexpr modulate_move_constructor& operator=(const modulate_move_constructor&) = default;
+ constexpr modulate_move_constructor(modulate_move_constructor&&) = delete;
+ constexpr modulate_move_constructor& operator=(modulate_move_constructor&&) = default;
+};
+
+// Mixin that implicitly deletes the subclass move assignment operator when type
+// T is not move assignable.
+template <size_t Index, typename T, bool = std::is_move_assignable<T>::value>
+struct modulate_move_assignment {};
+template <size_t Index, typename T>
+struct modulate_move_assignment<Index, T, false> {
+ constexpr modulate_move_assignment() = default;
+ constexpr modulate_move_assignment(const modulate_move_assignment&) = default;
+ constexpr modulate_move_assignment& operator=(const modulate_move_assignment&) = default;
+ constexpr modulate_move_assignment(modulate_move_assignment&&) = default;
+ constexpr modulate_move_assignment& operator=(modulate_move_assignment&&) = delete;
+};
+
+// Utility that takes an index sequence and an equally sized parameter pack and
+// mixes in each of the above copy/move construction/assignment modulators for
+// each type in Ts. The indices are used to avoid duplicate direct base errors
+// by ensuring that each mixin type is unique, even when there are duplicate
+// types within the parameter pack Ts.
+template <typename IndexSequence, typename... Ts>
+struct modulate_copy_and_move_index;
+
+template <size_t... Is, typename... Ts>
+struct modulate_copy_and_move_index<std::index_sequence<Is...>, Ts...>
+ : modulate_copy_constructor<Is, Ts>...,
+ modulate_copy_assignment<Is, Ts>...,
+ modulate_move_constructor<Is, Ts>...,
+ modulate_move_assignment<Is, Ts>... {};
+
+// Mixin that modulates the subclass copy/move constructors and assignment
+// operators based on the copy/move characteristics of each type in Ts.
+template <typename... Ts>
+struct modulate_copy_and_move
+ : modulate_copy_and_move_index<std::index_sequence_for<Ts...>, Ts...> {};
+
+} // namespace internal
+} // namespace fit
+
+#endif // LIB_FIT_CONSTRUCTORS_INTERNAL_H_
diff --git a/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/defer.h b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/defer.h
new file mode 100644
index 0000000..850a6f6
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/defer.h
@@ -0,0 +1,144 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIT_DEFER_H_
+#define LIB_FIT_DEFER_H_
+
+#include <utility>
+
+#include "function.h"
+#include "nullable.h"
+
+namespace fit {
+
+// A move-only deferred action wrapper with RAII semantics.
+// This class is not thread safe.
+//
+// The wrapper holds a function-like callable target with no arguments
+// which it invokes when it goes out of scope unless canceled, called, or
+// moved to a wrapper in a different scope.
+//
+// See |fit::defer()| for idiomatic usage.
+template <typename T>
+class deferred_action final {
+ public:
+ // Creates a deferred action without a pending target.
+ deferred_action() = default;
+ explicit deferred_action(decltype(nullptr)) {}
+
+ // Creates a deferred action with a pending target.
+ explicit deferred_action(T target) : target_(std::move(target)) {}
+
+ // Creates a deferred action with a pending target moved from another
+ // deferred action, leaving the other one without a pending target.
+ deferred_action(deferred_action&& other) : target_(std::move(other.target_)) {
+ other.target_.reset();
+ }
+
+ // Invokes and releases the deferred action's pending target (if any).
+ ~deferred_action() { call(); }
+
+ // Returns true if the deferred action has a pending target.
+ explicit operator bool() const { return !!target_; }
+
+ // Invokes and releases the deferred action's pending target (if any),
+ // then move-assigns it from another deferred action, leaving the latter
+ // one without a pending target.
+ deferred_action& operator=(deferred_action&& other) {
+ if (&other == this)
+ return *this;
+ call();
+ target_ = std::move(other.target_);
+ other.target_.reset();
+ return *this;
+ }
+
+ // Invokes and releases the deferred action's pending target (if any).
+ void call() {
+ if (target_) {
+ // Move to a local to guard against re-entrance.
+ T local_target = std::move(*target_);
+ target_.reset();
+ local_target();
+ }
+ }
+
+ // Releases the deferred action's pending target (if any) without
+ // invoking it.
+ void cancel() { target_.reset(); }
+ deferred_action& operator=(decltype(nullptr)) {
+ cancel();
+ return *this;
+ }
+
+ // Assigns a new target to the deferred action.
+ deferred_action& operator=(T target) {
+ target_ = std::move(target);
+ return *this;
+ }
+
+ deferred_action(const deferred_action& other) = delete;
+ deferred_action& operator=(const deferred_action& other) = delete;
+
+ private:
+ nullable<T> target_;
+};
+
+template <typename T>
+bool operator==(const deferred_action<T>& action, decltype(nullptr)) {
+ return !action;
+}
+template <typename T>
+bool operator==(decltype(nullptr), const deferred_action<T>& action) {
+ return !action;
+}
+template <typename T>
+bool operator!=(const deferred_action<T>& action, decltype(nullptr)) {
+ return !!action;
+}
+template <typename T>
+bool operator!=(decltype(nullptr), const deferred_action<T>& action) {
+ return !!action;
+}
+
+// Defers execution of a function-like callable target with no arguments
+// until the value returned by this function goes out of scope unless canceled,
+// called, or moved to a wrapper in a different scope.
+//
+// // This example prints "Hello..." then "Goodbye!".
+// void test() {
+// auto d = fit::defer([]{ puts("Goodbye!"); });
+// puts("Hello...");
+// }
+//
+// // This example prints nothing because the deferred action is canceled.
+// void do_nothing() {
+// auto d = fit::defer([]{ puts("I'm not here."); });
+// d.cancel();
+// }
+//
+// // This example shows how the deferred action can be reassigned assuming
+// // the new target has the same type and the old one, in this case by
+// // representing the target as a |fit::closure|.
+// void reassign() {
+// auto d = fit::defer<fit::closure>([] { puts("This runs first."); });
+// d = fit::defer<fit::closure>([] { puts("This runs afterwards."); });
+// }
+template <typename T>
+inline deferred_action<T> defer(T target) {
+ return deferred_action<T>(std::move(target));
+}
+
+// Alias for a deferred_action using a fit::callback.
+using deferred_callback = deferred_action<fit::callback<void()>>;
+
+// Defers execution of a fit::callback with no arguments. See |fit::defer| for
+// details.
+inline deferred_callback defer_callback(fit::callback<void()> target) {
+ return deferred_callback(std::move(target));
+}
+
+} // namespace fit
+
+#endif // LIB_FIT_DEFER_H_
diff --git a/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/function.h b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/function.h
new file mode 100644
index 0000000..21f6138
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/function.h
@@ -0,0 +1,464 @@
+// Copyright 2017 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.
+
+#ifndef LIB_FIT_FUNCTION_H_
+#define LIB_FIT_FUNCTION_H_
+
+#include "function_internal.h"
+
+namespace fit {
+
+template <size_t inline_target_size, bool require_inline, typename Result, typename... Args>
+class function_impl;
+
+template <size_t inline_target_size, bool require_inline, typename Result, typename... Args>
+class callback_impl;
+
+// The default size allowance for storing a target inline within a function
+// object, in bytes. This default allows for inline storage of targets
+// as big as two pointers, such as an object pointer and a pointer to a member
+// function.
+constexpr size_t default_inline_target_size = sizeof(void*) * 2;
+
+// A |fit::function| is a move-only polymorphic function wrapper.
+//
+// If you need a class with similar characteristics that also ensures
+// "run-once" semantics (such as callbacks shared with timeouts, or for
+// service requests with redundant, failover, or fallback service providers),
+// see |fit::callback|.
+//
+// |fit::function<T>| behaves like |std::function<T>| except that it is
+// move-only instead of copyable, so it can hold targets that cannot be copied,
+// such as mutable lambdas, and immutable lambdas that capture move-only
+// objects.
+//
+// Targets of up to |inline_target_size| bytes in size (rounded up for memory
+// alignment) are stored inline within the function object without incurring
+// any heap allocation. Larger callable objects will be moved to the heap as
+// required.
+//
+// See also |fit::inline_function<T, size>| for more control over allocation
+// behavior.
+//
+// SYNOPSIS
+//
+// |T| is the function's signature. e.g. void(int, std::string).
+//
+// |inline_target_size| is the minimum size of target that is guaranteed to
+// fit within a function without requiring heap allocation.
+// Defaults to |default_inline_target_size|.
+//
+// Class members are documented in |fit::function_impl|, below.
+//
+// EXAMPLES
+//
+// -
+// https://fuchsia.googlesource.com/fuchsia/+/master/zircon/system/ulib/fit/test/examples/function_example1.cc
+// -
+// https://fuchsia.googlesource.com/fuchsia/+/master/zircon/system/ulib/fit/test/examples/function_example2.cc
+//
+template <typename T, size_t inline_target_size = default_inline_target_size>
+using function = function_impl<inline_target_size,
+ /*require_inline=*/false, T>;
+
+// A move-only callable object wrapper that forces callables to be stored inline
+// and never performs heap allocation.
+//
+// Behaves just like |fit::function<T, inline_target_size>| except that
+// attempting to store a target larger than |inline_target_size| will fail to
+// compile.
+template <typename T, size_t inline_target_size = default_inline_target_size>
+using inline_function = function_impl<inline_target_size,
+ /*require_inline=*/true, T>;
+
+// Synonym for a function which takes no arguments and produces no result.
+using closure = function<void()>;
+
+// A |fit::callback| is a move-only polymorphic function wrapper that also
+// ensures "run-once" semantics (such as callbacks shared with timeouts, or for
+// service requests with redundant, failover, or fallback service providers).
+// A |fit::callback| releases it's resources after the first call, and can be
+// inspected before calling, so a potential caller can know if it should call
+// the function, or skip the call because the target was already called.
+//
+// If you need a move-only function class with typical function characteristics,
+// that permits multiple invocations of the same function, see |fit::function|.
+//
+// |fit::callback<T>| behaves like |std::function<T>| except:
+//
+// 1. It is move-only instead of copyable, so it can hold targets that cannot
+// be copied, such as mutable lambdas, and immutable lambdas that capture
+// move-only objects.
+// 2. On the first call to invoke a |fit::callback|, the target function held
+// by the |fit::callback| cannot be called again.
+//
+// When a |fit::callback| is invoked for the first time, the target function is
+// released and destructed, along with any resources owned by that function
+// (typically the objects captured by a lambda).
+//
+// A |fit::callback| in the "already called" state has the same state as a
+// |fit::callback| that has been assigned to |nullptr|. It can be compared to
+// |nullptr| (via "==" or "!=", and its "operator bool()" returns false, which
+// provides a convenient way to gate whether or not the |fit::callback| should
+// be called. (Note that invoking an empty |fit::callback| or |fit::function|
+// will cause a program abort!)
+//
+// As an example, sharing |fit::callback| between both a service and a timeout
+// might look something like this:
+//
+// void service_with_timeout(fit::callback<void(bool)> cb, uint timeout_ms) {
+// service_request([cb = cb.share()]() mutable { if (cb) cb(false); });
+// timeout(timeout_ms, [cb = std::move(cb)]() mutable { if (cb) cb(true); });
+// }
+//
+// Since |fit::callback| objects are move-only, and not copyable, duplicate
+// references to the same |fit::callback| can be obtained via share(), as shown
+// in the example above. This method converts the |fit::callback| into a
+// reference-counted version of the |fit::callback| and returns a copy of the
+// reference as another |fit::callback| with the same target function.
+//
+// What is notable about |fit::callback<T>.share()| is that invoking any shared
+// copy will "nullify" all shared copies, as shown in the example.
+//
+// Note that |fit::callback| is NOT thread-safe by default. If multi-threaded
+// support is required, you would need to implement your own mutex, or similar
+// guard, before checking and calling a |fit::callback|.
+//
+// Targets of up to |inline_target_size| bytes in size (rounded up for memory
+// alignment) are stored inline within the callback object without incurring
+// any heap allocation. Larger callable objects will be moved to the heap as
+// required.
+//
+// See also |fit::inline_callback<T, size>| for more control over allocation
+// behavior.
+//
+// SYNOPSIS
+//
+// |T| is the callback's signature. e.g. void(int, std::string).
+//
+// |inline_target_size| is the minimum size of target that is guaranteed to
+// fit within a callback without requiring heap allocation.
+// Defaults to |default_inline_target_size|.
+//
+// Class members are documented in |fit::callback_impl|, below.
+//
+template <typename T, size_t inline_target_size = default_inline_target_size>
+using callback = callback_impl<inline_target_size, /*require_inline=*/false, T>;
+
+// A move-only, run-once, callable object wrapper that forces callables to be
+// stored inline and never performs heap allocation.
+//
+// Behaves just like |fit::callback<T, inline_target_size>| except that
+// attempting to store a target larger than |inline_target_size| will fail to
+// compile.
+template <typename T, size_t inline_target_size = default_inline_target_size>
+using inline_callback = callback_impl<inline_target_size,
+ /*require_inline=*/true, T>;
+
+template <size_t inline_target_size, bool require_inline, typename Result, typename... Args>
+class function_impl<inline_target_size, require_inline, Result(Args...)> final
+ : private ::fit::internal::function_base<inline_target_size, require_inline, Result(Args...)> {
+ using base = ::fit::internal::function_base<inline_target_size, require_inline, Result(Args...)>;
+
+ // function_base requires private access during share()
+ friend class ::fit::internal::function_base<inline_target_size, require_inline, Result(Args...)>;
+
+ // supports target() for shared functions
+ friend const void* ::fit::internal::get_target_type_id<>(
+ const function_impl<inline_target_size, require_inline, Result(Args...)>&);
+
+ public:
+ // The function's result type.
+ using typename base::result_type;
+
+ // Initializes an empty (null) function. Attempting to call an empty
+ // function will abort the program.
+ function_impl() = default;
+
+ // Creates a function with an empty target (same outcome as the default
+ // constructor).
+ function_impl(decltype(nullptr)) : base(nullptr) {}
+
+ // Creates a function bound to the specified function pointer.
+ // If target == nullptr, assigns an empty target.
+ function_impl(Result (*target)(Args...)) : base(target) {}
+
+ // Creates a function bound to the specified callable object.
+ // If target == nullptr, assigns an empty target.
+ //
+ // For functors, we need to capture the raw type but also restrict on the
+ // existence of an appropriate operator () to resolve overloads and implicit
+ // casts properly.
+ //
+ // Note that specializations of this template method that take fit::callback
+ // objects as the target Callable are deleted (see below).
+ template <typename Callable,
+ typename = std::enable_if_t<std::is_convertible<
+ decltype(std::declval<Callable&>()(std::declval<Args>()...)), result_type>::value>>
+ function_impl(Callable target) : base(std::move(target)) {}
+
+ // Deletes the specializations of function_impl(Callable) that would allow
+ // a |fit::function| to be constructed from a |fit::callback|. This prevents
+ // unexpected behavior of a |fit::function| that would otherwise fail after
+ // one call. To explicitly allow this, simply wrap the |fit::callback| in a
+ // pass-through lambda before passing it to the |fit::function|.
+ template <size_t other_inline_target_size, bool other_require_inline>
+ function_impl(
+ ::fit::callback_impl<other_inline_target_size, other_require_inline, Result(Args...)>) =
+ delete;
+
+ // Creates a function with a target moved from another function,
+ // leaving the other function with an empty target.
+ function_impl(function_impl&& other) : base(static_cast<base&&>(other)) {}
+
+ // Destroys the function, releasing its target.
+ ~function_impl() = default;
+
+ // Assigns the function to an empty target. Attempting to invoke the
+ // function will abort the program.
+ function_impl& operator=(decltype(nullptr)) {
+ base::assign(nullptr);
+ return *this;
+ }
+
+ // Assigns the function to the specified callable object. If target ==
+ // nullptr, assigns an empty target.
+ //
+ // For functors, we need to capture the raw type but also restrict on the
+ // existence of an appropriate operator () to resolve overloads and implicit
+ // casts properly.
+ //
+ // Note that specializations of this template method that take fit::callback
+ // objects as the target Callable are deleted (see below).
+ template <typename Callable,
+ typename = std::enable_if_t<std::is_convertible<
+ decltype(std::declval<Callable&>()(std::declval<Args>()...)), result_type>::value>>
+ function_impl& operator=(Callable target) {
+ base::assign(std::move(target));
+ return *this;
+ }
+
+ // Deletes the specializations of operator=(Callable) that would allow
+ // a |fit::function| to be assigned from a |fit::callback|. This
+ // prevents unexpected behavior of a |fit::function| that would otherwise
+ // fail after one call. To explicitly allow this, simply wrap the
+ // |fit::callback| in a pass-through lambda before assigning it to the
+ // |fit::function|.
+ template <size_t other_inline_target_size, bool other_require_inline>
+ function_impl& operator=(
+ ::fit::callback_impl<other_inline_target_size, other_require_inline, Result(Args...)>) =
+ delete;
+
+ // Move assignment
+ function_impl& operator=(function_impl&& other) {
+ if (&other == this)
+ return *this;
+ base::assign(static_cast<base&&>(other));
+ return *this;
+ }
+
+ // Swaps the functions' targets.
+ void swap(function_impl& other) { base::swap(other); }
+
+ // Returns a pointer to the function's target.
+ using base::target;
+
+ // Returns true if the function has a non-empty target.
+ using base::operator bool;
+
+ // Invokes the function's target.
+ // Aborts if the function's target is empty.
+ Result operator()(Args... args) const { return base::invoke(std::forward<Args>(args)...); }
+
+ // Returns a new function object that invokes the same target.
+ // The target itself is not copied; it is moved to the heap and its
+ // lifetime is extended until all references have been released.
+ //
+ // Note: This method is not supported on |fit::inline_function<>|
+ // because it may incur a heap allocation which is contrary to
+ // the stated purpose of |fit::inline_function<>|.
+ function_impl share() {
+ function_impl copy;
+ base::template share_with<function_impl>(copy);
+ return copy;
+ }
+};
+
+template <size_t inline_target_size, bool require_inline, typename Result, typename... Args>
+void swap(function_impl<inline_target_size, require_inline, Result, Args...>& a,
+ function_impl<inline_target_size, require_inline, Result, Args...>& b) {
+ a.swap(b);
+}
+
+template <size_t inline_target_size, bool require_inline, typename Result, typename... Args>
+bool operator==(const function_impl<inline_target_size, require_inline, Result, Args...>& f,
+ decltype(nullptr)) {
+ return !f;
+}
+template <size_t inline_target_size, bool require_inline, typename Result, typename... Args>
+bool operator==(decltype(nullptr),
+ const function_impl<inline_target_size, require_inline, Result, Args...>& f) {
+ return !f;
+}
+template <size_t inline_target_size, bool require_inline, typename Result, typename... Args>
+bool operator!=(const function_impl<inline_target_size, require_inline, Result, Args...>& f,
+ decltype(nullptr)) {
+ return !!f;
+}
+template <size_t inline_target_size, bool require_inline, typename Result, typename... Args>
+bool operator!=(decltype(nullptr),
+ const function_impl<inline_target_size, require_inline, Result, Args...>& f) {
+ return !!f;
+}
+
+template <size_t inline_target_size, bool require_inline, typename Result, typename... Args>
+class callback_impl<inline_target_size, require_inline, Result(Args...)> final
+ : private ::fit::internal::function_base<inline_target_size, require_inline, Result(Args...)> {
+ using base = ::fit::internal::function_base<inline_target_size, require_inline, Result(Args...)>;
+
+ // function_base requires private access during share()
+ friend class ::fit::internal::function_base<inline_target_size, require_inline, Result(Args...)>;
+
+ // supports target() for shared functions
+ friend const void* ::fit::internal::get_target_type_id<>(
+ const callback_impl<inline_target_size, require_inline, Result(Args...)>&);
+
+ public:
+ // The callback function's result type.
+ using typename base::result_type;
+
+ // Initializes an empty (null) callback. Attempting to call an empty
+ // callback will abort the program.
+ callback_impl() = default;
+
+ // Creates a callback with an empty target (same outcome as the default
+ // constructor).
+ callback_impl(decltype(nullptr)) : base(nullptr) {}
+
+ // Creates a callback bound to the specified function pointer.
+ // If target == nullptr, assigns an empty target.
+ callback_impl(Result (*target)(Args...)) : base(target) {}
+
+ // Creates a callback bound to the specified callable object.
+ // If target == nullptr, assigns an empty target.
+ //
+ // For functors, we need to capture the raw type but also restrict on the
+ // existence of an appropriate operator () to resolve overloads and implicit
+ // casts properly.
+ template <typename Callable,
+ typename = std::enable_if_t<std::is_convertible<
+ decltype(std::declval<Callable&>()(std::declval<Args>()...)), result_type>::value>>
+ callback_impl(Callable target) : base(std::move(target)) {}
+
+ // Creates a callback with a target moved from another callback,
+ // leaving the other callback with an empty target.
+ callback_impl(callback_impl&& other) : base(static_cast<base&&>(other)) {}
+
+ // Destroys the callback, releasing its target.
+ ~callback_impl() = default;
+
+ // Assigns the callback to an empty target. Attempting to invoke the
+ // callback will abort the program.
+ callback_impl& operator=(decltype(nullptr)) {
+ base::assign(nullptr);
+ return *this;
+ }
+
+ // Assigns the callback to the specified callable object. If target ==
+ // nullptr, assigns an empty target.
+ //
+ // For functors, we need to capture the raw type but also restrict on the
+ // existence of an appropriate operator () to resolve overloads and implicit
+ // casts properly.
+ template <typename Callable,
+ typename = std::enable_if_t<std::is_convertible<
+ decltype(std::declval<Callable&>()(std::declval<Args>()...)), result_type>::value>>
+ callback_impl& operator=(Callable target) {
+ base::assign(std::move(target));
+ return *this;
+ }
+
+ // Move assignment
+ callback_impl& operator=(callback_impl&& other) {
+ if (&other == this)
+ return *this;
+ base::assign(static_cast<base&&>(other));
+ return *this;
+ }
+
+ // Swaps the callbacks' targets.
+ void swap(callback_impl& other) { base::swap(other); }
+
+ // Returns a pointer to the callback's target.
+ using base::target;
+
+ // Returns true if the callback has a non-empty target.
+ using base::operator bool;
+
+ // Invokes the callback's target.
+ // Aborts if the callback's target is empty.
+ // |fit::callback| must be non-const to invoke. Before the target function
+ // is actually called, the fit::callback will be set to the default empty
+ // state (== nullptr, and operator bool() will subsequently return |false|).
+ // The target function will then be released after the function is called.
+ // If the callback was shared, any remaining copies will also be cleared.
+ Result operator()(Args... args) {
+ auto temp = std::move(*this);
+ return temp.invoke(std::forward<Args>(args)...);
+ }
+
+ // Returns a new callback object that invokes the same target.
+ // The target itself is not copied; it is moved to the heap and its
+ // lifetime is extended until all references have been released.
+ // For |fit::callback| (unlike fit::function), the first invocation of the
+ // callback will release all references to the target. All callbacks
+ // derived from the same original callback (via share()) will be cleared,
+ // as if set to |nullptr|, and "operator bool()" will return false.
+ //
+ // Note: This method is not supported on |fit::inline_function<>|
+ // because it may incur a heap allocation which is contrary to
+ // the stated purpose of |fit::inline_function<>|.
+ callback_impl share() {
+ callback_impl copy;
+ base::template share_with<callback_impl>(copy);
+ return copy;
+ }
+};
+
+template <size_t inline_target_size, bool require_inline, typename Result, typename... Args>
+void swap(callback_impl<inline_target_size, require_inline, Result, Args...>& a,
+ callback_impl<inline_target_size, require_inline, Result, Args...>& b) {
+ a.swap(b);
+}
+
+template <size_t inline_target_size, bool require_inline, typename Result, typename... Args>
+bool operator==(const callback_impl<inline_target_size, require_inline, Result, Args...>& f,
+ decltype(nullptr)) {
+ return !f;
+}
+template <size_t inline_target_size, bool require_inline, typename Result, typename... Args>
+bool operator==(decltype(nullptr),
+ const callback_impl<inline_target_size, require_inline, Result, Args...>& f) {
+ return !f;
+}
+template <size_t inline_target_size, bool require_inline, typename Result, typename... Args>
+bool operator!=(const callback_impl<inline_target_size, require_inline, Result, Args...>& f,
+ decltype(nullptr)) {
+ return !!f;
+}
+template <size_t inline_target_size, bool require_inline, typename Result, typename... Args>
+bool operator!=(decltype(nullptr),
+ const callback_impl<inline_target_size, require_inline, Result, Args...>& f) {
+ return !!f;
+}
+
+// Returns a Callable object that invokes a member function of an object.
+template <typename R, typename T, typename... Args>
+auto bind_member(T* instance, R (T::*fn)(Args...)) {
+ return [instance, fn](Args... args) { return (instance->*fn)(std::forward<Args>(args)...); };
+}
+
+} // namespace fit
+
+#endif // LIB_FIT_FUNCTION_H_
diff --git a/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/function_internal.h b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/function_internal.h
new file mode 100644
index 0000000..a7c3670
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/function_internal.h
@@ -0,0 +1,399 @@
+// Copyright 2017 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.
+
+#ifndef LIB_FIT_FUNCTION_INTERNAL_H_
+#define LIB_FIT_FUNCTION_INTERNAL_H_
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#include <memory>
+
+#include "nullable.h"
+
+#include <new>
+#include <type_traits>
+#include <utility>
+
+namespace fit {
+namespace internal {
+
+template <typename Result, typename... Args>
+struct target_ops final {
+ const void* (*target_type_id)(void* bits, const void* impl_ops);
+ void* (*get)(void* bits);
+ Result (*invoke)(void* bits, Args... args);
+ void (*move)(void* from_bits, void* to_bits);
+ void (*destroy)(void* bits);
+};
+
+template <typename Callable, bool is_inline, bool is_shared, typename Result, typename... Args>
+struct target;
+
+inline const void* unshared_target_type_id(void* bits, const void* impl_ops) { return impl_ops; }
+
+// vtable for nullptr (empty target function)
+
+template <typename Result, typename... Args>
+struct target<decltype(nullptr),
+ /*is_inline=*/true, /*is_shared=*/false, Result, Args...>
+ final {
+ static Result invoke(void* bits, Args... args) { __builtin_abort(); }
+
+ static const target_ops<Result, Args...> ops;
+};
+
+inline void* null_target_get(void* bits) { return nullptr; }
+inline void null_target_move(void* from_bits, void* to_bits) {}
+inline void null_target_destroy(void* bits) {}
+
+template <typename Result, typename... Args>
+constexpr target_ops<Result, Args...> target<decltype(nullptr),
+ /*is_inline=*/true,
+ /*is_shared=*/false, Result, Args...>::ops = {
+ &unshared_target_type_id, &null_target_get, &target::invoke, &null_target_move,
+ &null_target_destroy};
+
+// vtable for inline target function
+
+template <typename Callable, typename Result, typename... Args>
+struct target<Callable,
+ /*is_inline=*/true, /*is_shared=*/false, Result, Args...>
+ final {
+ static void initialize(void* bits, Callable&& target) { new (bits) Callable(std::move(target)); }
+ static Result invoke(void* bits, Args... args) {
+ auto& target = *static_cast<Callable*>(bits);
+ return target(std::forward<Args>(args)...);
+ }
+ static void move(void* from_bits, void* to_bits) {
+ auto& from_target = *static_cast<Callable*>(from_bits);
+ new (to_bits) Callable(std::move(from_target));
+ from_target.~Callable();
+ }
+ static void destroy(void* bits) {
+ auto& target = *static_cast<Callable*>(bits);
+ target.~Callable();
+ }
+
+ static const target_ops<Result, Args...> ops;
+};
+
+inline void* inline_target_get(void* bits) { return bits; }
+
+template <typename Callable, typename Result, typename... Args>
+constexpr target_ops<Result, Args...> target<Callable,
+ /*is_inline=*/true,
+ /*is_shared=*/false, Result, Args...>::ops = {
+ &unshared_target_type_id, &inline_target_get, &target::invoke, &target::move, &target::destroy};
+
+// vtable for pointer to target function
+
+template <typename Callable, typename Result, typename... Args>
+struct target<Callable,
+ /*is_inline=*/false, /*is_shared=*/false, Result, Args...>
+ final {
+ static void initialize(void* bits, Callable&& target) {
+ auto ptr = static_cast<Callable**>(bits);
+ *ptr = new Callable(std::move(target));
+ }
+ static Result invoke(void* bits, Args... args) {
+ auto& target = **static_cast<Callable**>(bits);
+ return target(std::forward<Args>(args)...);
+ }
+ static void move(void* from_bits, void* to_bits) {
+ auto from_ptr = static_cast<Callable**>(from_bits);
+ auto to_ptr = static_cast<Callable**>(to_bits);
+ *to_ptr = *from_ptr;
+ }
+ static void destroy(void* bits) {
+ auto ptr = static_cast<Callable**>(bits);
+ delete *ptr;
+ }
+
+ static const target_ops<Result, Args...> ops;
+};
+
+inline void* heap_target_get(void* bits) { return *static_cast<void**>(bits); }
+
+template <typename Callable, typename Result, typename... Args>
+constexpr target_ops<Result, Args...> target<Callable,
+ /*is_inline=*/false,
+ /*is_shared=*/false, Result, Args...>::ops = {
+ &unshared_target_type_id, &heap_target_get, &target::invoke, &target::move, &target::destroy};
+
+// vtable for fit::function std::shared_ptr to target function
+
+template <typename SharedFunction>
+const void* get_target_type_id(const SharedFunction& function_or_callback) {
+ return function_or_callback.target_type_id();
+}
+
+// For this vtable,
+// Callable by definition will be either a fit::function or fit::callback
+template <typename SharedFunction, typename Result, typename... Args>
+struct target<SharedFunction,
+ /*is_inline=*/false, /*is_shared=*/true, Result, Args...>
+ final {
+ static void initialize(void* bits, SharedFunction target) {
+ new (bits) std::shared_ptr<SharedFunction>(
+ std::move(std::make_shared<SharedFunction>(std::move(target))));
+ }
+ static void copy_shared_ptr(void* from_bits, void* to_bits) {
+ auto& from_shared_ptr = *static_cast<std::shared_ptr<SharedFunction>*>(from_bits);
+ new (to_bits) std::shared_ptr<SharedFunction>(from_shared_ptr);
+ }
+ static const void* target_type_id(void* bits, const void* impl_ops) {
+ auto& function_or_callback = **static_cast<std::shared_ptr<SharedFunction>*>(bits);
+ return ::fit::internal::get_target_type_id(function_or_callback);
+ }
+ static void* get(void* bits) {
+ auto& function_or_callback = **static_cast<std::shared_ptr<SharedFunction>*>(bits);
+ return function_or_callback.template target<SharedFunction>(
+ /*check=*/false); // void* will fail the check
+ }
+ static Result invoke(void* bits, Args... args) {
+ auto& function_or_callback = **static_cast<std::shared_ptr<SharedFunction>*>(bits);
+ return function_or_callback(std::forward<Args>(args)...);
+ }
+ static void move(void* from_bits, void* to_bits) {
+ auto from_shared_ptr = std::move(*static_cast<std::shared_ptr<SharedFunction>*>(from_bits));
+ new (to_bits) std::shared_ptr<SharedFunction>(std::move(from_shared_ptr));
+ }
+ static void destroy(void* bits) { static_cast<std::shared_ptr<SharedFunction>*>(bits)->reset(); }
+
+ static const target_ops<Result, Args...> ops;
+};
+
+template <typename SharedFunction, typename Result, typename... Args>
+constexpr target_ops<Result, Args...> target<SharedFunction,
+ /*is_inline=*/false,
+ /*is_shared=*/true, Result, Args...>::ops = {
+ &target::target_type_id, &target::get, &target::invoke, &target::move, &target::destroy};
+
+template <size_t inline_target_size, bool require_inline, typename Result, typename... Args>
+class function_base;
+
+// Function implementation details.
+// See |fit::function| and |fit::callback| documentation for more information.
+template <size_t inline_target_size, bool require_inline, typename Result, typename... Args>
+class function_base<inline_target_size, require_inline, Result(Args...)> {
+ using ops_type = const target_ops<Result, Args...>*;
+ using storage_type = typename std::aligned_storage<(
+ inline_target_size >= sizeof(void*) ? inline_target_size : sizeof(void*))>::
+ type; // avoid including <algorithm> for max
+ template <typename Callable>
+ using target_type = target<Callable, (sizeof(Callable) <= sizeof(storage_type)),
+ /*is_shared=*/false, Result, Args...>;
+ template <typename SharedFunction>
+ using shared_target_type = target<SharedFunction,
+ /*is_inline=*/false,
+ /*is_shared=*/true, Result, Args...>;
+ using null_target_type = target_type<decltype(nullptr)>;
+
+ protected:
+ using result_type = Result;
+
+ function_base() { initialize_null_target(); }
+
+ function_base(decltype(nullptr)) { initialize_null_target(); }
+
+ function_base(Result (*target)(Args...)) { initialize_target(target); }
+
+ template <typename Callable,
+ typename = std::enable_if_t<std::is_convertible<
+ decltype(std::declval<Callable&>()(std::declval<Args>()...)), result_type>::value>>
+ function_base(Callable target) {
+ initialize_target(std::move(target));
+ }
+
+ function_base(function_base&& other) { move_target_from(std::move(other)); }
+
+ ~function_base() { destroy_target(); }
+
+ // Returns true if the function has a non-empty target.
+ explicit operator bool() const { return ops_->get(&bits_) != nullptr; }
+
+ // Returns a pointer to the function's target.
+ // If |check| is true (the default), the function _may_ abort if the
+ // caller tries to assign the target to a varible of the wrong type. (This
+ // check is currently skipped for share()d objects.)
+ // Note the shared pointer vtable must set |check| to false to assign the
+ // target to |void*|.
+ template <typename Callable>
+ Callable* target(bool check = true) {
+ if (check)
+ check_target_type<Callable>();
+ return static_cast<Callable*>(ops_->get(&bits_));
+ }
+
+ // Returns a pointer to the function's target (const version).
+ // If |check| is true (the default), the function _may_ abort if the
+ // caller tries to assign the target to a varible of the wrong type. (This
+ // check is currently skipped for share()d objects.)
+ // Note the shared pointer vtable must set |check| to false to assign the
+ // target to |void*|.
+ template <typename Callable>
+ const Callable* target(bool check = true) const {
+ if (check)
+ check_target_type<Callable>();
+ return static_cast<Callable*>(ops_->get(&bits_));
+ }
+
+ // Used by the derived "impl" classes to implement share().
+ //
+ // The caller creates a new object of the same type as itself, and passes in
+ // the empty object. This function first checks if |this| is already shared,
+ // and if not, creates a new version of itself containing a
+ // |std::shared_ptr| to its original self, and updates |ops_| to the vtable
+ // for the shared version.
+ //
+ // Then it copies its |shared_ptr| to the |bits_| of the given |copy|,
+ // and assigns the same shared pointer vtable to the copy's |ops_|.
+ //
+ // The target itself is not copied; it is moved to the heap and its
+ // lifetime is extended until all references have been released.
+ //
+ // Note: This method is not supported on |fit::inline_function<>|
+ // because it may incur a heap allocation which is contrary to
+ // the stated purpose of |fit::inline_function<>|.
+ template <typename SharedFunction>
+ void share_with(SharedFunction& copy) {
+ static_assert(!require_inline, "Inline functions cannot be shared.");
+ if (ops_->get(&bits_) != nullptr) {
+ if (ops_ != &shared_target_type<SharedFunction>::ops) {
+ convert_to_shared_target<SharedFunction>();
+ }
+ copy_shared_target_to(copy);
+ }
+ }
+
+ // Used by derived "impl" classes to implement operator()().
+ // Invokes the function's target.
+ // Note that fit::callback will release the target immediately after
+ // invoke() (also affecting any share()d copies).
+ // Aborts if the function's target is empty.
+ Result invoke(Args... args) const { return ops_->invoke(&bits_, std::forward<Args>(args)...); }
+
+ // Used by derived "impl" classes to implement operator=().
+ // Assigns an empty target.
+ void assign(decltype(nullptr)) {
+ destroy_target();
+ initialize_null_target();
+ }
+
+ // Used by derived "impl" classes to implement operator=().
+ // Assigns the function's target.
+ // If target == nullptr, assigns an empty target.
+ template <typename Callable,
+ typename = std::enable_if_t<std::is_convertible<
+ decltype(std::declval<Callable&>()(std::declval<Args>()...)), result_type>::value>>
+ void assign(Callable target) {
+ destroy_target();
+ initialize_target(std::move(target));
+ }
+
+ // Used by derived "impl" classes to implement operator=().
+ // Assigns the function with a target moved from another function,
+ // leaving the other function with an empty target.
+ void assign(function_base&& other) {
+ destroy_target();
+ move_target_from(std::move(other));
+ }
+
+ void swap(function_base& other) {
+ if (&other == this)
+ return;
+ ops_type temp_ops = ops_;
+ storage_type temp_bits;
+ ops_->move(&bits_, &temp_bits);
+
+ ops_ = other.ops_;
+ other.ops_->move(&other.bits_, &bits_);
+
+ other.ops_ = temp_ops;
+ temp_ops->move(&temp_bits, &other.bits_);
+ }
+
+ // returns an opaque ID unique to the |Callable| type of the target.
+ // Used by check_target_type.
+ const void* target_type_id() const { return ops_->target_type_id(&bits_, ops_); }
+
+ // Deleted copy constructor and assign. |function_base| implementations are
+ // move-only.
+ function_base(const function_base& other) = delete;
+ function_base& operator=(const function_base& other) = delete;
+
+ // Move assignment must be provided by subclasses.
+ function_base& operator=(function_base&& other) = delete;
+
+ private:
+ // Implements the move operation, used by move construction and move
+ // assignment. Leaves other target initialized to null.
+ void move_target_from(function_base&& other) {
+ ops_ = other.ops_;
+ other.ops_->move(&other.bits_, &bits_);
+ other.initialize_null_target();
+ }
+
+ // fit::function and fit::callback are not directly copyable, but share()
+ // will create shared references to the original object. This method
+ // implements the copy operation for the |std::shared_ptr| wrapper.
+ template <typename SharedFunction>
+ void copy_shared_target_to(SharedFunction& copy) {
+ copy.destroy_target();
+ assert(ops_ == &shared_target_type<SharedFunction>::ops);
+ shared_target_type<SharedFunction>::copy_shared_ptr(&bits_, ©.bits_);
+ copy.ops_ = ops_;
+ }
+
+ // assumes target is uninitialized
+ void initialize_null_target() { ops_ = &null_target_type::ops; }
+
+ // assumes target is uninitialized
+ template <typename Callable>
+ void initialize_target(Callable target) {
+ static_assert(std::alignment_of<Callable>::value <= std::alignment_of<storage_type>::value,
+ "Alignment of Callable must be <= alignment of max_align_t.");
+ static_assert(!require_inline || sizeof(Callable) <= inline_target_size,
+ "Callable too large to store inline as requested.");
+ if (is_null(target)) {
+ initialize_null_target();
+ } else {
+ ops_ = &target_type<Callable>::ops;
+ target_type<Callable>::initialize(&bits_, std::move(target));
+ }
+ }
+
+ // assumes target is uninitialized
+ template <typename SharedFunction>
+ void convert_to_shared_target() {
+ shared_target_type<SharedFunction>::initialize(&bits_,
+ std::move(*static_cast<SharedFunction*>(this)));
+ ops_ = &shared_target_type<SharedFunction>::ops;
+ }
+
+ // leaves target uninitialized
+ void destroy_target() { ops_->destroy(&bits_); }
+
+ // Called by target() if |check| is true.
+ // Checks the template parameter, usually inferred from the context of
+ // the call to target(), and aborts the program if it can determine that
+ // the Callable type is not compatible with the function's Result and Args.
+ template <typename Callable>
+ void check_target_type() const {
+ if (target_type<Callable>::ops.target_type_id(nullptr, &target_type<Callable>::ops) !=
+ target_type_id()) {
+ __builtin_abort();
+ }
+ }
+
+ ops_type ops_;
+ mutable storage_type bits_;
+};
+
+} // namespace internal
+
+} // namespace fit
+
+#endif // LIB_FIT_FUNCTION_INTERNAL_H_
diff --git a/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/function_traits.h b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/function_traits.h
new file mode 100644
index 0000000..6b02288
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/function_traits.h
@@ -0,0 +1,18 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIT_FUNCTION_TRAITS_H_
+#define LIB_FIT_FUNCTION_TRAITS_H_
+
+#include "traits.h"
+
+namespace fit {
+
+// function_traits is deprecated, please use callable_traits
+template <typename T>
+using function_traits = callable_traits<T>;
+
+} // namespace fit
+
+#endif // LIB_FIT_FUNCTION_TRAITS_H_
diff --git a/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/in_place_internal.h b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/in_place_internal.h
new file mode 100644
index 0000000..529d5ba
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/in_place_internal.h
@@ -0,0 +1,81 @@
+// 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.
+
+#ifndef LIB_FIT_IN_PLACE_INTERNAL_H_
+#define LIB_FIT_IN_PLACE_INTERNAL_H_
+
+namespace fit {
+
+// Tag for requesting in-place initialization.
+struct in_place_t {
+ explicit constexpr in_place_t() = default;
+};
+
+// Tag for requesting in-place initialization by type.
+template <typename T>
+struct in_place_type_t {
+ explicit constexpr in_place_type_t() = default;
+};
+
+// Tag for requesting in-place initialization by index.
+template <size_t Index>
+struct in_place_index_t final {
+ explicit constexpr in_place_index_t() = default;
+};
+
+#ifdef __cpp_inline_variables
+
+// Inline variables are only available on C++ 17 and beyond.
+
+inline constexpr in_place_t in_place{};
+
+template <typename T>
+inline constexpr in_place_type_t<T> in_place_type{};
+
+template <size_t Index>
+inline constexpr in_place_index_t<Index> in_place_index{};
+
+#else
+
+// For C++ 14 we need to provide storage for the variable so we define
+// a reference instead.
+
+template <typename Dummy = void>
+struct in_place_holder {
+ static constexpr in_place_t instance{};
+};
+
+template <typename T>
+struct in_place_type_holder {
+ static constexpr in_place_type_t<T> instance{};
+};
+
+template <size_t Index>
+struct in_place_index_holder {
+ static constexpr in_place_index_t<Index> instance{};
+};
+
+template <typename Dummy>
+constexpr in_place_t in_place_holder<Dummy>::instance;
+
+template <typename T>
+constexpr in_place_type_t<T> in_place_type_holder<T>::instance;
+
+template <size_t Index>
+constexpr in_place_index_t<Index> in_place_index_holder<Index>::instance;
+
+static constexpr const in_place_t& in_place = in_place_holder<>::instance;
+
+template <typename T>
+static constexpr const in_place_type_t<T>& in_place_type = in_place_type_holder<T>::instance;
+
+template <size_t Index>
+static constexpr const in_place_index_t<Index>& in_place_index =
+ in_place_index_holder<Index>::instance;
+
+#endif // __cpp_inline_variables
+
+} // namespace fit
+
+#endif // LIB_FIT_IN_PLACE_INTERNAL_H_
diff --git a/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/nullable.h b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/nullable.h
new file mode 100644
index 0000000..ae18f26
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/nullable.h
@@ -0,0 +1,251 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIT_NULLABLE_H_
+#define LIB_FIT_NULLABLE_H_
+
+#include <assert.h>
+
+#include <type_traits>
+#include <utility>
+
+#include "optional.h"
+
+namespace fit {
+
+// Determines whether a type can be compared with nullptr.
+template <typename T, typename Comparable = bool>
+struct is_comparable_with_null : public std::false_type {};
+template <typename T>
+struct is_comparable_with_null<T, decltype(std::declval<const T&>() == nullptr)>
+ : public std::true_type {};
+
+// Suppress the warning when the compiler can see that a nullable value is
+// never equal to nullptr.
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Waddress"
+template <typename T, std::enable_if_t<is_comparable_with_null<T>::value, bool> = true>
+constexpr inline bool is_null(T&& value) {
+ return std::forward<T>(value) == nullptr;
+}
+#pragma GCC diagnostic pop
+
+template <typename T, std::enable_if_t<!is_comparable_with_null<T>::value, bool> = false>
+constexpr inline bool is_null(T&&) {
+ return false;
+}
+
+// Determines whether a type can be initialized, assigned, and compared
+// with nullptr.
+template <typename T>
+struct is_nullable
+ : public std::integral_constant<bool, std::is_constructible<T, decltype(nullptr)>::value &&
+ std::is_assignable<T&, decltype(nullptr)>::value &&
+ is_comparable_with_null<T>::value> {};
+template <>
+struct is_nullable<void> : public std::false_type {};
+
+// Holds a value or nullptr.
+//
+// This class is similar to |std::optional<T>| except that it uses less
+// storage when the value type can be initialized, assigned, and compared
+// with nullptr.
+//
+// For example:
+// - sizeof(fit::nullable<void*>) == sizeof(void*)
+// - sizeof(std::optional<void*>) == sizeof(struct { bool; void*; })
+// - sizeof(fit::nullable<int>) == sizeof(struct { bool; int; })
+// - sizeof(std::optional<int>) == sizeof(struct { bool; int; })
+//
+// TODO(CF-806): fit::nullable does not precisely mirror fit::optional now that
+// fit::optional is closer to standards compliant. This should be corrected to
+// avoid surprises when switching between the types.
+template <typename T, bool = (is_nullable<T>::value && std::is_constructible<T, T&&>::value &&
+ std::is_assignable<T&, T&&>::value)>
+class nullable final {
+ public:
+ using value_type = T;
+
+ ~nullable() = default;
+ constexpr nullable() = default;
+
+ explicit constexpr nullable(decltype(nullptr)) {}
+ explicit constexpr nullable(T value) : opt_(std::move(value)) {}
+
+ constexpr nullable(const nullable& other) = default;
+ constexpr nullable& operator=(const nullable& other) = default;
+
+ constexpr nullable(nullable&& other) = default;
+ constexpr nullable& operator=(nullable&& other) = default;
+
+ constexpr T& value() & { return opt_.value(); }
+ constexpr const T& value() const& { return opt_.value(); }
+ constexpr T&& value() && { return std::move(opt_.value()); }
+ constexpr const T&& value() const&& { return std::move(opt_.value()); }
+
+ template <typename U = T>
+ constexpr T value_or(U&& default_value) const {
+ return opt_.value_or(std::forward<U>(default_value));
+ }
+
+ constexpr T* operator->() { return &*opt_; }
+ constexpr const T* operator->() const { return &*opt_; }
+ constexpr T& operator*() { return *opt_; }
+ constexpr const T& operator*() const { return *opt_; }
+
+ constexpr bool has_value() const { return opt_.has_value(); }
+ explicit constexpr operator bool() const { return has_value(); }
+
+ constexpr nullable& operator=(decltype(nullptr)) {
+ reset();
+ return *this;
+ }
+
+ constexpr nullable& operator=(T value) {
+ opt_ = std::move(value);
+ return *this;
+ }
+
+ constexpr void reset() { opt_.reset(); }
+
+ constexpr void swap(nullable& other) { opt_.swap(other.opt_); }
+
+ private:
+ optional<T> opt_;
+};
+
+template <typename T>
+class nullable<T, true> final {
+ public:
+ using value_type = T;
+
+ constexpr nullable() : value_(nullptr) {}
+ explicit constexpr nullable(decltype(nullptr)) : value_(nullptr) {}
+ explicit constexpr nullable(T value) : value_(std::move(value)) {}
+ constexpr nullable(const nullable& other) = default;
+ constexpr nullable(nullable&& other) : value_(std::move(other.value_)) {}
+ ~nullable() = default;
+
+ constexpr T& value() & {
+ if (has_value()) {
+ return value_;
+ } else {
+ __builtin_abort();
+ }
+ }
+ constexpr const T& value() const& {
+ if (has_value()) {
+ return value_;
+ } else {
+ __builtin_abort();
+ }
+ }
+ constexpr T&& value() && {
+ if (has_value()) {
+ return std::move(value_);
+ } else {
+ __builtin_abort();
+ }
+ }
+ constexpr const T&& value() const&& {
+ if (has_value()) {
+ return std::move(value_);
+ } else {
+ __builtin_abort();
+ }
+ }
+
+ template <typename U = T>
+ constexpr T value_or(U&& default_value) const {
+ return has_value() ? value_ : static_cast<T>(std::forward<U>(default_value));
+ }
+
+ constexpr T* operator->() { return &value_; }
+ constexpr const T* operator->() const { return &value_; }
+ constexpr T& operator*() { return value_; }
+ constexpr const T& operator*() const { return value_; }
+
+ constexpr bool has_value() const { return !(value_ == nullptr); }
+ explicit constexpr operator bool() const { return has_value(); }
+
+ constexpr nullable& operator=(const nullable& other) = default;
+ constexpr nullable& operator=(nullable&& other) {
+ value_ = std::move(other.value_);
+ return *this;
+ }
+
+ constexpr nullable& operator=(decltype(nullptr)) {
+ reset();
+ return *this;
+ }
+
+ constexpr nullable& operator=(T value) {
+ value_ = std::move(value);
+ return *this;
+ }
+
+ constexpr void reset() { value_ = nullptr; }
+
+ constexpr void swap(nullable& other) {
+ using std::swap;
+ swap(value_, other.value_);
+ }
+
+ private:
+ T value_;
+};
+
+template <typename T>
+void swap(nullable<T>& a, nullable<T>& b) {
+ a.swap(b);
+}
+
+template <typename T>
+constexpr bool operator==(const nullable<T>& lhs, decltype(nullptr)) {
+ return !lhs.has_value();
+}
+template <typename T>
+constexpr bool operator!=(const nullable<T>& lhs, decltype(nullptr)) {
+ return lhs.has_value();
+}
+
+template <typename T>
+constexpr bool operator==(decltype(nullptr), const nullable<T>& rhs) {
+ return !rhs.has_value();
+}
+template <typename T>
+constexpr bool operator!=(decltype(nullptr), const nullable<T>& rhs) {
+ return rhs.has_value();
+}
+
+template <typename T, typename U>
+constexpr bool operator==(const nullable<T>& lhs, const nullable<U>& rhs) {
+ return (lhs.has_value() == rhs.has_value()) && (!lhs.has_value() || *lhs == *rhs);
+}
+template <typename T, typename U>
+constexpr bool operator!=(const nullable<T>& lhs, const nullable<U>& rhs) {
+ return (lhs.has_value() != rhs.has_value()) || (lhs.has_value() && *lhs != *rhs);
+}
+
+template <typename T, typename U>
+constexpr bool operator==(const nullable<T>& lhs, const U& rhs) {
+ return (lhs.has_value() != is_null(rhs)) && (!lhs.has_value() || *lhs == rhs);
+}
+template <typename T, typename U>
+constexpr bool operator!=(const nullable<T>& lhs, const U& rhs) {
+ return (lhs.has_value() == is_null(rhs)) || (lhs.has_value() && *lhs != rhs);
+}
+
+template <typename T, typename U>
+constexpr bool operator==(const T& lhs, const nullable<U>& rhs) {
+ return (is_null(lhs) != rhs.has_value()) && (!rhs.has_value() || lhs == *rhs);
+}
+template <typename T, typename U>
+constexpr bool operator!=(const T& lhs, const nullable<U>& rhs) {
+ return (is_null(lhs) == rhs.has_value()) || (rhs.has_value() && lhs != *rhs);
+}
+
+} // namespace fit
+
+#endif // LIB_FIT_NULLABLE_H_
diff --git a/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/optional.h b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/optional.h
new file mode 100644
index 0000000..8162db6
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/optional.h
@@ -0,0 +1,482 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIT_OPTIONAL_H_
+#define LIB_FIT_OPTIONAL_H_
+
+#if defined(__cplusplus) && __cplusplus >= 201703L && !defined(FORCE_FIT_OPTIONAL)
+
+// In C++17 fit::optional should simply be an alias for std::optional.
+
+#include <optional>
+
+namespace fit {
+
+using std::make_optional;
+using std::nullopt;
+using std::nullopt_t;
+using std::optional;
+
+} // namespace fit
+
+#else
+
+#include <exception>
+#include <new>
+#include <type_traits>
+#include <utility>
+
+#include "constructors_internal.h"
+#include "in_place_internal.h"
+#include "storage_internal.h"
+#include "traits.h"
+#include "utility_internal.h"
+
+namespace fit {
+
+// A sentinel value for indicating that it contains no value.
+struct nullopt_t {
+ explicit constexpr nullopt_t(int) {}
+};
+static constexpr nullopt_t nullopt{0};
+
+// Exception type to report bad accesses to optional.
+class bad_optional_access : public std::exception {
+ public:
+ bad_optional_access() noexcept {}
+
+ const char* what() const noexcept override { return reason_; }
+
+ private:
+ template <typename T>
+ friend class optional;
+
+ bad_optional_access(const char* reason) noexcept : reason_{reason} {}
+
+ // String describing the reason for the bad access. Must point to a string
+ // with static storage duration.
+ const char* reason_;
+};
+
+// A reasonably complete implementation of std::optional compatible with C++14.
+//
+// See also fit::nullable<T>, which may be more efficient in certain
+// circumstances when T can be initialized, assigned, and compared with nullptr.
+//
+template <typename T>
+class optional : private ::fit::internal::modulate_copy_and_move<T> {
+ private:
+ // Helper types and values for SFINAE and noexcept rules.
+ static constexpr bool nothrow_move_constructible = std::is_nothrow_move_constructible<T>::value;
+
+ static constexpr bool nothrow_swappable = std::is_nothrow_move_constructible<T>::value &&
+ ::fit::internal::is_nothrow_swappable<T>::value;
+
+ static constexpr auto trivial_init_v = ::fit::internal::trivial_init_v;
+ static constexpr auto maybe_init_v = ::fit::internal::maybe_init_v;
+ using type_tag = ::fit::internal::type_tag<T>;
+
+ template <typename U, typename V>
+ using converts_from_optional = disjunction<
+ std::is_constructible<U, const optional<V>&>, std::is_constructible<U, optional<V>&>,
+ std::is_constructible<U, const optional<V>&&>, std::is_constructible<U, optional<V>&&>,
+ std::is_convertible<const optional<V>&, U>, std::is_convertible<optional<V>&, U>,
+ std::is_convertible<const optional<V>&&, U>, std::is_convertible<optional<V>&&, U>>;
+
+ template <typename U, typename V>
+ using assigns_from_optional =
+ disjunction<std::is_assignable<U&, const optional<V>&>, std::is_assignable<U&, optional<V>&>,
+ std::is_assignable<U&, const optional<V>&&>,
+ std::is_assignable<U&, optional<V>&&>>;
+
+ template <typename U>
+ using not_self_type = ::fit::internal::not_same_type<optional, U>;
+
+ template <typename U>
+ using not_in_place = ::fit::internal::not_same_type<in_place_t, U>;
+
+ template <typename... Conditions>
+ using requires_conditions = ::fit::internal::requires_conditions<Conditions...>;
+
+ template <typename... Conditions>
+ using assignment_requires_conditions =
+ ::fit::internal::assignment_requires_conditions<optional&, Conditions...>;
+
+ template <typename... Args>
+ using emplace_constructible = std::enable_if_t<std::is_constructible<T, Args...>::value, T&>;
+
+ [[noreturn]] static constexpr void throw_bad_optional_access(const char* reason) {
+#if __cpp_exceptions
+ throw bad_optional_access(reason);
+#else
+ (void)reason;
+ __builtin_abort();
+#endif
+ }
+
+ public:
+ using value_type = T;
+
+ // Default constructors.
+
+ constexpr optional() = default;
+
+ constexpr optional(nullopt_t) noexcept {}
+
+ // Copy/move constructors and assignment operators.
+
+ constexpr optional(const optional&) = default;
+ constexpr optional& operator=(const optional&) = default;
+
+ constexpr optional(optional&&) = default;
+ constexpr optional& operator=(optional&&) = default;
+
+ // Converting constructors.
+
+ template <typename U = T,
+ requires_conditions<not_self_type<U>, not_in_place<U>, std::is_constructible<T, U&&>,
+ std::is_convertible<U&&, T>> = true>
+ constexpr optional(U&& value) : storage_(type_tag{}, std::forward<U>(value)) {}
+
+ template <typename U = T,
+ requires_conditions<not_self_type<U>, not_in_place<U>, std::is_constructible<T, U&&>,
+ negation<std::is_convertible<U&&, T>>> = false>
+ explicit constexpr optional(U&& value) : storage_{type_tag{}, std::forward<U>(value)} {}
+
+ template <typename U,
+ requires_conditions<negation<std::is_same<T, U>>, std::is_constructible<T, const U&>,
+ std::is_convertible<const U&, T>,
+ negation<converts_from_optional<T, U>>> = true>
+ constexpr optional(const optional<U>& other) : storage_{maybe_init_v, other.storage_} {}
+
+ template <typename U,
+ requires_conditions<negation<std::is_same<T, U>>, std::is_constructible<T, const U&>,
+ negation<std::is_convertible<const U&, T>>,
+ negation<converts_from_optional<T, U>>> = false>
+ explicit constexpr optional(const optional<U>& other) : storage_{maybe_init_v, other.storage_} {}
+
+ template <typename U,
+ requires_conditions<negation<std::is_same<T, U>>, std::is_constructible<T, U&&>,
+ std::is_convertible<U&&, T>,
+ negation<converts_from_optional<T, U>>> = true>
+ constexpr optional(optional<U>&& other) : storage_{maybe_init_v, std::move(other.storage_)} {}
+
+ template <typename U,
+ requires_conditions<negation<std::is_same<T, U>>, std::is_constructible<T, U&&>,
+ negation<std::is_convertible<U&&, T>>,
+ negation<converts_from_optional<T, U>>> = false>
+ explicit constexpr optional(optional<U>&& other)
+ : storage_{maybe_init_v, std::move(other.storage_)} {}
+
+ template <typename... Args, requires_conditions<std::is_constructible<T, Args&&...>> = false>
+ explicit constexpr optional(in_place_t, Args&&... args)
+ : storage_(type_tag{}, std::forward<Args>(args)...) {}
+
+ template <
+ typename U, typename... Args,
+ requires_conditions<std::is_constructible<T, std::initializer_list<U>&, Args&&...>> = false>
+ explicit constexpr optional(in_place_t, std::initializer_list<U> init_list, Args&&... args)
+ : storage_(type_tag{}, init_list, std::forward<Args>(args)...) {}
+
+ // Destructor.
+
+ ~optional() = default;
+
+ // Checked accessors.
+
+ constexpr T& value() & {
+ if (has_value()) {
+ return storage_.get(type_tag{});
+ } else {
+ throw_bad_optional_access("Accessed value of empty optional!");
+ }
+ }
+ constexpr const T& value() const& {
+ if (has_value()) {
+ return storage_.get(type_tag{});
+ } else {
+ throw_bad_optional_access("Accessed value of empty optional!");
+ }
+ }
+ constexpr T&& value() && {
+ if (has_value()) {
+ return std::move(storage_.get(type_tag{}));
+ } else {
+ throw_bad_optional_access("Accessed value of empty optional!");
+ }
+ }
+ constexpr const T&& value() const&& {
+ if (has_value()) {
+ return std::move(storage_.get(type_tag{}));
+ } else {
+ throw_bad_optional_access("Accessed value of empty optional!");
+ }
+ }
+
+ template <typename U>
+ constexpr T value_or(U&& default_value) const& {
+ static_assert(std::is_copy_constructible<T>::value,
+ "value_or() requires copy-constructible value_type!");
+ static_assert(std::is_convertible<U&&, T>::value,
+ "Default value must be convertible to value_type!");
+
+ return has_value() ? storage_.get(type_tag{}) : static_cast<T>(std::forward<U>(default_value));
+ }
+ template <typename U>
+ constexpr T value_or(U&& default_value) && {
+ static_assert(std::is_move_constructible<T>::value,
+ "value_or() requires move-constructible value_type!");
+ static_assert(std::is_convertible<U&&, T>::value,
+ "Default value must be convertible to value_type!");
+
+ return has_value() ? std::move(storage_.get(type_tag{}))
+ : static_cast<T>(std::forward<U>(default_value));
+ }
+
+ // Unchecked accessors.
+
+ constexpr T* operator->() { return std::addressof(storage_.get(type_tag{})); }
+ constexpr const T* operator->() const { return std::addressof(storage_.get(type_tag{})); }
+
+ constexpr T& operator*() { return storage_.get(type_tag{}); }
+ constexpr const T& operator*() const { return storage_.get(type_tag{}); }
+
+ // Availability accessors/operators.
+
+ constexpr bool has_value() const { return storage_.has_value(); }
+ constexpr explicit operator bool() const { return has_value(); }
+
+ // Assignment operators.
+
+ template <typename U>
+ constexpr assignment_requires_conditions<
+ not_self_type<U>, negation<conjunction<std::is_scalar<T>, std::is_same<T, std::decay_t<U>>>>,
+ std::is_constructible<T, U>, std::is_assignable<T&, U>>
+ operator=(U&& value) {
+ if (has_value()) {
+ storage_.get(type_tag{}) = std::forward<U>(value);
+ } else {
+ storage_.construct(type_tag{}, std::forward<U>(value));
+ }
+ return *this;
+ }
+
+ template <typename U>
+ constexpr assignment_requires_conditions<
+ negation<std::is_same<T, U>>, std::is_constructible<T, const U&>, std::is_assignable<T&, U>,
+ negation<converts_from_optional<T, U>>, negation<assigns_from_optional<T, U>>>
+ operator=(const optional<U>& other) {
+ storage_.assign(other.storage_);
+ return *this;
+ }
+
+ template <typename U>
+ constexpr assignment_requires_conditions<
+ negation<std::is_same<T, U>>, std::is_constructible<T, U>, std::is_assignable<T&, U>,
+ negation<converts_from_optional<T, U>>, negation<assigns_from_optional<T, U>>>
+ operator=(optional<U>&& other) {
+ storage_.assign(std::move(other.storage_));
+ return *this;
+ }
+
+ constexpr optional& operator=(nullopt_t) {
+ storage_.reset();
+ return *this;
+ }
+
+ // Swap.
+
+ constexpr void swap(optional& other) noexcept(nothrow_swappable) {
+ storage_.swap(other.storage_);
+ }
+
+ // Emplacement.
+
+ template <typename... Args>
+ constexpr emplace_constructible<Args&&...> emplace(Args&&... args) {
+ storage_.reset();
+ storage_.construct(type_tag{}, std::forward<Args>(args)...);
+ return storage_.get(type_tag{});
+ }
+
+ template <typename U, typename... Args>
+ constexpr emplace_constructible<std::initializer_list<U>&, Args&&...> emplace(
+ std::initializer_list<U> init_list, Args&&... args) {
+ storage_.reset();
+ storage_.construct(type_tag{}, init_list, std::forward<Args>(args)...);
+ return storage_.get(type_tag{});
+ }
+
+ // Reset.
+
+ void reset() noexcept { storage_.reset(); }
+
+ private:
+ ::fit::internal::storage_type<T> storage_;
+};
+
+// Swap.
+template <typename T>
+inline std::enable_if_t<(std::is_move_constructible<T>::value &&
+ ::fit::internal::is_swappable<T>::value)>
+swap(optional<T>& a, optional<T>& b) noexcept(noexcept(a.swap(b))) {
+ a.swap(b);
+}
+template <typename T>
+inline std::enable_if_t<(!std::is_move_constructible<T>::value &&
+ ::fit::internal::is_swappable<T>::value)>
+swap(optional<T>& a, optional<T>& b) = delete;
+
+// Make optional.
+template <typename T>
+constexpr optional<std::decay_t<T>> make_optional(T&& value) {
+ return optional<std::decay_t<T>>{std::forward<T>(value)};
+}
+template <typename T, typename... Args>
+constexpr optional<T> make_optional(Args&&... args) {
+ return optional<T>{in_place, std::forward<Args>(args)...};
+}
+template <typename T, typename U, typename... Args>
+constexpr optional<T> make_optional(std::initializer_list<U> init_list, Args&&... args) {
+ return optional<T>{in_place, init_list, std::forward<Args>(args)...};
+}
+
+// Empty.
+template <typename T>
+constexpr bool operator==(const optional<T>& lhs, nullopt_t) {
+ return !lhs.has_value();
+}
+template <typename T>
+constexpr bool operator!=(const optional<T>& lhs, nullopt_t) {
+ return lhs.has_value();
+}
+
+template <typename T>
+constexpr bool operator==(nullopt_t, const optional<T>& rhs) {
+ return !rhs.has_value();
+}
+template <typename T>
+constexpr bool operator!=(nullopt_t, const optional<T>& rhs) {
+ return rhs.has_value();
+}
+
+// Equal/not equal.
+template <typename T, typename U,
+ ::fit::internal::enable_relop_t<decltype(std::declval<T>() == std::declval<U>())> = true>
+constexpr bool operator==(const optional<T>& lhs, const optional<U>& rhs) {
+ return (lhs.has_value() == rhs.has_value()) && (!lhs.has_value() || *lhs == *rhs);
+}
+template <typename T, typename U,
+ ::fit::internal::enable_relop_t<decltype(std::declval<T>() != std::declval<U>())> = true>
+constexpr bool operator!=(const optional<T>& lhs, const optional<U>& rhs) {
+ return (lhs.has_value() != rhs.has_value()) || (lhs.has_value() && *lhs != *rhs);
+}
+
+template <typename T, typename U,
+ ::fit::internal::enable_relop_t<decltype(std::declval<T>() == std::declval<U>()),
+ ::fit::internal::not_same_type<nullopt_t, U>> = true>
+constexpr bool operator==(const optional<T>& lhs, const U& rhs) {
+ return lhs.has_value() && *lhs == rhs;
+}
+template <typename T, typename U,
+ ::fit::internal::enable_relop_t<decltype(std::declval<T>() != std::declval<U>()),
+ ::fit::internal::not_same_type<nullopt_t, U>> = true>
+constexpr bool operator!=(const optional<T>& lhs, const U& rhs) {
+ return !lhs.has_value() || *lhs != rhs;
+}
+
+template <typename T, typename U,
+ ::fit::internal::enable_relop_t<decltype(std::declval<T>() == std::declval<U>()),
+ ::fit::internal::not_same_type<nullopt_t, T>> = true>
+constexpr bool operator==(const T& lhs, const optional<U>& rhs) {
+ return rhs.has_value() && lhs == *rhs;
+}
+template <typename T, typename U,
+ ::fit::internal::enable_relop_t<decltype(std::declval<T>() != std::declval<U>()),
+ ::fit::internal::not_same_type<nullopt_t, T>> = true>
+constexpr bool operator!=(const T& lhs, const optional<U>& rhs) {
+ return !rhs.has_value() || lhs != *rhs;
+}
+
+// Less than/greater than.
+template <typename T, typename U,
+ ::fit::internal::enable_relop_t<decltype(std::declval<T>() < std::declval<U>())> = true>
+constexpr bool operator<(const optional<T>& lhs, const optional<U>& rhs) {
+ return rhs.has_value() && (!lhs.has_value() || *lhs < *rhs);
+}
+template <typename T, typename U,
+ ::fit::internal::enable_relop_t<decltype(std::declval<T>() > std::declval<U>())> = true>
+constexpr bool operator>(const optional<T>& lhs, const optional<U>& rhs) {
+ return lhs.has_value() && (!rhs.has_value() || *lhs > *rhs);
+}
+
+template <typename T, typename U,
+ ::fit::internal::enable_relop_t<decltype(std::declval<T>() < std::declval<U>()),
+ ::fit::internal::not_same_type<nullopt_t, U>> = true>
+constexpr bool operator<(const optional<T>& lhs, const U& rhs) {
+ return !lhs.has_value() || *lhs < rhs;
+}
+template <typename T, typename U,
+ ::fit::internal::enable_relop_t<decltype(std::declval<T>() > std::declval<U>()),
+ ::fit::internal::not_same_type<nullopt_t, U>> = true>
+constexpr bool operator>(const optional<T>& lhs, const U& rhs) {
+ return lhs.has_value() && *lhs > rhs;
+}
+
+template <typename T, typename U,
+ ::fit::internal::enable_relop_t<decltype(std::declval<T>() < std::declval<U>()),
+ ::fit::internal::not_same_type<nullopt_t, T>> = true>
+constexpr bool operator<(const T& lhs, const optional<U>& rhs) {
+ return rhs.has_value() && lhs < *rhs;
+}
+template <typename T, typename U,
+ ::fit::internal::enable_relop_t<decltype(std::declval<T>() > std::declval<U>()),
+ ::fit::internal::not_same_type<nullopt_t, T>> = true>
+constexpr bool operator>(const T& lhs, const optional<U>& rhs) {
+ return !rhs.has_value() || lhs > *rhs;
+}
+
+// Less than or equal/greater than or equal.
+template <typename T, typename U,
+ ::fit::internal::enable_relop_t<decltype(std::declval<T>() <= std::declval<U>())> = true>
+constexpr bool operator<=(const optional<T>& lhs, const optional<U>& rhs) {
+ return !lhs.has_value() || (rhs.has_value() && *lhs <= *rhs);
+}
+template <typename T, typename U,
+ ::fit::internal::enable_relop_t<decltype(std::declval<T>() >= std::declval<U>())> = true>
+constexpr bool operator>=(const optional<T>& lhs, const optional<U>& rhs) {
+ return !rhs.has_value() || (lhs.has_value() && *lhs >= *rhs);
+}
+
+template <typename T, typename U,
+ ::fit::internal::enable_relop_t<decltype(std::declval<T>() <= std::declval<U>()),
+ ::fit::internal::not_same_type<nullopt_t, U>> = true>
+constexpr bool operator<=(const optional<T>& lhs, const U& rhs) {
+ return !lhs.has_value() || *lhs <= rhs;
+}
+template <typename T, typename U,
+ ::fit::internal::enable_relop_t<decltype(std::declval<T>() >= std::declval<U>()),
+ ::fit::internal::not_same_type<nullopt_t, U>> = true>
+constexpr bool operator>=(const optional<T>& lhs, const U& rhs) {
+ return lhs.has_value() && *lhs >= rhs;
+}
+
+template <typename T, typename U,
+ ::fit::internal::enable_relop_t<decltype(std::declval<T>() <= std::declval<U>()),
+ ::fit::internal::not_same_type<nullopt_t, T>> = true>
+constexpr bool operator<=(const T& lhs, const optional<U>& rhs) {
+ return rhs.has_value() && lhs <= *rhs;
+}
+template <typename T, typename U,
+ ::fit::internal::enable_relop_t<decltype(std::declval<T>() >= std::declval<U>()),
+ ::fit::internal::not_same_type<nullopt_t, T>> = true>
+constexpr bool operator>=(const T& lhs, const optional<U>& rhs) {
+ return !rhs.has_value() || lhs >= *rhs;
+}
+
+} // namespace fit
+
+#endif
+
+#endif // LIB_FIT_OPTIONAL_H_
diff --git a/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/promise.h b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/promise.h
new file mode 100644
index 0000000..4e09905
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/promise.h
@@ -0,0 +1,1587 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIT_PROMISE_H_
+#define LIB_FIT_PROMISE_H_
+
+#include <assert.h>
+
+#include <tuple>
+#include <type_traits>
+#include <utility>
+
+#include "function.h"
+#include "promise_internal.h"
+#include "result.h"
+#include "variant.h"
+
+namespace fit {
+
+// A |fit::promise| is a building block for asynchronous control flow that
+// wraps an asynchronous task in the form of a "continuation" that is
+// repeatedly invoked by an executor until it produces a result.
+//
+// Additional asynchronous tasks can be chained onto the promise using
+// a variety of combinators such as |then()|.
+//
+// Use |fit::make_promise()| to create a promise.
+// Use |fit::make_ok_promise()| to create a promise that immediately returns a value.
+// Use |fit::make_error_promise()| to create a promise that immediately returns an error.
+// Use |fit::make_result_promise()| to create a promise that immediately returns a result.
+// Use |fit::future| to more conveniently hold a promise or its result.
+// Use |fit::pending_task| to wrap a promise as a pending task for execution.
+// Use |fit::executor| to execute a pending task.
+// See examples below.
+//
+// Always look to the future; never look back.
+//
+// SYNOPSIS
+//
+// |V| is the type of value produced when the completes successfully.
+// Defaults to |void|.
+//
+// |E| is the type of error produced when the completes with an error.
+// Defaults to |void|.
+//
+// Class members are documented in |fit::promise_impl|.
+//
+// CHAINING PROMISES USING COMBINATORS
+//
+// Promises can be chained together using combinators such as |then()|
+// which consume the original promise(s) and return a new combined promise.
+//
+// For example, the |then()| combinator returns a promise that has the effect
+// of asynchronously awaiting completion of the prior promise (the instance
+// upon which |then()| was called) then delivering its result to a handler
+// function.
+//
+// Available combinators defined in this library:
+//
+// |then()|: run a handler when prior promise completes
+// |and_then()|: run a handler when prior promise completes successfully
+// |or_else()|: run a handler when prior promise completes with an error
+// |inspect()|: examine result of prior promise
+// |discard_result()|: discard result and unconditionally return
+// fit::result<> when prior promise completes
+// |wrap_with()|: applies a wrapper to the promise
+// |box()|: wraps the promise's continuation into a |fit::function|
+// |fit::join_promises()|: await multiple promises in an argument list,
+// once they all complete return a tuple of
+// their results
+// |fit::join_promise_vector()|: await multiple promises in a vector,
+// once they all complete return a vector
+// of their results
+//
+// You can also create your own custom combinators by crafting new
+// types of continuations.
+//
+// CONTINUATIONS AND HANDLERS
+//
+// Internally, |fit::promise| wraps a continuation (a kind of callable
+// object) that holds the state of the asynchronous task and provides a
+// means for making progress through repeated invocation.
+//
+// A promise's continuation is generated through the use of factories
+// such as |make_promise()| and combinators such as |then()|. Most of
+// these functions accept a client-supplied "handler" (another kind
+// of callable object, often a lambda expression) which performs the actual
+// computations.
+//
+// Continuations have a very regular interface: they always accept a
+// |fit::context&| argument and return a |fit::result|. Conversely, handlers
+// have a very flexible interface: clients can provide them in many forms
+// all of which are documented by the individual functions which consume them.
+// It's pretty easy to use: the library takes care of wrapping client-supplied
+// handlers of all supported forms into the continuations it uses internally.
+//
+// THEORY OF OPERATION
+//
+// On its own, a promise is "inert"; it only makes progress in response to
+// actions taken by its owner. The state of the promise never changes
+// spontaneously or concurrently.
+//
+// Typically, a promise is executed by wrapping it into a |fit::pending_task|
+// and scheduling it for execution using |fit::executor::schedule_task()|.
+// A promise's |operator(fit::context&)| can also be invoked directly by its owner
+// from within the scope of another task (this is used to implement combinators
+// and futures) though the principle is the same.
+//
+// |fit::executor| is an abstract class that encapsulates a strategy for
+// executing tasks. The executor is responsible for invoking each tasks's
+// continuation until the task returns a non-pending result, indicating that
+// the task has been completed.
+//
+// The method of execution and scheduling of each continuation call is left
+// to the discretion of each executor implementation. Typical executor
+// implementations may dispatch tasks on an event-driven message loop or on
+// a thread pool. Developers are responsible for selecting appropriate
+// executor implementations for their programs.
+//
+// During each invocation, the executor passes the continuation an execution
+// context object represented by a subclass of |fit::context|. The continuation
+// attempts to make progress then returns a value of type |fit::result| to
+// indicate whether it completed successfully (signaled by |fit::ok()|),
+// failed with an error (signaled by |fit::error()|, or was unable to complete
+// the task during that invocation (signaled by |fit::pending()|).
+// For example, a continuation may be unable to complete the task if it must
+// asynchronously await completion of an I/O or IPC operation before it
+// can proceed any further.
+//
+// If the continuation was unable to complete the task during its invocation,
+// it may to call |fit::context::suspend_task()| to acquire a
+// |fit::suspended_task| object. The continuation then arranges for the
+// task to be resumed asynchronously (with |fit::suspended_task::resume_task()|)
+// once it becomes possible for the promise to make forward progress again.
+// Finally, the continuation returns returns |fit::pending()| to indicate to
+// the executor that it was unable to complete the task during that invocation.
+//
+// When the executor receives a pending result from a task's continuation,
+// it moves the task into a table of suspended tasks. A suspended task
+// is considered abandoned if has not been resume and all remaining
+// |fit::suspended_task| handles representing it have been dropped.
+// When a task is abandoned, the executor removes it from its table of
+// suspended tasks and destroys the task because it is not possible for the task
+// to be resumed or to make progress from that state.
+//
+// See also |fit::single_threaded_executor| for a simple executor implementation.
+//
+// BOXED AND UNBOXED PROMISES
+//
+// To make combination and execution as efficient as possible, the promises
+// returned by |fit::make_promise| and by combinators are parameterized by
+// complicated continuation types that are hard to describe, often consisting of
+// nested templates and lambdas. These are referred to as "unboxed"
+// promises. In contrast, "boxed" promises are parameterized by a
+// a |fit::function| that hides (or "erases") the type of the continuation
+// thereby yielding type that is easier to describe.
+//
+// You can recognize boxed and unboxed promises by their types.
+// Here are two examples:
+//
+// - A boxed promise type: `fit::promise<void, void>` which is an alias for
+// `fit::promise_impl<void, void, std::function<fit::result<void, void>>`.
+// - An unboxed promise type: `fit::promise_impl<void, void,
+// fit::internal::then_continuation<...something unintelligible...>>`
+//
+// Although boxed promises are easier to manipulate, they may cause the
+// continuation to be allocated on the heap. Chaining boxed promises can
+// result in multiple allocations being produced.
+//
+// Conversely, unboxed promises have full type information. Not only does
+// this defer heap allocation but it also makes it easier for the C++
+// compiler to fuse a chains of unboxed promises together into a single
+// object that is easier to optimize.
+//
+// Unboxed promises can be boxed by assigning them to a boxed promise
+// type (such as |fit::promise<>|) or using the |box()| combinator.
+//
+// As a rule of thumb, always defer boxing of promises until it is necessary
+// to transport them using a simpler type.
+//
+// Do this: (chaining as a single expression performs at most one heap allocation)
+//
+// fit::promise<> f = fit::make_promise([] { ... });
+// .then([](fit::result<>& result) { ... });
+// .and_then([] { ... });
+//
+// Or this: (still only performs at most one heap allocation)
+//
+// auto f = fit::make_promise([] { ... });
+// auto g = f.then([](fit::result<>& result) { ... });
+// auto h = g.and_then([] { ... });
+// fit::promise<> boxed_h = h;
+//
+// But don't do this: (incurs up to three heap allocations due to eager boxing)
+//
+// fit::promise<> f = fit::make_promise([] { ... });
+// fit::promise<> g = f.then([](fit::result<>& result) { ... });
+// fit::promise<> h = g.and_then([] { ... });
+//
+// SINGLE OWNERSHIP MODEL
+//
+// Promises have single-ownership semantics. This means that there
+// can only be at most one reference to the task represented by its
+// continuation along with any state held by that continuation.
+//
+// When a combinator is applied to a promise, ownership of its continuation
+// is transferred to the combined promise, leaving the original promise
+// in an "empty" state without a continuation. Note that it is an error
+// to attempt to invoke an empty promise (will assert at runtime).
+//
+// This model greatly simplifies reasoning about object lifetime.
+// If a promise goes out of scope without completing its task, the task
+// is considered "abandoned", causing all associated state to be destroyed.
+//
+// Note that a promise may capture references to other objects whose lifetime
+// differs from that of the promise. It is the responsibility of the promise
+// to ensure reachability of the objects whose reference it captures such
+// as by using reference counted pointers, weak pointers, or other appropriate
+// mechanisms to ensure memory safety.
+//
+// THREADING MODEL
+//
+// Promise objects are not thread-safe themselves. You cannot call their
+// methods concurrently (or re-entrantly). However, promises can safely
+// be moved to other threads and executed there (unless their continuation
+// requires thread affinity for some reason but that's beyond the scope
+// of this document).
+//
+// This property of being thread-independent, combined with the single
+// ownership model, greatly simplifies the implementation of thread pool
+// based executors.
+//
+// RESULT RETENTION AND FIT::FUTURES
+//
+// A promise's continuation can only be executed to completion once.
+// After it completes, it cannot be run again.
+//
+// This method of execution is very efficient; the promise's result is returned
+// directly to its invoker; it is not copied or retained within the promise
+// object itself. It is entirely the caller's responsibility to decide how to
+// consume or retain the result if need be.
+//
+// For example, the caller can move the promise into a |fit::future| to
+// more conveniently hold either the promise or its result upon completion.
+//
+// CLARIFICATION OF NOMENCLATURE
+//
+// In this library, the words "promise" and "future" have the following
+// definitions:
+//
+// - A *promise* holds the function that performs an asynchronous task.
+// It is the means to produce a value.
+// - A *future* holds the value produced by an asynchronous task or a
+// promise to produce that value if the task has not yet completed.
+// It is a proxy for a value that is to be computed.
+//
+// Be aware that other libraries may use these terms slightly differently.
+//
+// For more information about the theory of futures and promises, see
+// https://en.wikipedia.org/wiki/Futures_and_promises.
+//
+// COMPARISON WITH STD::FUTURE
+//
+// |std::future| provides a mechanism for running asynchronous tasks
+// and awaiting their results on other threads. Waiting can be performed
+// either by blocking the waiting thread or by polling the future.
+// The manner in which tasks are scheduled and executed is entirely
+// controlled by the C++ standard library and offers limited control
+// to developers.
+//
+// |fit::promise| and |fit::future| provide a mechanism for running asynchronous
+// tasks, chaining additional tasks using combinators, and awaiting their
+// results. An executor is responsible for suspending tasks awaiting
+// results of other tasks and is at liberty to run other tasks on the
+// same thread rather than blocking. In addition, developers can create custom
+// executors to implement their own policies for running tasks.
+//
+// Decoupling awaiting from blocking makes |fit::promise| quite versatile.
+// |fit::promise| can also interoperate with other task dispatching mechanisms
+// (including |std::future|) using adapters such as |fit::bridge|.
+//
+// EXAMPLE
+//
+// -
+// https://fuchsia.googlesource.com/fuchsia/+/master/zircon/system/utest/fit/examples/promise_example1.cc
+// -
+// https://fuchsia.googlesource.com/fuchsia/+/master/zircon/system/utest/fit/examples/promise_example2.cc
+//
+template <typename V = void, typename E = void>
+using promise = promise_impl<function<result<V, E>(fit::context&)>>;
+
+// Promise implementation details.
+// See |fit::promise| documentation for more information.
+template <typename Continuation>
+class promise_impl final {
+ static_assert(::fit::internal::is_continuation<Continuation>::value,
+ "Continuation type is invalid. A continuation is a callable object "
+ "with this signature: fit::result<V, E>(fit::context&).");
+
+ using state_type = nullable<Continuation>;
+
+ public:
+ // The type of callable object held by the promise.
+ // Its signature is: result_type(fit::context&).
+ using continuation_type = Continuation;
+
+ // The promise's result type.
+ // Equivalent to fit::result<value_type, error_type>.
+ using result_type = typename ::fit::internal::continuation_traits<Continuation>::result_type;
+
+ // The type of value produced when the promise completes successfully.
+ // May be void.
+ using value_type = typename result_type::value_type;
+
+ // The type of value produced when the promise completes with an error.
+ // May be void.
+ using error_type = typename result_type::error_type;
+
+ // Creates an empty promise without a continuation.
+ // A continuation must be assigned before the promise can be used.
+ promise_impl() = default;
+ explicit promise_impl(decltype(nullptr)) {}
+
+ promise_impl(const promise_impl&) = delete;
+ promise_impl& operator=(const promise_impl&) = delete;
+
+ // Constructs the promise by taking the continuation from another promise,
+ // leaving the other promise empty.
+ promise_impl(promise_impl&& other) : state_{std::move(other.state_)} { other.state_.reset(); }
+
+ // Assigns the promise by taking the continuation from another promise,
+ // leaving the other promise empty.
+ promise_impl& operator=(promise_impl&& other) {
+ if (this != &other) {
+ state_ = std::move(other.state_);
+ other.state_.reset();
+ }
+ return *this;
+ }
+
+ // Creates a promise with a continuation.
+ // If |continuation| equals nullptr then the promise is empty.
+ explicit promise_impl(continuation_type continuation) : state_(std::move(continuation)) {}
+
+ // Converts from a promise holding a continuation that is assignable to
+ // to this promise's continuation type.
+ //
+ // This is typically used to create a promise with a boxed continuation
+ // type (such as |fit::function|) from an unboxed promise produced by
+ // |fit::make_promise| or by combinators.
+ //
+ // EXAMPLE
+ //
+ // // f is a promise_impl with a complicated unboxed type
+ // auto f = fit::make_promise([] { ... });
+ //
+ // // g wraps f's continuation
+ // fit::promise<> g = std::move(f);
+ //
+ template <
+ typename OtherContinuation,
+ std::enable_if_t<!std::is_same<continuation_type, OtherContinuation>::value &&
+ std::is_constructible<continuation_type, OtherContinuation&&>::value,
+ bool> = true>
+ promise_impl(promise_impl<OtherContinuation> other)
+ : state_(other.state_.has_value() ? state_type(continuation_type(std::move(*other.state_)))
+ : state_type()) {}
+
+ // Destroys the promise, releasing its continuation.
+ ~promise_impl() = default;
+
+ // Returns true if the promise is non-empty (has a valid continuation).
+ explicit operator bool() const { return state_.has_value(); }
+
+ // Invokes the promise's continuation.
+ //
+ // This method should be called by an executor to evaluate the promise.
+ // If the result's state is |result_state::pending| then the executor
+ // is responsible for arranging to invoke the promise's continuation
+ // again once it determines that it is possible to make progress
+ // towards completion of the promise encapsulated within the promise.
+ //
+ // Once the continuation returns a result with status |result_state::ok|
+ // or |result_state::error|, the promise is assigned an empty continuation.
+ //
+ // Asserts that the promise is non-empty.
+ result_type operator()(context& context) {
+ result_type result = (state_.value())(context);
+ if (!result.is_pending())
+ state_.reset();
+ return result;
+ }
+
+ // Takes the promise's continuation, leaving it in an empty state.
+ // Asserts that the promise is non-empty.
+ continuation_type take_continuation() {
+ auto continuation = std::move(state_.value());
+ state_.reset();
+ return continuation;
+ }
+
+ // Discards the promise's continuation, leaving it empty.
+ promise_impl& operator=(decltype(nullptr)) {
+ state_.reset();
+ return *this;
+ }
+
+ // Assigns the promise's continuation.
+ promise_impl& operator=(continuation_type continuation) {
+ state_ = std::move(continuation);
+ return *this;
+ }
+
+ // Swaps the promises' continuations.
+ void swap(promise_impl& other) {
+ using std::swap;
+ swap(state_, other.state_);
+ }
+
+ // Returns an unboxed promise which invokes the specified handler
+ // function after this promise completes (successfully or unsuccessfully),
+ // passing its result.
+ //
+ // The received result's state is guaranteed to be either
+ // |fit::result_state::ok| or |fit::result_state::error|, never
+ // |fit::result_state::pending|.
+ //
+ // |handler| is a callable object (such as a lambda) which consumes the
+ // result of this promise and returns a new result with any value type
+ // and error type. Must not be null.
+ //
+ // The handler must return one of the following types:
+ // - void
+ // - fit::result<new_value_type, new_error_type>
+ // - fit::ok<new_value_type>
+ // - fit::error<new_error_type>
+ // - fit::pending
+ // - fit::promise<new_value_type, new_error_type>
+ // - any callable or unboxed promise with the following signature:
+ // fit::result<new_value_type, new_error_type>(fit::context&)
+ //
+ // The handler must accept one of the following argument lists:
+ // - (result_type&)
+ // - (const result_type&)
+ // - (fit::context&, result_type&)
+ // - (fit::context&, const result_type&)
+ //
+ // Asserts that the promise is non-empty.
+ // This method consumes the promise's continuation, leaving it empty.
+ //
+ // EXAMPLE
+ //
+ // auto f = fit::make_promise(...)
+ // .then([] (fit::result<int, std::string>& result)
+ // -> fit::result<std::string, void> {
+ // if (result.is_ok()) {
+ // printf("received value: %d\n", result.value());
+ // if (result.value() % 15 == 0)
+ // return ::fit::ok("fizzbuzz");
+ // if (result.value() % 3 == 0)
+ // return ::fit::ok("fizz");
+ // if (result.value() % 5 == 0)
+ // return ::fit::ok("buzz");
+ // return ::fit::ok(std::to_string(result.value()));
+ // } else {
+ // printf("received error: %s\n", result.error().c_str());
+ // return ::fit::error();
+ // }
+ // })
+ // .then(...);
+ //
+ template <typename ResultHandler>
+ promise_impl<::fit::internal::then_continuation<promise_impl, ResultHandler>> then(
+ ResultHandler handler) {
+ static_assert(is_callable<ResultHandler>::value, "ResultHandler must be a callable object.");
+
+ assert(!is_null(handler));
+ assert(state_.has_value());
+ return make_promise_with_continuation(
+ ::fit::internal::then_continuation<promise_impl, ResultHandler>(std::move(*this),
+ std::move(handler)));
+ }
+
+ // Returns an unboxed promise which invokes the specified handler
+ // function after this promise completes successfully, passing its
+ // resulting value.
+ //
+ // |handler| is a callable object (such as a lambda) which consumes the
+ // result of this promise and returns a new result with any value type
+ // but the same error type. Must not be null.
+ //
+ // The handler must return one of the following types:
+ // - void
+ // - fit::result<new_value_type, error_type>
+ // - fit::ok<new_value_type>
+ // - fit::error<error_type>
+ // - fit::pending
+ // - fit::promise<new_value_type, error_type>
+ // - any callable or unboxed promise with the following signature:
+ // fit::result<new_value_type, error_type>(fit::context&)
+ //
+ // The handler must accept one of the following argument lists:
+ // - (value_type&)
+ // - (const value_type&)
+ // - (fit::context&, value_type&)
+ // - (fit::context&, const value_type&)
+ //
+ // Asserts that the promise is non-empty.
+ // This method consumes the promise's continuation, leaving it empty.
+ //
+ // EXAMPLE
+ //
+ // auto f = fit::make_promise(...)
+ // .and_then([] (const int& value) {
+ // printf("received value: %d\n", value);
+ // if (value % 15 == 0)
+ // return ::fit::ok("fizzbuzz");
+ // if (value % 3 == 0)
+ // return ::fit::ok("fizz");
+ // if (value % 5 == 0)
+ // return ::fit::ok("buzz");
+ // return ::fit::ok(std::to_string(value));
+ // })
+ // .then(...);
+ //
+ template <typename ValueHandler>
+ promise_impl<::fit::internal::and_then_continuation<promise_impl, ValueHandler>> and_then(
+ ValueHandler handler) {
+ static_assert(is_callable<ValueHandler>::value, "ValueHandler must be a callable object.");
+
+ assert(!is_null(handler));
+ assert(state_.has_value());
+ return make_promise_with_continuation(
+ ::fit::internal::and_then_continuation<promise_impl, ValueHandler>(std::move(*this),
+ std::move(handler)));
+ }
+
+ // Returns an unboxed promise which invokes the specified handler
+ // function after this promise completes with an error, passing its
+ // resulting error.
+ //
+ // |handler| is a callable object (such as a lambda) which consumes the
+ // result of this promise and returns a new result with any error type
+ // but the same value type. Must not be null.
+ //
+ // The handler must return one of the following types:
+ // - void
+ // - fit::result<value_type, new_error_type>
+ // - fit::ok<value_type>
+ // - fit::error<new_error_type>
+ // - fit::pending
+ // - fit::promise<value_type, new_error_type>
+ // - any callable or unboxed promise with the following signature:
+ // fit::result<value_type, new_error_type>(fit::context&)
+ //
+ // The handler must accept one of the following argument lists:
+ // - (error_type&)
+ // - (const error_type&)
+ // - (fit::context&, error_type&)
+ // - (fit::context&, const error_type&)
+ //
+ // Asserts that the promise is non-empty.
+ // This method consumes the promise's continuation, leaving it empty.
+ //
+ // EXAMPLE
+ //
+ // auto f = fit::make_promise(...)
+ // .or_else([] (const std::string& error) {
+ // printf("received error: %s\n", error.c_str());
+ // return ::fit::error();
+ // })
+ // .then(...);
+ //
+ template <typename ErrorHandler>
+ promise_impl<::fit::internal::or_else_continuation<promise_impl, ErrorHandler>> or_else(
+ ErrorHandler handler) {
+ static_assert(is_callable<ErrorHandler>::value, "ErrorHandler must be a callable object.");
+
+ assert(!is_null(handler));
+ assert(state_.has_value());
+ return make_promise_with_continuation(
+ ::fit::internal::or_else_continuation<promise_impl, ErrorHandler>(std::move(*this),
+ std::move(handler)));
+ }
+
+ // Returns an unboxed promise which invokes the specified handler
+ // function after this promise completes (successfully or unsuccessfully),
+ // passing it the promise's result then delivering the result onwards
+ // to the next promise once the handler returns.
+ //
+ // The handler receives a const reference, or non-const reference
+ // depending on the signature of the handler's last argument.
+ //
+ // - Const references are especially useful for inspecting a
+ // result mid-stream without modification, such as printing it for
+ // debugging.
+ // - Non-const references are especially useful for synchronously
+ // modifying a result mid-stream, such as clamping its bounds or
+ // injecting a default value.
+ //
+ // |handler| is a callable object (such as a lambda) which can examine
+ // or modify the incoming result. Unlike |then()|, the handler does
+ // not need to propagate the result onwards. Must not be null.
+ //
+ // The handler must return one of the following types:
+ // - void
+ //
+ // The handler must accept one of the following argument lists:
+ // - (result_type&)
+ // - (const result_type&)
+ // - (fit::context&, result_type&)
+ // - (fit::context&, const result_type&)
+ //
+ // Asserts that the promise is non-empty.
+ // This method consumes the promise's continuation, leaving it empty.
+ //
+ // EXAMPLE
+ //
+ // auto f = fit::make_promise(...)
+ // .inspect([] (const fit::result<int, std::string>& result) {
+ // if (result.is_ok())
+ // printf("received value: %d\n", result.value());
+ // else
+ // printf("received error: %s\n", result.error().c_str());
+ // })
+ // .then(...);
+ //
+ template <typename InspectHandler>
+ promise_impl<::fit::internal::inspect_continuation<promise_impl, InspectHandler>> inspect(
+ InspectHandler handler) {
+ static_assert(is_callable<InspectHandler>::value, "InspectHandler must be a callable object.");
+ static_assert(std::is_void<typename callable_traits<InspectHandler>::return_type>::value,
+ "InspectHandler must return void.");
+
+ assert(!is_null(handler));
+ assert(state_.has_value());
+ return make_promise_with_continuation(
+ ::fit::internal::inspect_continuation<promise_impl, InspectHandler>(std::move(*this),
+ std::move(handler)));
+ }
+
+ // Returns an unboxed promise which discards the result of this promise
+ // once it completes, thereby always producing a successful result of
+ // type fit::result<void, void> regardless of whether this promise
+ // succeeded or failed.
+ //
+ // Asserts that the promise is non-empty.
+ // This method consumes the promise's continuation, leaving it empty.
+ //
+ // EXAMPLE
+ //
+ // auto f = fit::make_promise(...)
+ // .discard_result()
+ // .then(...);
+ //
+ promise_impl<::fit::internal::discard_result_continuation<promise_impl>> discard_result() {
+ assert(state_.has_value());
+ return make_promise_with_continuation(
+ ::fit::internal::discard_result_continuation<promise_impl>(std::move(*this)));
+ }
+
+ // Applies a |wrapper| to the promise. Invokes the wrapper's |wrap()|
+ // method, passes the promise to the wrapper by value followed by any
+ // additional |args| passed to |wrap_with()|, then returns the wrapper's
+ // result.
+ //
+ // |Wrapper| is a type that implements a method called |wrap()| which
+ // accepts a promise as its argument and produces a wrapped result of
+ // any type, such as another promise.
+ //
+ // Asserts that the promise is non-empty.
+ // This method consumes the promise's continuation, leaving it empty.
+ //
+ // EXAMPLE
+ //
+ // In this example, |fit::sequencer| is a wrapper type that imposes
+ // FIFO execution order onto a sequence of wrapped promises.
+ //
+ // // This wrapper type is intended to be applied to
+ // // a sequence of promises so we store it in a variable.
+ // fit::sequencer seq;
+ //
+ // // This task consists of some amount of work that must be
+ // // completed sequentially followed by other work that can
+ // // happen in any order. We use |wrap_with()| to wrap the
+ // // sequential work with the sequencer.
+ // fit::promise<> perform_complex_task() {
+ // return fit::make_promise([] { /* do sequential work */ })
+ // .then([] (fit::result<> result) { /* this will also be wrapped */ })
+ // .wrap_with(seq)
+ // .then([] (fit::result<> result) { /* do more work */ });
+ // }
+ //
+ // This example can also be written without using |wrap_with()|.
+ // The behavior is equivalent but the syntax may seem more awkward.
+ //
+ // fit::sequencer seq;
+ //
+ // promise<> perform_complex_task() {
+ // return seq.wrap(
+ // fit::make_promise([] { /* sequential work */ })
+ // ).then([] (fit::result<> result) { /* more work */ });
+ // }
+ //
+ template <typename Wrapper, typename... Args>
+ decltype(auto) wrap_with(Wrapper& wrapper, Args... args) {
+ assert(state_.has_value());
+ return wrapper.wrap(std::move(*this), std::forward<Args>(args)...);
+ }
+
+ // Wraps the promise's continuation into a |fit::function|.
+ //
+ // A boxed promise is easier to store and pass around than the unboxed
+ // promises produced by |fit::make_promise()| and combinators, though boxing
+ // may incur a heap allocation.
+ //
+ // It is a good idea to defer boxing the promise until after all
+ // desired combinators have been applied to prevent unnecessary heap
+ // allocation during intermediate states of the promise's construction.
+ //
+ // Returns an empty promise if this promise is empty.
+ // This method consumes the promise's continuation, leaving it empty.
+ //
+ // EXAMPLE
+ //
+ // // f's is a fit::promise_impl<> whose continuation contains an
+ // // anonymous type (the lambda)
+ // auto f = fit::make_promise([] {});
+ //
+ // // g's type will be fit::promise<> due to boxing
+ // auto boxed_f = f.box();
+ //
+ // // alternately, we can get exactly the same effect by assigning
+ // // the unboxed promise to a variable of a named type instead of
+ // // calling box()
+ // fit::promise<> boxed_f = std::move(f);
+ //
+ promise_impl<function<result_type(context&)>> box() { return std::move(*this); }
+
+ private:
+ template <typename>
+ friend class promise_impl;
+
+ state_type state_;
+};
+
+template <typename Continuation>
+void swap(promise_impl<Continuation>& a, promise_impl<Continuation>& b) {
+ a.swap(b);
+}
+
+template <typename Continuation>
+bool operator==(const promise_impl<Continuation>& f, decltype(nullptr)) {
+ return !f;
+}
+template <typename Continuation>
+bool operator==(decltype(nullptr), const promise_impl<Continuation>& f) {
+ return !f;
+}
+template <typename Continuation>
+bool operator!=(const promise_impl<Continuation>& f, decltype(nullptr)) {
+ return !!f;
+}
+template <typename Continuation>
+bool operator!=(decltype(nullptr), const promise_impl<Continuation>& f) {
+ return !!f;
+}
+
+// Makes a promise containing the specified continuation.
+//
+// This function is used for making a promises given a callable object
+// that represents a valid continuation type. In contrast,
+// |fit::make_promise()| supports a wider range of types and should be
+// preferred in most situations.
+//
+// |Continuation| is a callable object with the signature
+// fit::result<V, E>(fit::context&).
+template <typename Continuation>
+inline promise_impl<Continuation> make_promise_with_continuation(Continuation continuation) {
+ return promise_impl<Continuation>(std::move(continuation));
+}
+
+// Returns an unboxed promise that wraps the specified handler.
+// The type of the promise's result is inferred from the handler's result.
+//
+// |handler| is a callable object (such as a lambda. Must not be null.
+//
+// The handler must return one of the following types:
+// - void
+// - fit::result<value_type, error_type>
+// - fit::ok<value_type>
+// - fit::error<error_type>
+// - fit::pending
+// - fit::promise<value_type, error_type>
+// - any callable or unboxed promise with the following signature:
+// fit::result<value_type, error_type>(fit::context&)
+//
+// The handler must accept one of the following argument lists:
+// - ()
+// - (fit::context&)
+//
+// See documentation of |fit::promise| for more information.
+//
+// SYNOPSIS
+//
+// |Handler| is the handler function type. It is typically inferred by the
+// compiler from the |handler| argument.
+//
+// EXAMPLE
+//
+// enum class weather_type { sunny, glorious, cloudy, eerie, ... };
+//
+// weather_type look_outside() { ... }
+// void wait_for_tomorrow(fit::suspended_task task) {
+// ... arrange to call task.resume_task() tomorrow ...
+// }
+//
+// fit::promise<weather_type, std::string> wait_for_good_weather(int max_days) {
+// return fit::make_promise([days_left = max_days] (fit::context& context) mutable
+// -> fit::result<int, std::string> {
+// weather_type weather = look_outside();
+// if (weather == weather_type::sunny || weather == weather_type::glorious)
+// return fit::ok(weather);
+// if (days_left > 0) {
+// wait_for_tomorrow(context.suspend_task());
+// return fit::pending();
+// }
+// days_left--;
+// return fit::error("nothing but grey skies");
+// });
+// }
+//
+// auto f = wait_for_good_weather(7)
+// .and_then([] (const weather_type& weather) { ... })
+// .or_else([] (const std::string& error) { ... });
+//
+template <typename PromiseHandler>
+inline promise_impl<::fit::internal::context_handler_invoker<PromiseHandler>> make_promise(
+ PromiseHandler handler) {
+ static_assert(is_callable<PromiseHandler>::value, "PromiseHandler must be a callable object.");
+
+ assert(!is_null(handler));
+ return make_promise_with_continuation(
+ ::fit::internal::promise_continuation<PromiseHandler>(std::move(handler)));
+}
+
+// Returns an unboxed promise that immediately returns the specified result when invoked.
+//
+// This function is especially useful for returning promises from functions
+// that have multiple branches some of which complete synchronously.
+//
+// |result| is the result for the promise to return.
+//
+// See documentation of |fit::promise| for more information.
+template <typename V = void, typename E = void>
+inline promise_impl<::fit::internal::result_continuation<V, E>> make_result_promise(
+ fit::result<V, E> result) {
+ return make_promise_with_continuation(
+ ::fit::internal::result_continuation<V, E>(std::move(result)));
+}
+template <typename V = void, typename E = void>
+inline promise_impl<::fit::internal::result_continuation<V, E>> make_result_promise(
+ fit::ok_result<V> result) {
+ return make_promise_with_continuation(
+ ::fit::internal::result_continuation<V, E>(std::move(result)));
+}
+template <typename V = void, typename E = void>
+inline promise_impl<::fit::internal::result_continuation<V, E>> make_result_promise(
+ fit::error_result<E> result) {
+ return make_promise_with_continuation(
+ ::fit::internal::result_continuation<V, E>(std::move(result)));
+}
+template <typename V = void, typename E = void>
+inline promise_impl<::fit::internal::result_continuation<V, E>> make_result_promise(
+ fit::pending_result result) {
+ return make_promise_with_continuation(
+ ::fit::internal::result_continuation<V, E>(std::move(result)));
+}
+
+// Returns an unboxed promise that immediately returns the specified value when invoked.
+//
+// This function is especially useful for returning promises from functions
+// that have multiple branches some of which complete synchronously.
+//
+// |value| is the value for the promise to return.
+//
+// See documentation of |fit::promise| for more information.
+template <typename V>
+inline promise_impl<::fit::internal::result_continuation<V, void>> make_ok_promise(V value) {
+ return make_result_promise(fit::ok(std::move(value)));
+}
+
+// Overload of |make_ok_promise()| used when the value type is void.
+inline promise_impl<::fit::internal::result_continuation<void, void>> make_ok_promise() {
+ return make_result_promise(fit::ok());
+}
+
+// Returns an unboxed promise that immediately returns the specified error when invoked.
+//
+// This function is especially useful for returning promises from functions
+// that have multiple branches some of which complete synchronously.
+//
+// |error| is the error for the promise to return.
+//
+// See documentation of |fit::promise| for more information.
+template <typename E>
+inline promise_impl<::fit::internal::result_continuation<void, E>> make_error_promise(E error) {
+ return make_result_promise(fit::error(std::move(error)));
+}
+
+// Overload of |make_error_promise()| used when the error type is void.
+inline promise_impl<::fit::internal::result_continuation<void, void>> make_error_promise() {
+ return make_result_promise(fit::error());
+}
+
+// Jointly evaluates zero or more promises.
+// Returns a promise that produces a std::tuple<> containing the result
+// of each promise once they all complete.
+//
+// EXAMPLE
+//
+// auto get_random_number() {
+// return fit::make_promise([] { return rand() % 10 });
+// }
+//
+// auto get_random_product() {
+// auto f = get_random_number();
+// auto g = get_random_number();
+// return fit::join_promises(std::move(f), std::move(g))
+// .and_then([] (std::tuple<fit::result<int>, fit::result<int>>& results) {
+// return fit::ok(results.get<0>.value() + results.get<1>.value());
+// });
+// }
+//
+template <typename... Promises>
+inline promise_impl<::fit::internal::join_continuation<Promises...>> join_promises(
+ Promises... promises) {
+ return make_promise_with_continuation(
+ ::fit::internal::join_continuation<Promises...>(std::move(promises)...));
+}
+
+// Jointly evaluates zero or more homogenous promises (same result and error
+// type). Returns a promise that produces a std::vector<> containing the
+// result of each promise once they all complete.
+//
+// EXAMPLE
+//
+// auto get_random_number() {
+// return fit::make_promise([] { return rand() % 10 });
+// }
+//
+// auto get_random_product() {
+// std::vector<fit::promise<int>> promises;
+// promises.push_back(get_random_number());
+// promises.push_back(get_random_number());
+// return fit::join_promise_vector(std::move(promises))
+// .and_then([] (std::vector<fit::result<int>>& results) {
+// return fit::ok(results[0].value() + results[1].value());
+// });
+// }
+//
+template <typename V, typename E>
+inline promise_impl<::fit::internal::join_vector_continuation<fit::promise<V, E>>>
+join_promise_vector(std::vector<fit::promise<V, E>> promises) {
+ return make_promise_with_continuation(
+ ::fit::internal::join_vector_continuation<fit::promise<V, E>>(std::move(promises)));
+}
+
+// Describes the status of a future.
+enum class future_state {
+ // The future neither holds a result nor a promise that could produce a result.
+ // An empty future cannot make progress until a promise or result is assigned to it.
+ empty,
+ // The future holds a promise that may eventually produce a result but
+ // it currently doesn't have a result. The future's promise must be
+ // invoked in order to make progress from this state.
+ pending,
+ // The future holds a successful result.
+ ok,
+ // The future holds an error result.
+ error
+};
+
+// A |fit::future| holds onto a |fit::promise| until it has completed then
+// provides access to its |fit::result|.
+//
+// SYNOPSIS
+//
+// |V| is the type of value produced when the completes successfully.
+// Defaults to |void|.
+//
+// |E| is the type of error produced when the completes with an error.
+// Defaults to |void|.
+//
+// THEORY OF OPERATION
+//
+// A future has a single owner who is responsible for setting its promise
+// or result and driving its execution. Unlike |fit::promise|, a future retains
+// the result produced by completion of its asynchronous task. Result retention
+// eases the implementation of combined tasks that need to await the results
+// of other tasks before proceeding.
+//
+// See the example for details.
+//
+// A future can be in one of four states, depending on whether it holds...
+// - a successful result: |fit::future_state::ok|
+// - an error result: |fit::future_state::error|
+// - a promise that may eventually produce a result: |fit::future_state::pending|
+// - neither: |fit::future_state_empty|
+//
+// On its own, a future is "inert"; it only makes progress in response to
+// actions taken by its owner. The state of the future never changes
+// spontaneously or concurrently.
+//
+// When the future's state is |fit::future_state::empty|, its owner is
+// responsible for setting the future's promise or result thereby moving the
+// future into the pending or ready state.
+//
+// When the future's state is |fit::future_state::pending|, its owner is
+// responsible for calling the future's |operator()| to invoke the promise.
+// If the promise completes and returns a result, the future will transition
+// to the ok or error state according to the result. The promise itself will
+// then be destroyed since it has fulfilled its purpose.
+//
+// When the future's state is |fit::future_state::ok|, its owner is responsible
+// for consuming the stored value using |value()|, |take_value()|,
+// |result()|, |take_result()|, or |take_ok_result()|.
+//
+// When the future's state is |fit::future_state::error|, its owner is
+// responsible for consuming the stored error using |error()|, |take_error()|,
+// |result()|, |take_result()|, or |take_error_result()|.
+//
+// See also |fit::promise| for more information about promises and their
+// execution.
+//
+// EXAMPLE
+//
+// -
+// https://fuchsia.googlesource.com/fuchsia/+/master/zircon/system/utest/fit/examples/promise_example2.cc
+template <typename V = void, typename E = void>
+using future = future_impl<promise<V, E>>;
+
+// Future implementation details.
+// See |fit::future| documentation for more information.
+template <typename Promise>
+class future_impl final {
+ public:
+ // The type of promise held by the future.
+ using promise_type = Promise;
+
+ // The promise's result type.
+ // Equivalent to fit::result<value_type, error_type>.
+ using result_type = typename Promise::result_type;
+
+ // The type of value produced when the promise completes successfully.
+ // May be void.
+ using value_type = typename Promise::value_type;
+
+ // The type of value produced when the promise completes with an error.
+ // May be void.
+ using error_type = typename Promise::error_type;
+
+ // Creates a future in the empty state.
+ future_impl() = default;
+ future_impl(decltype(nullptr)) {}
+
+ // Creates a future and assigns a promise to compute its result.
+ // If the promise is empty, the future enters the empty state.
+ // Otherwise the future enters the pending state.
+ explicit future_impl(promise_type promise) {
+ if (promise) {
+ state_.template emplace<1>(std::move(promise));
+ }
+ }
+
+ // Creates a future and assigns its result.
+ // If the result is pending, the future enters the empty state.
+ // Otherwise the future enters the ok or error state.
+ explicit future_impl(result_type result) {
+ if (result) {
+ state_.template emplace<2>(std::move(result));
+ }
+ }
+
+ // Moves from another future, leaving the other one in an empty state.
+ future_impl(future_impl&& other) : state_(std::move(other.state_)) {
+ other.state_.template emplace<0>();
+ }
+
+ // Destroys the promise, releasing its promise and result (if any).
+ ~future_impl() = default;
+
+ // Returns the state of the future: empty, pending, ok, or error.
+ future_state state() const {
+ switch (state_.index()) {
+ case 0:
+ return future_state::empty;
+ case 1:
+ return future_state::pending;
+ case 2:
+ return state_.template get<2>().is_ok() ? future_state::ok : future_state::error;
+ }
+ __builtin_unreachable();
+ }
+
+ // Returns true if the future's state is not |fit::future_state::empty|:
+ // it either holds a result or holds a promise that can be invoked to make
+ // progress towards obtaining a result.
+ explicit operator bool() const { return !is_empty(); }
+
+ // Returns true if the future's state is |fit::future_state::empty|:
+ // it does not hold a result or a promise so it cannot make progress.
+ bool is_empty() const { return state() == fit::future_state::empty; }
+
+ // Returns true if the future's state is |fit::future_state::pending|:
+ // it does not hold a result yet but it does hold a promise that can be invoked
+ // to make progress towards obtaining a result.
+ bool is_pending() const { return state() == fit::future_state::pending; }
+
+ // Returns true if the future's state is |fit::future_state::ok|:
+ // it holds a value that can be retrieved using |value()|, |take_value()|,
+ // |result()|, |take_result()|, or |take_ok_result()|.
+ bool is_ok() const { return state() == fit::future_state::ok; }
+
+ // Returns true if the future's state is |fit::future_state::error|:
+ // it holds an error that can be retrieved using |error()|, |take_error()|,
+ // |result()|, |take_result()|, or |take_error_result()|.
+ bool is_error() const { return state() == fit::future_state::error; }
+
+ // Returns true if the future's state is either |fit::future_state::ok| or
+ // |fit::future_state::error|.
+ bool is_ready() const { return state_.index() == 2; }
+
+ // Evaluates the future and returns true if its result is ready.
+ // Asserts that the future is not empty.
+ //
+ // If the promise completes and returns a result, the future will transition
+ // to the ok or error state according to the result. The promise itself will
+ // then be destroyed since it has fulfilled its purpose.
+ bool operator()(fit::context& context) {
+ switch (state_.index()) {
+ case 0:
+ return false;
+ case 1: {
+ result_type result = state_.template get<1>()(context);
+ if (!result)
+ return false;
+ state_.template emplace<2>(std::move(result));
+ return true;
+ }
+ case 2:
+ return true;
+ }
+ __builtin_unreachable();
+ }
+
+ // Gets a reference to the future's promise.
+ // Asserts that the future's state is |fit::future_state::pending|.
+ const promise_type& promise() const {
+ assert(is_pending());
+ return state_.template get<1>();
+ }
+
+ // Takes the future's promise, leaving it in an empty state.
+ // Asserts that the future's state is |fit::future_state::pending|.
+ promise_type take_promise() {
+ assert(is_pending());
+ auto promise = std::move(state_.template get<1>());
+ state_.template emplace<0>();
+ return promise;
+ }
+
+ // Gets a reference to the future's result.
+ // Asserts that the future's state is |fit::future_state::ok| or
+ // |fit::future_state::error|.
+ result_type& result() {
+ assert(is_ready());
+ return state_.template get<2>();
+ }
+ const result_type& result() const {
+ assert(is_ready());
+ return state_.template get<2>();
+ }
+
+ // Takes the future's result, leaving it in an empty state.
+ // Asserts that the future's state is |fit::future_state::ok| or
+ // |fit::future_state::error|.
+ result_type take_result() {
+ assert(is_ready());
+ auto result = std::move(state_.template get<2>());
+ state_.template emplace<0>();
+ return result;
+ }
+
+ // Gets a reference to the future's value.
+ // Asserts that the future's state is |fit::future_state::ok|.
+ template <typename R = value_type, typename = std::enable_if_t<!std::is_void<R>::value>>
+ R& value() {
+ assert(is_ok());
+ return state_.template get<2>().value();
+ }
+ template <typename R = value_type, typename = std::enable_if_t<!std::is_void<R>::value>>
+ const R& value() const {
+ assert(is_ok());
+ return state_.template get<2>().value();
+ }
+
+ // Takes the future's value, leaving it in an empty state.
+ // Asserts that the future's state is |fit::future_state::ok|.
+ template <typename R = value_type, typename = std::enable_if_t<!std::is_void<R>::value>>
+ R take_value() {
+ assert(is_ok());
+ auto value = state_.template get<2>().take_value();
+ state_.template emplace<0>();
+ return value;
+ }
+ ok_result<value_type> take_ok_result() {
+ assert(is_ok());
+ auto result = state_.template get<2>().take_ok_result();
+ state_.template emplace<0>();
+ return result;
+ }
+
+ // Gets a reference to the future's error.
+ // Asserts that the future's state is |fit::future_state::error|.
+ template <typename R = error_type, typename = std::enable_if_t<!std::is_void<R>::value>>
+ R& error() {
+ assert(is_error());
+ return state_.template get<2>().error();
+ }
+ template <typename R = error_type, typename = std::enable_if_t<!std::is_void<R>::value>>
+ const R& error() const {
+ assert(is_error());
+ return state_.template get<2>().error();
+ }
+
+ // Takes the future's error, leaving it in an empty state.
+ // Asserts that the future's state is |fit::future_state::error|.
+ template <typename R = error_type, typename = std::enable_if_t<!std::is_void<R>::value>>
+ R take_error() {
+ assert(is_error());
+ auto error = state_.template get<2>().take_error();
+ state_.template emplace<0>();
+ return error;
+ }
+ error_result<error_type> take_error_result() {
+ assert(is_error());
+ auto result = state_.template get<2>().take_error_result();
+ state_.template emplace<0>();
+ return result;
+ }
+
+ // Move assigns from another future, leaving the other one in an empty state.
+ future_impl& operator=(future_impl&& other) = default;
+
+ // Discards the future's promise and result, leaving it empty.
+ future_impl& operator=(decltype(nullptr)) {
+ state_.template emplace<0>();
+ return *this;
+ }
+
+ // Assigns a promise to compute the future's result.
+ // If the promise is empty, the future enters the empty state.
+ // Otherwise the future enters the pending state.
+ future_impl& operator=(promise_type promise) {
+ if (promise) {
+ state_.template emplace<1>(std::move(promise));
+ } else {
+ state_.template emplace<0>();
+ }
+ return *this;
+ }
+
+ // Assigns the future's result.
+ // If the result is pending, the future enters the empty state.
+ // Otherwise the future enters the ok or error state.
+ future_impl& operator=(result_type result) {
+ if (result) {
+ state_.template emplace<2>(std::move(result));
+ } else {
+ state_.template emplace<0>();
+ }
+ return *this;
+ }
+
+ // Swaps the futures' contents.
+ void swap(future_impl& other) {
+ using std::swap;
+ swap(state_, other.state_);
+ }
+
+ future_impl(const future_impl&) = delete;
+ future_impl& operator=(const future_impl&) = delete;
+
+ private:
+ variant<monostate, promise_type, result_type> state_;
+};
+
+template <typename Promise>
+void swap(future_impl<Promise>& a, future_impl<Promise>& b) {
+ a.swap(b);
+}
+
+template <typename Promise>
+bool operator==(const future_impl<Promise>& f, decltype(nullptr)) {
+ return !f;
+}
+template <typename Promise>
+bool operator==(decltype(nullptr), const future_impl<Promise>& f) {
+ return !f;
+}
+template <typename Promise>
+bool operator!=(const future_impl<Promise>& f, decltype(nullptr)) {
+ return !!f;
+}
+template <typename Promise>
+bool operator!=(decltype(nullptr), const future_impl<Promise>& f) {
+ return !!f;
+}
+
+// Makes a future containing the specified promise.
+template <typename Promise>
+future_impl<Promise> make_future(Promise promise) {
+ return future_impl<Promise>(std::move(promise));
+}
+
+// A pending task holds a |fit::promise| that can be scheduled to run on
+// a |fit::executor| using |fit::executor::schedule_task()|.
+//
+// An executor repeatedly invokes a pending task until it returns true,
+// indicating completion. Note that the promise's resulting value or error
+// is discarded since it is not meaningful to the executor. If you need
+// to consume the result, use a combinator such as |fit::pending::then()|
+// to capture it prior to wrapping the promise into a pending task.
+//
+// See documentation of |fit::promise| for more information.
+class pending_task final {
+ public:
+ // The type of promise held by this task.
+ using promise_type = promise<void, void>;
+
+ // Creates an empty pending task without a promise.
+ pending_task() = default;
+
+ // Creates a pending task that wraps an already boxed promise that returns
+ // |fit::result<void, void>|.
+ pending_task(promise_type promise) : promise_(std::move(promise)) {}
+
+ // Creates a pending task that wraps any kind of promise, boxed or unboxed,
+ // regardless of its result type and with any context that is assignable
+ // from this task's context type.
+ template <typename Continuation>
+ pending_task(promise_impl<Continuation> promise)
+ : promise_(promise ? promise.discard_result().box() : promise_type()) {}
+
+ pending_task(pending_task&&) = default;
+ pending_task& operator=(pending_task&&) = default;
+
+ // Destroys the pending task, releasing its promise.
+ ~pending_task() = default;
+
+ // Returns true if the pending task is non-empty (has a valid promise).
+ explicit operator bool() const { return !!promise_; }
+
+ // Evaluates the pending task.
+ // If the task completes (returns a non-pending result), the task reverts
+ // to an empty state (because the promise it holds has reverted to an empty
+ // state) and returns true.
+ // It is an error to invoke this method if the pending task is empty.
+ bool operator()(fit::context& context) { return !promise_(context).is_pending(); }
+
+ // Extracts the pending task's promise.
+ promise_type take_promise() { return std::move(promise_); }
+
+ pending_task(const pending_task&) = delete;
+ pending_task& operator=(const pending_task&) = delete;
+
+ private:
+ promise_type promise_;
+};
+
+// Execution context for an asynchronous task, such as a |fit::promise|,
+// |fit::future|, or |fit::pending_task|.
+//
+// When a |fit::executor| executes a task, it provides the task with an
+// execution context which enables the task to communicate with the
+// executor and manage its own lifecycle. Specialized executors may subclass
+// |fit::context| and offer additional methods beyond those which are
+// defined here, such as to provide access to platform-specific features
+// supported by the executor.
+//
+// The context provided to a task is only valid within the scope of a single
+// invocation; the task must not retain a reference to the context across
+// invocations.
+//
+// See documentation of |fit::promise| for more information.
+class context {
+ public:
+ // Gets the executor that is running the task, never null.
+ virtual class executor* executor() const = 0;
+
+ // Obtains a handle that can be used to resume the task after it has been
+ // suspended.
+ //
+ // Clients should call this method before returning |fit::pending()| from
+ // the task. See documentation on |fit::executor|.
+ virtual suspended_task suspend_task() = 0;
+
+ // Converts this context to a derived context type.
+ template <typename Context, typename = std::enable_if_t<std::is_base_of<context, Context>::value>>
+ Context& as() & {
+ // TODO(CP-163): We should perform a run-time type check here rather
+ // than blindly casting. That's why this method exists.
+ return static_cast<Context&>(*this);
+ }
+
+ protected:
+ virtual ~context() = default;
+};
+
+// An abstract interface for executing asynchronous tasks, such as promises,
+// represented by |fit::pending_task|.
+//
+// EXECUTING TASKS
+//
+// An executor evaluates its tasks incrementally. During each iteration
+// of the executor's main loop, it invokes the next task from its ready queue.
+//
+// If the task returns true, then the task is deemed to have completed.
+// The executor removes the tasks from its queue and destroys it since there
+// it nothing left to do.
+//
+// If the task returns false, then the task is deemed to have voluntarily
+// suspended itself pending some event that it is awaiting. Prior to
+// returning, the task should acquire at least one |fit::suspended_task|
+// handle from its execution context using |fit::context::suspend_task()|
+// to provide a means for the task to be resumed once it can make forward
+// progress again.
+//
+// Once the suspended task is resumed with |fit::suspended_task::resume()|, it
+// is moved back to the ready queue and it will be invoked again during a later
+// iteration of the executor's loop.
+//
+// If all |fit::suspended_task| handles for a given task are destroyed without
+// the task ever being resumed then the task is also destroyed since there
+// would be no way for the task to be resumed from suspension. We say that
+// such a task has been "abandoned".
+//
+// The executor retains single-ownership of all active and suspended tasks.
+// When the executor is destroyed, all of its remaining tasks are also
+// destroyed.
+//
+// Please read |fit::promise| for a more detailed explanation of the
+// responsibilities of tasks and executors.
+//
+// NOTES FOR IMPLEMENTORS
+//
+// This interface is designed to support a variety of different executor
+// implementations. For example, one implementation might run its tasks on
+// a single thread whereas another might dispatch them on an event-driven
+// message loop or use a thread pool.
+//
+// See also |fit::single_threaded_executor| for a concrete implementation.
+class executor {
+ public:
+ // Destroys the executor along with all of its remaining scheduled tasks
+ // that have yet to complete.
+ virtual ~executor() = default;
+
+ // Schedules a task for eventual execution by the executor.
+ //
+ // This method is thread-safe.
+ virtual void schedule_task(pending_task task) = 0;
+};
+
+// Represents a task that is awaiting resumption.
+//
+// This object has RAII semantics. If the task is not resumed by at least
+// one holder of its |suspended_task| handles, then it will be destroyed
+// by the executor since it is no longer possible for the task to make
+// progress. The task is said have been "abandoned".
+//
+// See documentation of |fit::executor| for more information.
+class suspended_task final {
+ public:
+ // A handle that grants the capability to resume a suspended task.
+ // Each issued ticket must be individually resolved.
+ using ticket = uint64_t;
+
+ // The resolver mechanism implements a lightweight form of reference
+ // counting for tasks that have been suspended.
+ //
+ // When a suspended task is created in a non-empty state, it receives
+ // a pointer to a resolver interface and a ticket. The ticket is
+ // a one-time-use handle that represents the task that was suspended
+ // and provides a means to resume it. The |suspended_task| class ensures
+ // that every ticket is precisely accounted for.
+ //
+ // When |suspended_task::resume_task()| is called on an instance with
+ // a valid ticket, the resolver's |resolve_ticket()| method is invoked
+ // passing the ticket's value along with *true* to resume the task. This
+ // operation consumes the ticket so the |suspended_task| transitions to
+ // an empty state. The ticket and resolver cannot be used again by
+ // this |suspended_task| instance.
+ //
+ // Similarly, when |suspended_task::reset()| is called on an instance with
+ // a valid ticket or when the task goes out of scope on such an instance,
+ // the resolver's |resolve_ticket()| method is invoked but this time passes
+ // *false* to not resume the task. As before, the ticket is consumed.
+ //
+ // Finally, when the |suspended_task| is copied, its ticket is duplicated
+ // using |duplicate_ticket()| resulting in two tickets, both of which
+ // must be individually resolved.
+ //
+ // Resuming a task that has already been resumed has no effect.
+ // Conversely, a task is considered "abandoned" if all of its tickets
+ // have been resolved without it ever being resumed. See documentation
+ // of |fit::promise| for more information.
+ //
+ // The methods of this class are safe to call from any thread, including
+ // threads that may not be managed by the task's executor.
+ class resolver {
+ public:
+ // Duplicates the provided ticket, returning a new ticket.
+ // Note: The new ticket may have the same numeric value as the
+ // original ticket but should be considered a distinct instance
+ // that must be separately resolved.
+ virtual ticket duplicate_ticket(ticket ticket) = 0;
+
+ // Consumes the provided ticket, optionally resuming its associated task.
+ // The provided ticket must not be used again.
+ virtual void resolve_ticket(ticket ticket, bool resume_task) = 0;
+
+ protected:
+ virtual ~resolver() = default;
+ };
+
+ suspended_task() : resolver_(nullptr), ticket_(0) {}
+
+ suspended_task(resolver* resolver, ticket ticket) : resolver_(resolver), ticket_(ticket) {}
+
+ suspended_task(const suspended_task& other);
+ suspended_task(suspended_task&& other);
+
+ // Releases the task without resumption.
+ //
+ // Does nothing if this object does not hold a ticket.
+ ~suspended_task();
+
+ // Returns true if this object holds a ticket for a suspended task.
+ explicit operator bool() const { return resolver_ != nullptr; }
+
+ // Asks the task's executor to resume execution of the suspended task
+ // if it has not already been resumed or completed. Also releases
+ // the task's ticket as a side-effect.
+ //
+ // Clients should call this method when it is possible for the task to
+ // make progress; for example, because some event the task was
+ // awaiting has occurred. See documentation on |fit::executor|.
+ //
+ // Does nothing if this object does not hold a ticket.
+ void resume_task() { resolve(true); }
+
+ // Releases the suspended task without resumption.
+ //
+ // Does nothing if this object does not hold a ticket.
+ void reset() { resolve(false); }
+
+ // Swaps suspended tasks.
+ void swap(suspended_task& other);
+
+ suspended_task& operator=(const suspended_task& other);
+ suspended_task& operator=(suspended_task&& other);
+
+ private:
+ void resolve(bool resume_task);
+
+ resolver* resolver_;
+ ticket ticket_;
+};
+
+inline void swap(suspended_task& a, suspended_task& b) { a.swap(b); }
+
+} // namespace fit
+
+#endif // LIB_FIT_PROMISE_H_
diff --git a/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/promise_internal.h b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/promise_internal.h
new file mode 100644
index 0000000..01b7750
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/promise_internal.h
@@ -0,0 +1,699 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIT_PROMISE_INTERNAL_H_
+#define LIB_FIT_PROMISE_INTERNAL_H_
+
+#include <assert.h>
+
+#include <tuple>
+#include <type_traits>
+#include <utility>
+
+#include "function.h"
+#include "nullable.h"
+#include "result.h"
+#include "traits.h"
+#include "utility_internal.h"
+
+namespace fit {
+
+template <typename Continuation>
+class promise_impl;
+
+template <typename Promise>
+class future_impl;
+
+class context;
+class executor;
+class suspended_task;
+
+namespace internal {
+
+// Determines whether a type is a kind of fit::result.
+template <typename Result>
+struct is_result : std::false_type {};
+template <typename V, typename E>
+struct is_result<::fit::result<V, E>> : std::true_type {};
+
+// Deduces a continuation's result.
+// Also ensures that the continuation has a compatible signature.
+template <typename Continuation,
+ typename = std::enable_if_t<is_result<decltype(
+ std::declval<Continuation&>()(std::declval<::fit::context&>()))>::value>>
+struct continuation_traits {
+ using type = Continuation;
+ using result_type = decltype(std::declval<Continuation&>()(std::declval<::fit::context&>()));
+};
+template <typename Continuation, typename = fit::void_t<>>
+struct is_continuation : std::false_type {};
+template <typename Continuation>
+struct is_continuation<Continuation, fit::void_t<typename continuation_traits<Continuation>::type>>
+ : std::true_type {};
+
+// Interposer type that provides uniform move construction/assignment for
+// callable types that may or may not be move assignable. Lambdas are not
+// typically move assignable, even though they may be move constructible.
+//
+// This type has a well-defined empty state. Instances of this type that are
+// the source of move operation are left in the empty state.
+template <typename Handler>
+class movable_handler {
+ static_assert(std::is_move_constructible<Handler>::value, "Handler must be move constructible!");
+
+ template <typename... Conditions>
+ using requires_conditions = ::fit::internal::requires_conditions<Conditions...>;
+
+ template <typename... Conditions>
+ using assignment_requires_conditions =
+ ::fit::internal::assignment_requires_conditions<movable_handler&, Conditions...>;
+
+ template <typename U>
+ using not_self_type = ::fit::internal::not_same_type<movable_handler, U>;
+
+ public:
+ constexpr movable_handler() = default;
+
+ constexpr movable_handler(const movable_handler&) = delete;
+ constexpr movable_handler& operator=(const movable_handler&) = delete;
+
+ constexpr movable_handler(movable_handler&& other) : handler_{std::move(other.handler_)} {
+ other.handler_.reset();
+ }
+
+ constexpr movable_handler& operator=(movable_handler&& other) {
+ if (this != &other) {
+ reset();
+ if (other.handler_.has_value()) {
+ handler_.emplace(std::move(other.handler_.value()));
+ other.handler_.reset();
+ }
+ }
+ return *this;
+ }
+
+ template <typename U = Handler,
+ requires_conditions<not_self_type<U>, std::is_constructible<Handler, U&&>,
+ std::is_convertible<U&&, Handler>> = true>
+ constexpr movable_handler(U&& handler) {
+ if (!is_null(handler)) {
+ handler_.emplace(std::forward<U>(handler));
+ }
+ }
+
+ ~movable_handler() = default;
+
+ template <typename U>
+ constexpr assignment_requires_conditions<not_self_type<U>, std::is_constructible<Handler, U>,
+ std::is_assignable<Handler&, U>>
+ operator=(U&& handler) {
+ handler_.reset();
+ if (!is_null(handler)) {
+ handler_.emplace(std::forward<U>(handler));
+ }
+ return *this;
+ }
+
+ template <typename... Args>
+ constexpr auto operator()(Args&&... args) {
+ // Seamlessly handle void by casting call expression to return type.
+ using Return = typename callable_traits<Handler>::return_type;
+ return static_cast<Return>((handler_.value())(std::forward<Args>(args)...));
+ }
+
+ explicit constexpr operator bool() const { return handler_.has_value(); }
+
+ constexpr void reset() { handler_.reset(); }
+
+ private:
+ optional<Handler> handler_;
+};
+
+// Wraps a handler function and adapts its return type to a fit::result
+// via its specializations.
+template <typename Handler, typename DefaultV, typename DefaultE,
+ typename ReturnType = typename callable_traits<Handler>::return_type,
+ bool callable_result = ::fit::is_callable<ReturnType>::value>
+class result_adapter final {
+ // This expression always evaluates to false but depends on the template
+ // type parameters so that it only gets evaluated when the template is
+ // expanded. If we simply wrote "false", the compiler would raise the
+ // static assertion failure as soon as it encountered the statement.
+ template <typename T>
+ struct check_result {
+ static constexpr bool value = false;
+ };
+ static_assert(check_result<ReturnType>::value,
+ "The provided handler's result type was expected to be "
+ "fit::result<V, E>, fit::ok_result<V>, fit::error_result<E>, "
+ "fit::pending_result, void, or a continuation with the signature "
+ "fit::result<V, E>(fit::context&). "
+ "Please refer to the combinator's documentation for a list of "
+ "supported handler function signatures.");
+};
+
+// Supports handlers that return void.
+template <typename Handler, typename DefaultV, typename DefaultE>
+class result_adapter<Handler, DefaultV, DefaultE, void, false> final {
+ public:
+ using result_type = ::fit::result<DefaultV, DefaultE>;
+
+ explicit result_adapter(Handler handler) : handler_(std::move(handler)) {}
+
+ template <typename... Args>
+ result_type call(::fit::context& context, Args... args) {
+ handler_(std::forward<Args>(args)...);
+ return ::fit::ok();
+ }
+
+ result_adapter(const result_adapter&) = delete;
+ result_adapter& operator=(const result_adapter&) = delete;
+
+ result_adapter(result_adapter&&) = default;
+ result_adapter& operator=(result_adapter&&) = default;
+
+ private:
+ movable_handler<Handler> handler_;
+};
+
+// Supports handlers that return pending_result.
+template <typename Handler, typename DefaultV, typename DefaultE>
+class result_adapter<Handler, DefaultV, DefaultE, ::fit::pending_result, false> final {
+ public:
+ using result_type = ::fit::result<DefaultV, DefaultE>;
+
+ explicit result_adapter(movable_handler<Handler> handler) : handler_(std::move(handler)) {}
+
+ template <typename... Args>
+ result_type call(::fit::context& context, Args... args) {
+ return handler_(std::forward<Args>(args)...);
+ }
+
+ result_adapter(const result_adapter&) = delete;
+ result_adapter& operator=(const result_adapter&) = delete;
+
+ result_adapter(result_adapter&&) = default;
+ result_adapter& operator=(result_adapter&&) = default;
+
+ private:
+ movable_handler<Handler> handler_;
+};
+
+// Supports handlers that return ok_result<V>.
+template <typename Handler, typename DefaultV, typename DefaultE, typename V>
+class result_adapter<Handler, DefaultV, DefaultE, ::fit::ok_result<V>, false> final {
+ public:
+ using result_type = ::fit::result<V, DefaultE>;
+
+ explicit result_adapter(movable_handler<Handler> handler) : handler_(std::move(handler)) {}
+
+ template <typename... Args>
+ result_type call(::fit::context& context, Args... args) {
+ return handler_(std::forward<Args>(args)...);
+ }
+
+ result_adapter(const result_adapter&) = delete;
+ result_adapter& operator=(const result_adapter&) = delete;
+
+ result_adapter(result_adapter&&) = default;
+ result_adapter& operator=(result_adapter&&) = default;
+
+ private:
+ movable_handler<Handler> handler_;
+};
+
+// Supports handlers that return error_result<E>.
+template <typename Handler, typename DefaultV, typename DefaultE, typename E>
+class result_adapter<Handler, DefaultV, DefaultE, ::fit::error_result<E>, false> final {
+ public:
+ using result_type = ::fit::result<DefaultV, E>;
+
+ explicit result_adapter(movable_handler<Handler> handler) : handler_(std::move(handler)) {}
+
+ template <typename... Args>
+ result_type call(::fit::context& context, Args... args) {
+ return handler_(std::forward<Args>(args)...);
+ }
+
+ result_adapter(const result_adapter&) = delete;
+ result_adapter& operator=(const result_adapter&) = delete;
+
+ result_adapter(result_adapter&&) = default;
+ result_adapter& operator=(result_adapter&&) = default;
+
+ private:
+ movable_handler<Handler> handler_;
+};
+
+// Supports handlers that return result<V, E>.
+template <typename Handler, typename DefaultV, typename DefaultE, typename V, typename E>
+class result_adapter<Handler, DefaultV, DefaultE, ::fit::result<V, E>, false> final {
+ public:
+ using result_type = ::fit::result<V, E>;
+
+ explicit result_adapter(movable_handler<Handler> handler) : handler_(std::move(handler)) {}
+
+ template <typename... Args>
+ result_type call(::fit::context& context, Args... args) {
+ return handler_(std::forward<Args>(args)...);
+ }
+
+ result_adapter(const result_adapter&) = delete;
+ result_adapter& operator=(const result_adapter&) = delete;
+
+ result_adapter(result_adapter&&) = default;
+ result_adapter& operator=(result_adapter&&) = default;
+
+ private:
+ movable_handler<Handler> handler_;
+};
+
+// Supports handlers that return continuations or promises.
+// This works for any callable whose signature is:
+// fit::result<...>(fit::context&)
+template <typename Handler, typename DefaultV, typename DefaultE, typename ReturnType>
+class result_adapter<Handler, DefaultV, DefaultE, ReturnType, true> final {
+ // If the handler doesn't actually return a continuation then the
+ // compilation will fail here which is slightly easier to diagnose
+ // than if we dropped the result_adapter specialization entirely.
+ using result_continuation_traits = continuation_traits<ReturnType>;
+ using continuation_type = typename result_continuation_traits::type;
+
+ public:
+ using result_type = typename result_continuation_traits::result_type;
+
+ explicit result_adapter(movable_handler<Handler> handler) : handler_(std::move(handler)) {}
+
+ template <typename... Args>
+ result_type call(::fit::context& context, Args... args) {
+ if (handler_) {
+ continuation_ = handler_(std::forward<Args>(args)...);
+ handler_.reset();
+ }
+ if (!continuation_) {
+ return ::fit::pending();
+ }
+ return continuation_(context);
+ }
+
+ result_adapter(const result_adapter&) = delete;
+ result_adapter& operator=(const result_adapter&) = delete;
+
+ result_adapter(result_adapter&&) = default;
+ result_adapter& operator=(result_adapter&&) = default;
+
+ private:
+ movable_handler<Handler> handler_;
+ movable_handler<continuation_type> continuation_;
+};
+
+// Wraps a handler that may or may not have a fit::context& as first argument.
+// This is determined by checking the argument count.
+template <typename Handler, typename DefaultV, typename DefaultE, size_t num_args = 0,
+ int excess_args = (static_cast<int>(::fit::callable_traits<Handler>::args::size) -
+ static_cast<int>(num_args))>
+class context_adapter final {
+ static_assert(excess_args >= 0,
+ "The provided handler has too few arguments. "
+ "Please refer to the combinator's documentation for a list of "
+ "supported handler function signatures.");
+ static_assert(excess_args <= 1,
+ "The provided handler has too many arguments. "
+ "Please refer to the combinator's documentation for a list of "
+ "supported handler function signatures.");
+};
+
+// Supports handlers without a context argument.
+template <typename Handler, typename DefaultV, typename DefaultE, size_t num_args>
+class context_adapter<Handler, DefaultV, DefaultE, num_args, 0> final {
+ using base_type = result_adapter<Handler, DefaultV, DefaultE>;
+
+ public:
+ using result_type = typename base_type::result_type;
+ static constexpr size_t next_arg_index = 0;
+
+ explicit context_adapter(Handler handler) : base_(std::move(handler)) {}
+
+ template <typename... Args>
+ result_type call(::fit::context& context, Args... args) {
+ return base_.template call<Args...>(context, std::forward<Args>(args)...);
+ }
+
+ private:
+ base_type base_;
+};
+
+// Supports handlers with a context argument.
+template <typename Handler, typename DefaultV, typename DefaultE, size_t num_args>
+class context_adapter<Handler, DefaultV, DefaultE, num_args, 1> final {
+ using base_type = result_adapter<Handler, DefaultV, DefaultE>;
+ using context_arg_type = typename ::fit::callable_traits<Handler>::args::template at<0>;
+ static_assert(std::is_same<context_arg_type, ::fit::context&>::value,
+ "The provided handler's first argument was expected to be of type "
+ "fit::context& based on the number of arguments it has. "
+ "Please refer to the combinator's documentation for a list of "
+ "supported handler function signatures.");
+
+ public:
+ using result_type = typename base_type::result_type;
+ static constexpr size_t next_arg_index = 1;
+
+ explicit context_adapter(Handler handler) : base_(std::move(handler)) {}
+
+ template <typename... Args>
+ result_type call(::fit::context& context, Args... args) {
+ return base_.template call<::fit::context&, Args...>(context, context,
+ std::forward<Args>(args)...);
+ }
+
+ private:
+ base_type base_;
+};
+
+// Wraps a handler that may accept a context argument.
+template <typename Handler>
+class context_handler_invoker final {
+ using base_type = context_adapter<Handler, void, void, 0>;
+
+ public:
+ using result_type = typename base_type::result_type;
+
+ explicit context_handler_invoker(Handler handler) : base_(std::move(handler)) {}
+
+ result_type operator()(::fit::context& context) { return base_.template call<>(context); }
+
+ private:
+ base_type base_;
+};
+
+// Wraps a handler that may accept a context and result argument.
+template <typename Handler, typename PriorResult>
+class result_handler_invoker final {
+ using base_type = context_adapter<Handler, void, void, 1>;
+ using result_arg_type =
+ typename ::fit::callable_traits<Handler>::args::template at<base_type::next_arg_index>;
+ static_assert(std::is_same<result_arg_type, PriorResult&>::value ||
+ std::is_same<result_arg_type, const PriorResult&>::value,
+ "The provided handler's last argument was expected to be of type "
+ "fit::result<V, E>& or const fit::result<V, E>& where V is the prior "
+ "result's value type and E is the prior result's error type. "
+ "Please refer to the combinator's documentation for a list of "
+ "supported handler function signatures.");
+
+ public:
+ using result_type = typename base_type::result_type;
+
+ explicit result_handler_invoker(Handler handler) : base_(std::move(handler)) {}
+
+ result_type operator()(::fit::context& context, PriorResult& result) {
+ return base_.template call<PriorResult&>(context, result);
+ }
+
+ private:
+ base_type base_;
+};
+
+// Wraps a handler that may accept a context and value argument.
+template <typename Handler, typename PriorResult, typename V = typename PriorResult::value_type>
+class value_handler_invoker final {
+ using base_type = context_adapter<Handler, void, typename PriorResult::error_type, 1>;
+ using value_arg_type =
+ typename ::fit::callable_traits<Handler>::args::template at<base_type::next_arg_index>;
+ static_assert(std::is_same<value_arg_type, V&>::value ||
+ std::is_same<value_arg_type, const V&>::value,
+ "The provided handler's last argument was expected to be of type "
+ "V& or const V& where V is the prior result's value type. "
+ "Please refer to the combinator's documentation for a list of "
+ "supported handler function signatures.");
+
+ public:
+ using result_type = typename base_type::result_type;
+
+ explicit value_handler_invoker(Handler handler) : base_(std::move(handler)) {}
+
+ result_type operator()(::fit::context& context, PriorResult& result) {
+ return base_.template call<V&>(context, result.value());
+ }
+
+ private:
+ base_type base_;
+};
+
+// Specialization for void value.
+template <typename Handler, typename PriorResult>
+class value_handler_invoker<Handler, PriorResult, void> final {
+ using base_type = context_adapter<Handler, void, typename PriorResult::error_type, 0>;
+
+ public:
+ using result_type = typename base_type::result_type;
+
+ explicit value_handler_invoker(Handler handler) : base_(std::move(handler)) {}
+
+ result_type operator()(::fit::context& context, PriorResult& result) {
+ return base_.template call<>(context);
+ }
+
+ private:
+ base_type base_;
+};
+
+// Wraps a handler that may accept a context and error argument.
+template <typename Handler, typename PriorResult, typename E = typename PriorResult::error_type>
+class error_handler_invoker final {
+ using base_type = context_adapter<Handler, typename PriorResult::value_type, void, 1>;
+ using error_arg_type =
+ typename ::fit::callable_traits<Handler>::args::template at<base_type::next_arg_index>;
+ static_assert(std::is_same<error_arg_type, E&>::value ||
+ std::is_same<error_arg_type, const E&>::value,
+ "The provided handler's last argument was expected to be of type "
+ "E& or const E& where E is the prior result's error type. "
+ "Please refer to the combinator's documentation for a list of "
+ "supported handler function signatures.");
+
+ public:
+ using result_type = typename base_type::result_type;
+
+ explicit error_handler_invoker(Handler handler) : base_(std::move(handler)) {}
+
+ result_type operator()(::fit::context& context, PriorResult& result) {
+ return base_.template call<E&>(context, result.error());
+ }
+
+ private:
+ base_type base_;
+};
+
+// Specialization for void error.
+template <typename Handler, typename PriorResult>
+class error_handler_invoker<Handler, PriorResult, void> final {
+ using base_type = context_adapter<Handler, typename PriorResult::value_type, void, 0>;
+
+ public:
+ using result_type = typename base_type::result_type;
+
+ explicit error_handler_invoker(Handler handler) : base_(std::move(handler)) {}
+
+ result_type operator()(::fit::context& context, PriorResult& result) {
+ return base_.template call<>(context);
+ }
+
+ private:
+ base_type base_;
+};
+
+// The continuation produced by |fit::promise::then()|.
+template <typename PriorPromise, typename ResultHandler>
+class then_continuation final {
+ using invoker_type =
+ ::fit::internal::result_handler_invoker<ResultHandler, typename PriorPromise::result_type>;
+
+ public:
+ then_continuation(PriorPromise prior_promise, ResultHandler handler)
+ : prior_(std::move(prior_promise)), invoker_(std::move(handler)) {}
+
+ typename invoker_type::result_type operator()(::fit::context& context) {
+ if (!prior_(context))
+ return ::fit::pending();
+ return invoker_(context, prior_.result());
+ }
+
+ private:
+ future_impl<PriorPromise> prior_;
+ invoker_type invoker_;
+};
+
+// The continuation produced by |fit::promise::and_then()|.
+template <typename PriorPromise, typename ValueHandler>
+class and_then_continuation final {
+ using invoker_type =
+ ::fit::internal::value_handler_invoker<ValueHandler, typename PriorPromise::result_type>;
+
+ public:
+ and_then_continuation(PriorPromise prior_promise, ValueHandler handler)
+ : prior_(std::move(prior_promise)), invoker_(std::move(handler)) {}
+
+ typename invoker_type::result_type operator()(::fit::context& context) {
+ if (!prior_(context))
+ return ::fit::pending();
+ if (prior_.is_error())
+ return prior_.take_error_result();
+ return invoker_(context, prior_.result());
+ }
+
+ private:
+ future_impl<PriorPromise> prior_;
+ invoker_type invoker_;
+};
+
+// The continuation produced by |fit::promise::or_else()|.
+template <typename PriorPromise, typename ErrorHandler>
+class or_else_continuation final {
+ using invoker_type =
+ ::fit::internal::error_handler_invoker<ErrorHandler, typename PriorPromise::result_type>;
+
+ public:
+ or_else_continuation(PriorPromise prior_promise, ErrorHandler handler)
+ : prior_(std::move(prior_promise)), invoker_(std::move(handler)) {}
+
+ typename invoker_type::result_type operator()(::fit::context& context) {
+ if (!prior_(context))
+ return ::fit::pending();
+ if (prior_.is_ok())
+ return prior_.take_ok_result();
+ return invoker_(context, prior_.result());
+ }
+
+ private:
+ future_impl<PriorPromise> prior_;
+ invoker_type invoker_;
+};
+
+// The continuation produced by |fit::promise::inspect()|.
+template <typename PriorPromise, typename InspectHandler>
+class inspect_continuation final {
+ using invoker_type =
+ ::fit::internal::result_handler_invoker<InspectHandler, typename PriorPromise::result_type>;
+
+ public:
+ inspect_continuation(PriorPromise prior_promise, InspectHandler handler)
+ : prior_(std::move(prior_promise)), invoker_(std::move(handler)) {}
+
+ typename PriorPromise::result_type operator()(::fit::context& context) {
+ typename PriorPromise::result_type result = prior_(context);
+ if (result)
+ invoker_(context, result);
+ return result;
+ }
+
+ private:
+ PriorPromise prior_;
+ invoker_type invoker_;
+};
+
+// The continuation produced by |fit::promise::discard_result()|.
+template <typename PriorPromise>
+class discard_result_continuation final {
+ public:
+ explicit discard_result_continuation(PriorPromise prior_promise)
+ : prior_(std::move(prior_promise)) {}
+
+ fit::result<> operator()(::fit::context& context) {
+ if (!prior_(context))
+ return ::fit::pending();
+ return ::fit::ok();
+ }
+
+ private:
+ PriorPromise prior_;
+};
+
+// The continuation produced by |make_promise()|.
+// This turns out to be equivalent to a context handler invoker.
+template <typename PromiseHandler>
+using promise_continuation = context_handler_invoker<PromiseHandler>;
+
+// The continuation produced by |make_result_promise()|.
+template <typename V, typename E>
+class result_continuation final {
+ public:
+ explicit result_continuation(::fit::result<V, E> result) : result_(std::move(result)) {}
+
+ ::fit::result<V, E> operator()(::fit::context& context) { return std::move(result_); }
+
+ private:
+ ::fit::result<V, E> result_;
+};
+
+// Returns true if all arguments are true or if there are none.
+inline bool all_true() { return true; }
+template <typename... Ts>
+inline bool all_true(bool value, Ts... values) {
+ return value & all_true(values...);
+}
+
+// The continuation produced by |join_promises()|.
+template <typename... Promises>
+class join_continuation final {
+ public:
+ explicit join_continuation(Promises... promises)
+ : promises_(std::make_tuple(std::move(promises)...)) {}
+
+ ::fit::result<std::tuple<typename Promises::result_type...>> operator()(::fit::context& context) {
+ return evaluate(context, std::index_sequence_for<Promises...>{});
+ }
+
+ private:
+ template <size_t... i>
+ ::fit::result<std::tuple<typename Promises::result_type...>> evaluate(::fit::context& context,
+ std::index_sequence<i...>) {
+ bool done = all_true(std::get<i>(promises_)(context)...);
+ if (!done)
+ return ::fit::pending();
+ return ::fit::ok(std::make_tuple(std::get<i>(promises_).take_result()...));
+ }
+
+ std::tuple<future_impl<Promises>...> promises_;
+};
+
+// The continuation produced by |join_promise_vector()|.
+template <typename Promise>
+class join_vector_continuation final {
+ using promise_vector = std::vector<Promise>;
+ using result_vector = std::vector<typename Promise::result_type>;
+
+ public:
+ explicit join_vector_continuation(promise_vector promises)
+ : promises_(std::move(promises)), results_(promises_.size()) {}
+
+ ::fit::result<result_vector> operator()(::fit::context& context) {
+ bool all_done{true};
+ for (size_t i = 0; i < promises_.size(); ++i) {
+ if (!results_[i]) {
+ results_[i] = promises_[i](context);
+ all_done &= !results_[i].is_pending();
+ }
+ }
+ if (all_done) {
+ return fit::ok(std::move(results_));
+ }
+ return ::fit::pending();
+ }
+
+ private:
+ promise_vector promises_;
+ result_vector results_;
+};
+
+} // namespace internal
+
+template <typename PromiseHandler>
+inline promise_impl<::fit::internal::promise_continuation<PromiseHandler>> make_promise(
+ PromiseHandler handler);
+
+template <typename Continuation>
+inline promise_impl<Continuation> make_promise_with_continuation(Continuation continuation);
+
+} // namespace fit
+
+#endif // LIB_FIT_PROMISE_INTERNAL_H_
diff --git a/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/result.h b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/result.h
new file mode 100644
index 0000000..cb64ea7
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/result.h
@@ -0,0 +1,244 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIT_RESULT_H_
+#define LIB_FIT_RESULT_H_
+
+#include <assert.h>
+
+#include <new>
+#include <type_traits>
+#include <utility>
+
+#include "in_place_internal.h"
+#include "traits.h"
+#include "variant.h"
+
+namespace fit {
+
+// Represents the intermediate state of a result that has not yet completed.
+struct pending_result final {};
+
+// Returns an value that represents a pending result.
+constexpr inline pending_result pending() { return pending_result{}; }
+
+// Represents the result of a successful task.
+template <typename V = void>
+struct ok_result final {
+ using value_type = V;
+
+ explicit constexpr ok_result(V value) : value(std::move(value)) {}
+
+ V value;
+};
+template <>
+struct ok_result<void> {
+ using value_type = void;
+};
+
+// Wraps the result of a successful task as an |ok_result<T>|.
+template <typename V>
+constexpr inline ok_result<V> ok(V value) {
+ return ok_result<V>(std::move(value));
+}
+constexpr inline ok_result<> ok() { return ok_result<>{}; }
+
+// Represents the result of a failed task.
+template <typename E = void>
+struct error_result final {
+ using error_type = E;
+
+ explicit constexpr error_result(E error) : error(std::move(error)) {}
+
+ E error;
+};
+template <>
+struct error_result<void> {
+ using error_type = void;
+};
+
+// Wraps the result of a failed task as an |error_result<T>|.
+template <typename E>
+constexpr inline error_result<E> error(E error) {
+ return error_result<E>(std::move(error));
+}
+constexpr inline error_result<> error() { return error_result<>{}; }
+
+// Describes the status of a task's result.
+enum class result_state {
+ // The task is still in progress.
+ pending,
+ // The task completed successfully.
+ ok,
+ // The task failed.
+ error
+};
+
+// Represents the result of a task which may have succeeded, failed,
+// or still be in progress.
+//
+// Use |fit::pending()|, |fit::ok<T>()|, or |fit::error<T>| to initialize
+// the result.
+//
+// |V| is the type of value produced when the completes successfully.
+// Defaults to |void|.
+//
+// |E| is the type of error produced when the completes with an error.
+// Defaults to |void|.
+//
+// EXAMPLE:
+//
+// fit::result<int, std::string> divide(int dividend, int divisor) {
+// if (divisor == 0)
+// return fit::error<std::string>("divide by zero");
+// return fit::ok(dividend / divisor);
+// }
+//
+// int try_divide(int dividend, int divisor) {
+// auto result = divide(dividend, divisor);
+// if (result.is_ok()) {
+// printf("%d / %d = %d\n", dividend, divisor, result.value());
+// return result.value();
+// }
+// printf("%d / %d: ERROR %s\n", dividend, divisor, result.error().c_str());
+// return -999;
+// }
+//
+// EXAMPLE WITH VOID RESULT VALUE AND ERROR:
+//
+// fit::result<> open(std::string secret) {
+// printf("guessing \"%s\"\n", secret.c_str());
+// if (secret == "sesame") {
+// return fit::ok();
+// puts("yes!");
+// }
+// puts("no.");
+// return fit::error();
+// }
+//
+// bool guess_combination() {
+// return open("friend") || open("sesame") || open("I give up");
+// }
+template <typename V = void, typename E = void>
+class result final {
+ public:
+ using value_type = V;
+ using error_type = E;
+
+ // Creates a pending result.
+ constexpr result() = default;
+ constexpr result(pending_result) {}
+
+ // Creates an ok result.
+ constexpr result(ok_result<V> result) : state_(in_place_index<1>, std::move(result)) {}
+ template <typename OtherV, typename = std::enable_if_t<std::is_constructible<V, OtherV>::value>>
+ constexpr result(ok_result<OtherV> other)
+ : state_(in_place_index<1>, fit::ok<V>(std::move(other.value))) {}
+
+ // Creates an error result.
+ constexpr result(error_result<E> result) : state_(in_place_index<2>, std::move(result)) {}
+ template <typename OtherE, typename = std::enable_if_t<std::is_constructible<E, OtherE>::value>>
+ constexpr result(error_result<OtherE> other)
+ : state_(in_place_index<2>, fit::error<E>(std::move(other.error))) {}
+
+ // Copies another result (if copyable).
+ result(const result& other) = default;
+
+ // Moves from another result, leaving the other one in a pending state.
+ result(result&& other) noexcept : state_(std::move(other.state_)) { other.reset(); }
+
+ ~result() = default;
+
+ // Returns the state of the task's result: pending, ok, or error.
+ constexpr result_state state() const { return static_cast<result_state>(state_.index()); }
+
+ // Returns true if the result is not pending.
+ constexpr explicit operator bool() const { return !is_pending(); }
+
+ // Returns true if the task is still in progress.
+ constexpr bool is_pending() const { return state() == result_state::pending; }
+
+ // Returns true if the task succeeded.
+ constexpr bool is_ok() const { return state() == result_state::ok; }
+
+ // Returns true if the task failed.
+ constexpr bool is_error() const { return state() == result_state::error; }
+
+ // Gets the result's value.
+ // Asserts that the result's state is |fit::result_state::ok|.
+ template <typename R = V, typename = std::enable_if_t<!std::is_void<R>::value>>
+ constexpr R& value() {
+ return state_.template get<1>().value;
+ }
+ template <typename R = V, typename = std::enable_if_t<!std::is_void<R>::value>>
+ constexpr const R& value() const {
+ return state_.template get<1>().value;
+ }
+
+ // Takes the result's value, leaving it in a pending state.
+ // Asserts that the result's state is |fit::result_state::ok|.
+ template <typename R = V, typename = std::enable_if_t<!std::is_void<R>::value>>
+ R take_value() {
+ auto value = std::move(state_.template get<1>().value);
+ reset();
+ return value;
+ }
+ ok_result<V> take_ok_result() {
+ auto result = std::move(state_.template get<1>());
+ reset();
+ return result;
+ }
+
+ // Gets a reference to the result's error.
+ // Asserts that the result's state is |fit::result_state::error|.
+ template <typename R = E, typename = std::enable_if_t<!std::is_void<R>::value>>
+ constexpr R& error() {
+ return state_.template get<2>().error;
+ }
+ template <typename R = E, typename = std::enable_if_t<!std::is_void<R>::value>>
+ constexpr const R& error() const {
+ return state_.template get<2>().error;
+ }
+
+ // Takes the result's error, leaving it in a pending state.
+ // Asserts that the result's state is |fit::result_state::error|.
+ template <typename R = E, typename = std::enable_if_t<!std::is_void<R>::value>>
+ R take_error() {
+ auto error = std::move(state_.template get<2>().error);
+ reset();
+ return error;
+ }
+ error_result<E> take_error_result() {
+ auto result = std::move(state_.template get<2>());
+ reset();
+ return result;
+ }
+
+ // Assigns from another result (if copyable).
+ result& operator=(const result& other) = default;
+
+ // Moves from another result, leaving the other one in a pending state.
+ result& operator=(result&& other) {
+ state_ = std::move(other.state_);
+ other.reset();
+ return *this;
+ }
+
+ // Swaps results.
+ void swap(result& other) { state_.swap(other.state_); }
+
+ private:
+ void reset() { state_.template emplace<0>(); }
+
+ variant<monostate, ok_result<V>, error_result<E>> state_;
+};
+
+template <typename V, typename E>
+void swap(result<V, E>& a, result<V, E>& b) {
+ a.swap(b);
+}
+
+} // namespace fit
+
+#endif // LIB_FIT_RESULT_H_
diff --git a/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/scheduler.h b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/scheduler.h
new file mode 100644
index 0000000..99283e2
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/scheduler.h
@@ -0,0 +1,153 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIT_SCHEDULER_H_
+#define LIB_FIT_SCHEDULER_H_
+
+#include <map>
+#include <queue>
+#include <utility>
+
+#include "promise.h"
+
+namespace fit {
+namespace subtle {
+
+// Keeps track of runnable and suspended tasks.
+// This is a low-level building block for implementing executors.
+// For a concrete implementation, see |fit::single_threaded_executor|.
+//
+// Instances of this object are not thread-safe. Its client is responsible
+// for providing all necessary synchronization.
+class scheduler final {
+ public:
+ using task_queue = std::queue<pending_task>;
+ using ref_count_type = uint32_t;
+
+ scheduler();
+ ~scheduler();
+
+ // Adds a task to the runnable queue.
+ //
+ // Preconditions:
+ // - |task| must be non-empty
+ void schedule_task(pending_task task);
+
+ // Obtains a new ticket with a ref-count of |initial_refs|.
+ // The executor must eventually call |finalize_ticket()| to update the
+ // state of the ticket.
+ //
+ // Preconditions:
+ // - |initial_refs| must be at least 1
+ suspended_task::ticket obtain_ticket(ref_count_type initial_refs = 1);
+
+ // Updates a ticket after one run of a task's continuation according
+ // to the state of the task after its run. The executor must call this
+ // method after calling |obtain_ticket()| to indicate the disposition of
+ // the task for which the ticket was obtained.
+ //
+ // Passing an empty |task| indicates that the task has completed so it
+ // does not need to be resumed.
+ //
+ // Passing a non-empty |task| indicates that the task returned a pending
+ // result and may need to be suspended depending on the current state
+ // of the ticket.
+ // - If the ticket has already been resumed, moves |task| into the
+ // runnable queue.
+ // - Otherwise, if the ticket still has a non-zero ref-count, moves |task|
+ // into the suspended task table.
+ // - Otherwise, considers the task abandoned and the caller retains
+ // ownership of |task|.
+ //
+ // Preconditions:
+ // - |task| must be non-null (may be empty)
+ // - the ticket must not have already been finalized
+ void finalize_ticket(suspended_task::ticket ticket, pending_task* task);
+
+ // Increments the ticket's ref-count.
+ //
+ // Preconditions:
+ // - the ticket's ref-count must be non-zero (positive)
+ void duplicate_ticket(suspended_task::ticket ticket);
+
+ // Decrements the ticket's ref-count.
+ //
+ // If the task's ref-count reaches 0 and has an associated task that
+ // has not already been resumed, returns the associated task back
+ // to the caller.
+ // Otherwise, returns an empty task.
+ //
+ // Preconditions:
+ // - the ticket's ref-count must be non-zero (positive)
+ pending_task release_ticket(suspended_task::ticket ticket);
+
+ // Resumes a task and decrements the ticket's ref-count.
+ //
+ // If the ticket has an associated task that has not already been resumed,
+ // moves its associated task to the runnable queue and returns true.
+ // Otherwise, returns false.
+ //
+ // Preconditions:
+ // - the ticket's ref-count must be non-zero (positive)
+ bool resume_task_with_ticket(suspended_task::ticket ticket);
+
+ // Takes all tasks in the runnable queue.
+ //
+ // Preconditions:
+ // - |tasks| must be non-null and empty
+ void take_runnable_tasks(task_queue* tasks);
+
+ // Takes all remaining tasks, regardless of whether they are runnable
+ // or suspended.
+ //
+ // This operation is useful when shutting down an executor.
+ //
+ // Preconditions:
+ // - |tasks| must be non-null and empty
+ void take_all_tasks(task_queue* tasks);
+
+ // Returns true if there are any runnable tasks.
+ bool has_runnable_tasks() const { return !runnable_tasks_.empty(); }
+
+ // Returns true if there are any suspended tasks that have yet to
+ // be resumed.
+ bool has_suspended_tasks() const { return suspended_task_count_ > 0; }
+
+ // Returns true if there are any tickets that have yet to be finalized,
+ // released, or resumed.
+ bool has_outstanding_tickets() const { return !tickets_.empty(); }
+
+ scheduler(const scheduler&) = delete;
+ scheduler(scheduler&&) = delete;
+ scheduler& operator=(const scheduler&) = delete;
+ scheduler& operator=(scheduler&&) = delete;
+
+ private:
+ struct ticket_record {
+ ticket_record(ref_count_type initial_refs) : ref_count(initial_refs), was_resumed(false) {}
+
+ // The current reference count.
+ ref_count_type ref_count;
+
+ // True if the task has been resumed using |resume_task_with_ticket()|.
+ bool was_resumed;
+
+ // The task is initially empty when the ticket is obtained.
+ // It is later set to non-empty if the task needs to be suspended when
+ // the ticket is finalized. It becomes empty again when the task
+ // is moved into the runnable queue, released, or taken.
+ pending_task task;
+ };
+ using ticket_map = std::map<suspended_task::ticket, ticket_record>;
+
+ task_queue runnable_tasks_;
+ ticket_map tickets_;
+ uint64_t suspended_task_count_ = 0;
+ suspended_task::ticket next_ticket_ = 1;
+};
+
+} // namespace subtle
+} // namespace fit
+
+#endif // LIB_FIT_SCHEDULER_H_
diff --git a/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/scope.h b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/scope.h
new file mode 100644
index 0000000..21089b8
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/scope.h
@@ -0,0 +1,271 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIT_SCOPE_H_
+#define LIB_FIT_SCOPE_H_
+
+#include <assert.h>
+
+#include <atomic>
+#include <mutex>
+
+#include "promise.h"
+#include "thread_safety.h"
+
+namespace fit {
+
+// Provides a mechanism for binding promises to the lifetime of another object
+// such that they are destroyed before that object goes out of scope. It is
+// particularly useful for ensuring that the lifetime of a promise does not
+// exceed the lifetime of any variables that it has captured by reference.
+//
+// A scope is thread-safe but non-reentrant: it must not be destroyed while
+// any of its associated promises are running.
+//
+// EXAMPLE
+//
+// Define a |fit::scope| as a member of the object to whose lifetime the
+// promises should be bound.
+//
+// // We mark this class final because its destructor has side-effects
+// // that rely on the order of destruction. If this object were
+// // subclassed there would be a possibility for promises bound to its
+// // scope to inadvertently access the subclass's state while the object
+// // was being destroyed.
+// class accumulator final {
+// public:
+// accumulator() = default;
+// ~accumulator() = default;
+//
+// fit::promise<int> accumulate(int value);
+//
+// private:
+// int prior_total_ = 0;
+//
+// // This member is last so that the scope is exited before all
+// // other members of the object are destroyed. Alternately, we
+// // could enforce this ordering by explicitly invoking
+// // |fit::scope::exit()| where appropriate.
+// fit::scope scope_;
+// };
+//
+// Use |fit::promise::wrap_with()| to wrap up promises that capture pointers
+// to the object. In this example, the captured pointer is "this".
+//
+// fit::promise<int> accumulator::accumulate(int value) {
+// return fit::make_promise([this, value] {
+// prior_total_ += value;
+// return fit::ok(prior_total_);
+// }).wrap_with(scope_); /* binding to scope happens here */
+// }
+//
+class scope final {
+ public:
+ // Creates a new scope.
+ scope();
+
+ // Exits the scope and destroys all of its wrapped promises.
+ // Asserts that no promises are currently running.
+ ~scope();
+
+ // Returns true if the scope has been exited.
+ //
+ // This method is thread-safe.
+ bool exited() const { return state_->exited(); }
+
+ // Exits the scope and destroys all of its wrapped promises.
+ // Assets that no promises are currently running.
+ //
+ // This method is thread-safe.
+ void exit() { return state_->exit(false /*scope_was_destroyed*/); }
+
+ // Returns a promise which wraps the specified |promise| and binds the
+ // promise to this scope.
+ //
+ // The specified promise will automatically be destroyed when its wrapper
+ // is destroyed or when the scope is exited. If the scope has already
+ // exited then the wrapped promise will be immediately destroyed.
+ //
+ // When the returned promise is invoked before the scope is exited,
+ // the promise that it wraps will be invoked as usual. However, when
+ // the returned promise is invoked after the scope is exited, it
+ // immediately returns a pending result (since the promise that it
+ // previously wrapped has already been destroyed). By returning a
+ // pending result, the return promise effectively indicates to the
+ // executor that the task has been "abandoned" due to the scope being
+ // exited.
+ //
+ // This method is thread-safe.
+ template <typename Promise>
+ decltype(auto) wrap(Promise promise) {
+ assert(promise);
+ return fit::make_promise_with_continuation(scoped_continuation<Promise>(
+ state_->adopt_promise(new promise_holder<Promise>(std::move(promise)))));
+ }
+
+ scope(const scope&) = delete;
+ scope(scope&&) = delete;
+ scope& operator=(const scope&) = delete;
+ scope& operator=(scope&&) = delete;
+
+ private:
+ class state;
+ class promise_holder_base;
+
+ // Holds a reference to a promise that is owned by the state.
+ class promise_handle final {
+ public:
+ promise_handle() = default;
+
+ private:
+ // |state| and |promise_holder| belong to the state object.
+ // Invariant: If |promise_holder| is non-null then |state| is
+ // also non-null.
+ friend state;
+ promise_handle(state* state, promise_holder_base* promise_holder)
+ : state_(state), promise_holder_(promise_holder) {}
+
+ state* state_ = nullptr;
+ promise_holder_base* promise_holder_ = nullptr;
+ };
+
+ // Holds the shared state of the scope.
+ // This object is destroyed once the scope and all of its promises
+ // have been destroyed.
+ class state final {
+ public:
+ state();
+ ~state();
+
+ // The following methods are called from the |scope|.
+
+ bool exited() const;
+ void exit(bool scope_was_destroyed);
+
+ // The following methods are called from the |scoped_continuation|.
+
+ // Links a promise to the scope's lifecycle such that it will be
+ // destroyed when the scope is exited. Returns a handle that may
+ // be used to access the promise later.
+ // The state takes ownership of the promise.
+ promise_handle adopt_promise(promise_holder_base* promise_holder);
+
+ // Unlinks a promise from the scope's lifecycle given its handle
+ // and causes the underlying promise to be destroyed if it hasn't
+ // already been destroyed due to the scope exiting.
+ // Does nothing if the handle was default-initialized.
+ static void drop_promise(promise_handle promise_handle);
+
+ // Acquires a promise given its handle.
+ // Returns nullptr if the handle was default-initialized or if
+ // the scope exited, meaning that the promise was not acquired.
+ // The promise must be released before it can be acquired again.
+ static promise_holder_base* try_acquire_promise(promise_handle promise_handle);
+
+ // Releases a promise that was successfully acquired.
+ static void release_promise(promise_handle promise_handle);
+
+ state(const state&) = delete;
+ state(state&&) = delete;
+ state& operator=(const state&) = delete;
+ state& operator=(state&&) = delete;
+
+ private:
+ bool should_delete_self() const FIT_REQUIRES(mutex_) {
+ return scope_was_destroyed_ && promise_handle_count_ == 0;
+ }
+
+ static constexpr uint64_t scope_exited = static_cast<uint64_t>(1u) << 63;
+
+ // Tracks of the number of promises currently running ("acquired").
+ // The top bit is set when the scope is exited, at which point no
+ // new promises can be acquired. After exiting, the count can
+ // be incremented transiently but is immediately decremented again
+ // until all promise handles have been released. Once no promise
+ // handles remain, the count will equal |scope_exited| and will not
+ // change again.
+ std::atomic_uint64_t acquired_promise_count_{0};
+
+ mutable std::mutex mutex_;
+ bool scope_was_destroyed_ FIT_GUARDED(mutex_) = false;
+ uint64_t promise_handle_count_ FIT_GUARDED(mutex_) = 0;
+ promise_holder_base* head_promise_holder_ FIT_GUARDED(mutex_) = nullptr;
+ };
+
+ // Base type for managing the lifetime of a promise of any type.
+ // It is owned by the state and retained indirectly by the continuation
+ // using a |promise_handle|.
+ class promise_holder_base {
+ public:
+ promise_holder_base() = default;
+ virtual ~promise_holder_base() = default;
+
+ promise_holder_base(const promise_holder_base&) = delete;
+ promise_holder_base(promise_holder_base&&) = delete;
+ promise_holder_base& operator=(const promise_holder_base&) = delete;
+ promise_holder_base& operator=(promise_holder_base&&) = delete;
+
+ private:
+ // |next| and |prev| belong to the state object.
+ friend class state;
+ promise_holder_base* next = nullptr;
+ promise_holder_base* prev = nullptr;
+ };
+
+ // Holder for a promise of a particular type.
+ template <typename Promise>
+ class promise_holder final : public promise_holder_base {
+ public:
+ explicit promise_holder(Promise promise) : promise(std::move(promise)) {}
+ ~promise_holder() override = default;
+
+ Promise promise;
+ };
+
+ // Wraps a promise whose lifetime is managed by the scope.
+ template <typename Promise>
+ class scoped_continuation final {
+ public:
+ explicit scoped_continuation(promise_handle promise_handle) : promise_handle_(promise_handle) {}
+
+ scoped_continuation(scoped_continuation&& other) : promise_handle_(other.promise_handle_) {
+ other.promise_handle_ = promise_handle{};
+ }
+
+ ~scoped_continuation() { state::drop_promise(promise_handle_); }
+
+ typename Promise::result_type operator()(context& context) {
+ typename Promise::result_type result;
+ auto holder =
+ static_cast<promise_holder<Promise>*>(state::try_acquire_promise(promise_handle_));
+ if (holder) {
+ result = holder->promise(context);
+ state::release_promise(promise_handle_);
+ }
+ return result;
+ }
+
+ scoped_continuation& operator=(scoped_continuation&& other) {
+ if (this != &other) {
+ state::drop_promise(promise_handle_);
+ promise_handle_ = other.promise_handle_;
+ other.promise_handle_ = promise_handle{};
+ }
+ return *this;
+ }
+
+ scoped_continuation(const scoped_continuation&) = delete;
+ scoped_continuation& operator=(const scoped_continuation&) = delete;
+
+ private:
+ promise_handle promise_handle_;
+ };
+
+ // The scope's shared state.
+ state* const state_;
+};
+
+} // namespace fit
+
+#endif // LIB_FIT_SCOPE_H_
diff --git a/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/sequencer.h b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/sequencer.h
new file mode 100644
index 0000000..888df7b
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/sequencer.h
@@ -0,0 +1,84 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIT_SEQUENCER_H_
+#define LIB_FIT_SEQUENCER_H_
+
+#include <assert.h>
+
+#include <mutex>
+
+#include "bridge.h"
+#include "thread_safety.h"
+
+namespace fit {
+
+// A sequencer imposes a first-in-first-out sequential execution order onto a
+// sequence of promises. Each successively enqueued promise remains suspended
+// until all previously enqueued promises complete or are abandoned.
+//
+// |fit::sequencer| is designed to be used either on its own or chained
+// onto a promise using |fit::promise::wrap_with()|.
+//
+// EXAMPLE
+//
+// // This wrapper type is intended to be applied to
+// // a sequence of promises so we store it in a variable.
+// fit::sequencer seq;
+//
+// // This task consists of some amount of work that must be
+// // completed sequentially followed by other work that can
+// // happen in any order. We use |wrap_with()| to wrap the
+// // sequential work with the sequencer.
+// fit::promise<> perform_complex_task() {
+// return fit::make_promise([] { /* do sequential work */ })
+// .then([] (fit::result<>& result) { /* this will also be wrapped */ })
+// .wrap_with(seq)
+// .then([] (fit::result<>& result) { /* do more work */ });
+// }
+//
+class sequencer final {
+ public:
+ sequencer();
+ ~sequencer();
+
+ // Returns a new promise which will invoke |promise| after all previously
+ // enqueued promises on this sequencer have completed or been abandoned.
+ //
+ // This method is thread-safe.
+ template <typename Promise>
+ decltype(auto) wrap(Promise promise) {
+ assert(promise);
+
+ fit::bridge<> bridge;
+ fit::consumer<> prior = swap_prior(std::move(bridge.consumer));
+ return prior.promise_or(fit::ok()).then(
+ [promise = std::move(promise), completer = std::move(bridge.completer)](
+ fit::context& context, const fit::result<>&) mutable {
+ // This handler will run once the completer associated
+ // with the |prior| promise is abandoned. Once the promise
+ // has finished, both the promise and completer will be
+ // destroyed thereby causing the next promise chained onto
+ // the |bridge|'s associated consumer to become runnable.
+ return promise(context);
+ });
+ }
+
+ sequencer(const sequencer&) = delete;
+ sequencer(sequencer&&) = delete;
+ sequencer& operator=(const sequencer&) = delete;
+ sequencer& operator=(sequencer&&) = delete;
+
+ private:
+ fit::consumer<> swap_prior(fit::consumer<> new_prior);
+
+ std::mutex mutex_;
+
+ // Holds the consumption capability of the most recently wrapped promise.
+ fit::consumer<> prior_ FIT_GUARDED(mutex_);
+};
+
+} // namespace fit
+
+#endif // LIB_FIT_SEQUENCER_H_
diff --git a/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/single_threaded_executor.h b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/single_threaded_executor.h
new file mode 100644
index 0000000..826df83
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/single_threaded_executor.h
@@ -0,0 +1,84 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIT_SINGLE_THREADED_EXECUTOR_H_
+#define LIB_FIT_SINGLE_THREADED_EXECUTOR_H_
+
+#include <utility>
+
+#include "promise.h"
+#include "scheduler.h"
+
+namespace fit {
+
+// A simple platform-independent single-threaded asynchronous task executor.
+//
+// This implementation is designed for use when writing simple single-threaded
+// platform-independent applications. It may be less efficient or provide
+// fewer features than more specialized or platform-dependent executors.
+//
+// See documentation of |fit::promise| for more information.
+class single_threaded_executor final : public executor {
+ public:
+ single_threaded_executor();
+
+ // Destroys the executor along with all of its remaining scheduled tasks
+ // that have yet to complete.
+ ~single_threaded_executor() override;
+
+ // Schedules a task for eventual execution by the executor.
+ //
+ // This method is thread-safe.
+ void schedule_task(pending_task task) override;
+
+ // Runs all scheduled tasks (including additional tasks scheduled while
+ // they run) until none remain.
+ //
+ // This method is thread-safe but must only be called on at most one
+ // thread at a time.
+ void run();
+
+ single_threaded_executor(const single_threaded_executor&) = delete;
+ single_threaded_executor(single_threaded_executor&&) = delete;
+ single_threaded_executor& operator=(const single_threaded_executor&) = delete;
+ single_threaded_executor& operator=(single_threaded_executor&&) = delete;
+
+ private:
+ class dispatcher_impl;
+
+ // The task context for tasks run by the executor.
+ class context_impl final : public context {
+ public:
+ explicit context_impl(single_threaded_executor* executor);
+ ~context_impl() override;
+
+ single_threaded_executor* executor() const override;
+ suspended_task suspend_task() override;
+
+ private:
+ single_threaded_executor* const executor_;
+ };
+
+ context_impl context_;
+ dispatcher_impl* const dispatcher_;
+};
+
+// Creates a new |fit::single_threaded_executor|, schedules a promise as a task,
+// runs all of the executor's scheduled tasks until none remain, then returns
+// the promise's result.
+template <typename Continuation>
+static typename promise_impl<Continuation>::result_type run_single_threaded(
+ promise_impl<Continuation> promise) {
+ using result_type = typename promise_impl<Continuation>::result_type;
+ single_threaded_executor exec;
+ result_type saved_result;
+ exec.schedule_task(
+ promise.then([&saved_result](result_type& result) { saved_result = std::move(result); }));
+ exec.run();
+ return saved_result;
+}
+
+} // namespace fit
+
+#endif // LIB_FIT_SINGLE_THREADED_EXECUTOR_H_
diff --git a/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/storage_internal.h b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/storage_internal.h
new file mode 100644
index 0000000..7ddde49
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/storage_internal.h
@@ -0,0 +1,838 @@
+// 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.
+
+#ifndef LIB_FIT_STORAGE_INTERNAL_H_
+#define LIB_FIT_STORAGE_INTERNAL_H_
+
+#include <cstdint>
+#include <limits>
+#include <type_traits>
+
+#include "utility_internal.h"
+
+namespace fit {
+namespace internal {
+
+// Type tag to select overloads based on type T.
+template <typename T>
+struct type_tag {
+ using type = T;
+};
+
+// Type tag to select overloads based on index Index.
+template <size_t Index>
+struct index_tag {
+ static constexpr size_t index = Index;
+};
+
+// Type tag to select trivial initialization.
+enum trivial_init_t { trivial_init_v };
+
+// Type tag to select default initialization.
+enum default_init_t { default_init_v };
+
+// Type tag to select conditional initialization.
+enum maybe_init_t { maybe_init_v };
+
+// Represents the pair (T, Index) in the type system.
+template <typename T, size_t Index>
+struct type_index {};
+
+// Represents whether a type is trivially/non-trivially destructible.
+enum class destructor_class {
+ trivial,
+ non_trivial,
+};
+
+// Represents whether a type is trivially/non-trivially copyable.
+enum class copy_class {
+ trivial,
+ non_trivial,
+};
+
+// Represents whether a type is trivially/non-trivially movable.
+enum class move_class {
+ trivial,
+ non_trivial,
+};
+
+// Represents the full complement of move/copy/destruct classes for a type.
+template <destructor_class DestructorClass, copy_class CopyClass, move_class MoveClass>
+struct storage_class {};
+
+template <typename... Ts>
+using make_storage_class =
+ storage_class<is_trivially_destructible_v<Ts...> ? destructor_class::trivial
+ : destructor_class::non_trivial,
+ is_trivially_copyable_v<Ts...> ? copy_class::trivial : copy_class::non_trivial,
+ is_trivially_movable_v<Ts...> ? move_class::trivial : move_class::non_trivial>;
+
+// A trivial type for the empty alternative of union-based storage.
+struct empty_type {};
+
+// Index type used to track the active variant. Tracking uses zero-based
+// indices. Empty is denoted by the maximum representable value.
+using index_type = size_t;
+
+// Index denoting that no user-specified variant is active. Take care not to
+// ODR-use this value.
+constexpr index_type empty_index = std::numeric_limits<index_type>::max();
+
+#ifdef NDEBUG
+#define FIT_INTERNAL_UNREACHABLE_OR_ABORT __builtin_unreachable
+#else
+#define FIT_INTERNAL_UNREACHABLE_OR_ABORT __builtin_abort
+#endif
+
+// Base type for lazy-initialized union storage types. This type implements a
+// recursive union of the element types in Ts. Specializations handle the
+// recursive and terminal cases, and the different storage requirements for
+// trivially/non-trivially destructible types.
+template <destructor_class, typename...>
+union storage_base;
+
+// Non-trivial terminal case.
+template <>
+union storage_base<destructor_class::non_trivial, type_index<empty_type, empty_index>> {
+ storage_base() : empty{} {}
+
+ template <typename... Args>
+ storage_base(type_tag<empty_type>, Args&&...) : empty{} {}
+ template <typename... Args>
+ storage_base(index_tag<empty_index>, Args&&...) : empty{} {}
+
+ // Non-trivial destructor.
+ ~storage_base() {}
+
+ storage_base(const storage_base&) = default;
+ storage_base(storage_base&&) = default;
+ storage_base& operator=(const storage_base&) = default;
+ storage_base& operator=(storage_base&&) = default;
+
+ void construct_at(size_t index, const storage_base&) {
+ if (index == empty_index) {
+ new (&empty) empty_type{};
+ } else {
+ FIT_INTERNAL_UNREACHABLE_OR_ABORT();
+ }
+ }
+ void construct_at(size_t index, storage_base&&) {
+ if (index == empty_index) {
+ new (&empty) empty_type{};
+ } else {
+ FIT_INTERNAL_UNREACHABLE_OR_ABORT();
+ }
+ }
+
+ void assign_at(size_t index, const storage_base& other) {
+ if (index == empty_index) {
+ empty = other.empty;
+ } else {
+ FIT_INTERNAL_UNREACHABLE_OR_ABORT();
+ }
+ }
+ void assign_at(size_t index, storage_base&& other) {
+ if (index == empty_index) {
+ empty = std::move(other.empty);
+ } else {
+ FIT_INTERNAL_UNREACHABLE_OR_ABORT();
+ }
+ }
+
+ void swap_at(size_t index, storage_base& other) {
+ if (index == empty_index) {
+ using std::swap;
+ swap(empty, other.empty);
+ } else {
+ FIT_INTERNAL_UNREACHABLE_OR_ABORT();
+ }
+ }
+
+ template <typename... Args>
+ size_t construct(type_tag<empty_type>, Args&&...) {
+ new (&empty) empty_type{};
+ return empty_index;
+ }
+ template <typename... Args>
+ size_t construct(index_tag<empty_index>, Args&&...) {
+ new (&empty) empty_type{};
+ return empty_index;
+ }
+
+ void reset(size_t index) {
+ if (index == empty_index) {
+ empty.empty_type::~empty_type();
+ } else {
+ FIT_INTERNAL_UNREACHABLE_OR_ABORT();
+ }
+ }
+
+ empty_type& get(type_tag<empty_type>) { return empty; }
+ const empty_type& get(type_tag<empty_type>) const { return empty; }
+ empty_type& get(index_tag<empty_index>) { return empty; }
+ const empty_type& get(index_tag<empty_index>) const { return empty; }
+
+ size_t index(type_tag<empty_type>) const { return empty_index; }
+
+ template <typename V>
+ bool visit(size_t, V&&) {
+ return false;
+ }
+ template <typename V>
+ bool visit(size_t, V&&) const {
+ return false;
+ }
+
+ empty_type empty;
+};
+
+// Trivial terminal case.
+template <>
+union storage_base<destructor_class::trivial, type_index<empty_type, empty_index>> {
+ constexpr storage_base() : empty{} {}
+
+ template <typename... Args>
+ constexpr storage_base(type_tag<empty_type>, Args&&...) : empty{} {}
+ template <typename... Args>
+ constexpr storage_base(index_tag<empty_index>, Args&&...) : empty{} {}
+
+ // Trivial destructor.
+ ~storage_base() = default;
+
+ constexpr storage_base(const storage_base&) = default;
+ constexpr storage_base(storage_base&&) = default;
+ constexpr storage_base& operator=(const storage_base&) = default;
+ constexpr storage_base& operator=(storage_base&&) = default;
+
+ constexpr void construct_at(size_t index, const storage_base&) {
+ if (index == empty_index) {
+ new (&empty) empty_type{};
+ } else {
+ FIT_INTERNAL_UNREACHABLE_OR_ABORT();
+ }
+ }
+ constexpr void construct_at(size_t index, storage_base&&) {
+ if (index == empty_index) {
+ new (&empty) empty_type{};
+ } else {
+ FIT_INTERNAL_UNREACHABLE_OR_ABORT();
+ }
+ }
+
+ constexpr void assign_at(size_t index, const storage_base& other) {
+ if (index == empty_index) {
+ empty = other.empty;
+ } else {
+ FIT_INTERNAL_UNREACHABLE_OR_ABORT();
+ }
+ }
+ constexpr void assign_at(size_t index, storage_base&& other) {
+ if (index == empty_index) {
+ empty = std::move(other.empty);
+ } else {
+ FIT_INTERNAL_UNREACHABLE_OR_ABORT();
+ }
+ }
+
+ constexpr void swap_at(size_t index, storage_base& other) {
+ if (index == empty_index) {
+ using std::swap;
+ swap(empty, other.empty);
+ } else {
+ FIT_INTERNAL_UNREACHABLE_OR_ABORT();
+ }
+ }
+
+ template <typename... Args>
+ constexpr size_t construct(type_tag<empty_type>, Args&&...) {
+ new (&empty) empty_type{};
+ return empty_index;
+ }
+ template <typename... Args>
+ constexpr size_t construct(index_tag<empty_index>, Args&&...) {
+ new (&empty) empty_type{};
+ return empty_index;
+ }
+
+ constexpr void reset(size_t index) {
+ if (index == empty_index) {
+ empty.empty_type::~empty_type();
+ } else {
+ FIT_INTERNAL_UNREACHABLE_OR_ABORT();
+ }
+ }
+
+ constexpr empty_type& get(type_tag<empty_type>) { return empty; }
+ constexpr const empty_type& get(type_tag<empty_type>) const { return empty; }
+ constexpr empty_type& get(index_tag<empty_index>) { return empty; }
+ constexpr const empty_type& get(index_tag<empty_index>) const { return empty; }
+
+ constexpr size_t index(type_tag<empty_type>) const { return empty_index; }
+
+ template <typename V>
+ constexpr bool visit(size_t, V&&) {
+ return false;
+ }
+ template <typename V>
+ constexpr bool visit(size_t, V&&) const {
+ return false;
+ }
+
+ empty_type empty;
+};
+
+template <typename T, size_t Index, typename... Ts, size_t... Is>
+union storage_base<destructor_class::non_trivial, type_index<T, Index>, type_index<Ts, Is>...> {
+ storage_base() : empty{} {}
+
+ template <typename... Args>
+ storage_base(type_tag<T>, Args&&... args) : value(std::forward<Args>(args)...) {}
+ template <typename... Args>
+ storage_base(index_tag<Index>, Args&&... args) : value(std::forward<Args>(args)...) {}
+
+ template <typename U, typename... Args>
+ storage_base(type_tag<U>, Args&&... args) : rest(type_tag<U>{}, std::forward<Args>(args)...) {}
+ template <size_t OtherIndex, typename... Args>
+ storage_base(index_tag<OtherIndex>, Args&&... args)
+ : rest(index_tag<OtherIndex>{}, std::forward<Args>(args)...) {}
+
+ // Non-trivial destructor.
+ ~storage_base() {}
+
+ // Trival copy/move construction and assignment.
+ storage_base(const storage_base&) = default;
+ storage_base(storage_base&&) = default;
+ storage_base& operator=(const storage_base&) = default;
+ storage_base& operator=(storage_base&&) = default;
+
+ void construct_at(size_t index, const storage_base& other) {
+ if (index == Index) {
+ new (&value) T{other.value};
+ } else {
+ rest.construct_at(index, other.rest);
+ }
+ }
+ void construct_at(size_t index, storage_base&& other) {
+ if (index == Index) {
+ new (&value) T{std::move(other.value)};
+ } else {
+ rest.construct_at(index, std::move(other.rest));
+ }
+ }
+
+ void assign_at(size_t index, const storage_base& other) {
+ if (index == Index) {
+ value = other.value;
+ } else {
+ rest.assign_at(index, other.rest);
+ }
+ }
+ void assign_at(size_t index, storage_base&& other) {
+ if (index == Index) {
+ value = std::move(other.value);
+ } else {
+ rest.assign_at(index, std::move(other.rest));
+ }
+ }
+
+ void swap_at(size_t index, storage_base& other) {
+ if (index == Index) {
+ using std::swap;
+ swap(value, other.value);
+ } else {
+ rest.swap_at(index, other.rest);
+ }
+ }
+
+ template <typename... Args>
+ size_t construct(type_tag<T>, Args&&... args) {
+ new (&value) T(std::forward<Args>(args)...);
+ return Index;
+ }
+ template <typename U, typename... Args>
+ size_t construct(type_tag<U>, Args&&... args) {
+ return rest.construct(type_tag<U>{}, std::forward<Args>(args)...);
+ }
+ template <typename... Args>
+ size_t construct(index_tag<Index>, Args&&... args) {
+ new (&value) T(std::forward<Args>(args)...);
+ return Index;
+ }
+ template <size_t OtherIndex, typename... Args>
+ size_t construct(index_tag<OtherIndex>, Args&&... args) {
+ return rest.construct(index_tag<OtherIndex>{}, std::forward<Args>(args)...);
+ }
+
+ void reset(size_t index) {
+ if (index == Index) {
+ value.~T();
+ } else {
+ rest.reset(index);
+ }
+ }
+
+ T& get(type_tag<T>) { return value; }
+ const T& get(type_tag<T>) const { return value; }
+ template <typename U>
+ U& get(type_tag<U>) {
+ return rest.get(type_tag<U>{});
+ }
+ template <typename U>
+ const U& get(type_tag<U>) const {
+ return rest.get(type_tag<U>{});
+ }
+ T& get(index_tag<Index>) { return value; }
+ const T& get(index_tag<Index>) const { return value; }
+ template <size_t OtherIndex>
+ auto& get(index_tag<OtherIndex>) {
+ return rest.get(index_tag<OtherIndex>{});
+ }
+ template <size_t OtherIndex>
+ const auto& get(index_tag<OtherIndex>) const {
+ return rest.get(index_tag<OtherIndex>{});
+ }
+
+ size_t index(type_tag<T>) const { return Index; }
+ template <typename U>
+ size_t index(type_tag<U>) const {
+ return rest.index(type_tag<U>{});
+ }
+
+ template <typename V>
+ bool visit(size_t index, V&& visitor) {
+ if (index == Index) {
+ std::forward<V>(visitor)(type_tag<T>{}, index_tag<Index>{}, this);
+ return true;
+ } else {
+ return rest.visit(index, std::forward<V>(visitor));
+ }
+ }
+ template <typename V>
+ bool visit(size_t index, V&& visitor) const {
+ if (index == Index) {
+ std::forward<V>(visitor)(type_tag<T>{}, index_tag<Index>{}, this);
+ return true;
+ } else {
+ return rest.visit(index, std::forward<V>(visitor));
+ }
+ }
+
+ empty_type empty;
+ T value;
+ storage_base<destructor_class::non_trivial, type_index<Ts, Is>...> rest;
+};
+
+template <typename T, size_t Index, typename... Ts, size_t... Is>
+union storage_base<destructor_class::trivial, type_index<T, Index>, type_index<Ts, Is>...> {
+ constexpr storage_base() : empty{} {}
+
+ template <typename... Args>
+ constexpr storage_base(type_tag<T>, Args&&... args) : value(std::forward<Args>(args)...) {}
+ template <typename... Args>
+ constexpr storage_base(index_tag<Index>, Args&&... args) : value(std::forward<Args>(args)...) {}
+
+ template <typename U, typename... Args>
+ constexpr storage_base(type_tag<U>, Args&&... args)
+ : rest(type_tag<U>{}, std::forward<Args>(args)...) {}
+ template <size_t OtherIndex, typename... Args>
+ constexpr storage_base(index_tag<OtherIndex>, Args&&... args)
+ : rest(index_tag<OtherIndex>{}, std::forward<Args>(args)...) {}
+
+ // Trivial destructor.
+ ~storage_base() = default;
+
+ // Trival copy/move construction and assignment.
+ constexpr storage_base(const storage_base&) = default;
+ constexpr storage_base(storage_base&&) = default;
+ constexpr storage_base& operator=(const storage_base&) = default;
+ constexpr storage_base& operator=(storage_base&&) = default;
+
+ constexpr void construct_at(size_t index, const storage_base& other) {
+ if (index == Index) {
+ new (&value) T{other.value};
+ } else {
+ rest.construct_at(index, other.rest);
+ }
+ }
+ constexpr void construct_at(size_t index, storage_base&& other) {
+ if (index == Index) {
+ new (&value) T{std::move(other.value)};
+ } else {
+ rest.construct_at(index, std::move(other.rest));
+ }
+ }
+
+ constexpr void assign_at(size_t index, const storage_base& other) {
+ if (index == Index) {
+ value = other.value;
+ } else {
+ rest.assign_at(index, other.rest);
+ }
+ }
+ constexpr void assign_at(size_t index, storage_base&& other) {
+ if (index == Index) {
+ value = std::move(other.value);
+ } else {
+ rest.assign_at(index, std::move(other.rest));
+ }
+ }
+
+ constexpr void swap_at(size_t index, storage_base& other) {
+ if (index == Index) {
+ using std::swap;
+ swap(value, other.value);
+ } else {
+ rest.swap_at(index, other.rest);
+ }
+ }
+
+ template <typename... Args>
+ constexpr size_t construct(type_tag<T>, Args&&... args) {
+ new (&value) T(std::forward<Args>(args)...);
+ return Index;
+ }
+ template <typename U, typename... Args>
+ constexpr size_t construct(type_tag<U>, Args&&... args) {
+ return rest.construct(type_tag<U>{}, std::forward<Args>(args)...);
+ }
+ template <typename... Args>
+ constexpr size_t construct(index_tag<Index>, Args&&... args) {
+ new (&value) T(std::forward<Args>(args)...);
+ return Index;
+ }
+ template <size_t OtherIndex, typename... Args>
+ constexpr size_t construct(index_tag<OtherIndex>, Args&&... args) {
+ return rest.construct(index_tag<OtherIndex>{}, std::forward<Args>(args)...);
+ }
+
+ constexpr void reset(size_t) {}
+
+ constexpr T& get(type_tag<T>) { return value; }
+ constexpr const T& get(type_tag<T>) const { return value; }
+ template <typename U>
+ constexpr U& get(type_tag<U>) {
+ return rest.get(type_tag<U>{});
+ }
+ template <typename U>
+ constexpr const U& get(type_tag<U>) const {
+ return rest.get(type_tag<U>{});
+ }
+ constexpr T& get(index_tag<Index>) { return value; }
+ constexpr const T& get(index_tag<Index>) const { return value; }
+ template <size_t OtherIndex>
+ constexpr auto& get(index_tag<OtherIndex>) {
+ return rest.get(index_tag<OtherIndex>{});
+ }
+ template <size_t OtherIndex>
+ constexpr const auto& get(index_tag<OtherIndex>) const {
+ return rest.get(index_tag<OtherIndex>{});
+ }
+
+ constexpr size_t index(type_tag<T>) const { return Index; }
+ template <typename U>
+ constexpr size_t index(type_tag<U>) const {
+ return rest.index(type_tag<U>{});
+ }
+
+ template <typename V>
+ constexpr bool visit(size_t index, V&& visitor) {
+ if (index == Index) {
+ std::forward<V>(visitor)(type_tag<T>{}, index_tag<Index>{}, this);
+ return true;
+ } else {
+ return rest.visit(index, std::forward<V>(visitor));
+ }
+ }
+ template <typename V>
+ constexpr bool visit(size_t index, V&& visitor) const {
+ if (index == Index) {
+ std::forward<V>(visitor)(type_tag<T>{}, index_tag<Index>{}, this);
+ return true;
+ } else {
+ return rest.visit(index, std::forward<V>(visitor));
+ }
+ }
+
+ empty_type empty;
+ T value;
+ storage_base<destructor_class::trivial, type_index<Ts, Is>...> rest;
+};
+
+// Lazy-initialized union storage type that tracks the index of the active
+// variant.
+template <destructor_class, typename...>
+class indexed_storage;
+
+template <destructor_class DestructorClass, typename... Ts, size_t... Is>
+class indexed_storage<DestructorClass, type_index<Ts, Is>...> {
+ private:
+ using base_type =
+ storage_base<DestructorClass, type_index<Ts, Is>..., type_index<empty_type, empty_index>>;
+
+ public:
+ static constexpr bool nothrow_default_constructible =
+ std::is_nothrow_default_constructible<first_t<Ts...>>::value;
+ static constexpr bool nothrow_move_constructible =
+ conjunction_v<std::is_nothrow_move_constructible<Ts>...>;
+ static constexpr bool nothrow_move_assignable =
+ conjunction_v<std::is_nothrow_move_assignable<Ts>...>;
+
+ constexpr indexed_storage() = default;
+
+ constexpr indexed_storage(trivial_init_t) : indexed_storage{} {}
+
+ constexpr indexed_storage(default_init_t) : index_{0}, base_{index_tag<0>{}} {}
+
+ // Only used by trivial copy/move types.
+ constexpr indexed_storage(const indexed_storage& other) = default;
+ constexpr indexed_storage& operator=(const indexed_storage& other) = default;
+ constexpr indexed_storage(indexed_storage&& other) = default;
+ constexpr indexed_storage& operator=(indexed_storage&& other) = default;
+
+ template <typename T, typename... Args>
+ constexpr indexed_storage(type_tag<T>, Args&&... args)
+ : base_(type_tag<T>{}, std::forward<Args>(args)...) {
+ index_ = base_.index(type_tag<T>{});
+ }
+ template <size_t Index, typename... Args>
+ constexpr indexed_storage(index_tag<Index>, Args&&... args)
+ : index_{Index}, base_(index_tag<Index>{}, std::forward<Args>(args)...) {}
+
+ constexpr indexed_storage(maybe_init_t, const indexed_storage& other)
+ : index_{other.index()}, base_{} {
+ base_.construct_at(other.index(), other.base_);
+ }
+ constexpr indexed_storage(maybe_init_t, indexed_storage&& other)
+ : index_{other.index()}, base_{} {
+ base_.construct_at(other.index(), std::move(other.base_));
+ }
+
+ ~indexed_storage() = default;
+
+ constexpr index_type index() const { return index_; }
+ constexpr bool has_value() const { return index() != empty_index; }
+
+ template <typename T>
+ constexpr auto& get(type_tag<T>) {
+ return base_.get(type_tag<T>{});
+ }
+ template <typename T>
+ constexpr const auto& get(type_tag<T>) const {
+ return base_.get(type_tag<T>{});
+ }
+ template <size_t Index>
+ constexpr auto& get(index_tag<Index>) {
+ return base_.get(index_tag<Index>{});
+ }
+ template <size_t Index>
+ constexpr const auto& get(index_tag<Index>) const {
+ return base_.get(index_tag<Index>{});
+ }
+
+ template <typename T, typename... Args>
+ constexpr void construct(type_tag<T>, Args&&... args) {
+ index_ = base_.construct(type_tag<T>{}, std::forward<Args>(args)...);
+ }
+ template <size_t Index, typename... Args>
+ constexpr void construct(index_tag<Index>, Args&&... args) {
+ index_ = base_.construct(index_tag<Index>{}, std::forward<Args>(args)...);
+ }
+
+ constexpr void assign(const indexed_storage& other) {
+ if (index() == other.index()) {
+ base_.assign_at(index_, other.base_);
+ } else {
+ reset();
+ base_.construct_at(other.index_, other.base_);
+ index_ = other.index_;
+ }
+ }
+ constexpr void assign(indexed_storage&& other) {
+ if (index() == other.index()) {
+ base_.assign_at(index_, std::move(other.base_));
+ } else {
+ reset();
+ base_.construct_at(other.index_, std::move(other.base_));
+ index_ = other.index_;
+ }
+ }
+
+ template <typename V>
+ constexpr bool visit(V&& visitor) {
+ return base_.visit(index_, std::forward<V>(visitor));
+ }
+ template <typename V>
+ constexpr bool visit(V&& visitor) const {
+ return base_.visit(index_, std::forward<V>(visitor));
+ }
+
+ constexpr void swap(indexed_storage& other) {
+ if (index() == other.index()) {
+ // Swap directly when the variants are the same, including empty.
+ base_.swap_at(index_, other.base_);
+ } else {
+ // Swap when the variants are different, including one being empty.
+ // This approach avoids GCC -Wmaybe-uninitialized warnings by
+ // initializing and accessing |temp| unconditionally within a
+ // conditional scope. The alternative, using the maybe_init_t
+ // constructor confuses GCC because it doesn't understand that the
+ // index checks prevent uninitialized access.
+ auto do_swap = [](indexed_storage& a, indexed_storage& b) {
+ return a.base_.visit(a.index_, [&a, &b](auto type_tag_v, auto index_tag_v, auto* element) {
+ indexed_storage temp{index_tag_v, std::move(element->value)};
+ a.reset();
+
+ a.base_.construct_at(b.index_, std::move(b.base_));
+ a.index_ = b.index_;
+ b.reset();
+
+ b.base_.construct_at(temp.index_, std::move(temp.base_));
+ b.index_ = temp.index_;
+ temp.reset();
+ });
+ };
+
+ // The visitor above returns false when the first argument is empty
+ // and no action is taken. In that case, the other order is tried to
+ // complete the half-empty swap.
+ do_swap(*this, other) || do_swap(other, *this);
+ }
+ }
+
+ // Destroys the active variant. Does nothing when already empty.
+ constexpr void reset() {
+ base_.reset(index_);
+ index_ = empty_index;
+ }
+
+ private:
+ index_type index_{empty_index};
+ base_type base_;
+};
+
+// Internal variant storage type used by fit::optional and fit::variant.
+// Specializations of this type select trivial vs. non-trivial copy/move
+// construction, assignment operators, and destructor based on the storage class
+// of the types in Ts.
+template <typename StorageClass, typename... Ts>
+struct storage;
+
+template <typename... Ts, size_t... Is>
+struct storage<storage_class<destructor_class::trivial, copy_class::trivial, move_class::trivial>,
+ type_index<Ts, Is>...>
+ : indexed_storage<destructor_class::trivial, type_index<Ts, Is>...> {
+ using base_type = indexed_storage<destructor_class::trivial, type_index<Ts, Is>...>;
+ using base_type::base_type;
+ constexpr storage() = default;
+};
+
+template <typename... Ts, size_t... Is>
+struct storage<
+ storage_class<destructor_class::trivial, copy_class::non_trivial, move_class::trivial>,
+ type_index<Ts, Is>...> : indexed_storage<destructor_class::trivial, type_index<Ts, Is>...> {
+ using base_type = indexed_storage<destructor_class::trivial, type_index<Ts, Is>...>;
+ using base_type::base_type;
+
+ ~storage() = default;
+ constexpr storage() = default;
+
+ constexpr storage(const storage& other) : base_type{maybe_init_v, other} {}
+
+ constexpr storage& operator=(const storage& other) {
+ this->assign(other);
+ return *this;
+ }
+
+ constexpr storage(storage&&) = default;
+ constexpr storage& operator=(storage&&) = default;
+};
+
+template <typename... Ts, size_t... Is>
+struct storage<
+ storage_class<destructor_class::trivial, copy_class::trivial, move_class::non_trivial>,
+ type_index<Ts, Is>...> : indexed_storage<destructor_class::trivial, type_index<Ts, Is>...> {
+ using base_type = indexed_storage<destructor_class::trivial, type_index<Ts, Is>...>;
+ using base_type::base_type;
+
+ ~storage() = default;
+ constexpr storage() = default;
+ constexpr storage(const storage&) = default;
+ constexpr storage& operator=(const storage&) = default;
+
+ constexpr storage(storage&& other) noexcept(base_type::nothrow_move_constructible)
+ : base_type{maybe_init_v, std::move(other)} {}
+
+ constexpr storage& operator=(storage&& other) noexcept(base_type::nothrow_move_assignable) {
+ this->assign(std::move(other));
+ return *this;
+ }
+};
+
+template <typename... Ts, size_t... Is>
+struct storage<
+ storage_class<destructor_class::trivial, copy_class::non_trivial, move_class::non_trivial>,
+ type_index<Ts, Is>...> : indexed_storage<destructor_class::trivial, type_index<Ts, Is>...> {
+ using base_type = indexed_storage<destructor_class::trivial, type_index<Ts, Is>...>;
+ using base_type::base_type;
+
+ ~storage() = default;
+ constexpr storage() = default;
+
+ constexpr storage(const storage& other) : base_type{maybe_init_v, other} {}
+
+ constexpr storage& operator=(const storage& other) {
+ this->assign(other);
+ return *this;
+ }
+
+ constexpr storage(storage&& other) noexcept(base_type::nothrow_move_constructible)
+ : base_type{maybe_init_v, std::move(other)} {}
+
+ constexpr storage& operator=(storage&& other) noexcept(base_type::nothrow_move_assignable) {
+ this->assign(std::move(other));
+ return *this;
+ }
+};
+
+// Specialization for non-trivially movable/copyable types. Types with a non-
+// trivial destructor are always non-trivially movable/copyable.
+template <copy_class CopyClass, move_class MoveClass, typename... Ts, size_t... Is>
+struct storage<storage_class<destructor_class::non_trivial, CopyClass, MoveClass>,
+ type_index<Ts, Is>...>
+ : indexed_storage<destructor_class::non_trivial, type_index<Ts, Is>...> {
+ using base_type = indexed_storage<destructor_class::non_trivial, type_index<Ts, Is>...>;
+ using base_type::base_type;
+
+ ~storage() { this->reset(); }
+
+ constexpr storage() = default;
+
+ constexpr storage(const storage& other) : base_type{maybe_init_v, other} {}
+
+ constexpr storage& operator=(const storage& other) {
+ this->assign(other);
+ return *this;
+ }
+
+ constexpr storage(storage&& other) noexcept(base_type::nothrow_move_constructible)
+ : base_type{maybe_init_v, std::move(other)} {}
+
+ constexpr storage& operator=(storage&& other) noexcept(base_type::nothrow_move_assignable) {
+ this->assign(std::move(other));
+ return *this;
+ }
+};
+
+template <typename... Ts, size_t... Is>
+constexpr auto make_storage(std::index_sequence<Is...>) {
+ return storage<make_storage_class<Ts...>, type_index<Ts, Is>...>{};
+}
+
+template <typename... Ts>
+using storage_type = decltype(make_storage<Ts...>(std::index_sequence_for<Ts...>{}));
+
+} // namespace internal
+} // namespace fit
+
+#endif // LIB_FIT_STORAGE_INTERNAL_H_
diff --git a/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/string_view.h b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/string_view.h
new file mode 100644
index 0000000..b5a3f59
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/string_view.h
@@ -0,0 +1,557 @@
+// 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.
+
+#ifndef LIB_FIT_STRING_VIEW_H_
+#define LIB_FIT_STRING_VIEW_H_
+
+#include <cassert>
+#include <cstdlib>
+#include <ios>
+#include <iterator>
+#include <memory>
+#include <string>
+#include <type_traits>
+#include <utility>
+
+namespace fit {
+
+namespace internal {
+
+// Constexpr filler for std::swap. No specialization for arrays.
+template <typename T>
+constexpr void constexpr_swap(T& a, T& b) noexcept {
+ T tmp = std::move(a);
+ a = std::move(b);
+ b = std::move(tmp);
+}
+
+// Constexpr filler for C++17 std::addressof.
+template <typename T>
+constexpr T* addressof(T& arg) {
+ return reinterpret_cast<T*>(&const_cast<char&>(reinterpret_cast<const volatile char&>(arg)));
+}
+
+// Filler for char_traits<CharT>::compare
+template <typename CharT>
+constexpr int compare(const CharT* s1, const CharT* s2, std::size_t count) {
+ for (std::size_t curr = 0; curr < count; ++curr) {
+ // Exit as soon as we find a different character.
+ if (std::char_traits<CharT>::lt(s1[curr], s2[curr])) {
+ return -1;
+ } else if (!std::char_traits<CharT>::eq(s1[curr], s2[curr])) {
+ return 1;
+ }
+ }
+ // If all characters within [s1, s1+count) and [s2, s2+count) are equal
+ // return 0.
+ return 0;
+}
+
+// Returns the distance from |begin| to first character in [|it|, |end|) that is equal to
+// |needle.front()|.
+// Returns |StringViewType::npos| if no such character is found.
+//
+// Complexity: O(|std::distance(it, end)|).
+template <typename StringViewType, typename Iterator>
+typename StringViewType::size_type find_char(Iterator it, Iterator begin, Iterator end,
+ StringViewType needle) {
+ // Look starting point.
+ while (it != end && !StringViewType::traits_type::eq(*it, needle.front())) {
+ ++it;
+ }
+
+ if (it == end) {
+ return StringViewType::npos;
+ }
+ return static_cast<typename StringViewType::size_type>(std::distance(begin, it));
+}
+
+// Returns the distance from the first character starting from |begin| that matches
+// any characters in |matchers|.
+// Returns |StringViewType::npos| if no characters are within |matchers|.
+//
+// Complexity: O(|std::distance(begin, end)|*|matchers.length()|).
+template <typename StringViewType, typename Iterator>
+constexpr typename StringViewType::size_type find_first_of(Iterator begin, Iterator end,
+ StringViewType matchers) {
+ typename StringViewType::size_type curr = 0;
+ for (Iterator it = begin; it < end; ++it) {
+ for (const auto& matcher : matchers) {
+ if (StringViewType::traits_type::eq(*it, matcher)) {
+ return curr;
+ }
+ }
+ ++curr;
+ }
+
+ return StringViewType::npos;
+}
+
+// Returns the distance from the first character starting from |begin| that does not match
+// any characters in |matchers|.
+// Returns |StringViewType::npos| if all characters are within |matchers|.
+//
+// Complexity: O(|std::distance(begin, end)|*|matchers.length()|).
+template <typename StringViewType, typename Iterator>
+constexpr typename StringViewType::size_type find_first_not_of(Iterator begin, Iterator end,
+ StringViewType matchers) {
+ typename StringViewType::size_type curr = 0;
+
+ for (Iterator it = begin; it < end; ++it) {
+ bool matched = false;
+ for (const auto& matcher : matchers) {
+ if (StringViewType::traits_type::eq(*it, matcher)) {
+ matched = true;
+ break;
+ }
+ }
+
+ if (!matched) {
+ return curr;
+ }
+ ++curr;
+ }
+
+ return StringViewType::npos;
+}
+
+// Returns the starting point of |needle| within |haystack|.
+// If no match is found, return |StringViewType::npos|.
+//
+// Complexity: O(|std::distance(begin, end)| * |needle.length()|)
+template <typename StringViewType, typename Iterator>
+constexpr typename StringViewType::size_type find(Iterator begin, Iterator end,
+ const StringViewType needle) {
+ // If the needle does not fit in the haystack, there is no possible match.
+ if (static_cast<typename StringViewType::size_type>(std::distance(begin, end)) <
+ needle.length()) {
+ return StringViewType::npos;
+ }
+
+ if (needle.empty()) {
+ return 0;
+ }
+
+ Iterator it = begin;
+
+ while (it < end) {
+ typename StringViewType::size_type offset = find_char(it, begin, end, needle);
+ // If no match discard.
+ if (offset == StringViewType::npos) {
+ return StringViewType::npos;
+ }
+ it = begin + offset;
+
+ if (internal::compare<typename StringViewType::value_type>(&(*it), needle.data(),
+ needle.size()) == 0) {
+ return std::distance(begin, it);
+ }
+ ++it;
+ }
+
+ // We did not find the substring in the haystack.
+ return StringViewType::npos;
+}
+
+} // namespace internal
+
+// Provides a view to a sequence of characters.
+template <class CharT, class Traits = std::char_traits<CharT>>
+class basic_string_view {
+ public:
+ using traits_type = Traits;
+ using value_type = CharT;
+ using pointer = CharT*;
+ using const_pointer = const CharT*;
+ using reference = CharT&;
+ using const_reference = const CharT&;
+ using iterator = const_pointer;
+ using const_iterator = iterator;
+ using reverse_iterator = std::reverse_iterator<const_iterator>;
+ using const_reverse_iterator = reverse_iterator;
+ using size_type = std::size_t;
+ using difference_type = std::ptrdiff_t;
+
+ static constexpr size_type npos = static_cast<size_type>(-1);
+
+ constexpr basic_string_view() noexcept : data_(nullptr), length_(0) {}
+ constexpr basic_string_view(const CharT* s, size_type count) noexcept
+ : data_(s), length_(count) {}
+ constexpr basic_string_view(const CharT* s) noexcept : data_(s), length_(Traits::length(s)) {}
+ template <typename Allocator>
+ basic_string_view(const std::basic_string<CharT, Traits, Allocator>& s) noexcept
+ : data_(s.data()), length_(s.length()) {}
+ constexpr basic_string_view(const basic_string_view& other) noexcept = default;
+ basic_string_view(basic_string_view&&) noexcept = default;
+ constexpr basic_string_view& operator=(const basic_string_view& view) noexcept = default;
+ constexpr basic_string_view& operator=(basic_string_view&&) noexcept = default;
+ ~basic_string_view() = default;
+
+ constexpr iterator begin() const { return data_; }
+ constexpr iterator end() const { return begin() + length_; }
+ constexpr const_iterator cbegin() const { return data_; }
+ constexpr const_iterator cend() const { return begin() + length_; }
+
+ constexpr reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
+ constexpr reverse_iterator rend() const { return const_reverse_iterator(begin()); }
+ constexpr const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); }
+ constexpr const_reverse_iterator crend() const { return const_reverse_iterator(begin()); }
+
+ constexpr const_pointer data() const { return data_; }
+ constexpr size_type size() const { return length_; }
+ constexpr size_type length() const { return length_; }
+ constexpr size_type max_size() const { return std::numeric_limits<size_type>::max(); }
+
+ constexpr const_reference front() const { return this->operator[](0); }
+ constexpr const_reference back() const { return this->operator[](size() - 1); }
+ constexpr bool empty() const { return size() == 0; }
+
+ constexpr const_reference operator[](size_type pos) const { return *(data() + pos); }
+ constexpr const_reference at(size_type pos) const {
+ assert(pos < size());
+ return this->operator[](pos);
+ }
+
+ constexpr void remove_prefix(size_type n) {
+ data_ += n;
+ length_ -= n;
+ }
+ constexpr void remove_suffix(size_type n) { length_ -= n; }
+
+ constexpr void swap(basic_string_view& other) noexcept {
+ internal::constexpr_swap(data_, other.data_);
+ internal::constexpr_swap(length_, other.length_);
+ }
+
+ size_type copy(CharT* dest, size_type count, size_type pos = 0) const {
+ assert(pos < size());
+ Traits::copy(dest, data() + pos, calculate_length(pos, count));
+ return count;
+ }
+
+ constexpr basic_string_view substr(size_type pos = 0, size_type count = npos) const {
+ return basic_string_view(data() + pos, calculate_length(pos, count));
+ }
+
+ constexpr int compare(basic_string_view v) const {
+ const int result = internal::compare(data(), v.data(), std::min(size(), v.size()));
+ if (result == 0) {
+ return static_cast<int>(size() - v.size());
+ }
+ return result;
+ }
+
+ constexpr int compare(size_type pos1, size_type count1, basic_string_view v) const {
+ return substr(pos1, count1).compare(v);
+ }
+
+ constexpr int compare(size_type pos1, size_type count1, basic_string_view v, size_type pos2,
+ size_type count2) const {
+ return substr(pos1, count1).compare(v.substr(pos2, count2));
+ }
+
+ constexpr int compare(const CharT* s) const { return compare(basic_string_view(s)); }
+
+ constexpr int compare(size_type pos1, size_type count1, const CharT* s) const {
+ return substr(pos1, count1).compare(basic_string_view(s));
+ }
+
+ constexpr int compare(size_type pos1, size_type count1, const CharT* s, size_type count2) const {
+ return substr(pos1, count1).compare(basic_string_view(s, count2));
+ }
+
+ constexpr size_type find(basic_string_view v, size_type pos = 0) const noexcept {
+ auto tmp = internal::find(substr(pos).begin(), substr(pos).end(), v);
+ return (tmp == npos) ? npos : pos + tmp;
+ }
+
+ constexpr size_type find(CharT ch, size_type pos = 0) const {
+ return find(basic_string_view(internal::addressof(ch), 1), pos);
+ }
+
+ constexpr size_type find(const CharT* s, size_type pos, size_type count) const {
+ return find(basic_string_view(s, count), pos);
+ }
+
+ constexpr size_type find(const CharT* s, size_type pos) const {
+ return find(basic_string_view(s), pos);
+ }
+
+ constexpr size_type rfind(basic_string_view v, size_type pos = 0) const noexcept {
+ auto tmp = internal::find(substr(pos).rbegin(), substr(pos).rend(), v);
+ return (tmp == npos) ? npos : length() - 1 - tmp;
+ }
+
+ constexpr size_type rfind(CharT ch, size_type pos = 0) const {
+ return rfind(basic_string_view(internal::addressof(ch), 1), pos);
+ }
+
+ constexpr size_type rfind(const CharT* s, size_type pos, size_type count) const {
+ return rfind(basic_string_view(s, count), pos);
+ }
+
+ constexpr size_type rfind(const CharT* s, size_type pos) const {
+ return rfind(basic_string_view(s), pos);
+ }
+
+ constexpr size_type find_first_of(basic_string_view v, size_type pos = 0) const noexcept {
+ auto tmp = internal::find_first_of(substr(pos).begin(), substr(pos).end(), v);
+ return tmp == npos ? npos : pos + tmp;
+ }
+
+ constexpr size_type find_first_of(CharT c, size_type pos = 0) const noexcept {
+ return find_first_of(basic_string_view(internal::addressof(c), 1), pos);
+ }
+
+ constexpr size_type find_first_of(const CharT* s, size_type pos, size_type count) const {
+ return find_first_of(basic_string_view(s, count), pos);
+ }
+
+ constexpr size_type find_first_of(const CharT* s, size_type pos = 0) const {
+ return find_first_of(basic_string_view(s), pos);
+ }
+
+ constexpr size_type find_last_of(basic_string_view v,
+ size_type pos = basic_string_view::npos) const noexcept {
+ const size_type fixed_length = (pos == npos) ? size() : pos + 1;
+ const size_type tmp = internal::find_first_of(substr(0, fixed_length).rbegin(),
+ substr(0, fixed_length).rend(), v);
+ return tmp == npos ? npos : fixed_length - 1 - tmp;
+ }
+
+ constexpr size_type find_last_of(CharT c, size_type pos = basic_string_view::npos) const
+ noexcept {
+ return find_last_of(basic_string_view(internal::addressof(c), 1), pos);
+ }
+
+ constexpr size_type find_last_of(const CharT* s, size_type pos, size_type count) const {
+ return find_last_of(basic_string_view(s, count), pos);
+ }
+
+ constexpr size_type find_last_of(const CharT* s, size_type pos = basic_string_view::npos) const {
+ return find_last_of(basic_string_view(s), pos);
+ }
+
+ constexpr size_type find_first_not_of(basic_string_view v, size_type pos = 0) const noexcept {
+ const auto tmp = internal::find_first_not_of(substr(pos).begin(), substr(pos).end(), v);
+ return tmp == npos ? npos : pos + tmp;
+ }
+
+ constexpr size_type find_first_not_of(CharT c, size_type pos = 0) const noexcept {
+ return find_first_not_of(basic_string_view(internal::addressof(c), 1), pos);
+ }
+
+ constexpr size_type find_first_not_of(const CharT* s, size_type pos, size_type count) const {
+ return find_first_not_of(basic_string_view(s, count), pos);
+ }
+
+ constexpr size_type find_first_not_of(const CharT* s, size_type pos = 0) const {
+ return find_first_not_of(basic_string_view(s), pos);
+ }
+
+ constexpr size_type find_last_not_of(basic_string_view v,
+ size_type pos = basic_string_view::npos) const noexcept {
+ const size_type fixed_length = (pos == npos) ? size() : pos + 1;
+ auto tmp = internal::find_first_not_of(substr(0, fixed_length).rbegin(),
+ substr(0, fixed_length).rend(), v);
+ return tmp == npos ? npos : fixed_length - 1 - tmp;
+ }
+
+ constexpr size_type find_last_not_of(CharT c, size_type pos = basic_string_view::npos) const
+ noexcept {
+ return find_last_not_of(basic_string_view(internal::addressof(c), 1), pos);
+ }
+
+ constexpr size_type find_last_not_of(const CharT* s, size_type pos, size_type count) const {
+ return find_last_not_of(basic_string_view(s, count), pos);
+ }
+
+ constexpr size_type find_last_not_of(const CharT* s,
+ size_type pos = basic_string_view::npos) const {
+ return find_last_not_of(basic_string_view(s), pos);
+ }
+
+ private:
+ constexpr size_type calculate_length(size_type pos, size_type count) const {
+ if (count == npos) {
+ count = size();
+ }
+ return std::min(count, size() - pos);
+ }
+
+ const_pointer data_;
+ size_type length_;
+};
+
+// Operators and overloads to satisfy all conversions.
+//
+// Defined overloads are of the form:
+// <basic_string_view, basic_string_view>
+// <RawType, basic_string_view>
+// <basic_string_view, RawType>
+//
+// When |RawType| is lhs: std::is_constructible<basic_string_view, RawType>::value must be true.
+// When |RawType| is rhs: There must be an overload of basic_string_view::compare for |RawType|.
+template <class CharT, class Traits>
+constexpr bool operator==(fit::basic_string_view<CharT, Traits> lhs,
+ fit::basic_string_view<CharT, Traits> rhs) noexcept {
+ return lhs.compare(rhs) == 0;
+}
+
+template <class CharT, class Traits, class RawType>
+constexpr bool operator==(RawType lhs, fit::basic_string_view<CharT, Traits> rhs) noexcept {
+ return fit::basic_string_view<CharT, Traits>(lhs).compare(rhs) == 0;
+}
+
+template <class CharT, class Traits, class RawType>
+constexpr bool operator==(fit::basic_string_view<CharT, Traits> lhs, RawType rhs) noexcept {
+ return lhs.compare(rhs) == 0;
+}
+
+template <class CharT, class Traits>
+constexpr bool operator!=(fit::basic_string_view<CharT, Traits> lhs,
+ fit::basic_string_view<CharT, Traits> rhs) noexcept {
+ return lhs.compare(rhs) != 0;
+}
+
+template <class CharT, class Traits, class RawType>
+constexpr bool operator!=(RawType lhs, fit::basic_string_view<CharT, Traits> rhs) noexcept {
+ return fit::basic_string_view<CharT, Traits>(lhs).compare(rhs) != 0;
+}
+
+template <class CharT, class Traits, class RawType>
+constexpr bool operator!=(fit::basic_string_view<CharT, Traits> lhs, RawType rhs) noexcept {
+ return lhs.compare(rhs) != 0;
+}
+
+template <class CharT, class Traits>
+constexpr bool operator<(fit::basic_string_view<CharT, Traits> lhs,
+ fit::basic_string_view<CharT, Traits> rhs) noexcept {
+ return lhs.compare(rhs) < 0;
+}
+
+template <class CharT, class Traits, class RawType>
+constexpr bool operator<(RawType lhs, fit::basic_string_view<CharT, Traits> rhs) noexcept {
+ return fit::basic_string_view<CharT, Traits>(lhs).compare(rhs) < 0;
+}
+
+template <class CharT, class Traits, class RawType>
+constexpr bool operator<(fit::basic_string_view<CharT, Traits> lhs, RawType rhs) noexcept {
+ return lhs.compare(rhs) < 0;
+}
+
+template <class CharT, class Traits>
+constexpr bool operator>(fit::basic_string_view<CharT, Traits> lhs,
+ fit::basic_string_view<CharT, Traits> rhs) noexcept {
+ return lhs.compare(rhs) > 0;
+}
+
+template <class CharT, class Traits, class RawType>
+constexpr bool operator>(RawType lhs, fit::basic_string_view<CharT, Traits> rhs) noexcept {
+ return fit::basic_string_view<CharT, Traits>(lhs).compare(rhs) > 0;
+}
+
+template <class CharT, class Traits, class RawType>
+constexpr bool operator>(fit::basic_string_view<CharT, Traits> lhs, RawType rhs) noexcept {
+ return lhs.compare(rhs) > 0;
+}
+
+template <class CharT, class Traits>
+constexpr bool operator<=(fit::basic_string_view<CharT, Traits> lhs,
+ fit::basic_string_view<CharT, Traits> rhs) noexcept {
+ return lhs.compare(rhs) <= 0;
+}
+
+template <class CharT, class Traits, class RawType>
+constexpr bool operator<=(RawType lhs, fit::basic_string_view<CharT, Traits> rhs) noexcept {
+ return fit::basic_string_view<CharT, Traits>(lhs).compare(rhs) <= 0;
+}
+
+template <class CharT, class Traits, class RawType>
+constexpr bool operator<=(fit::basic_string_view<CharT, Traits> lhs, RawType rhs) noexcept {
+ return lhs.compare(rhs) <= 0;
+}
+
+template <class CharT, class Traits>
+constexpr bool operator>=(fit::basic_string_view<CharT, Traits> lhs,
+ fit::basic_string_view<CharT, Traits> rhs) noexcept {
+ return lhs.compare(rhs) >= 0;
+}
+
+template <class CharT, class Traits, class RawType>
+constexpr bool operator>=(RawType lhs, fit::basic_string_view<CharT, Traits> rhs) noexcept {
+ return fit::basic_string_view<CharT, Traits>(lhs).compare(rhs) >= 0;
+}
+
+template <class CharT, class Traits, class RawType>
+constexpr bool operator>=(fit::basic_string_view<CharT, Traits> lhs, RawType rhs) noexcept {
+ return lhs.compare(rhs) >= 0;
+}
+
+// Specializations.
+using string_view = fit::basic_string_view<char>;
+
+// Constructs a string_view from ""_sv literal.
+// Literals with no leading underscore are reserved for the standard library.
+// https://en.cppreference.com/w/cpp/string/basic_string_view/operator%22%22sv
+inline namespace literals {
+inline namespace string_view_literals {
+
+constexpr fit::string_view operator"" _sv(typename fit::string_view::const_pointer str,
+ typename fit::string_view::size_type len) noexcept {
+ return fit::string_view(str, len);
+}
+} // namespace string_view_literals
+} // namespace literals
+
+} // namespace fit
+
+namespace std {
+// Hash needs to match basic_string view hash of the same string, so we need to rely on compiler
+// implementation.
+// https://en.cppreference.com/w/cpp/string/basic_string_view/hash
+template <class CharT>
+struct hash<fit::basic_string_view<CharT, std::char_traits<CharT>>> {
+ std::size_t operator()(const fit::basic_string_view<CharT, std::char_traits<CharT>> val) const {
+ return __do_string_hash(val.data(), val.data() + val.length());
+ }
+};
+
+// Ouput stream specialization for fit::string_view.
+//
+// https://en.cppreference.com/w/cpp/string/basic_string_view/operator_ltlt
+template <class CharT, class Traits>
+std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os,
+ fit::basic_string_view<CharT, Traits> v) {
+ using size_type = typename fit::basic_string_view<CharT, Traits>::size_type;
+ const size_type fixed_length = std::min(static_cast<size_type>(os.width()), v.length());
+ const size_type fill_length =
+ (static_cast<size_type>(os.width()) > v.length()) ? os.width() - v.length() : 0;
+
+ auto fill_space = [](std::basic_ostream<CharT, Traits>& os, size_type fill_length) {
+ for (std::size_t i = 0; i < fill_length; ++i) {
+ os.put(os.fill());
+ }
+ };
+
+ bool fill_left = (os.flags() & std::ios_base::adjustfield) == std::ios_base::left;
+
+ if (!fill_left) {
+ fill_space(os, fill_length);
+ }
+
+ os.write(v.data(), fixed_length);
+
+ if (fill_left) {
+ fill_space(os, fill_length);
+ }
+
+ os.width(0);
+
+ return os;
+}
+
+} // namespace std
+
+#endif
diff --git a/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/thread_safety.h b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/thread_safety.h
new file mode 100644
index 0000000..9545def
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/thread_safety.h
@@ -0,0 +1,29 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIT_THREAD_SAFETY_H_
+#define LIB_FIT_THREAD_SAFETY_H_
+
+// Thread-safety annotations.
+// Currently these are only supported on Clang.
+#if defined(__clang__) && defined(_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS) && \
+ __has_attribute(acquire_capability)
+#define FIT_THREAD_ANNOTATION(x) __attribute__((x))
+#else
+#define FIT_THREAD_ANNOTATION(x)
+#endif
+#define FIT_CAPABILITY(x) FIT_THREAD_ANNOTATION(__capability__(x))
+#define FIT_GUARDED(x) FIT_THREAD_ANNOTATION(__guarded_by__(x))
+#define FIT_ACQUIRE(...) FIT_THREAD_ANNOTATION(__acquire_capability__(__VA_ARGS__))
+#define FIT_TRY_ACQUIRE(...) FIT_THREAD_ANNOTATION(__try_acquire_capability__(__VA_ARGS__))
+#define FIT_ACQUIRED_BEFORE(...) FIT_THREAD_ANNOTATION(__acquired_before__(__VA_ARGS__))
+#define FIT_ACQUIRED_AFTER(...) FIT_THREAD_ANNOTATION(__acquired_after__(__VA_ARGS__))
+#define FIT_RELEASE(...) FIT_THREAD_ANNOTATION(__release_capability__(__VA_ARGS__))
+#define FIT_REQUIRES(...) FIT_THREAD_ANNOTATION(__requires_capability__(__VA_ARGS__))
+#define FIT_EXCLUDES(...) FIT_THREAD_ANNOTATION(__locks_excluded__(__VA_ARGS__))
+#define FIT_RETURN_CAPABILITY(x) FIT_THREAD_ANNOTATION(__lock_returned__(x))
+#define FIT_SCOPED_CAPABILITY FIT_THREAD_ANNOTATION(__scoped_lockable__)
+#define FIT_NO_THREAD_SAFETY_ANALYSIS FIT_THREAD_ANNOTATION(__no_thread_safety_analysis__)
+
+#endif // LIB_FIT_THREAD_SAFETY_H_
diff --git a/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/traits.h b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/traits.h
new file mode 100644
index 0000000..ff43b92
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/traits.h
@@ -0,0 +1,155 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIT_TRAITS_H_
+#define LIB_FIT_TRAITS_H_
+
+#include <tuple>
+#include <type_traits>
+
+namespace fit {
+
+// C++14 compatible polyfill for C++17 traits.
+#if defined(__cplusplus) && __cplusplus >= 201703L
+
+template <typename... T>
+using void_t = std::void_t<T...>;
+
+template <typename... Ts>
+using conjunction = std::conjunction<Ts...>;
+template <typename... Ts>
+inline constexpr bool conjunction_v = std::conjunction_v<Ts...>;
+
+template <typename... Ts>
+using disjunction = std::disjunction<Ts...>;
+template <typename... Ts>
+inline constexpr bool disjunction_v = std::disjunction_v<Ts...>;
+
+template <typename... Ts>
+using negation = std::negation<Ts...>;
+template <typename... Ts>
+inline constexpr bool negation_v = std::negation_v<Ts...>;
+
+#else
+
+template <typename... T>
+struct make_void {
+ typedef void type;
+};
+template <typename... T>
+using void_t = typename make_void<T...>::type;
+
+template <typename... Ts>
+struct conjunction : std::true_type {};
+template <typename T>
+struct conjunction<T> : T {};
+template <typename First, typename... Rest>
+struct conjunction<First, Rest...>
+ : std::conditional_t<bool(First::value), conjunction<Rest...>, First> {};
+
+template <typename... Ts>
+constexpr bool conjunction_v = conjunction<Ts...>::value;
+
+template <typename... Ts>
+struct disjunction : std::false_type {};
+template <typename T>
+struct disjunction<T> : T {};
+template <typename First, typename... Rest>
+struct disjunction<First, Rest...>
+ : std::conditional_t<bool(First::value), First, disjunction<Rest...>> {};
+
+template <typename... Ts>
+constexpr bool disjunction_v = disjunction<Ts...>::value;
+
+// Utility type that negates its truth-like parameter type.
+template <typename T>
+struct negation : std::integral_constant<bool, !bool(T::value)> {};
+
+template <typename T>
+constexpr bool negation_v = negation<T>::value;
+
+#endif
+
+// Encapsulates capture of a parameter pack. Typical use is to use instances of this empty struct
+// for type dispatch in function template deduction/overload resolution.
+//
+// Example:
+// template <typename Callable, typename... Args>
+// auto inspect_args(Callable c, parameter_pack<Args...>) {
+// // do something with Args...
+// }
+//
+// template <typename Callable>
+// auto inspect_args(Callable c) {
+// return inspect_args(std::move(c), typename callable_traits<Callable>::args{});
+// }
+template <typename... T>
+struct parameter_pack {
+ static constexpr size_t size = sizeof...(T);
+
+ template <size_t i>
+ using at = typename std::tuple_element_t<i, std::tuple<T...>>;
+};
+
+// |callable_traits| captures elements of interest from function-like types (functions, function
+// pointers, and functors, including lambdas). Due to common usage patterns, const and non-const
+// functors are treated identically.
+//
+// Member types:
+// |args| - a |parameter_pack| that captures the parameter types of the function. See
+// |parameter_pack| for usage and details.
+// |return_type| - the return type of the function.
+// |type| - the underlying functor or function pointer type. This member is absent if
+// |callable_traits| are requested for a raw function signature (as opposed to a
+// function pointer or functor; e.g. |callable_traits<void()>|).
+// |signature| - the type of the equivalent function.
+
+template <typename T>
+struct callable_traits : public callable_traits<decltype(&T::operator())> {};
+
+// Treat mutable call operators the same as const call operators.
+//
+// It would be equivalent to erase the const instead, but the common case is lambdas, which are
+// const, so prefer to nest less deeply for the common const case.
+template <typename FunctorType, typename ReturnType, typename... ArgTypes>
+struct callable_traits<ReturnType (FunctorType::*)(ArgTypes...)>
+ : public callable_traits<ReturnType (FunctorType::*)(ArgTypes...) const> {};
+
+// Common functor specialization.
+template <typename FunctorType, typename ReturnType, typename... ArgTypes>
+struct callable_traits<ReturnType (FunctorType::*)(ArgTypes...) const>
+ : public callable_traits<ReturnType (*)(ArgTypes...)> {
+ using type = FunctorType;
+};
+
+// Function pointer specialization.
+template <typename ReturnType, typename... ArgTypes>
+struct callable_traits<ReturnType (*)(ArgTypes...)>
+ : public callable_traits<ReturnType(ArgTypes...)> {
+ using type = ReturnType (*)(ArgTypes...);
+};
+
+// Base specialization.
+template <typename ReturnType, typename... ArgTypes>
+struct callable_traits<ReturnType(ArgTypes...)> {
+ using signature = ReturnType(ArgTypes...);
+ using return_type = ReturnType;
+ using args = parameter_pack<ArgTypes...>;
+
+ callable_traits() = delete;
+};
+
+// Determines whether a type has an operator() that can be invoked.
+template <typename T, typename = void_t<>>
+struct is_callable : public std::false_type {};
+template <typename ReturnType, typename... ArgTypes>
+struct is_callable<ReturnType (*)(ArgTypes...)> : public std::true_type {};
+template <typename FunctorType, typename ReturnType, typename... ArgTypes>
+struct is_callable<ReturnType (FunctorType::*)(ArgTypes...)> : public std::true_type {};
+template <typename T>
+struct is_callable<T, void_t<decltype(&T::operator())>> : public std::true_type {};
+
+} // namespace fit
+
+#endif // LIB_FIT_TRAITS_H_
diff --git a/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/utility_internal.h b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/utility_internal.h
new file mode 100644
index 0000000..2351831
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/utility_internal.h
@@ -0,0 +1,134 @@
+// 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.
+
+#ifndef LIB_FIT_UTILITY_INTERNAL_H_
+#define LIB_FIT_UTILITY_INTERNAL_H_
+
+#include <type_traits>
+#include <utility>
+
+#include "traits.h"
+
+namespace fit {
+namespace internal {
+
+// Utility to return the first type in a parameter pack.
+template <typename... Ts>
+struct first;
+template <typename First, typename... Rest>
+struct first<First, Rest...> {
+ using type = First;
+};
+
+template <typename... Ts>
+using first_t = typename first<Ts...>::type;
+
+// Utility to count the occurences of type T in the parameter pack Ts.
+template <typename T, typename... Ts>
+struct occurences_of : std::integral_constant<size_t, 0> {};
+template <typename T, typename U>
+struct occurences_of<T, U> : std::integral_constant<size_t, std::is_same<T, U>::value> {};
+template <typename T, typename First, typename... Rest>
+struct occurences_of<T, First, Rest...>
+ : std::integral_constant<size_t,
+ occurences_of<T, First>::value + occurences_of<T, Rest...>::value> {};
+
+template <typename T, typename... Ts>
+constexpr size_t occurences_of_v = occurences_of<T, Ts...>::value;
+
+// Utility to remove const, volatile, and reference qualifiers.
+template <typename T>
+using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>;
+
+// Evaluates to truth-like when type T matches type U with cv-reference removed.
+template <typename T, typename U>
+using not_same_type = negation<std::is_same<T, remove_cvref_t<U>>>;
+
+// Concept helper for constructors.
+template <typename... Conditions>
+using requires_conditions = std::enable_if_t<conjunction_v<Conditions...>, bool>;
+
+// Concept helper for assignment operators.
+template <typename Return, typename... Conditions>
+using assignment_requires_conditions =
+ std::enable_if_t<conjunction_v<Conditions...>, std::add_lvalue_reference_t<Return>>;
+
+// Evaluates to true when every element type of Ts is trivially destructible.
+template <typename... Ts>
+constexpr bool is_trivially_destructible_v = conjunction_v<std::is_trivially_destructible<Ts>...>;
+
+// Evaluates to true when every element type of Ts is trivially copyable.
+template <typename... Ts>
+constexpr bool is_trivially_copyable_v =
+ (conjunction_v<std::is_trivially_copy_assignable<Ts>...> &&
+ conjunction_v<std::is_trivially_copy_constructible<Ts>...>);
+
+// Evaluates to true when every element type of Ts is trivially movable.
+template <typename... Ts>
+constexpr bool is_trivially_movable_v =
+ (conjunction_v<std::is_trivially_move_assignable<Ts>...> &&
+ conjunction_v<std::is_trivially_move_constructible<Ts>...>);
+
+// Enable if relational operator is convertible to bool and the optional
+// conditions are true.
+template <typename Op, typename... Conditions>
+using enable_relop_t =
+ std::enable_if_t<(std::is_convertible<Op, bool>::value && conjunction_v<Conditions...>), bool>;
+
+template <typename T>
+struct identity {
+ using type = T;
+};
+
+// Evaluates to true when T is an unbounded array.
+template <typename T>
+struct is_unbounded_array : conjunction<std::is_array<T>, negation<std::extent<T>>> {};
+
+// Returns true when T is a complete type or an unbounded array.
+template <typename T, size_t = sizeof(T)>
+constexpr bool is_complete_or_unbounded_array(identity<T>) {
+ return true;
+}
+template <typename Identity, typename T = typename Identity::type>
+constexpr bool is_complete_or_unbounded_array(Identity) {
+ return disjunction<std::is_reference<T>, std::is_function<T>, std::is_void<T>,
+ is_unbounded_array<T>>::value;
+}
+
+// Using swap for ADL. This directive is contained within the fit::internal
+// namespace, which prevents leaking std::swap into user namespaces. Doing this
+// at namespace scope is necessary to lookup swap via ADL while preserving the
+// noexcept() specification of the resulting lookup.
+using std::swap;
+
+// Evaluates to true when T is swappable.
+template <typename T, typename = void>
+struct is_swappable : std::false_type {
+ static_assert(is_complete_or_unbounded_array(identity<T>{}),
+ "T must be a complete type or an unbounded array!");
+};
+template <typename T>
+struct is_swappable<T, void_t<decltype(swap(std::declval<T&>(), std::declval<T&>()))>>
+ : std::true_type {
+ static_assert(is_complete_or_unbounded_array(identity<T>{}),
+ "T must be a complete type or an unbounded array!");
+};
+
+// Evaluates to true when T is nothrow swappable.
+template <typename T, typename = void>
+struct is_nothrow_swappable : std::false_type {
+ static_assert(is_complete_or_unbounded_array(identity<T>{}),
+ "T must be a complete type or an unbounded array!");
+};
+template <typename T>
+struct is_nothrow_swappable<T, void_t<decltype(swap(std::declval<T&>(), std::declval<T&>()))>>
+ : std::integral_constant<bool, noexcept(swap(std::declval<T&>(), std::declval<T&>()))> {
+ static_assert(is_complete_or_unbounded_array(identity<T>{}),
+ "T must be a complete type or an unbounded array!");
+};
+
+} // namespace internal
+} // namespace fit
+
+#endif // LIB_FIT_UTILITY_INTERNAL_H_
diff --git a/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/variant.h b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/variant.h
new file mode 100644
index 0000000..5e168b2
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/include/lib/fit/variant.h
@@ -0,0 +1,633 @@
+// Copyright 2018 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.
+
+#ifndef LIB_FIT_VARIANT_H_
+#define LIB_FIT_VARIANT_H_
+
+#include <exception>
+#include <new>
+#include <type_traits>
+#include <utility>
+
+#include "constructors_internal.h"
+#include "in_place_internal.h"
+#include "storage_internal.h"
+#include "traits.h"
+#include "utility_internal.h"
+
+namespace fit {
+
+// A default-constructible type that may be used as the first variant type to
+// make fit::variant default-constructible when other variants are not. This
+// type may also be used as an alternative representing an empty value.
+struct monostate final {
+ constexpr bool operator==(const monostate& other) const { return true; }
+ constexpr bool operator!=(const monostate& other) const { return false; }
+ constexpr bool operator<(const monostate& other) const { return false; }
+ constexpr bool operator>(const monostate& other) const { return false; }
+ constexpr bool operator<=(const monostate& other) const { return true; }
+ constexpr bool operator>=(const monostate& other) const { return true; }
+};
+
+namespace internal {
+
+// Helper type to avoid recursive instantiations of the full variant type.
+template <typename...>
+struct variant_list {};
+
+// Gets the number of alternatives in a variant_list as a compile-time constant.
+template <typename T>
+struct variant_list_size;
+
+template <typename... Ts>
+struct variant_list_size<variant_list<Ts...>> : std::integral_constant<size_t, sizeof...(Ts)> {};
+
+// Helper to get the type of a variant_list alternative with the given index.
+template <size_t Index, typename VariantList>
+struct variant_alternative;
+
+template <size_t Index, typename T0, typename... Ts>
+struct variant_alternative<Index, variant_list<T0, Ts...>>
+ : variant_alternative<Index - 1, variant_list<Ts...>> {};
+
+template <typename T0, typename... Ts>
+struct variant_alternative<0, variant_list<T0, Ts...>> {
+ using type = T0;
+};
+
+} // namespace internal
+
+// Forward declaration.
+template <typename... Ts>
+class variant;
+
+// Gets the type of a variant alternative with the given index.
+template <size_t Index, typename Variant>
+struct variant_alternative;
+
+template <size_t Index, typename... Ts>
+struct variant_alternative<Index, variant<Ts...>>
+ : ::fit::internal::variant_alternative<Index, ::fit::internal::variant_list<Ts...>> {};
+
+template <size_t index, typename Variant>
+using variant_alternative_t = typename variant_alternative<index, Variant>::type;
+
+// Gets the number of alternatives in a variant as a compile-time constant
+// expression.
+template <typename T>
+struct variant_size;
+
+template <typename... Ts>
+struct variant_size<variant<Ts...>> : std::integral_constant<size_t, sizeof...(Ts)> {};
+
+template <typename T>
+struct variant_size<const T> : variant_size<T> {};
+template <typename T>
+struct variant_size<volatile T> : variant_size<T> {};
+template <typename T>
+struct variant_size<const volatile T> : variant_size<T> {};
+
+#ifdef __cpp_inline_variables
+
+template <typename T>
+inline constexpr size_t variant_size_v = variant_size<T>::value;
+
+#else
+
+template <typename T>
+struct variant_size_holder {
+ static constexpr size_t value{variant_size<T>::value};
+};
+
+template <typename T>
+constexpr size_t variant_size_holder<T>::value;
+
+template <typename T>
+static constexpr const size_t& variant_size_v = variant_size_holder<T>::value;
+
+#endif
+
+// Exception type to report bad accesses to variant.
+class bad_variant_access : public std::exception {
+ public:
+ bad_variant_access() noexcept {}
+
+ const char* what() const noexcept override { return reason_; }
+
+ private:
+ template <typename... Ts>
+ friend class variant;
+
+ bad_variant_access(const char* reason) noexcept : reason_{reason} {}
+
+ // String describing the reason for the bad access. Must point to a string
+ // with static storage duration.
+ const char* reason_;
+};
+
+namespace internal {
+
+// Helper type to check that conversions do not narrow.
+template <typename T>
+struct check_narrow {
+ T x[1];
+};
+
+// Builds a check(Ti) function for each alternative Ti. This trait is evaluated
+// for each element of fit::variant<Ts...>. Essentially: for (Index, Ti) in Ts.
+//
+// Index is the zero-based index of the corresponding element Ti in the pack Ts.
+// T is the type deduced from the converting constructor or assignment operator
+// of fit::variant for which we want to find an appropriately convertible
+// element.
+//
+// The specializations below match the element Ti that passes the conversion
+// checks.
+template <size_t Index, typename T, typename Ti,
+ bool IsBool = std::is_same<bool, std::remove_cv_t<Ti>>::value, typename = void>
+struct check_valid_option {
+ // Non-static so that check_valid_option<...>::check is always a valid
+ // name, but doesn't participate in the overload resolution in the
+ // valid_option_index selection trait.
+ void check();
+};
+
+// Checks that Ti x[] = {std::forward<T>()} is well formed.
+template <size_t Index, typename T, typename Ti>
+struct check_valid_option<Index, T, Ti, false,
+ void_t<decltype(check_narrow<Ti>{{std::declval<T>()}})>> {
+ static std::integral_constant<size_t, Index> check(Ti);
+};
+
+// Checks that remove_cvref_t<T> is bool when Ti is cv bool.
+template <size_t Index, typename T, typename Ti>
+struct check_valid_option<Index, T, Ti, true,
+ std::enable_if_t<std::is_same<bool, remove_cvref_t<T>>::value>> {
+ static std::integral_constant<size_t, Index> check(Ti);
+};
+
+// Mixes in instantiations of check_valid_option for each element in
+// fit::variant<Ts...>, creating a set of check(Ti) functions that might match
+// T following the conversion rules.
+template <typename T, typename VariantList,
+ typename = std::make_index_sequence<variant_list_size<VariantList>::value>>
+struct find_valid_option {
+ // Non-static so that find_valid_option<...>::check is always a valid name
+ // in the using clause of the recursive case, but doesn't participate in the
+ // overload resolution in the valid_option_index trait.
+ void check();
+};
+
+// Recursive case. This would be simpler with C++17 pack expansion in using
+// directives, but this must function in C++14.
+template <typename T, typename Ti, size_t Index, typename... Ts, size_t... Is>
+struct find_valid_option<T, variant_list<Ti, Ts...>, std::index_sequence<Index, Is...>>
+ : check_valid_option<Index, T, Ti>,
+ find_valid_option<T, variant_list<Ts...>, std::index_sequence<Is...>> {
+ // Introduce the base class definitions of check() into this scope. The
+ // static check(Ti) methods participate in overload resolution in the
+ // valid_option_index trait, while the non-static check() methods are
+ // ignored.
+ using check_valid_option<Index, T, Ti>::check;
+ using find_valid_option<T, variant_list<Ts...>, std::index_sequence<Is...>>::check;
+};
+
+// Evaluates to the index of the valid target type Ti selected from
+// fit::variant<Ts...>. The type expression is well formed IFF a single valid
+// target type is available that converts from T.
+template <typename T, typename VariantList>
+using valid_option_index = decltype(find_valid_option<T, VariantList>::check(std::declval<T>()));
+
+// Evaluates to the index of the valid target Ti that converts from T or the
+// reserved empty index when no uniquely suitable option is available.
+template <typename T, typename Variant, typename = void>
+struct selected_index : std::integral_constant<size_t, ::fit::internal::empty_index> {};
+
+template <typename T, typename... Ts>
+struct selected_index<T, variant<Ts...>, void_t<valid_option_index<T, variant_list<Ts...>>>>
+ : valid_option_index<T, variant_list<Ts...>> {};
+
+} // namespace internal
+
+// A resonably complete implementation of std::variant compatible with C++14.
+template <typename... Ts>
+class variant
+ : private ::fit::internal::modulate_default_constructor<::fit::internal::first_t<Ts...>>,
+ private ::fit::internal::modulate_copy_and_move<Ts...> {
+ private:
+ static_assert(sizeof...(Ts) > 0, "Variant must have at least one type!");
+
+ static constexpr bool nothrow_default_constructible =
+ std::is_nothrow_default_constructible<::fit::internal::first_t<Ts...>>::value;
+
+ static constexpr bool nothrow_move_constructible =
+ conjunction_v<std::is_nothrow_move_constructible<Ts>...>;
+
+ static constexpr auto default_init_v = ::fit::internal::default_init_v;
+ static constexpr auto trivial_init_v = ::fit::internal::trivial_init_v;
+
+ template <typename T>
+ using type_tag = ::fit::internal::type_tag<T>;
+ template <size_t Index>
+ using index_tag = ::fit::internal::index_tag<Index>;
+
+ template <typename T>
+ using not_self_type = ::fit::internal::not_same_type<variant, T>;
+
+ template <typename T>
+ using not_in_place = ::fit::internal::not_same_type<in_place_t, T>;
+
+ template <typename T>
+ struct occurs_once
+ : std::integral_constant<bool, ::fit::internal::occurences_of_v<T, Ts...> == 1> {};
+
+ template <typename... Conditions>
+ using requires_conditions = ::fit::internal::requires_conditions<Conditions...>;
+
+ template <typename... Conditions>
+ using assignment_requires_conditions =
+ ::fit::internal::assignment_requires_conditions<variant&, Conditions...>;
+
+ template <typename T, typename... Args>
+ using emplace_constructible_by_type =
+ std::enable_if_t<(::fit::internal::occurences_of_v<T, Ts...> == 1 &&
+ std::is_constructible<T, Args...>::value),
+ std::add_lvalue_reference_t<T>>;
+
+ template <size_t Index, typename = std::enable_if_t<(Index < sizeof...(Ts))>>
+ using alternative_t = variant_alternative_t<Index, variant>;
+
+ template <size_t Index, typename... Args>
+ using emplace_constructible_by_index =
+ std::enable_if_t<std::is_constructible<alternative_t<Index>, Args...>::value,
+ std::add_lvalue_reference_t<alternative_t<Index>>>;
+
+ template <typename T>
+ static constexpr size_t selected_index = ::fit::internal::selected_index<T, variant>::value;
+
+ template <typename T, typename = std::enable_if<not_self_type<T>::value>>
+ using selected_t = alternative_t<selected_index<T>>;
+
+ [[noreturn]] static constexpr void throw_bad_variant_access(const char* reason) {
+#if __cpp_exceptions
+ throw bad_variant_access(reason);
+#else
+ (void)reason;
+ __builtin_abort();
+#endif
+ }
+
+ public:
+ // Default constructors.
+
+ constexpr variant() noexcept(nothrow_default_constructible) : storage_{default_init_v} {}
+
+ // Copy/move constructors and assignment operators.
+
+ constexpr variant(const variant&) = default;
+ constexpr variant& operator=(const variant&) = default;
+
+ constexpr variant(variant&&) noexcept(nothrow_move_constructible) = default;
+ constexpr variant& operator=(variant&&) = default;
+
+ // Converting constructors.
+
+ template <typename T,
+ requires_conditions<std::integral_constant<bool, (sizeof...(Ts) > 0)>,
+ not_in_place<T>> = true,
+ typename Ti = selected_t<T&&>,
+ requires_conditions<occurs_once<Ti>, std::is_constructible<Ti, T>> = true>
+ constexpr variant(T&& value) noexcept(std::is_nothrow_constructible<Ti, T>::value)
+ : storage_(type_tag<Ti>{}, std::forward<T>(value)) {}
+
+ template <typename T, typename... Args,
+ requires_conditions<occurs_once<T>, std::is_constructible<T, Args...>> = true>
+ explicit constexpr variant(in_place_type_t<T>, Args&&... args)
+ : storage_(type_tag<T>{}, std::forward<Args>(args)...) {}
+
+ template <typename T, typename U, typename... Args,
+ requires_conditions<occurs_once<T>, std::is_constructible<T, std::initializer_list<T>&,
+ Args...>> = true>
+ explicit constexpr variant(in_place_type_t<T>, std::initializer_list<U> init_list, Args&&... args)
+ : storage_(type_tag<T>{}, init_list, std::forward<Args>(args)...) {}
+
+ template <size_t Index, typename... Args,
+ requires_conditions<std::is_constructible<alternative_t<Index>, Args...>> = true>
+ explicit constexpr variant(in_place_index_t<Index>, Args&&... args)
+ : storage_(index_tag<Index>{}, std::forward<Args>(args)...) {}
+
+ template <size_t Index, typename U, typename... Args,
+ requires_conditions<std::is_constructible<alternative_t<Index>,
+ std::initializer_list<U>&, Args...>> = true>
+ explicit constexpr variant(in_place_index_t<Index>, std::initializer_list<U> init_list,
+ Args&&... args)
+ : storage_(index_tag<Index>{}, init_list, std::forward<Args>(args)...) {}
+
+ ~variant() = default;
+
+ // Converting assignment.
+
+ template <typename T>
+ constexpr assignment_requires_conditions<
+ occurs_once<selected_t<T>>, std::is_constructible<selected_t<T&&>, T>,
+ std::is_assignable<selected_t<T&&>&, T>,
+ disjunction<std::is_nothrow_constructible<selected_t<T&&>, T>,
+ negation<std::is_nothrow_move_constructible<selected_t<T&&>>>>>
+ operator=(T&& value) noexcept(std::is_nothrow_assignable<selected_t<T&&>&, T>::value&&
+ std::is_nothrow_constructible<selected_t<T&&>, T>::value) {
+ constexpr auto index = selected_index<T>;
+ if (storage_.index() == index) {
+ storage_.get(index_tag<index>{}) = std::forward<T>(value);
+ } else {
+ this->emplace<index>(std::forward<T>(value));
+ }
+ return *this;
+ }
+
+ template <typename T>
+ constexpr assignment_requires_conditions<
+ occurs_once<selected_t<T>>, std::is_constructible<selected_t<T&&>, T>,
+ std::is_assignable<selected_t<T&&>&, T>,
+ conjunction<negation<std::is_nothrow_constructible<selected_t<T&&>, T>>,
+ std::is_nothrow_move_constructible<selected_t<T&&>>>>
+ operator=(T&& value) noexcept(std::is_nothrow_assignable<selected_t<T&&>&, T>::value&&
+ std::is_nothrow_constructible<selected_t<T&&>, T>::value) {
+ constexpr auto index = selected_index<T>;
+ if (storage_.index() == index) {
+ storage_.get(index_tag<index>{}) = std::forward<T>(value);
+ } else {
+ this->operator=(variant(std::forward<T>(value)));
+ }
+ return *this;
+ }
+
+ constexpr size_t index() const noexcept { return storage_.index(); }
+
+ // TODO(eieio): Remove uses of these in favor of non-member get.
+ template <size_t Index>
+ constexpr auto& get() & {
+ if (storage_.has_value()) {
+ return storage_.get(index_tag<Index>{});
+ } else {
+ throw_bad_variant_access("Access to empty variant!");
+ }
+ }
+ template <size_t Index>
+ constexpr const auto& get() const& {
+ if (storage_.has_value()) {
+ return storage_.get(index_tag<Index>{});
+ } else {
+ throw_bad_variant_access("Access to empty variant!");
+ }
+ }
+ template <size_t Index>
+ constexpr auto&& get() && {
+ if (storage_.has_value()) {
+ return std::move(storage_.get(index_tag<Index>{}));
+ } else {
+ throw_bad_variant_access("Access to empty variant!");
+ }
+ }
+ template <size_t Index>
+ constexpr const auto&& get() const&& {
+ if (storage_.has_value()) {
+ return std::move(storage_.get(index_tag<Index>{}));
+ } else {
+ throw_bad_variant_access("Access to empty variant!");
+ }
+ }
+
+ template <typename T>
+ constexpr auto& get() & {
+ if (storage_.has_value()) {
+ return storage_.get(type_tag<T>{});
+ } else {
+ throw_bad_variant_access("Access to empty variant!");
+ }
+ }
+ template <typename T>
+ constexpr const auto& get() const& {
+ if (storage_.has_value()) {
+ return storage_.get(type_tag<T>{});
+ } else {
+ throw_bad_variant_access("Access to empty variant!");
+ }
+ }
+ template <typename T>
+ constexpr auto&& get() && {
+ if (storage_.has_value()) {
+ return std::move(storage_.get(type_tag<T>{}));
+ } else {
+ throw_bad_variant_access("Access to empty variant!");
+ }
+ }
+ template <typename T>
+ constexpr const auto&& get() const&& {
+ if (storage_.has_value()) {
+ return std::move(storage_.get(type_tag<T>{}));
+ } else {
+ throw_bad_variant_access("Access to empty variant!");
+ }
+ }
+
+ // Emplacement.
+
+ template <typename T, typename... Args>
+ constexpr emplace_constructible_by_type<T, Args&&...> emplace(Args&&... args) {
+ storage_.reset();
+ storage_.construct(type_tag<T>{}, std::forward<Args>(args)...);
+ return storage_.get(type_tag<T>{});
+ }
+
+ template <typename T, typename U, typename... Args>
+ constexpr emplace_constructible_by_type<T, std::initializer_list<U>&, Args&&...> emplace(
+ std::initializer_list<U> init_list, Args&&... args) {
+ storage_.reset();
+ storage_.construct(type_tag<T>{}, init_list, std::forward<Args>(args)...);
+ return storage_.get(type_tag<T>{});
+ }
+
+ template <size_t Index, typename... Args>
+ constexpr emplace_constructible_by_index<Index, Args&&...> emplace(Args&&... args) {
+ storage_.reset();
+ storage_.construct(index_tag<Index>{}, std::forward<Args>(args)...);
+ return storage_.get(index_tag<Index>{});
+ }
+
+ template <size_t Index, typename U, typename... Args>
+ constexpr emplace_constructible_by_index<Index, std::initializer_list<U>&, Args&&...> emplace(
+ std::initializer_list<U> init_list, Args&&... args) {
+ storage_.reset();
+ storage_.construct(index_tag<Index>{}, init_list, std::forward<Args>(args)...);
+ return storage_.get(index_tag<Index>{});
+ }
+
+ // Swap.
+
+ void swap(variant& other) { storage_.swap(other.storage_); }
+
+ // Comparison.
+
+ friend constexpr bool operator==(const variant& lhs, const variant& rhs) {
+ bool result = false;
+ const bool has_value =
+ lhs.storage_.visit([&result, &lhs, &rhs](auto, auto active_index_tag, const auto*) {
+ if (lhs.index() != rhs.index()) {
+ result = false;
+ } else {
+ result = lhs.storage_.get(active_index_tag) == rhs.storage_.get(active_index_tag);
+ }
+ });
+ return !has_value || result;
+ }
+ friend constexpr bool operator!=(const variant& lhs, const variant& rhs) {
+ bool result = true;
+ const bool has_value =
+ lhs.storage_.visit([&result, &lhs, &rhs](auto, auto active_index_tag, const auto*) {
+ if (lhs.index() != rhs.index()) {
+ result = true;
+ } else {
+ result = lhs.storage_.get(active_index_tag) != rhs.storage_.get(active_index_tag);
+ }
+ });
+ return has_value && result;
+ }
+ friend constexpr bool operator<(const variant& lhs, const variant& rhs) {
+ bool result = true;
+ const bool has_value =
+ rhs.storage_.visit([&result, &lhs, &rhs](auto, auto active_index_tag, const auto*) {
+ if (!lhs.storage_.has_value()) {
+ result = true;
+ } else if (lhs.index() < rhs.index()) {
+ result = true;
+ } else if (lhs.index() > rhs.index()) {
+ result = false;
+ } else {
+ result = lhs.storage_.get(active_index_tag) < rhs.storage_.get(active_index_tag);
+ }
+ });
+ return has_value && result;
+ }
+ friend constexpr bool operator>(const variant& lhs, const variant& rhs) {
+ bool result = true;
+ const bool has_value =
+ lhs.storage_.visit([&result, &lhs, &rhs](auto, auto active_index_tag, const auto*) {
+ if (!rhs.storage_.has_value()) {
+ result = true;
+ } else if (lhs.index() > rhs.index()) {
+ result = true;
+ } else if (lhs.index() < rhs.index()) {
+ result = false;
+ } else {
+ result = lhs.storage_.get(active_index_tag) > rhs.storage_.get(active_index_tag);
+ }
+ });
+ return has_value && result;
+ }
+ friend constexpr bool operator<=(const variant& lhs, const variant& rhs) {
+ bool result = false;
+ const bool has_value =
+ lhs.storage_.visit([&result, &lhs, &rhs](auto, auto active_index_tag, const auto*) {
+ if (!rhs.storage_.has_value()) {
+ result = false;
+ } else if (lhs.index() < rhs.index()) {
+ result = true;
+ } else if (lhs.index() > rhs.index()) {
+ result = false;
+ } else {
+ result = lhs.storage_.get(active_index_tag) <= rhs.storage_.get(active_index_tag);
+ }
+ });
+ return !has_value || result;
+ }
+ friend constexpr bool operator>=(const variant& lhs, const variant& rhs) {
+ bool result = false;
+ const bool has_value =
+ rhs.storage_.visit([&result, &lhs, &rhs](auto, auto active_index_tag, const auto*) {
+ if (!lhs.storage_.has_value()) {
+ result = false;
+ } else if (lhs.index() > rhs.index()) {
+ result = true;
+ } else if (lhs.index() < rhs.index()) {
+ result = false;
+ } else {
+ result = lhs.storage_.get(active_index_tag) >= rhs.storage_.get(active_index_tag);
+ }
+ });
+ return !has_value || result;
+ }
+
+ private:
+ ::fit::internal::storage_type<Ts...> storage_;
+};
+
+// Swaps variants.
+template <typename... Ts>
+void swap(variant<Ts...>& a, variant<Ts...>& b) {
+ a.swap(b);
+}
+
+// Accesses the variant by zero-based index.
+//
+// Accesses should use ADL, similar to the pattern for std::swap:
+//
+// using std::get;
+// get<some_index>(some_fit_variant);
+//
+// This makes code adaptable to substituting std::variant for fit::variant on
+// newer compilers.
+template <size_t Index, typename... Ts>
+constexpr auto& get(variant<Ts...>& value) {
+ return value.template get<Index>();
+}
+template <size_t Index, typename... Ts>
+constexpr auto&& get(variant<Ts...>&& value) {
+ return std::move(value).template get<Index>();
+}
+template <size_t Index, typename... Ts>
+constexpr const auto& get(const variant<Ts...>& value) {
+ return value.template get<Index>();
+}
+template <size_t Index, typename... Ts>
+constexpr const auto&& get(const variant<Ts...>&& value) {
+ return std::move(value).template get<Index>();
+}
+
+// Accesses the variant by unique type. See note above about ADL.
+template <typename T, typename... Ts>
+constexpr auto& get(variant<Ts...>& value) {
+ return value.template get<T>();
+}
+template <typename T, typename... Ts>
+constexpr auto&& get(variant<Ts...>&& value) {
+ return std::move(value).template get<T>();
+}
+template <typename T, typename... Ts>
+constexpr const auto& get(const variant<Ts...>& value) {
+ return value.template get<T>();
+}
+template <typename T, typename... Ts>
+constexpr const auto&& get(const variant<Ts...>&& value) {
+ return std::move(value).template get<T>();
+}
+
+// Checks if the variant holds type T. See note above about ADL.
+template <typename T, typename... Ts>
+constexpr bool holds_alternative(const variant<Ts...>& value) {
+ constexpr auto index = ::fit::internal::selected_index<T, variant<Ts...>>::value;
+ return value.index() == index;
+}
+
+// TODO(eieio): Remove once the old ::fit::internal spellings of these types is
+// removed from FIDL.
+namespace internal {
+
+using ::fit::monostate;
+using ::fit::variant;
+
+} // namespace internal
+
+} // namespace fit
+
+#endif // LIB_FIT_VARIANT_H_
diff --git a/third_party/fuchsia-sdk/pkg/fit/meta.json b/third_party/fuchsia-sdk/pkg/fit/meta.json
new file mode 100644
index 0000000..49ee8b4
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/meta.json
@@ -0,0 +1,43 @@
+{
+ "banjo_deps": [],
+ "deps": [],
+ "fidl_deps": [],
+ "headers": [
+ "pkg/fit/include/lib/fit/barrier.h",
+ "pkg/fit/include/lib/fit/bridge.h",
+ "pkg/fit/include/lib/fit/bridge_internal.h",
+ "pkg/fit/include/lib/fit/constructors_internal.h",
+ "pkg/fit/include/lib/fit/defer.h",
+ "pkg/fit/include/lib/fit/function.h",
+ "pkg/fit/include/lib/fit/function_internal.h",
+ "pkg/fit/include/lib/fit/function_traits.h",
+ "pkg/fit/include/lib/fit/in_place_internal.h",
+ "pkg/fit/include/lib/fit/nullable.h",
+ "pkg/fit/include/lib/fit/optional.h",
+ "pkg/fit/include/lib/fit/promise.h",
+ "pkg/fit/include/lib/fit/promise_internal.h",
+ "pkg/fit/include/lib/fit/result.h",
+ "pkg/fit/include/lib/fit/scheduler.h",
+ "pkg/fit/include/lib/fit/string_view.h",
+ "pkg/fit/include/lib/fit/scope.h",
+ "pkg/fit/include/lib/fit/sequencer.h",
+ "pkg/fit/include/lib/fit/single_threaded_executor.h",
+ "pkg/fit/include/lib/fit/storage_internal.h",
+ "pkg/fit/include/lib/fit/thread_safety.h",
+ "pkg/fit/include/lib/fit/traits.h",
+ "pkg/fit/include/lib/fit/utility_internal.h",
+ "pkg/fit/include/lib/fit/variant.h"
+ ],
+ "include_dir": "pkg/fit/include",
+ "name": "fit",
+ "root": "pkg/fit",
+ "sources": [
+ "pkg/fit/barrier.cc",
+ "pkg/fit/promise.cc",
+ "pkg/fit/scheduler.cc",
+ "pkg/fit/scope.cc",
+ "pkg/fit/sequencer.cc",
+ "pkg/fit/single_threaded_executor.cc"
+ ],
+ "type": "cc_source_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/fit/promise.cc b/third_party/fuchsia-sdk/pkg/fit/promise.cc
new file mode 100644
index 0000000..f25e8ab
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/promise.cc
@@ -0,0 +1,58 @@
+// Copyright 2018 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.
+
+#include <lib/fit/promise.h>
+
+namespace fit {
+
+suspended_task::suspended_task(const suspended_task& other)
+ : resolver_(other.resolver_),
+ ticket_(resolver_ ? resolver_->duplicate_ticket(other.ticket_) : 0) {}
+
+suspended_task::suspended_task(suspended_task&& other)
+ : resolver_(other.resolver_), ticket_(other.ticket_) {
+ other.resolver_ = nullptr;
+}
+
+suspended_task::~suspended_task() { reset(); }
+
+void suspended_task::resolve(bool resume_task) {
+ if (resolver_) {
+ // Move the ticket to the stack to guard against possible re-entrance
+ // occurring as a side-effect of the task's own destructor running.
+ resolver* cached_resolver = resolver_;
+ ticket cached_ticket = ticket_;
+ resolver_ = nullptr;
+ cached_resolver->resolve_ticket(cached_ticket, resume_task);
+ }
+}
+
+suspended_task& suspended_task::operator=(const suspended_task& other) {
+ if (this != &other) {
+ reset();
+ resolver_ = other.resolver_;
+ ticket_ = resolver_ ? resolver_->duplicate_ticket(other.ticket_) : 0;
+ }
+ return *this;
+}
+
+suspended_task& suspended_task::operator=(suspended_task&& other) {
+ if (this != &other) {
+ reset();
+ resolver_ = other.resolver_;
+ ticket_ = other.ticket_;
+ other.resolver_ = nullptr;
+ }
+ return *this;
+}
+
+void suspended_task::swap(suspended_task& other) {
+ if (this != &other) {
+ using std::swap;
+ swap(resolver_, other.resolver_);
+ swap(ticket_, other.ticket_);
+ }
+}
+
+} // namespace fit
diff --git a/third_party/fuchsia-sdk/pkg/fit/scheduler.cc b/third_party/fuchsia-sdk/pkg/fit/scheduler.cc
new file mode 100644
index 0000000..144cc76
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/scheduler.cc
@@ -0,0 +1,122 @@
+// Copyright 2018 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.
+
+#include <lib/fit/scheduler.h>
+
+#include <map>
+#include <queue>
+#include <utility>
+
+namespace fit {
+namespace subtle {
+
+scheduler::scheduler() = default;
+
+scheduler::~scheduler() = default;
+
+void scheduler::schedule_task(pending_task task) {
+ assert(task);
+ runnable_tasks_.push(std::move(task));
+}
+
+suspended_task::ticket scheduler::obtain_ticket(uint32_t initial_refs) {
+ suspended_task::ticket ticket = next_ticket_++;
+ tickets_.emplace(ticket, ticket_record(initial_refs));
+ return ticket;
+}
+
+void scheduler::finalize_ticket(suspended_task::ticket ticket, pending_task* task) {
+ auto it = tickets_.find(ticket);
+ assert(it != tickets_.end());
+ assert(!it->second.task);
+ assert(it->second.ref_count > 0);
+ assert(task);
+
+ it->second.ref_count--;
+ if (!*task) {
+ // task already finished
+ } else if (it->second.was_resumed) {
+ // task immediately became runnable
+ runnable_tasks_.push(std::move(*task));
+ } else if (it->second.ref_count > 0) {
+ // task remains suspended
+ it->second.task = std::move(*task);
+ suspended_task_count_++;
+ } // else, task was abandoned and caller retains ownership of it
+ if (it->second.ref_count == 0) {
+ tickets_.erase(it);
+ }
+}
+
+void scheduler::duplicate_ticket(suspended_task::ticket ticket) {
+ auto it = tickets_.find(ticket);
+ assert(it != tickets_.end());
+ assert(it->second.ref_count > 0);
+
+ it->second.ref_count++;
+ assert(it->second.ref_count != 0); // did we really make 4 billion refs?!
+}
+
+pending_task scheduler::release_ticket(suspended_task::ticket ticket) {
+ auto it = tickets_.find(ticket);
+ assert(it != tickets_.end());
+ assert(it->second.ref_count > 0);
+
+ it->second.ref_count--;
+ if (it->second.ref_count == 0) {
+ pending_task task = std::move(it->second.task);
+ if (task) {
+ assert(suspended_task_count_ > 0);
+ suspended_task_count_--;
+ }
+ tickets_.erase(it);
+ return task;
+ }
+ return pending_task();
+}
+
+bool scheduler::resume_task_with_ticket(suspended_task::ticket ticket) {
+ auto it = tickets_.find(ticket);
+ assert(it != tickets_.end());
+ assert(it->second.ref_count > 0);
+
+ bool did_resume = false;
+ it->second.ref_count--;
+ if (!it->second.was_resumed) {
+ it->second.was_resumed = true;
+ if (it->second.task) {
+ did_resume = true;
+ assert(suspended_task_count_ > 0);
+ suspended_task_count_--;
+ runnable_tasks_.push(std::move(it->second.task));
+ }
+ }
+ if (it->second.ref_count == 0) {
+ tickets_.erase(it);
+ }
+ return did_resume;
+}
+
+void scheduler::take_runnable_tasks(task_queue* tasks) {
+ assert(tasks && tasks->empty());
+ runnable_tasks_.swap(*tasks);
+}
+
+void scheduler::take_all_tasks(task_queue* tasks) {
+ assert(tasks && tasks->empty());
+
+ runnable_tasks_.swap(*tasks);
+ if (suspended_task_count_ > 0) {
+ for (auto& item : tickets_) {
+ if (item.second.task) {
+ assert(suspended_task_count_ > 0);
+ suspended_task_count_--;
+ tasks->push(std::move(item.second.task));
+ }
+ }
+ }
+}
+
+} // namespace subtle
+} // namespace fit
diff --git a/third_party/fuchsia-sdk/pkg/fit/scope.cc b/third_party/fuchsia-sdk/pkg/fit/scope.cc
new file mode 100644
index 0000000..8777f4a
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/scope.cc
@@ -0,0 +1,143 @@
+// Copyright 2018 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.
+
+#include <lib/fit/scope.h>
+
+namespace fit {
+
+scope::scope() : state_(new state()) {}
+
+scope::~scope() { state_->exit(true /*scope_was_destroyed*/); }
+
+scope::state::state() = default;
+
+scope::state::~state() {
+ assert(acquired_promise_count_.load(std::memory_order_relaxed) == scope_exited);
+ assert(scope_was_destroyed_);
+ assert(promise_handle_count_ == 0);
+ assert(head_promise_holder_ == nullptr);
+}
+
+bool scope::state::exited() const {
+ return acquired_promise_count_.load(std::memory_order_relaxed) & scope_exited;
+}
+
+void scope::state::exit(bool scope_was_destroyed) {
+ promise_holder_base* release_head = nullptr;
+ bool delete_self = false;
+ {
+ std::lock_guard<std::mutex> lock(mutex_);
+ assert(!scope_was_destroyed_);
+ scope_was_destroyed_ = scope_was_destroyed;
+
+ // Atomically exit the scope. We cannot do this safely if there are
+ // any running promises since they might still be accessing state which
+ // is guarded by the scope. Worse, if a promise re-entrantly destroys
+ // the scope during its execution then as a side-effect the promise
+ // itself will be destroyed. So assert!
+ uint64_t prior_count =
+ acquired_promise_count_.exchange(scope_exited, std::memory_order_relaxed);
+ if (!(prior_count & scope_exited)) {
+ // Cannot exit fit::scope while any of its promises are running!
+ assert(prior_count == 0);
+
+ // Take the promises so they can be deleted outside of the lock.
+ release_head = head_promise_holder_;
+ head_promise_holder_ = nullptr;
+ }
+
+ // If there are no more handles then we can delete the state now.
+ delete_self = should_delete_self();
+ }
+
+ // Delete aborted promises and self outside of the lock.
+ while (release_head) {
+ promise_holder_base* release_next = release_head->next;
+ delete release_head;
+ release_head = release_next;
+ }
+ if (delete_self) {
+ delete this;
+ }
+}
+
+scope::promise_handle scope::state::adopt_promise(promise_holder_base* promise_holder) {
+ {
+ std::lock_guard<std::mutex> lock(mutex_);
+ assert(!scope_was_destroyed_); // otherwise how did we get here?
+
+ // If the scope hasn't been exited yet, link the promise and mint
+ // a new handle. Otherwise we will abort the promise.
+ if (!exited()) {
+ if (head_promise_holder_) {
+ head_promise_holder_->prev = promise_holder;
+ promise_holder->next = head_promise_holder_;
+ }
+ head_promise_holder_ = promise_holder;
+ promise_handle_count_++;
+ return promise_handle(this, promise_holder);
+ }
+ }
+
+ // Delete aborted promise outside of the lock.
+ delete promise_holder;
+ return promise_handle{};
+}
+
+void scope::state::drop_promise(promise_handle promise_handle) {
+ if (!promise_handle.promise_holder_) {
+ return; // invalid handle, nothing to do
+ }
+
+ {
+ std::lock_guard<std::mutex> lock(promise_handle.state_->mutex_);
+
+ // If the scope hasn't been exited yet, unlink the promise and
+ // prepare to destroy it. Otherwise, it's already been unlinked
+ // and destroyed so release the handle but don't touch the pointer!
+ assert(promise_handle.state_->promise_handle_count_ > 0);
+ promise_handle.state_->promise_handle_count_--;
+ if (!promise_handle.state_->exited()) {
+ if (promise_handle.promise_holder_->next) {
+ promise_handle.promise_holder_->next->prev = promise_handle.promise_holder_->prev;
+ }
+ if (promise_handle.promise_holder_->prev) {
+ promise_handle.promise_holder_->prev->next = promise_handle.promise_holder_->next;
+ } else {
+ promise_handle.state_->head_promise_holder_ = promise_handle.promise_holder_->next;
+ }
+ // Fallthrough to delete the promise.
+ } else if (!promise_handle.state_->should_delete_self()) {
+ return;
+ } else {
+ // Fallthrough to delete self.
+ promise_handle.promise_holder_ = nullptr;
+ }
+ }
+
+ // Delete the promise or scope outside of the lock.
+ if (promise_handle.promise_holder_) {
+ delete promise_handle.promise_holder_;
+ } else {
+ delete promise_handle.state_;
+ }
+}
+
+scope::promise_holder_base* scope::state::try_acquire_promise(promise_handle promise_handle) {
+ if (promise_handle.promise_holder_) {
+ uint64_t prior_count =
+ promise_handle.state_->acquired_promise_count_.fetch_add(1u, std::memory_order_relaxed);
+ if (!(prior_count & scope_exited)) {
+ return promise_handle.promise_holder_;
+ }
+ promise_handle.state_->acquired_promise_count_.fetch_sub(1u, std::memory_order_relaxed);
+ }
+ return nullptr;
+}
+
+void scope::state::release_promise(promise_handle promise_handle) {
+ promise_handle.state_->acquired_promise_count_.fetch_sub(1u, std::memory_order_relaxed);
+}
+
+} // namespace fit
diff --git a/third_party/fuchsia-sdk/pkg/fit/sequencer.cc b/third_party/fuchsia-sdk/pkg/fit/sequencer.cc
new file mode 100644
index 0000000..69d4da0
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/sequencer.cc
@@ -0,0 +1,26 @@
+// Copyright 2018 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.
+
+#include <lib/fit/sequencer.h>
+
+namespace fit {
+
+sequencer::sequencer() {
+ // Capture a new consumer and intentionally abandon its associated
+ // completer so that a promise chained onto the consumer using
+ // |promise_or()| will become immediately runnable.
+ fit::bridge<> bridge;
+ prior_ = std::move(bridge.consumer);
+}
+
+sequencer::~sequencer() = default;
+
+fit::consumer<> sequencer::swap_prior(fit::consumer<> new_prior) {
+ std::lock_guard<std::mutex> lock(mutex_);
+ fit::consumer<> old_prior = std::move(prior_);
+ prior_ = std::move(new_prior);
+ return old_prior;
+}
+
+} // namespace fit
diff --git a/third_party/fuchsia-sdk/pkg/fit/single_threaded_executor.cc b/third_party/fuchsia-sdk/pkg/fit/single_threaded_executor.cc
new file mode 100644
index 0000000..9b3909f
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/fit/single_threaded_executor.cc
@@ -0,0 +1,224 @@
+// Copyright 2018 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.
+
+#include <condition_variable>
+#include <mutex>
+
+#include <lib/fit/single_threaded_executor.h>
+#include <lib/fit/thread_safety.h>
+
+namespace fit {
+
+// The dispatcher runs tasks and provides the suspended task resolver.
+//
+// The lifetime of this object is somewhat complex since there are pointers
+// to it from multiple sources which are released in different ways.
+//
+// - |single_threaded_executor| holds a pointer in |dispatcher_| which it releases
+// after calling |shutdown()| to inform the dispatcher of its own demise
+// - |suspended_task| holds a pointer to the dispatcher's resolver
+// interface and the number of outstanding pointers corresponds to the
+// number of outstanding suspended task tickets tracked by |scheduler_|.
+//
+// The dispatcher deletes itself once all pointers have been released.
+class single_threaded_executor::dispatcher_impl final : public suspended_task::resolver {
+ public:
+ dispatcher_impl();
+
+ void shutdown();
+ void schedule_task(pending_task task);
+ void run(context_impl& context);
+ suspended_task suspend_current_task();
+
+ suspended_task::ticket duplicate_ticket(suspended_task::ticket ticket) override;
+ void resolve_ticket(suspended_task::ticket ticket, bool resume_task) override;
+
+ private:
+ ~dispatcher_impl() override;
+
+ void wait_for_runnable_tasks(fit::subtle::scheduler::task_queue* out_tasks);
+ void run_task(pending_task* task, context& context);
+
+ suspended_task::ticket current_task_ticket_ = 0;
+ std::condition_variable wake_;
+
+ // A bunch of state that is guarded by a mutex.
+ struct {
+ std::mutex mutex_;
+ bool was_shutdown_ FIT_GUARDED(mutex_) = false;
+ bool need_wake_ FIT_GUARDED(mutex_) = false;
+ fit::subtle::scheduler scheduler_ FIT_GUARDED(mutex_);
+ } guarded_;
+};
+
+single_threaded_executor::single_threaded_executor()
+ : context_(this), dispatcher_(new dispatcher_impl()) {}
+
+single_threaded_executor::~single_threaded_executor() { dispatcher_->shutdown(); }
+
+void single_threaded_executor::schedule_task(pending_task task) {
+ assert(task);
+ dispatcher_->schedule_task(std::move(task));
+}
+
+void single_threaded_executor::run() { dispatcher_->run(context_); }
+
+single_threaded_executor::context_impl::context_impl(single_threaded_executor* executor)
+ : executor_(executor) {}
+
+single_threaded_executor::context_impl::~context_impl() = default;
+
+single_threaded_executor* single_threaded_executor::context_impl::executor() const {
+ return executor_;
+}
+
+suspended_task single_threaded_executor::context_impl::suspend_task() {
+ return executor_->dispatcher_->suspend_current_task();
+}
+
+single_threaded_executor::dispatcher_impl::dispatcher_impl() = default;
+
+single_threaded_executor::dispatcher_impl::~dispatcher_impl() {
+ std::lock_guard<std::mutex> lock(guarded_.mutex_);
+ assert(guarded_.was_shutdown_);
+ assert(!guarded_.scheduler_.has_runnable_tasks());
+ assert(!guarded_.scheduler_.has_suspended_tasks());
+ assert(!guarded_.scheduler_.has_outstanding_tickets());
+}
+
+void single_threaded_executor::dispatcher_impl::shutdown() {
+ fit::subtle::scheduler::task_queue tasks; // drop outside of the lock
+ {
+ std::lock_guard<std::mutex> lock(guarded_.mutex_);
+ assert(!guarded_.was_shutdown_);
+ guarded_.was_shutdown_ = true;
+ guarded_.scheduler_.take_all_tasks(&tasks);
+ if (guarded_.scheduler_.has_outstanding_tickets()) {
+ return; // can't delete self yet
+ }
+ }
+
+ // Must destroy self outside of the lock.
+ delete this;
+}
+
+void single_threaded_executor::dispatcher_impl::schedule_task(pending_task task) {
+ {
+ std::lock_guard<std::mutex> lock(guarded_.mutex_);
+ assert(!guarded_.was_shutdown_);
+ guarded_.scheduler_.schedule_task(std::move(task));
+ if (!guarded_.need_wake_) {
+ return; // don't need to wake
+ }
+ guarded_.need_wake_ = false;
+ }
+
+ // It is more efficient to notify outside the lock.
+ wake_.notify_one();
+}
+
+void single_threaded_executor::dispatcher_impl::run(context_impl& context) {
+ fit::subtle::scheduler::task_queue tasks;
+ for (;;) {
+ wait_for_runnable_tasks(&tasks);
+ if (tasks.empty()) {
+ return; // all done!
+ }
+
+ do {
+ run_task(&tasks.front(), context);
+ tasks.pop(); // the task may be destroyed here if it was not suspended
+ } while (!tasks.empty());
+ }
+}
+
+// Must only be called while |run_task()| is running a task.
+// This happens when the task's continuation calls |context::suspend_task()|
+// upon the context it received as an argument.
+suspended_task single_threaded_executor::dispatcher_impl::suspend_current_task() {
+ std::lock_guard<std::mutex> lock(guarded_.mutex_);
+ assert(!guarded_.was_shutdown_);
+ if (current_task_ticket_ == 0) {
+ current_task_ticket_ = guarded_.scheduler_.obtain_ticket(2 /*initial_refs*/);
+ } else {
+ guarded_.scheduler_.duplicate_ticket(current_task_ticket_);
+ }
+ return suspended_task(this, current_task_ticket_);
+}
+
+// Unfortunately std::unique_lock does not support thread-safety annotations
+void single_threaded_executor::dispatcher_impl::wait_for_runnable_tasks(
+ fit::subtle::scheduler::task_queue* out_tasks) FIT_NO_THREAD_SAFETY_ANALYSIS {
+ std::unique_lock<std::mutex> lock(guarded_.mutex_);
+ for (;;) {
+ assert(!guarded_.was_shutdown_);
+ guarded_.scheduler_.take_runnable_tasks(out_tasks);
+ if (!out_tasks->empty()) {
+ return; // got some tasks
+ }
+ if (!guarded_.scheduler_.has_suspended_tasks()) {
+ return; // all done!
+ }
+ guarded_.need_wake_ = true;
+ wake_.wait(lock);
+ guarded_.need_wake_ = false;
+ }
+}
+
+void single_threaded_executor::dispatcher_impl::run_task(pending_task* task, context& context) {
+ assert(current_task_ticket_ == 0);
+ const bool finished = (*task)(context);
+ assert(!*task == finished);
+ (void)finished;
+ if (current_task_ticket_ == 0) {
+ return; // task was not suspended, no ticket was produced
+ }
+
+ std::lock_guard<std::mutex> lock(guarded_.mutex_);
+ assert(!guarded_.was_shutdown_);
+ guarded_.scheduler_.finalize_ticket(current_task_ticket_, task);
+ current_task_ticket_ = 0;
+}
+
+suspended_task::ticket single_threaded_executor::dispatcher_impl::duplicate_ticket(
+ suspended_task::ticket ticket) {
+ std::lock_guard<std::mutex> lock(guarded_.mutex_);
+ guarded_.scheduler_.duplicate_ticket(ticket);
+ return ticket;
+}
+
+void single_threaded_executor::dispatcher_impl::resolve_ticket(suspended_task::ticket ticket,
+ bool resume_task) {
+ pending_task abandoned_task; // drop outside of the lock
+ bool do_wake = false;
+ {
+ std::lock_guard<std::mutex> lock(guarded_.mutex_);
+ if (resume_task) {
+ guarded_.scheduler_.resume_task_with_ticket(ticket);
+ } else {
+ abandoned_task = guarded_.scheduler_.release_ticket(ticket);
+ }
+ if (guarded_.was_shutdown_) {
+ assert(!guarded_.need_wake_);
+ if (guarded_.scheduler_.has_outstanding_tickets()) {
+ return; // can't shutdown yet
+ }
+ } else if (guarded_.need_wake_ && (guarded_.scheduler_.has_runnable_tasks() ||
+ !guarded_.scheduler_.has_suspended_tasks())) {
+ guarded_.need_wake_ = false;
+ do_wake = true;
+ } else {
+ return; // nothing else to do
+ }
+ }
+
+ // Must do this outside of the lock.
+ if (do_wake) {
+ wake_.notify_one();
+ } else {
+ delete this;
+ }
+}
+
+} // namespace fit
diff --git a/third_party/fuchsia-sdk/pkg/images_cpp/BUILD.gn b/third_party/fuchsia-sdk/pkg/images_cpp/BUILD.gn
new file mode 100644
index 0000000..567a36b
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/images_cpp/BUILD.gn
@@ -0,0 +1,26 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("images_cpp") {
+ sources = [
+ "images.cc",
+ "include/lib/images/cpp/images.h",
+ ]
+ include_dirs = [ "include" ]
+ public_deps = [
+ "../../fidl/fuchsia.images",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":images_cpp",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/images_cpp/images.cc b/third_party/fuchsia-sdk/pkg/images_cpp/images.cc
new file mode 100644
index 0000000..ac425f1
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/images_cpp/images.cc
@@ -0,0 +1,82 @@
+// Copyright 2018 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.
+
+#include "lib/images/cpp/images.h"
+
+#include <zircon/assert.h>
+
+namespace images {
+
+// Overall bits per pixel, across all pixel data in the whole image.
+size_t BitsPerPixel(const fuchsia::images::PixelFormat& pixel_format) {
+ switch (pixel_format) {
+ case fuchsia::images::PixelFormat::BGRA_8:
+ return 4u * 8u;
+ case fuchsia::images::PixelFormat::YUY2:
+ return 2u * 8u;
+ case fuchsia::images::PixelFormat::NV12:
+ return 12;
+ case fuchsia::images::PixelFormat::YV12:
+ return 12;
+ }
+ ZX_PANIC("Unknown Pixel Format: %d", static_cast<int>(pixel_format));
+ return 0;
+}
+
+size_t StrideBytesPerWidthPixel(const fuchsia::images::PixelFormat& pixel_format) {
+ switch (pixel_format) {
+ case fuchsia::images::PixelFormat::BGRA_8:
+ return 4u;
+ case fuchsia::images::PixelFormat::YUY2:
+ return 2u;
+ case fuchsia::images::PixelFormat::NV12:
+ return 1u;
+ case fuchsia::images::PixelFormat::YV12:
+ return 1u;
+ }
+ ZX_PANIC("Unknown Pixel Format: %d", static_cast<int>(pixel_format));
+ return 0;
+}
+
+size_t MaxSampleAlignment(const fuchsia::images::PixelFormat& pixel_format) {
+ switch (pixel_format) {
+ case fuchsia::images::PixelFormat::BGRA_8:
+ return 4u;
+ case fuchsia::images::PixelFormat::YUY2:
+ return 2u;
+ case fuchsia::images::PixelFormat::NV12:
+ // In the sense that line stride "must preserve pixel alignment", which is
+ // what MaxSampleAlignment() is used for, NV12 ~~has (very roughly
+ // speaking) a pixel alignment of 2, ~~because the width of the Y plane in
+ // this implementation must be even, and ~because the interleaved UV data
+ // after the planar Y data is 2 bytes per sample, so we may as well
+ // require UV samples to remain aligned UV line to UV line.
+ return 2u;
+ case fuchsia::images::PixelFormat::YV12:
+ // In the sense that line stride "must preserve pixel alignment", which is
+ // what MaxSampleAlignment() is used for, YV12 ~~has (very roughly
+ // speaking) a pixel alignment of 2, ~~because the width of the Y plane in
+ // this implementation must be even.
+ return 2u;
+ }
+ ZX_PANIC("Unknown Pixel Format: %d", static_cast<int>(pixel_format));
+ return 0;
+}
+
+size_t ImageSize(const fuchsia::images::ImageInfo& image_info) {
+ ZX_DEBUG_ASSERT(image_info.tiling == fuchsia::images::Tiling::LINEAR);
+ switch (image_info.pixel_format) {
+ case fuchsia::images::PixelFormat::BGRA_8:
+ case fuchsia::images::PixelFormat::YUY2:
+ return image_info.height * image_info.stride;
+ case fuchsia::images::PixelFormat::NV12:
+ return image_info.height * image_info.stride * 3 / 2;
+ case fuchsia::images::PixelFormat::YV12:
+ return image_info.height * image_info.stride * 3 / 2;
+ }
+ ZX_PANIC("Unknown Pixel Format: %d", static_cast<int>(image_info.pixel_format));
+ return 0;
+}
+
+} // namespace images
diff --git a/third_party/fuchsia-sdk/pkg/images_cpp/include/lib/images/cpp/images.h b/third_party/fuchsia-sdk/pkg/images_cpp/include/lib/images/cpp/images.h
new file mode 100644
index 0000000..a5be88b
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/images_cpp/include/lib/images/cpp/images.h
@@ -0,0 +1,39 @@
+// Copyright 2018 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.
+
+#ifndef LIB_IMAGES_CPP_IMAGES_H_
+#define LIB_IMAGES_CPP_IMAGES_H_
+
+#include <fuchsia/images/cpp/fidl.h>
+#include <stdint.h>
+
+namespace images {
+
+// Returns the number of bits per pixel for the given format. This is the bits
+// per pixel in the overall image across all bytes that contain pixel data. For
+// example, NV12 is 12 bits per pixel.
+size_t BitsPerPixel(const fuchsia::images::PixelFormat& pixel_format);
+
+// This is the number of stride bytes per pixel of width. For formats such as
+// NV12 that separate Y and UV data, this is the number of stride bytes of the Y
+// plane. NV12 has the same stride for the UV data. formats with a different
+// stride for UV data vs Y data are not handled yet.
+size_t StrideBytesPerWidthPixel(const fuchsia::images::PixelFormat& pixel_format);
+
+// Returns the pixel alignment for the given format.
+//
+// This is technically something closer to "max sample alignment" for the given
+// format. For example, NV12 returns 2 here because its UV interleaved data has
+// 2 bytes per sample, despite its Y plane having 1 byte per sample.
+//
+// The stride is required to be divisible by this alignment.
+size_t MaxSampleAlignment(const fuchsia::images::PixelFormat& pixel_format);
+
+// This would be height * stride, if it weren't for formats like NV12, where it
+// isn't. The output is bytes.
+size_t ImageSize(const fuchsia::images::ImageInfo& image_info);
+
+} // namespace images
+
+#endif // LIB_IMAGES_CPP_IMAGES_H_
diff --git a/third_party/fuchsia-sdk/pkg/images_cpp/meta.json b/third_party/fuchsia-sdk/pkg/images_cpp/meta.json
new file mode 100644
index 0000000..a5041f1
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/images_cpp/meta.json
@@ -0,0 +1,17 @@
+{
+ "banjo_deps": [],
+ "deps": [],
+ "fidl_deps": [
+ "fuchsia.images"
+ ],
+ "headers": [
+ "pkg/images_cpp/include/lib/images/cpp/images.h"
+ ],
+ "include_dir": "pkg/images_cpp/include",
+ "name": "images_cpp",
+ "root": "pkg/images_cpp",
+ "sources": [
+ "pkg/images_cpp/images.cc"
+ ],
+ "type": "cc_source_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/inspect/BUILD.gn b/third_party/fuchsia-sdk/pkg/inspect/BUILD.gn
new file mode 100644
index 0000000..f925f05
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/inspect/BUILD.gn
@@ -0,0 +1,50 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("inspect") {
+ sources = [
+ "health.cc",
+ "hierarchy.cc",
+ "inspector.cc",
+ "reader.cc",
+ "vmo/heap.cc",
+ "vmo/scanner.cc",
+ "vmo/snapshot.cc",
+ "vmo/state.cc",
+ "vmo/types.cc",
+ "include/lib/inspect/cpp/health.h",
+ "include/lib/inspect/cpp/hierarchy.h",
+ "include/lib/inspect/cpp/inspect.h",
+ "include/lib/inspect/cpp/inspector.h",
+ "include/lib/inspect/cpp/reader.h",
+ "include/lib/inspect/cpp/value_list.h",
+ "include/lib/inspect/cpp/vmo/block.h",
+ "include/lib/inspect/cpp/vmo/heap.h",
+ "include/lib/inspect/cpp/vmo/limits.h",
+ "include/lib/inspect/cpp/vmo/scanner.h",
+ "include/lib/inspect/cpp/vmo/snapshot.h",
+ "include/lib/inspect/cpp/vmo/state.h",
+ "include/lib/inspect/cpp/vmo/types.h",
+ ]
+ include_dirs = [ "include" ]
+ public_deps = [
+ "../async",
+ "../async-default",
+ "../fdio",
+ "../fit",
+ "../zx",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":inspect",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/inspect/health.cc b/third_party/fuchsia-sdk/pkg/inspect/health.cc
new file mode 100644
index 0000000..a895fe6
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/inspect/health.cc
@@ -0,0 +1,49 @@
+// 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.
+
+#include <lib/inspect/cpp/health.h>
+#include <lib/zx/time.h>
+
+namespace inspect {
+
+NodeHealth::NodeHealth(Node* parent_node, const std::function<zx_time_t()>& clock_fn)
+ : health_node_(parent_node->CreateChild(kHealthNodeName)),
+ health_status_(health_node_.CreateString("status", kHealthStartingUp)),
+ timestamp_nanos_(health_node_.CreateInt(kStartTimestamp, clock_fn())) {}
+
+NodeHealth::NodeHealth(Node* parent_node) : NodeHealth(parent_node, zx_clock_get_monotonic) {}
+
+void NodeHealth::Ok() {
+ health_message_.reset();
+ health_status_.Set(kHealthOk);
+}
+
+void NodeHealth::StartingUp() {
+ health_message_.reset();
+ health_status_.Set(kHealthStartingUp);
+}
+
+void NodeHealth::StartingUp(const std::string& message) {
+ health_status_.Set(kHealthStartingUp);
+ SetMessage(message);
+}
+
+void NodeHealth::Unhealthy(const std::string& message) {
+ health_status_.Set(kHealthUnhealthy);
+ SetMessage(message);
+}
+
+void NodeHealth::SetStatus(const std::string& status, const std::string& message) {
+ health_status_.Set(status);
+ SetMessage(message);
+}
+
+void NodeHealth::SetMessage(const std::string& message) {
+ if (!health_message_) {
+ health_message_ = health_node_.CreateString("message", "");
+ }
+ health_message_->Set(message);
+}
+
+} // namespace inspect
diff --git a/third_party/fuchsia-sdk/pkg/inspect/hierarchy.cc b/third_party/fuchsia-sdk/pkg/inspect/hierarchy.cc
new file mode 100644
index 0000000..b14c31b
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/inspect/hierarchy.cc
@@ -0,0 +1,118 @@
+// 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.
+
+#include <assert.h>
+#include <lib/inspect/cpp/hierarchy.h>
+
+#include <algorithm>
+#include <cctype>
+#include <stack>
+#include <vector>
+
+namespace inspect {
+
+namespace {
+// Helper to sort an array of T by the value of T::name().
+// If names are numeric unsigned integers, this function will sort numerically
+// rather than lexicographically. Note that this will not handle negative or
+// decimal numbers.
+template <typename T>
+void SortByName(std::vector<T>* values) {
+ if (std::all_of(values->begin(), values->end(), [](const T& value) {
+ for (char c : value.name()) {
+ if (!std::isdigit(c)) {
+ return false;
+ }
+ }
+ return !value.name().empty();
+ })) {
+ std::sort(values->begin(), values->end(), [](const T& a, const T& b) {
+ uint64_t a_val = atoll(a.name().c_str());
+ uint64_t b_val = atoll(b.name().c_str());
+ return a_val < b_val;
+ });
+ } else {
+ std::sort(values->begin(), values->end(),
+ [](const T& a, const T& b) { return a.name() < b.name(); });
+ }
+}
+} // namespace
+
+NodeValue::NodeValue(std::string name) : name_(std::move(name)) {}
+
+NodeValue::NodeValue(std::string name, std::vector<PropertyValue> properties)
+ : name_(std::move(name)), properties_(std::move(properties)) {}
+
+void NodeValue::Sort() { SortByName(&properties_); }
+
+Hierarchy::Hierarchy(NodeValue node, std::vector<Hierarchy> children)
+ : node_(std::move(node)), children_(std::move(children)) {}
+
+const Hierarchy* Hierarchy::GetByPath(const std::vector<std::string>& path) const {
+ const Hierarchy* current = this;
+ auto path_it = path.begin();
+
+ while (current && path_it != path.end()) {
+ const Hierarchy* next = nullptr;
+ for (const auto& obj : current->children_) {
+ if (obj.node().name() == *path_it) {
+ next = &obj;
+ break;
+ }
+ }
+ current = next;
+ ++path_it;
+ }
+ return current;
+}
+
+void Hierarchy::Visit(fit::function<bool(const std::vector<std::string>&, Hierarchy*)> callback) {
+ std::vector<std::string> path;
+ // Keep a stack of hierarchies and the offset into the children vector for the hierarchy.
+ // A work entry is complete once the offset == children().size().
+ std::stack<std::pair<Hierarchy*, size_t>> work_stack;
+ work_stack.push({this, 0});
+ path.push_back(name());
+ if (!callback(path, this)) {
+ return;
+ }
+
+ while (!work_stack.empty()) {
+ Hierarchy* cur;
+ size_t child_index;
+
+ std::tie(cur, child_index) = work_stack.top();
+
+ if (child_index >= cur->children_.size()) {
+ path.pop_back();
+ work_stack.pop();
+ } else {
+ std::get<1>(work_stack.top())++;
+ work_stack.push({&cur->children_[child_index], 0});
+ auto* child = std::get<0>(work_stack.top());
+ path.push_back(child->name());
+ if (!callback(path, child)) {
+ return;
+ }
+ }
+ }
+}
+
+void Hierarchy::Visit(
+ fit::function<bool(const std::vector<std::string>&, const Hierarchy*)> callback) const {
+ const_cast<Hierarchy*>(this)->Visit(
+ [&](const std::vector<std::string>& path, Hierarchy* hierarchy) {
+ return callback(path, hierarchy);
+ });
+}
+
+void Hierarchy::Sort() {
+ node_.Sort();
+ SortByName(&children_);
+ for (auto& child : children_) {
+ child.Sort();
+ }
+}
+
+} // namespace inspect
diff --git a/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/health.h b/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/health.h
new file mode 100644
index 0000000..6b4958b
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/health.h
@@ -0,0 +1,82 @@
+// 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.
+
+#ifndef LIB_INSPECT_CPP_HEALTH_H_
+#define LIB_INSPECT_CPP_HEALTH_H_
+
+#include <lib/fit/optional.h>
+#include <lib/inspect/cpp/inspect.h>
+#include <lib/zx/time.h>
+
+namespace inspect {
+
+// The name of nodes implementing health for a parent node.
+constexpr char kHealthNodeName[] = "fuchsia.inspect.Health";
+
+// Health status designating that the node is healthy.
+constexpr char kHealthOk[] = "OK";
+
+// Health status designating that the node is not yet healthy, but is still
+// starting up and may become healthy.
+constexpr char kHealthStartingUp[] = "STARTING_UP";
+
+// Health status designating that the node is not healthy.
+constexpr char kHealthUnhealthy[] = "UNHEALTHY";
+
+// The metric representing timestamp in nanoseconds, at which this health node
+// has been initialized.
+const char kStartTimestamp[] = "start_timestamp_nanos";
+
+// Represents the health associated with a given inspect_deprecated::Node.
+//
+// This class supports adding a Node with name "fuchsia.inspect.Health" that
+// consists of "status" and "message" properties. Nodes implementing
+// fuchsia.inspect.Health can be aggregated in health checking scripts
+// inspecttem-wide.
+class NodeHealth final {
+ public:
+ // Constructs a new NodeHealth object that wraps a health designation for the
+ // given node.
+ //
+ // The initial status is STARTING_UP.
+ explicit NodeHealth(::inspect::Node* parent_node);
+
+ // Constructs a new NodeHealth object, which uses the passed-in clock to
+ // get the needed timestamps. Useful for testing, for example. Does not
+ // take ownership of the clock.
+ NodeHealth(::inspect::Node* parent_node, const std::function<zx_time_t()>& clock_fn);
+
+ // Allow moving, disallow copying.
+ NodeHealth(NodeHealth&&) = default;
+ NodeHealth(const NodeHealth&) = delete;
+ NodeHealth& operator=(NodeHealth&&) = default;
+ NodeHealth& operator=(const NodeHealth&) = delete;
+
+ // Sets the health of this node to OK, with no message.
+ void Ok();
+
+ // Sets the health of this node to STARTING_UP, with no message.
+ void StartingUp();
+
+ // Sets the health of this node to STARTING_UP, with the given message.
+ void StartingUp(const std::string& message);
+
+ // Sets the health of this node to UNHEALTHY, with the given message.
+ void Unhealthy(const std::string& message);
+
+ // Explicitly sets the status to the given value with the given message.
+ void SetStatus(const std::string& status, const std::string& message);
+
+ private:
+ void SetMessage(const std::string& message);
+
+ ::inspect::Node health_node_;
+ ::inspect::StringProperty health_status_;
+ fit::optional<::inspect::StringProperty> health_message_;
+ ::inspect::IntProperty timestamp_nanos_;
+};
+
+} // namespace inspect
+
+#endif // LIB_INSPECT_CPP_HEALTH_H_
diff --git a/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/hierarchy.h b/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/hierarchy.h
new file mode 100644
index 0000000..75ee841
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/hierarchy.h
@@ -0,0 +1,463 @@
+// 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.
+
+#ifndef LIB_INSPECT_CPP_HIERARCHY_H_
+#define LIB_INSPECT_CPP_HIERARCHY_H_
+
+#include <lib/fit/function.h>
+#include <lib/fit/optional.h>
+#include <lib/fit/variant.h>
+
+#include <limits>
+#include <map>
+#include <string>
+#include <vector>
+
+namespace inspect {
+
+// Describes how an array of values should be displayed.
+enum class ArrayDisplayFormat : uint8_t {
+ // The array should be displayed as a flat list of numeric types.
+ kFlat,
+
+ // The array consists of parameters and buckets for a linear histogram.
+ kLinearHistogram,
+
+ // The array consists of parameters and buckets for an exponential
+ // histogram.
+ kExponentialHistogram,
+};
+
+namespace internal {
+template <typename T, size_t FormatIndex>
+// Internal class wrapping a typed value.
+class Value {
+ public:
+ // Index into the format enum for this type.
+ constexpr static size_t format_index = FormatIndex;
+
+ // Construct an empty value.
+ Value() = default;
+
+ Value(const Value&) = delete;
+ Value(Value&&) = default;
+ Value& operator=(const Value&) = delete;
+ Value& operator=(Value&&) = default;
+
+ // Construct a Value wrapping the specific value.
+ explicit Value(T value) : value_(std::move(value)) {}
+
+ // Obtain the wrapped value.
+ const T& value() const { return value_; }
+
+ private:
+ T value_;
+};
+
+// An Array is a specialization of Value that contains multiple values as well
+// as a display format.
+template <typename T, size_t FormatIndex>
+class Array final : public Value<std::vector<T>, FormatIndex> {
+ public:
+ // Describes a single bucket in a histogram.
+ //
+ // This contains the count of values falling in interval [floor, upper_limit).
+ struct HistogramBucket final {
+ // The floor of values falling in this bucket, inclusive.
+ T floor;
+
+ // The upper limit for values falling in this bucket, exclusive.
+ T upper_limit;
+
+ // The count of values falling in [floor, upper_limit).
+ T count;
+
+ HistogramBucket(T floor, T upper_limit, T count)
+ : floor(floor), upper_limit(upper_limit), count(count) {}
+
+ bool operator==(const HistogramBucket& other) const {
+ return floor == other.floor && upper_limit == other.upper_limit && count == other.count;
+ }
+
+ bool operator!=(const HistogramBucket& other) const { return !((*this) == other); }
+ };
+
+ // Constructs an array consisting of values and a display format.
+ Array(std::vector<T> values, ArrayDisplayFormat display_format)
+ : Value<std::vector<T>, FormatIndex>(std::move(values)), display_format_(display_format) {}
+
+ // Gets the display format for this array.
+ ArrayDisplayFormat GetDisplayFormat() const { return display_format_; }
+
+ // Gets the buckets for this array interpreted as a histogram.
+ // If the array does not represent a valid histogram, the returned array will
+ // be empty.
+ std::vector<HistogramBucket> GetBuckets() const;
+
+ private:
+ // The display format for this array.
+ ArrayDisplayFormat display_format_;
+};
+
+template <typename T, size_t FormatIndex>
+std::vector<typename Array<T, FormatIndex>::HistogramBucket> Array<T, FormatIndex>::GetBuckets()
+ const {
+ std::vector<HistogramBucket> ret;
+
+ const auto& value = this->value();
+
+ if (display_format_ == ArrayDisplayFormat::kLinearHistogram) {
+ if (value.size() < 5) {
+ // We need at least floor, step_size, underflow, bucket 0, overflow.
+ return ret;
+ }
+ T floor = value[0];
+ const T step_size = value[1];
+
+ if (std::numeric_limits<T>::has_infinity) {
+ ret.push_back(HistogramBucket(-std::numeric_limits<T>::infinity(), floor, value[2]));
+ } else {
+ ret.push_back(HistogramBucket(std::numeric_limits<T>::min(), floor, value[2]));
+ }
+
+ for (size_t i = 3; i < value.size() - 1; i++) {
+ ret.push_back(HistogramBucket(floor, floor + step_size, value[i]));
+ floor += step_size;
+ }
+
+ if (std::numeric_limits<T>::has_infinity) {
+ ret.push_back(
+ HistogramBucket(floor, std::numeric_limits<T>::infinity(), value[value.size() - 1]));
+ } else {
+ ret.push_back(HistogramBucket(floor, std::numeric_limits<T>::max(), value[value.size() - 1]));
+ }
+
+ } else if (display_format_ == ArrayDisplayFormat::kExponentialHistogram) {
+ if (value.size() < 6) {
+ // We need at least floor, initial_step, step_multiplier, underflow,
+ // bucket 0, overflow.
+ return ret;
+ }
+ T floor = value[0];
+ T current_step = value[1];
+ const T step_multiplier = value[2];
+
+ if (std::numeric_limits<T>::has_infinity) {
+ ret.push_back(HistogramBucket(-std::numeric_limits<T>::infinity(), floor, value[3]));
+ } else {
+ ret.push_back(HistogramBucket(std::numeric_limits<T>::min(), floor, value[3]));
+ }
+
+ T current_floor = floor;
+ T offset = current_step;
+ for (size_t i = 4; i < value.size() - 1; i++) {
+ T upper = floor + offset;
+ ret.push_back(HistogramBucket(current_floor, upper, value[i]));
+ offset *= step_multiplier;
+ current_floor = upper;
+ }
+
+ if (std::numeric_limits<T>::has_infinity) {
+ ret.push_back(HistogramBucket(current_floor, std::numeric_limits<T>::infinity(),
+ value[value.size() - 1]));
+ } else {
+ ret.push_back(
+ HistogramBucket(current_floor, std::numeric_limits<T>::max(), value[value.size() - 1]));
+ }
+ }
+
+ return ret;
+}
+
+// Internal class associating a name with one of several types of value.
+template <typename TypeVariant, typename FormatType>
+class NamedValue final {
+ public:
+ // Constructs a NamedValue associating the given name with the value.
+ template <typename T>
+ NamedValue(std::string name, T value) : name_(std::move(name)) {
+ format_ = static_cast<FormatType>(T::format_index);
+ value_.template emplace<T::format_index>(std::move(value));
+ }
+
+ // Checks if this NamedValue contains the templated type.
+ template <typename T>
+ bool Contains() const {
+ return value_.index() == T::format_index;
+ }
+
+ // Gets the value by type. If this NamedValue does not contain the given type,
+ // this method panics.
+ template <typename T>
+ const T& Get() const {
+ return value_.template get<T::format_index>();
+ }
+
+ // Gets the value by type. If this NamedValue does not contain the given type, this method returns
+ // nullptr.
+ template <typename T>
+ const T* GetOrNull() const {
+ if (!Contains<T>()) {
+ return nullptr;
+ }
+
+ return &Get<T>();
+ }
+
+ // Gets the name of this NamedValue.
+ const std::string& name() const { return name_; }
+
+ // Gets the format of the wrapped value.
+ FormatType format() const { return format_; }
+
+ private:
+ FormatType format_;
+ std::string name_;
+ TypeVariant value_;
+};
+
+} // namespace internal
+
+// The disposition for a LinkValue describes how its contents should be included in the parent node.
+enum LinkDisposition {
+ // Include the linked Tree as a child of the parent node.
+ kChild = 0,
+ // Inline all children of the linked Tree's root as children of the parent node.
+ kInline = 1,
+};
+
+// Wrapper for a particular LINK_VALUE.
+class LinkValue final {
+ public:
+ explicit LinkValue(std::string name, std::string content, LinkDisposition disposition)
+ : name_(std::move(name)), content_(std::move(content)), disposition_(disposition) {}
+
+ const std::string& name() const { return name_; }
+ const std::string& content() const { return content_; }
+ LinkDisposition disposition() const { return disposition_; }
+
+ private:
+ std::string name_;
+ std::string content_;
+ LinkDisposition disposition_;
+};
+
+// Describes the format of a parsed property.
+enum class PropertyFormat : uint8_t {
+ kInvalid = 0,
+ kInt = 1,
+ kUint = 2,
+ kDouble = 3,
+ kIntArray = 4,
+ kUintArray = 5,
+ kDoubleArray = 6,
+ kString = 7,
+ kBytes = 8,
+ kBool = 9,
+};
+
+using IntPropertyValue = internal::Value<int64_t, static_cast<size_t>(PropertyFormat::kInt)>;
+using UintPropertyValue = internal::Value<uint64_t, static_cast<size_t>(PropertyFormat::kUint)>;
+using DoublePropertyValue = internal::Value<double, static_cast<size_t>(PropertyFormat::kDouble)>;
+using BoolPropertyValue = internal::Value<bool, static_cast<size_t>(PropertyFormat::kBool)>;
+using IntArrayValue = internal::Array<int64_t, static_cast<size_t>(PropertyFormat::kIntArray)>;
+using UintArrayValue = internal::Array<uint64_t, static_cast<size_t>(PropertyFormat::kUintArray)>;
+using DoubleArrayValue = internal::Array<double, static_cast<size_t>(PropertyFormat::kDoubleArray)>;
+using StringPropertyValue =
+ internal::Value<std::string, static_cast<size_t>(PropertyFormat::kString)>;
+using ByteVectorPropertyValue =
+ internal::Value<std::vector<uint8_t>, static_cast<size_t>(PropertyFormat::kBytes)>;
+
+// Property consists of a name and a value corresponding to one PropertyFormat.
+using PropertyValue = internal::NamedValue<
+ fit::internal::variant<fit::internal::monostate, IntPropertyValue, UintPropertyValue,
+ DoublePropertyValue, IntArrayValue, UintArrayValue, DoubleArrayValue,
+ StringPropertyValue, ByteVectorPropertyValue, BoolPropertyValue>,
+ PropertyFormat>;
+
+// A Node parsed from a Hierarchy.
+//
+// This is named NodeValue to differentiate it from Node, the write-side definition of nodes.
+class NodeValue final {
+ public:
+ // Construct an empty NodeValue.
+ NodeValue() = default;
+
+ // Construct a NodeValue with a name and no properties.
+ explicit NodeValue(std::string name);
+
+ // Construct a NodeValue with a name and properties.
+ NodeValue(std::string name, std::vector<PropertyValue> properties);
+
+ // Obtains reference to name.
+ const std::string& name() const { return name_; }
+
+ // Sets the name.
+ void set_name(std::string name) { name_ = std::move(name); }
+
+ // Obtains reference to properties.
+ const std::vector<PropertyValue>& properties() const { return properties_; }
+
+ // Takes the properties, leaving the vector owned by this node blank.
+ std::vector<PropertyValue> take_properties() {
+ std::vector<PropertyValue> ret;
+ ret.swap(properties_);
+ return ret;
+ }
+
+ // Gets a pointer to the property with the given name and type.
+ //
+ // Returns a pointer if the property exists and is the correct type, nullptr otherwise.
+ //
+ // Note: The returned pointer is invalidated if any mutation occurs to this NodeValue.
+ template <typename T>
+ const T* get_property(const std::string& name) const {
+ auto it = std::find_if(properties_.begin(), properties_.end(),
+ [&](const PropertyValue& val) { return val.name() == name; });
+ if (it == properties_.end()) {
+ return nullptr;
+ }
+
+ return it->template GetOrNull<T>();
+ }
+
+ // Adds a property to this node.
+ void add_property(PropertyValue property) { properties_.emplace_back(std::move(property)); }
+
+ // Obtains reference to links.
+ const std::vector<LinkValue>& links() const { return links_; }
+
+ // Adds a link to this node.
+ void add_link(LinkValue link) { links_.emplace_back(std::move(link)); }
+
+ // Sets the vector of links for this node.
+ void set_links(std::vector<LinkValue> links) { links_ = std::move(links); }
+
+ // Sorts the properties of this node by name.
+ //
+ // See description of Hierarchy::Sort.
+ void Sort();
+
+ private:
+ // The name of this NodeValue.
+ std::string name_;
+
+ // The properties for this NodeValue.
+ std::vector<PropertyValue> properties_;
+
+ // The links for this NodeValue.
+ std::vector<LinkValue> links_;
+};
+
+enum class MissingValueReason {
+ // A referenced hierarchy in a link was not found.
+ kLinkNotFound = 1,
+
+ // A linked hierarchy at this location could not be parsed successfully.
+ kLinkHierarchyParseFailure = 2,
+
+ // A link we attempted to follow was not properly formatted, or its format is not known to this
+ // reader.
+ kLinkInvalid = 3,
+};
+
+// Wrapper for a value that was missing at a location in the hierarchy.
+struct MissingValue {
+ MissingValue() = default;
+ MissingValue(MissingValueReason reason, std::string name)
+ : reason(reason), name(std::move(name)) {}
+
+ // The reason why the value is missing.
+ MissingValueReason reason;
+
+ // The name of the missing value.
+ std::string name;
+};
+
+// Represents a hierarchy of node objects rooted under one particular node.
+//
+// NodeValues do not contain children because they are parsed directly from a buffer. Hierarchies
+// provide a wrapper around a hierarchy of nodes including named children. They additionally provide
+// links to hierarchies that can be parsed and spliced in from nested files.
+class Hierarchy final {
+ public:
+ Hierarchy() = default;
+
+ // Directly construct a hierarchy consisting of a node and a list
+ // of children.
+ Hierarchy(NodeValue node, std::vector<Hierarchy> children);
+
+ // Allow moving, disallow copying.
+ Hierarchy(Hierarchy&&) = default;
+ Hierarchy(const Hierarchy&) = delete;
+ Hierarchy& operator=(Hierarchy&&) = default;
+ Hierarchy& operator=(const Hierarchy&) = delete;
+
+ // Obtains the NodeValue at this level of this hierarchy.
+ const NodeValue& node() const { return node_; }
+
+ // Obtains a pointer to the underlying NodeValue.
+ NodeValue* node_ptr() { return &node_; }
+
+ // Obtains the name of the Node at this level of the hierarchy.
+ const std::string& name() const { return node_.name(); }
+
+ // Gets the children of this object in the hierarchy.
+ const std::vector<Hierarchy>& children() const { return children_; }
+
+ // Takes the children from this hierarchy.
+ std::vector<Hierarchy> take_children() { return std::move(children_); }
+
+ // Adds a child to this hierarchy.
+ void add_child(Hierarchy child) { children_.emplace_back(std::move(child)); }
+
+ // Gets the list of missing values for this location in the hierarchy.
+ const std::vector<MissingValue>& missing_values() const { return missing_values_; }
+
+ // Adds a missing value for this location in the hierarchy.
+ void add_missing_value(MissingValueReason reason, std::string name) {
+ missing_values_.emplace_back(reason, std::move(name));
+ }
+
+ // Gets a child in this Hierarchy by path.
+ // Returns nullptr if the requested child could not be found.
+ //
+ // The returned pointer will be invalidated if the Hierarchy is modified.
+ const Hierarchy* GetByPath(const std::vector<std::string>& path) const;
+
+ // Visit all descendents of this Hierarchy, calling the given callback with a mutable pointer to
+ // each child.
+ //
+ // Traversal stops when all descendents are visited or the callback returns false.
+ void Visit(fit::function<bool(const std::vector<std::string>&, Hierarchy*)> callback);
+
+ // Visit all descendents of this Hierarchy, calling the given callback with a const pointer to
+ // each child.
+ //
+ // Traversal stops when all descendents are visited or the callback returns false.
+ void Visit(fit::function<bool(const std::vector<std::string>&, const Hierarchy*)> callback) const;
+
+ // Sort properties and children of this node by, and recursively sort each child.
+ //
+ // This method imposes a canonical ordering on every child value in the hierarchy for purposes of
+ // comparison and output. It does not optimize operations in any way.
+ //
+ // The sorting rule for each of children and property values is as follows:
+ // - If and only if all names match non-negative integral strings, sort numerically.
+ // - Otherwise, sort lexicographically.
+ //
+ // For example:
+ // 3b 2 1 11 -> 1 11 2 3b
+ // 2 1 11 3 -> 1 2 3 11
+ // -1 3 20 -> -1 20 3
+ void Sort();
+
+ private:
+ NodeValue node_;
+ std::vector<Hierarchy> children_;
+ std::vector<MissingValue> missing_values_;
+};
+} // namespace inspect
+
+#endif // LIB_INSPECT_CPP_HIERARCHY_H_
diff --git a/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/inspect.h b/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/inspect.h
new file mode 100644
index 0000000..7a86f9d
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/inspect.h
@@ -0,0 +1,13 @@
+// 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.
+
+#ifndef LIB_INSPECT_CPP_INSPECT_H_
+#define LIB_INSPECT_CPP_INSPECT_H_
+
+#include <lib/inspect/cpp/inspector.h>
+#include <lib/inspect/cpp/value_list.h>
+#include <lib/inspect/cpp/vmo/state.h>
+#include <lib/inspect/cpp/vmo/types.h>
+
+#endif // LIB_INSPECT_CPP_INSPECT_H_
diff --git a/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/inspector.h b/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/inspector.h
new file mode 100644
index 0000000..411d2e5
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/inspector.h
@@ -0,0 +1,116 @@
+// Copyright 2018 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.
+
+#ifndef LIB_INSPECT_CPP_INSPECTOR_H_
+#define LIB_INSPECT_CPP_INSPECTOR_H_
+
+#include <lib/fit/optional.h>
+#include <lib/fit/result.h>
+#include <lib/inspect/cpp/value_list.h>
+#include <lib/zx/vmo.h>
+
+#include <string>
+
+namespace inspect {
+
+class Inspector;
+class Node;
+
+namespace internal {
+class State;
+
+// Internal accessor for obtaining fields from an Inspector.
+std::shared_ptr<State> GetState(const Inspector* inspector);
+} // namespace internal
+
+// Settings to configure a specific Inspector.
+struct InspectSettings final {
+ // The maximum size of the created VMO, in bytes.
+ //
+ // The size must be non-zero, and it will be rounded up to the next page size.
+ size_t maximum_size;
+};
+
+// The entry point into the Inspection API.
+//
+// An Inspector wraps a particular tree of Inspect data.
+//
+// This class is thread safe and copyable.
+class Inspector final {
+ public:
+ // Construct a new Inspector.
+ Inspector();
+
+ // Construct a new Inspector with the given settings.
+ explicit Inspector(const InspectSettings& settings);
+
+ // Construct a new Inspector backed by the given VMO.
+ //
+ // The VMO must support ZX_RIGHT_WRITE, ZX_VM_CAN_MAP_WRITE, and ZX_VM_CAN_MAP_READ permissions.
+ //
+ // If an invalid VMO is passed all Node operations will will have no effect.
+ explicit Inspector(zx::vmo vmo);
+
+ // Returns a duplicated read-only version of the VMO backing this inspector.
+ zx::vmo DuplicateVmo() const;
+
+ // Returns a copied version of the VMO backing this inspector.
+ //
+ // The returned copy will always be a consistent snapshot of the inspector state, truncated to
+ // include only relevant pages from the underlying VMO.
+ zx::vmo CopyVmo() const;
+
+ // Returns a copy of the bytes of the VMO backing this inspector.
+ //
+ // The returned bytes will always be a consistent snapshot of the inspector state, truncated to
+ // include only relevant bytes from the underlying VMO.
+ std::vector<uint8_t> CopyBytes() const;
+
+ // Returns a reference to the root node owned by this inspector.
+ Node& GetRoot() const;
+
+ // Boolean value of an Inspector is whether it is actually backed by a VMO.
+ //
+ // This method returns false if and only if Node operations on the Inspector are no-ops.
+ explicit operator bool() { return state_ != nullptr; }
+
+ // Emplace a value to be owned by this Inspector.
+ template <typename T>
+ void emplace(T value) {
+ value_list_->emplace(std::move(value));
+ }
+
+ // Gets the names of the inspectors linked off of this inspector.
+ std::vector<std::string> GetChildNames() const;
+
+ // Open a child of this inspector by name.
+ //
+ // Returns a promise for the opened inspector.
+ fit::promise<Inspector> OpenChild(const std::string& name) const;
+
+ private:
+ friend std::shared_ptr<internal::State> internal::GetState(const Inspector* inspector);
+
+ // The root node for the Inspector.
+ //
+ // Shared pointers are used so Inspector is copyable.
+ std::shared_ptr<Node> root_;
+
+ // The internal state for this inspector.
+ //
+ // Shared pointers are used so Inspector is copyable.
+ std::shared_ptr<internal::State> state_;
+
+ // Internally stored values owned by this Inspector.
+ //
+ // Shared pointers are used so Inspector is copyable.
+ std::shared_ptr<ValueList> value_list_;
+};
+
+// Generate a unique name with the given prefix.
+std::string UniqueName(const std::string& prefix);
+
+} // namespace inspect
+
+#endif // LIB_INSPECT_CPP_INSPECTOR_H_
diff --git a/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/reader.h b/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/reader.h
new file mode 100644
index 0000000..aec6552
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/reader.h
@@ -0,0 +1,47 @@
+// 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.
+
+#ifndef LIB_INSPECT_CPP_READER_H_
+#define LIB_INSPECT_CPP_READER_H_
+
+#include <lib/fit/promise.h>
+#include <lib/inspect/cpp/hierarchy.h>
+#include <lib/inspect/cpp/inspect.h>
+#include <lib/inspect/cpp/vmo/snapshot.h>
+
+namespace inspect {
+
+// Construct a new Hierarchy by synchronously reading nodes out of
+// the given VMO.
+fit::result<Hierarchy> ReadFromVmo(const zx::vmo& vmo);
+
+// Construct a new Hierarchy by synchronously reading nodes out of the
+// given VMO Snapshot.
+fit::result<Hierarchy> ReadFromSnapshot(Snapshot snapshot);
+
+// Construct a new Hierarchy by synchronously reading nodes out of the
+// contents of the given buffer.
+fit::result<Hierarchy> ReadFromBuffer(std::vector<uint8_t> buffer);
+
+// Construct a new Hierarchy by reading nodes out of the given Inspector, including
+// all linked hierarchies.
+fit::promise<Hierarchy> ReadFromInspector(Inspector insp);
+
+namespace internal {
+// Keeps track of a particular snapshot and the snapshots that are linked off of it.
+struct SnapshotTree {
+ // The snapshot of a VMO at a point in the tree.
+ Snapshot snapshot;
+
+ // Map from name to the SnapshotTree for a child of this snapshot.
+ std::map<std::string, SnapshotTree> children;
+};
+
+// Parses a tree of snapshots into its corresponding Hierarchy, following all links.
+fit::result<Hierarchy> ReadFromSnapshotTree(const SnapshotTree& tree);
+} // namespace internal
+
+} // namespace inspect
+
+#endif // LIB_INSPECT_CPP_READER_H_
diff --git a/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/value_list.h b/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/value_list.h
new file mode 100644
index 0000000..c596193
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/value_list.h
@@ -0,0 +1,75 @@
+// 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.
+
+#ifndef LIB_INSPECT_CPP_VALUE_LIST_H_
+#define LIB_INSPECT_CPP_VALUE_LIST_H_
+
+#include <lib/fit/variant.h>
+#include <lib/inspect/cpp/vmo/types.h>
+
+namespace inspect {
+
+namespace internal {
+// Base class for ValueHolder types, which approximate std::any.
+struct BaseHolder {
+ virtual ~BaseHolder() = default;
+};
+
+// Holder for an arbitrary type.
+template <typename T>
+struct ValueHolder : public BaseHolder {
+ explicit ValueHolder(T val) : value(std::move(val)) {}
+ ~ValueHolder() override = default;
+ T value;
+};
+
+} // namespace internal
+
+// A ValueList is a holder for arbitrary values that do not need to be explicitly named or modified
+// after creation.
+//
+// This class is not thread-safe, and it requires external synchronization if accessed from multiple
+// threads.
+//
+// Example:
+// struct Item {
+// // The inspect::Node for this item.
+// Node node;
+//
+// // List of unnamed values that should be retained for this item.
+// ValueList values;
+//
+// Item(Node* parent, const std::string& name, int value) {
+// node = parent->CreateChild(name);
+// // Expose the value, but enlist it in the ValueList so it doesn't need a name.
+// node.CreateInt("value", value, &values);
+// // "Stats" computes and stores some stats under the node it is given. Keep this in the
+// // ValueList as well since it doesn't need a name.
+// values.emplace(Stats(this, node.CreateChild("stats")));
+// }
+// }
+class ValueList final {
+ public:
+ ValueList() = default;
+
+ // Movable but not copyable.
+ ValueList(const ValueList&) = delete;
+ ValueList(ValueList&& other) = default;
+ ValueList& operator=(const ValueList&) = delete;
+ ValueList& operator=(ValueList&& other) = default;
+
+ // Emplaces a value in this ValueList.
+ template <typename T>
+ void emplace(T value) {
+ values_.emplace_back(std::make_unique<internal::ValueHolder<T>>(std::move(value)));
+ }
+
+ private:
+ // The list of values.
+ std::vector<std::unique_ptr<internal::BaseHolder>> values_;
+};
+
+} // namespace inspect
+
+#endif // LIB_INSPECT_CPP_VALUE_LIST_H_
diff --git a/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/vmo/block.h b/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/vmo/block.h
new file mode 100644
index 0000000..25ee1ff
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/vmo/block.h
@@ -0,0 +1,215 @@
+// 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.
+
+#ifndef LIB_INSPECT_CPP_VMO_BLOCK_H_
+#define LIB_INSPECT_CPP_VMO_BLOCK_H_
+
+#include <lib/inspect/cpp/vmo/limits.h>
+#include <zircon/types.h>
+
+#include <algorithm>
+#include <type_traits>
+
+namespace inspect {
+namespace internal {
+
+enum class BlockType : uint8_t {
+ kFree = 0,
+ kReserved = 1,
+ kHeader = 2,
+ kNodeValue = 3,
+ kIntValue = 4,
+ kUintValue = 5,
+ kDoubleValue = 6,
+ kBufferValue = 7,
+ kExtent = 8,
+ kName = 9,
+ kTombstone = 10,
+ kArrayValue = 11,
+ kLinkValue = 12,
+ kBoolValue = 13,
+};
+
+enum class PropertyBlockFormat : uint8_t {
+ // The property is a UTF-8 string.
+ kUtf8 = 0,
+
+ // The property is a binary string of uint8_t.
+ kBinary = 1
+};
+
+enum class ArrayBlockFormat : uint8_t {
+ // The array stores N raw values in N slots.
+ kDefault = 0,
+
+ // The array is a linear histogram with N buckets and N+4 slots, which are:
+ // - param_floor_value
+ // - param_step_size
+ // - underflow_bucket
+ // - ...N buckets...
+ // - overflow_bucket
+ kLinearHistogram = 1,
+
+ // The array is an exponential histogram with N buckets and N+5 slots, which are:
+ // - param_floor_value
+ // - param_initial_step
+ // - param_step_multiplier
+ // - underflow_bucket
+ // - ...N buckets...
+ // - overflow_bucket
+ kExponentialHistogram = 2
+};
+
+enum class LinkBlockDisposition : uint8_t {
+ // The linked sub-hierarchy root is a child of the LINK_VALUE's parent.
+ kChild = 0,
+
+ // The linked sub-hierarchy root's properties and children belong to the LINK_VALUE's parent.
+ kInline = 1,
+};
+
+using BlockOrder = uint32_t;
+using BlockIndex = uint64_t;
+
+// Returns the smallest order such that (kMinOrderSize << order) >= size.
+// Size must be non-zero.
+constexpr BlockOrder FitOrder(size_t size) {
+ auto ret = 64 - __builtin_clzl(size - 1) - kMinOrderShift;
+ return static_cast<BlockOrder>(ret);
+}
+
+// Structure of the block header and payload.
+struct Block final {
+ union {
+ uint64_t header;
+ char header_data[8];
+ };
+ union {
+ int64_t i64;
+ uint64_t u64;
+ double f64;
+ char data[8];
+ } payload;
+
+ // Get the payload as a const char*.
+ const char* payload_ptr() const { return static_cast<const char*>(payload.data); }
+
+ // Get the payload as a char*.
+ char* payload_ptr() { return static_cast<char*>(payload.data); }
+};
+
+static_assert(sizeof(Block) == 16, "Block header must be 16 bytes");
+static_assert(sizeof(Block) == kMinOrderSize,
+ "Minimum allocation size must exactly hold a block header");
+
+// Describes the layout of a bit-field packed into a 64-bit word.
+template <size_t begin, size_t end>
+struct Field final {
+ static_assert(begin < sizeof(uint64_t) * 8, "begin is out of bounds");
+ static_assert(end < sizeof(uint64_t) * 8, "end is out of bounds");
+ static_assert(begin <= end, "begin must not be larger than end");
+ static_assert(end - begin + 1 < 64, "must be a part of a word, not a whole word");
+
+ static constexpr uint64_t kMask = (uint64_t(1) << (end - begin + 1)) - 1;
+
+ template <typename T>
+ static constexpr uint64_t Make(T value) {
+ return static_cast<uint64_t>(value) << begin;
+ }
+
+ template <typename U>
+ static constexpr U Get(uint64_t word) {
+ return static_cast<U>((word >> (begin % 64)) & kMask);
+ }
+
+ static constexpr void Set(uint64_t* word, uint64_t value) {
+ *word = (*word & ~(kMask << begin)) | (value << begin);
+ }
+};
+
+// Describes the base fields present for all blocks.
+struct BlockFields {
+ using Order = Field<0, 3>;
+ using Type = Field<8, 15>;
+};
+
+struct HeaderBlockFields final : public BlockFields {
+ using Version = Field<16, 31>;
+ using MagicNumber = Field<32, 63>;
+};
+
+struct FreeBlockFields final : public BlockFields {
+ using NextFreeBlock = Field<16, 39>;
+};
+
+// Describes the fields common to all value blocks.
+struct ValueBlockFields final : public BlockFields {
+ using ParentIndex = Field<16, 39>;
+ using NameIndex = Field<40, 63>;
+};
+
+struct PropertyBlockPayload final {
+ using TotalLength = Field<0, 31>;
+ using ExtentIndex = Field<32, 59>;
+ using Flags = Field<60, 63>;
+};
+
+// Describes the fields for ARRAY_VALUE payloads.
+struct ArrayBlockPayload final {
+ using EntryType = Field<0, 3>;
+ using Flags = Field<4, 7>;
+ using Count = Field<8, 15>;
+};
+
+struct ExtentBlockFields final : public BlockFields {
+ using NextExtentIndex = Field<16, 39>;
+};
+
+struct NameBlockFields final : public BlockFields {
+ using Length = Field<16, 27>;
+};
+
+struct LinkBlockPayload final {
+ using ContentIndex = Field<0, 19>;
+ using Flags = Field<60, 63>;
+};
+
+constexpr BlockOrder GetOrder(const Block* block) {
+ return BlockFields::Order::Get<BlockOrder>(block->header);
+}
+
+constexpr BlockType GetType(const Block* block) {
+ return BlockFields::Type::Get<BlockType>(block->header);
+}
+
+constexpr size_t PayloadCapacity(BlockOrder order) {
+ return OrderToSize(order) - sizeof(Block::header);
+}
+
+constexpr size_t ArrayCapacity(BlockOrder order) {
+ return (OrderToSize(order) - sizeof(Block::header) - sizeof(Block::payload)) / sizeof(uint64_t);
+}
+
+constexpr size_t BlockSizeForPayload(size_t payload_size) {
+ return std::max(payload_size + sizeof(Block::header), kMinOrderSize);
+}
+
+// For array types, get a pointer to a specific slot in the array.
+// If the index is out of bounds, return nullptr.
+template <typename T, typename BlockType>
+constexpr T* GetArraySlot(BlockType* block, size_t index) {
+ if (index > ArrayCapacity(GetOrder(block))) {
+ return nullptr;
+ }
+
+ T* arr = reinterpret_cast<T*>(&block->payload);
+ return arr + index + 1 /* skip inline payload */;
+}
+
+constexpr size_t kMaxPayloadSize = kMaxOrderSize - sizeof(Block::header);
+
+} // namespace internal
+} // namespace inspect
+
+#endif // LIB_INSPECT_CPP_VMO_BLOCK_H_
diff --git a/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/vmo/heap.h b/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/vmo/heap.h
new file mode 100644
index 0000000..d7db1dc
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/vmo/heap.h
@@ -0,0 +1,96 @@
+// Copyright 2018 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.
+
+#ifndef LIB_INSPECT_CPP_VMO_HEAP_H_
+#define LIB_INSPECT_CPP_VMO_HEAP_H_
+
+#include <lib/inspect/cpp/vmo/block.h>
+#include <lib/inspect/cpp/vmo/limits.h>
+#include <lib/zx/vmo.h>
+#include <zircon/assert.h>
+
+namespace inspect {
+namespace internal {
+
+// A buddy-allocated heap of blocks stored in a VMO.
+//
+// |Heap| supports Allocate and Free operations to
+// allocate memory stored in a VMO. |Heap| allocations
+// touch a new page of the VMO (up to its capacity) only
+// when necessary to satisfy the allocation. This ensures
+// the VMO's default behavior of mapping all untouched
+// pages to a single physical "zero" page results in the
+// heap using the least amount of physical memory to
+// satisfy requests.
+//
+// This class is not thread safe.
+class Heap final {
+ public:
+ // Create a new heap that allocates out of the given |vmo|.
+ //
+ // The VMO must not be zero-sized.
+ explicit Heap(zx::vmo vmo);
+ ~Heap();
+
+ // Gets a reference to the underlying VMO.
+ const zx::vmo& GetVmo() const;
+
+ // Allocate a |BlockIndex| out of the heap that can contain at least |min_size| bytes.
+ // Allocating a block larger that |kMaxOrderSize| bytes will fail.
+ //
+ // Returns ZX_OK on success or an error on failure.
+ // |out_block| will be set to the allocated block index on success only.
+ //
+ // Warning: It is an error to destroy the heap without freeing all blocks first.
+ zx_status_t Allocate(size_t min_size, BlockIndex* out_block);
+
+ // Free a |BlockIndex| allocated from this heap.
+ void Free(BlockIndex block_index);
+
+ // Get a pointer to the |Block| for the given |Block|.
+ Block* GetBlock(BlockIndex block) const {
+ return reinterpret_cast<Block*>((reinterpret_cast<uint8_t*>(buffer_addr_)) +
+ block * kMinOrderSize);
+ }
+
+ // Return a pointer to the data buffer.
+ const uint8_t* data() const { return reinterpret_cast<uint8_t*>(buffer_addr_); }
+
+ // Return the current usable size of the VMO.
+ size_t size() const { return cur_size_; }
+
+ private:
+ static constexpr const size_t kDefaultMaxSize = 256 * 1024;
+
+ // Returns true if the given block is free and of the expected order.
+ inline bool IsFreeBlock(BlockIndex block, size_t expected_order) const;
+
+ bool SplitBlock(BlockIndex block);
+ bool RemoveFree(BlockIndex block);
+ zx_status_t Extend(size_t new_size);
+
+ zx::vmo vmo_;
+ size_t cur_size_ = 0;
+ size_t max_size_ = 0;
+ uintptr_t buffer_addr_ = 0;
+ BlockIndex free_blocks_[8] = {};
+
+ // Keep track of the number of allocated blocks to assert that they are all freed
+ // before the heap is destroyed.
+ size_t num_allocated_blocks_ = 0;
+};
+
+bool Heap::IsFreeBlock(BlockIndex block, size_t expected_order) const {
+ ZX_DEBUG_ASSERT_MSG(block < IndexForOffset(cur_size_), "Block out of bounds");
+ if (block >= cur_size_ / kMinOrderSize) {
+ return false;
+ }
+ auto* b = GetBlock(block);
+ return GetType(b) == BlockType::kFree && GetOrder(b) == expected_order;
+}
+
+} // namespace internal
+} // namespace inspect
+
+#endif // LIB_INSPECT_CPP_VMO_HEAP_H_
diff --git a/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/vmo/limits.h b/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/vmo/limits.h
new file mode 100644
index 0000000..abd28aa
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/vmo/limits.h
@@ -0,0 +1,44 @@
+// Copyright 2018 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.
+
+#ifndef LIB_INSPECT_CPP_VMO_LIMITS_H_
+#define LIB_INSPECT_CPP_VMO_LIMITS_H_
+
+#include <zircon/types.h>
+
+namespace inspect {
+namespace internal {
+
+// The size for order 0.
+constexpr size_t kMinOrderShift = 4;
+constexpr size_t kMinOrderSize = 1 << kMinOrderShift; // 16 bytes
+
+// The total number of orders in the buddy allocator.
+constexpr size_t kNumOrders = 8;
+
+// The size of the maximum order.
+constexpr size_t kMaxOrderShift = kMinOrderShift + kNumOrders - 1;
+constexpr size_t kMaxOrderSize = 1 << kMaxOrderShift;
+
+// The minimum size for the inspection VMO.
+constexpr size_t kMinVmoSize = 4096;
+static_assert(kMinVmoSize >= kMaxOrderSize, "Maximum order size must fit in the smallest VMO");
+
+// The magic number for verifying the VMO format.
+constexpr char kMagicNumber[5] = "INSP";
+
+// The version of Inspect Format we support.
+constexpr size_t kVersion = 1;
+
+template <typename T>
+constexpr size_t OrderToSize(T order) {
+ return kMinOrderSize << order;
+}
+
+constexpr size_t IndexForOffset(size_t offset) { return offset / kMinOrderSize; }
+
+} // namespace internal
+} // namespace inspect
+
+#endif // LIB_INSPECT_CPP_VMO_LIMITS_H_
diff --git a/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/vmo/scanner.h b/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/vmo/scanner.h
new file mode 100644
index 0000000..13e3d9c
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/vmo/scanner.h
@@ -0,0 +1,29 @@
+// 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.
+
+#ifndef LIB_INSPECT_CPP_VMO_SCANNER_H_
+#define LIB_INSPECT_CPP_VMO_SCANNER_H_
+
+#include <lib/fit/function.h>
+#include <lib/inspect/cpp/vmo/block.h>
+#include <zircon/types.h>
+
+namespace inspect {
+namespace internal {
+
+// Read blocks out of the buffer.
+//
+// For each block that it found, this function calls the callback function
+// with the block's index and a pointer to the block. If the callback
+// returns false, it will not be called again.
+//
+// Returns ZX_OK if the buffer was valid and successfully loaded,
+// otherwise returns an error describing what went wrong.
+zx_status_t ScanBlocks(const uint8_t* buffer, size_t size,
+ fit::function<bool(BlockIndex, const Block*)> callback);
+
+} // namespace internal
+} // namespace inspect
+
+#endif // LIB_INSPECT_CPP_VMO_SCANNER_H_
diff --git a/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/vmo/snapshot.h b/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/vmo/snapshot.h
new file mode 100644
index 0000000..65b5667
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/vmo/snapshot.h
@@ -0,0 +1,106 @@
+// 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.
+
+#ifndef LIB_INSPECT_CPP_VMO_SNAPSHOT_H_
+#define LIB_INSPECT_CPP_VMO_SNAPSHOT_H_
+
+#include <lib/fit/function.h>
+#include <lib/inspect/cpp/vmo/block.h>
+#include <lib/zx/vmo.h>
+#include <unistd.h>
+#include <zircon/types.h>
+
+#include <functional>
+#include <vector>
+
+namespace inspect {
+
+// |Snapshot| parses an incoming VMO buffer and produces a snapshot of
+// the VMO contents. |Snapshot::Options| determines the behavior of
+// snapshotting if a concurrent write potentially occurred.
+//
+// Example:
+// Snapshot* snapshot;
+// zx_status_t status = Snapshot::Create(std::move(vmo),
+// {.read_attempts = 1024, .skip_consistency_check = false},
+// &snapshot);
+//
+// Test Example:
+// zx_status_t status = Snapshot::Create(std::move(vmo),
+// {.read_attempts = 1024, .skip_consistency_check = false},
+// std::make_unique<TestCallback>(),
+// &snapshot);
+class Snapshot final {
+ public:
+ struct Options final {
+ // The number of attempts to read a consistent snapshot.
+ // Reading fails if the number of attempts exceeds this number.
+ int read_attempts = 1024;
+
+ // If true, skip checking the buffer for consistency.
+ bool skip_consistency_check = false;
+ };
+
+ // Type for observing reads on the VMO.
+ using ReadObserver = fit::function<void(uint8_t* buffer, size_t buffer_size)>;
+
+ // By default, ensure consistency of the incoming Inspect VMO and retry up to
+ // 1024 times.
+ static constexpr Options kDefaultOptions = {.read_attempts = 1024,
+ .skip_consistency_check = false};
+
+ // Create a new snapshot of the given VMO using default options.
+ static zx_status_t Create(const zx::vmo& vmo, Snapshot* out_snapshot);
+
+ // Create a new snapshot of the given VMO using the given options.
+ static zx_status_t Create(const zx::vmo& vmo, Options options, Snapshot* out_snapshot);
+
+ // Create a new snapshot of the given VMO using the given options, and use the read_observer
+ // for observing snapshot operations.
+ static zx_status_t Create(const zx::vmo& vmo, Options options, ReadObserver read_observer,
+ Snapshot* out_snapshot);
+
+ // Create a new snapshot over the supplied buffer. If the buffer cannot be interpreted as a
+ // snapshot, an error status is returned. There are no observers or writers involved.
+ static zx_status_t Create(std::vector<uint8_t> buffer, Snapshot* out_snapshot);
+
+ Snapshot() = default;
+ ~Snapshot() = default;
+ Snapshot(Snapshot&&) = default;
+ Snapshot(const Snapshot&) = default;
+ Snapshot& operator=(Snapshot&&) = default;
+ Snapshot& operator=(const Snapshot&) = default;
+
+ explicit operator bool() const { return buffer_ != nullptr && !buffer_->empty(); }
+
+ // Returns the start of the snapshot data.
+ const uint8_t* data() const { return buffer_ ? buffer_->data() : nullptr; }
+
+ // Returns the size of the snapshot.
+ size_t size() const { return buffer_ ? buffer_->size() : 0; }
+
+ private:
+ // Read from the VMO into a buffer.
+ static zx_status_t Read(const zx::vmo& vmo, size_t size, uint8_t* buffer);
+
+ // Parse the header from a buffer and obtain the generation count.
+ static zx_status_t ParseHeader(uint8_t* buffer, uint64_t* out_generation_count);
+
+ // Take a new snapshot of the VMO with default options.
+ // If reading fails, the boolean value of the constructed |Snapshot| will be false.
+ explicit Snapshot(std::vector<uint8_t> buffer);
+
+ // The buffer storing the snapshot.
+ std::shared_ptr<std::vector<uint8_t>> buffer_;
+};
+
+namespace internal {
+// Get a pointer to a block in the snapshot by index.
+// Returns nullptr if the index is out of bounds.
+const Block* GetBlock(const Snapshot* snapshot, BlockIndex index);
+} // namespace internal
+
+} // namespace inspect
+
+#endif // LIB_INSPECT_CPP_VMO_SNAPSHOT_H_
diff --git a/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/vmo/state.h b/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/vmo/state.h
new file mode 100644
index 0000000..b32bc60
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/vmo/state.h
@@ -0,0 +1,334 @@
+// Copyright 2018 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.
+
+#ifndef LIB_INSPECT_CPP_VMO_STATE_H_
+#define LIB_INSPECT_CPP_VMO_STATE_H_
+
+#include <lib/async/dispatcher.h>
+#include <lib/fit/function.h>
+#include <lib/fit/promise.h>
+#include <lib/fit/sequencer.h>
+#include <lib/fit/thread_safety.h>
+#include <lib/inspect/cpp/inspector.h>
+#include <lib/inspect/cpp/vmo/block.h>
+#include <lib/inspect/cpp/vmo/heap.h>
+#include <lib/inspect/cpp/vmo/types.h>
+
+#include <iterator>
+#include <map>
+#include <mutex>
+
+namespace inspect {
+
+namespace internal {
+
+// |State| wraps a |Heap| and implements the Inspect VMO API on top of
+// that heap. This class contains the low-level operations necessary to
+// deal with the various Inspect types and wrappers to denote ownership of
+// those values.
+//
+// This class should not be used directly, prefer to use |Inspector|.
+class State final {
+ public:
+ // Create a new State wrapping the given Heap.
+ // On failure, returns nullptr.
+ static std::shared_ptr<State> Create(std::unique_ptr<Heap> heap);
+
+ // Create a new State wrapping a new heap of the given size.
+ // On failure, returns an empty shared_ptr.
+ static std::shared_ptr<State> CreateWithSize(size_t size);
+
+ // Destructor for State, which performs necessary cleanup.
+ ~State();
+
+ // Disallow copy and assign.
+ State(const State&) = delete;
+ State(State&&) = delete;
+ State& operator=(const State&) = delete;
+ State& operator=(State&&) = delete;
+
+ // Obtain a reference to the wrapped VMO.
+ // This may be duplicated read-only to pass to a reader process.
+ const zx::vmo& GetVmo() const;
+
+ // Obtain a read-only duplicate of the VMO backing this State.
+ bool DuplicateVmo(zx::vmo* vmo) const;
+
+ // Obtain a copy of the VMO backing this state.
+ //
+ // Returns true on success, false otherwise.
+ bool Copy(zx::vmo* vmo) const;
+
+ // Obtain a copy of the bytes in the VMO backing this state.
+ //
+ // Returns true on success, false otherwise.
+ bool CopyBytes(std::vector<uint8_t>* out) const;
+
+ // Create a new |IntProperty| in the Inspect VMO. The returned value releases
+ // the property when destroyed.
+ IntProperty CreateIntProperty(const std::string& name, BlockIndex parent, int64_t value);
+
+ // Create a new |UintProperty| in the Inspect VMO. The returned value releases
+ // the property when destroyed.
+ UintProperty CreateUintProperty(const std::string& name, BlockIndex parent, uint64_t value);
+
+ // Create a new |DoubleProperty| in the Inspect VMO. The returned value releases
+ // the property when destroyed.
+ DoubleProperty CreateDoubleProperty(const std::string& name, BlockIndex parent, double value);
+
+ // Create a new |BoolProperty| in the Inspect VMO. The returned value releases
+ // the property when destroyed.
+ BoolProperty CreateBoolProperty(const std::string& name, BlockIndex parent, bool value);
+
+ // Create a new |IntArray| in the Inspect VMO. The returned value releases
+ // the array when destroyed.
+ IntArray CreateIntArray(const std::string& name, BlockIndex parent, size_t slots,
+ ArrayBlockFormat format);
+
+ // Create a new |UintArray| in the Inspect VMO. The returned value releases
+ // the array when destroyed.
+ UintArray CreateUintArray(const std::string& name, BlockIndex parent, size_t slots,
+ ArrayBlockFormat format);
+
+ // Create a new |DoubleArray| in the Inspect VMO. The returned value releases
+ // the array when destroyed.
+ DoubleArray CreateDoubleArray(const std::string& name, BlockIndex parent, size_t slots,
+ ArrayBlockFormat format);
+
+ // Create a new |StringProperty| in the Inspect VMO. The returned value releases
+ // the property when destroyed.
+ StringProperty CreateStringProperty(const std::string& name, BlockIndex parent,
+ const std::string& value);
+
+ // Create a new |ByteVectorProperty| in the Inspect VMO. The returned value releases
+ // the property when destroyed.
+ ByteVectorProperty CreateByteVectorProperty(const std::string& name, BlockIndex parent,
+ const std::vector<uint8_t>& value);
+
+ // Create a new [Link] in the Inspect VMO. The returned node releases the link when destroyed.
+ //
+ // A Link is a low-level reference to a new Inspector linked off of the one managed by this
+ // state. A Link alone is not sufficient to populate the linked tree, see CreateLazyNode and
+ // CreateLazyValues.
+ Link CreateLink(const std::string& name, BlockIndex parent, const std::string& content,
+ LinkBlockDisposition disposition);
+
+ // Create a new |Node| in the Inspect VMO. Nodes are refcounted such that values nested under the
+ // node remain valid until all such values values are destroyed.
+ Node CreateNode(const std::string& name, BlockIndex parent);
+
+ // Create a special root |Node| in the Inspect VMO. This node is not backed by any storage, rather
+ // it allows clients to use the |Node| iterface to add properties and children directly to the
+ // root of the VMO.
+ Node CreateRootNode();
+
+ // Create a new |LazyNode| with a new named |Link| that calls the given callback with child
+ // disposition.
+ LazyNode CreateLazyNode(const std::string& name, BlockIndex parent, LazyNodeCallbackFn callback);
+
+ // Create a new |LazyNode| with a new named |Link| that calls the given callback with inline
+ // disposition.
+ LazyNode CreateLazyValues(const std::string& name, BlockIndex parent,
+ LazyNodeCallbackFn callback);
+
+ // Setters for various property types
+ void SetIntProperty(IntProperty* property, int64_t value);
+ void SetUintProperty(UintProperty* property, uint64_t value);
+ void SetDoubleProperty(DoubleProperty* property, double value);
+ void SetBoolProperty(BoolProperty* property, bool value);
+ void SetIntArray(IntArray* array, size_t index, int64_t value);
+ void SetUintArray(UintArray* array, size_t index, uint64_t value);
+ void SetDoubleArray(DoubleArray* array, size_t index, double value);
+ void SetStringProperty(StringProperty* property, const std::string& value);
+ void SetByteVectorProperty(ByteVectorProperty* property, const std::vector<uint8_t>& value);
+
+ // Adders for various property types
+ void AddIntProperty(IntProperty* property, int64_t value);
+ void AddUintProperty(UintProperty* property, uint64_t value);
+ void AddDoubleProperty(DoubleProperty* property, double value);
+ void AddIntArray(IntArray* array, size_t index, int64_t value);
+ void AddUintArray(UintArray* array, size_t index, uint64_t value);
+ void AddDoubleArray(DoubleArray* array, size_t index, double value);
+
+ // Subtractors for various property types
+ void SubtractIntProperty(IntProperty* property, int64_t value);
+ void SubtractUintProperty(UintProperty* property, uint64_t value);
+ void SubtractDoubleProperty(DoubleProperty* property, double value);
+ void SubtractIntArray(IntArray* array, size_t index, int64_t value);
+ void SubtractUintArray(UintArray* array, size_t index, uint64_t value);
+ void SubtractDoubleArray(DoubleArray* array, size_t index, double value);
+
+ // Free various entities
+ void FreeIntProperty(IntProperty* property);
+ void FreeUintProperty(UintProperty* property);
+ void FreeDoubleProperty(DoubleProperty* property);
+ void FreeBoolProperty(BoolProperty* property);
+ void FreeIntArray(IntArray* array);
+ void FreeUintArray(UintArray* array);
+ void FreeDoubleArray(DoubleArray* array);
+ void FreeStringProperty(StringProperty* property);
+ void FreeByteVectorProperty(ByteVectorProperty* property);
+ void FreeLink(Link* link);
+ void FreeNode(Node* node);
+ void FreeLazyNode(LazyNode* lazy_node);
+
+ // Get the names of all links in this state.
+ std::vector<std::string> GetLinkNames() const;
+
+ // Call a specific link by name, return a promise for the Inspector it produces.
+ fit::promise<Inspector> CallLinkCallback(const std::string& name);
+
+ // Create a unique name for children in this State.
+ //
+ // Returned strings are guaranteed to be unique and will start with the given prefix.
+ std::string UniqueName(const std::string& prefix);
+
+ private:
+ // Holder for a LazyNodeCallbackFn.
+ //
+ // This class ensures that the callback function is only called once at a time, and it allows
+ // future calls to the callback to be cancelled to prevent calling it when the corresponding
+ // LazyNode has been deleted.
+ //
+ // This class is copyable and thread-safe. Each copy refers to the same underlying callback, and
+ // cancelling one copy cancels all copies.
+ class LazyNodeCallbackHolder {
+ public:
+ LazyNodeCallbackHolder() = default;
+ explicit LazyNodeCallbackHolder(LazyNodeCallbackFn callback)
+ : inner_(new Inner(std::move(callback))) {}
+
+ // This class is copyable but not movable. This ensures LazyNodeCallbackHolder objects are
+ // always in a valid state.
+ LazyNodeCallbackHolder(const LazyNodeCallbackHolder&) = default;
+ LazyNodeCallbackHolder(LazyNodeCallbackHolder&&) = delete;
+ LazyNodeCallbackHolder& operator=(const LazyNodeCallbackHolder&) = default;
+ LazyNodeCallbackHolder& operator=(LazyNodeCallbackHolder&&) = delete;
+
+ // Cancel and release the callback. Future attempts to call the callback will do nothing.
+ void cancel() {
+ std::lock_guard<std::mutex> lock(inner_->mutex);
+ inner_->callback = {};
+ }
+
+ // Call the callback if it is not cancelled.
+ fit::promise<Inspector> call() {
+ std::lock_guard<std::mutex> lock(inner_->mutex);
+ if (inner_->callback) {
+ return inner_->callback();
+ } else {
+ return fit::make_result_promise<Inspector>(fit::error());
+ }
+ }
+
+ private:
+ // Inner structure to share a mutex and a callback.
+ struct Inner {
+ explicit Inner(LazyNodeCallbackFn fn) : callback(std::move(fn)) {}
+
+ std::mutex mutex;
+ LazyNodeCallbackFn callback FIT_GUARDED(mutex);
+ };
+ std::shared_ptr<Inner> inner_;
+ };
+
+ State(std::unique_ptr<Heap> heap, BlockIndex header)
+ : heap_(std::move(heap)), header_(header), next_unique_id_(0), next_unique_link_number_(0) {}
+
+ void DecrementParentRefcount(BlockIndex value_index) __TA_REQUIRES(mutex_);
+
+ // Helper method for creating a new VALUE block type.
+ zx_status_t InnerCreateValue(const std::string& name, BlockType type, BlockIndex parent_index,
+ BlockIndex* out_name, BlockIndex* out_value,
+ size_t min_size_required = kMinOrderSize) __TA_REQUIRES(mutex_);
+
+ // Helper method to create a new LINK block that calls a callback when followed.
+ LazyNode InnerCreateLazyLink(const std::string& name, BlockIndex parent,
+ LazyNodeCallbackFn callback, LinkBlockDisposition disposition);
+
+ // Returns true if the block is an extent, false otherwise.
+ constexpr bool IsExtent(const Block* block) {
+ return block && GetType(block) == BlockType::kExtent;
+ }
+
+ // Helper to set the value of a string across its extents.
+ zx_status_t InnerSetStringExtents(BlockIndex string_index, const char* value, size_t length)
+ __TA_REQUIRES(mutex_);
+
+ // Helper to free all extents for a given string.
+ // This leaves the string value allocated and empty.
+ void InnerFreeStringExtents(BlockIndex string_index) __TA_REQUIRES(mutex_);
+
+ // Helper to create a new name block with the given name.
+ zx_status_t CreateName(const std::string& name, BlockIndex* out) __TA_REQUIRES(mutex_);
+
+ // Helper function to create an array with the given name, number of slots, and format.
+ template <typename NumericType, typename WrapperType, BlockType BlockTypeValue>
+ WrapperType InnerCreateArray(const std::string& name, BlockIndex parent, size_t slots,
+ ArrayBlockFormat format);
+
+ // Helper function to create a property with a byte format.
+ template <typename WrapperType, typename ValueType>
+ WrapperType InnerCreateProperty(const std::string& name, BlockIndex parent, const char* value,
+ size_t length, PropertyBlockFormat format);
+
+ template <typename WrapperType>
+ void InnerSetProperty(WrapperType* property, const char* value, size_t length);
+
+ // Helper function to delete String or ByteVector properties.
+ template <typename WrapperType>
+ void InnerFreePropertyWithExtents(WrapperType* property);
+
+ // Helper function to set the value of a specific index in an array.
+ template <typename NumericType, typename WrapperType, BlockType BlockTypeValue>
+ void InnerSetArray(WrapperType* property, size_t index, NumericType value);
+
+ // Helper function to perform an operation on a specific index in an array.
+ // Common operations are std::plus and std::minus.
+ template <typename NumericType, typename WrapperType, BlockType BlockTypeValue,
+ typename Operation>
+ void InnerOperationArray(WrapperType* property, size_t index, NumericType value);
+
+ // Helper function to free an array type.
+ template <typename WrapperType>
+ void InnerFreeArray(WrapperType* value);
+
+ // Helper function to generate a unique name for a link.
+ std::string UniqueLinkName(const std::string& prefix);
+
+ // Mutex wrapping all fields in the state.
+ // The mutex is mutable to support locking when reading fields of a
+ // const reference to state.
+ mutable std::mutex mutex_;
+
+ // Weak pointer reference to this object, used to pass shared pointers to children.
+ std::weak_ptr<State> weak_self_ptr_;
+
+ // The wrapped |Heap|, protected by the mutex.
+ std::unique_ptr<Heap> heap_ FIT_GUARDED(mutex_);
+
+ // Map from the key of a linked inspect tree to the callback that populates that tree.
+ //
+ // An ordered map is used to ensure consistent iteration ordering for clients reading this data.
+ std::map<std::string, LazyNodeCallbackHolder> link_callbacks_ FIT_GUARDED(mutex_);
+
+ // The index for the header block containing the generation count
+ // to increment
+ BlockIndex header_ FIT_GUARDED(mutex_);
+
+ // The next unique ID to give out from UniqueName.
+ //
+ // Uses the fastest available atomic uint64 type for fetch_and_add.
+ std::atomic_uint_fast64_t next_unique_id_;
+
+ // Next value to be used as a suffix for links.
+ //
+ // Uses the fastest available atomic uint64 type for fetch_and_add.
+ std::atomic_uint_fast64_t next_unique_link_number_;
+};
+
+} // namespace internal
+} // namespace inspect
+
+#endif // LIB_INSPECT_CPP_VMO_STATE_H_
diff --git a/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/vmo/types.h b/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/vmo/types.h
new file mode 100644
index 0000000..fc888a2
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/inspect/include/lib/inspect/cpp/vmo/types.h
@@ -0,0 +1,648 @@
+// Copyright 2018 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.
+
+#ifndef LIB_INSPECT_CPP_VMO_TYPES_H_
+#define LIB_INSPECT_CPP_VMO_TYPES_H_
+
+#include <lib/fit/function.h>
+#include <lib/fit/promise.h>
+#include <lib/inspect/cpp/vmo/block.h>
+#include <zircon/assert.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+#include <string>
+#include <vector>
+
+namespace inspect {
+class Node;
+class Inspector;
+
+using LazyNodeCallbackFn = fit::function<fit::promise<Inspector>()>;
+
+namespace internal {
+class State;
+
+// A property containing a templated numeric type. All methods wrap the
+// corresponding functionality on |State|, and concrete
+// implementations are available only for int64_t, uint64_t and double.
+template <typename T>
+class NumericProperty final {
+ public:
+ // Construct a default numeric metric. Operations on this metric are
+ // no-ops.
+ NumericProperty() = default;
+ ~NumericProperty();
+
+ // Allow moving, disallow copying.
+ NumericProperty(const NumericProperty& other) = delete;
+ NumericProperty(NumericProperty&& other) = default;
+ NumericProperty& operator=(const NumericProperty& other) = delete;
+ NumericProperty& operator=(NumericProperty&& other) noexcept;
+
+ // Set the value of this numeric metric to the given value.
+ void Set(T value);
+
+ // Add the given value to the value of this numeric metric.
+ void Add(T value);
+
+ // Subtract the given value from the value of this numeric metric.
+ void Subtract(T value);
+
+ // Return true if this metric is stored in a buffer. False otherwise.
+ explicit operator bool() { return state_ != nullptr; }
+
+ private:
+ friend class ::inspect::internal::State;
+ NumericProperty(std::shared_ptr<internal::State> state, internal::BlockIndex name,
+ internal::BlockIndex value)
+ : state_(std::move(state)), name_index_(name), value_index_(value) {}
+
+ // Reference to the state containing this metric.
+ std::shared_ptr<internal::State> state_;
+
+ // Index of the name block in the state.
+ internal::BlockIndex name_index_;
+
+ // Index of the value block in the state.
+ internal::BlockIndex value_index_;
+};
+
+// A value containing an array of numeric types. All methods wrap the
+// corresponding functionality on |State|, and concrete
+// implementations are available only for int64_t, uint64_t and double.
+template <typename T>
+class ArrayValue final {
+ public:
+ // Construct a default array value. Operations on this value are
+ // no-ops.
+ ArrayValue() = default;
+ ~ArrayValue();
+
+ // Allow moving, disallow copying.
+ ArrayValue(const ArrayValue& other) = delete;
+ ArrayValue(ArrayValue&& other) = default;
+ ArrayValue& operator=(const ArrayValue& other) = delete;
+ ArrayValue& operator=(ArrayValue&& other) noexcept;
+
+ // Set the value of the given index of this array.
+ void Set(size_t index, T value);
+
+ // Add the given value to the value of this numeric metric.
+ void Add(size_t index, T value);
+
+ // Subtract the given value from the value of this numeric metric.
+ void Subtract(size_t index, T value);
+
+ // Return true if this metric is stored in a buffer. False otherwise.
+ explicit operator bool() { return state_ != nullptr; }
+
+ private:
+ friend class ::inspect::internal::State;
+ ArrayValue(std::shared_ptr<internal::State> state, internal::BlockIndex name,
+ internal::BlockIndex value)
+ : state_(std::move(state)), name_index_(name), value_index_(value) {}
+
+ // Reference to the state containing this value.
+ std::shared_ptr<internal::State> state_;
+
+ // Index of the name block in the state.
+ internal::BlockIndex name_index_;
+
+ // Index of the value block in the state.
+ internal::BlockIndex value_index_;
+};
+
+template <typename T>
+class LinearHistogram final {
+ public:
+ // Create a default histogram.
+ // Operations on the metric will have no effect.
+ LinearHistogram() = default;
+
+ // Movable but not copyable.
+ LinearHistogram(const LinearHistogram& other) = delete;
+ LinearHistogram(LinearHistogram&& other) = default;
+ LinearHistogram& operator=(const LinearHistogram& other) = delete;
+ LinearHistogram& operator=(LinearHistogram&& other) = default;
+
+ // Insert the given value once to the correct bucket of the histogram.
+ void Insert(T value) { Insert(value, 1); }
+
+ // Insert the given value |count| times to the correct bucket of the
+ // histogram.
+ void Insert(T value, T count) { array_.Add(GetIndexForValue(value), count); }
+
+ private:
+ friend class ::inspect::Node;
+
+ // First slots are floor, step_size, and underflow.
+ static const size_t kBucketOffset = 3;
+
+ // Get the number of buckets, which excludes the two parameter slots and the
+ // two overflow slots.
+ size_t BucketCount() { return array_size_ - 4; }
+
+ // Calculates the correct array index to store the given value.
+ size_t GetIndexForValue(T value) {
+ if (array_size_ == 0) {
+ return 0;
+ }
+ size_t ret = kBucketOffset - 1;
+ T current_floor = floor_;
+ for (; value >= current_floor && ret < array_size_ - 1; current_floor += step_size_, ret++) {
+ }
+ return ret;
+ }
+
+ // Internal constructor wrapping an array.
+ LinearHistogram(T floor, T step_size, size_t array_size, ArrayValue<T> array)
+ : floor_(floor), step_size_(step_size), array_size_(array_size), array_(std::move(array)) {
+ ZX_ASSERT(array_size_ > 4);
+ array_.Set(0, floor_);
+ array_.Set(1, step_size_);
+ }
+
+ T floor_ = 0;
+ T step_size_ = 0;
+ size_t array_size_ = 0;
+ ArrayValue<T> array_;
+};
+
+template <typename T>
+class ExponentialHistogram final {
+ public:
+ // Create a default histogram.
+ // Operations on the metric will have no effect.
+ ExponentialHistogram() = default;
+
+ // Movable but not copyable.
+ ExponentialHistogram(const ExponentialHistogram& other) = delete;
+ ExponentialHistogram(ExponentialHistogram&& other) = default;
+ ExponentialHistogram& operator=(const ExponentialHistogram& other) = delete;
+ ExponentialHistogram& operator=(ExponentialHistogram&& other) = default;
+
+ // Insert the given value once to the correct bucket of the histogram.
+ void Insert(T value) { Insert(value, 1); }
+
+ // Insert the given value |count| times to the correct bucket of the
+ // histogram.
+ void Insert(T value, T count) { array_.Add(GetIndexForValue(value), count); }
+
+ private:
+ friend class ::inspect::Node;
+
+ // First slots are floor, initial_step, step_multiplier, and underflow.
+ static const size_t kBucketOffset = 4;
+
+ // Get the number of buckets, which excludes the two parameter slots and the
+ // two overflow slots.
+ size_t BucketCount() { return array_size_ - 5; }
+
+ // Calculates the correct array index to store the given value.
+ size_t GetIndexForValue(T value) {
+ if (array_size_ == 0) {
+ return 0;
+ }
+ T current_floor = floor_;
+ T current_step = initial_step_;
+ size_t ret = kBucketOffset - 1;
+ while (value >= current_floor && ret < array_size_ - 1) {
+ current_floor = floor_ + current_step;
+ current_step *= step_multiplier_;
+ ret++;
+ }
+ return ret;
+ }
+
+ // Internal constructor wrapping a VMO type.
+ ExponentialHistogram(T floor, T initial_step, T step_multiplier, size_t array_size,
+ ArrayValue<T> array)
+ : floor_(floor),
+ initial_step_(initial_step),
+ step_multiplier_(step_multiplier),
+ array_size_(array_size),
+ array_(std::move(array)) {
+ ZX_ASSERT(array_size_ > 5);
+ array_.Set(0, floor_);
+ array_.Set(1, initial_step_);
+ array_.Set(2, step_multiplier_);
+ }
+
+ T floor_ = 0;
+ T initial_step_ = 0;
+ T step_multiplier_ = 0;
+ size_t array_size_ = 0;
+ ArrayValue<T> array_;
+};
+
+// A property containing a string value.
+// All methods wrap the corresponding functionality on |State|.
+template <typename T>
+class Property final {
+ public:
+ // Construct a default property. Operations on this property are
+ // no-ops.
+ Property() = default;
+ ~Property();
+
+ // Allow moving, disallow copying.
+ Property(const Property& other) = delete;
+ Property(Property&& other) = default;
+ Property& operator=(const Property& other) = delete;
+ Property& operator=(Property&& other) noexcept;
+
+ // Return true if this property is stored in a buffer. False otherwise.
+ explicit operator bool() { return state_ != nullptr; }
+
+ // Set the value of this property.
+ void Set(const T& value);
+
+ private:
+ friend class ::inspect::internal::State;
+ Property(std::shared_ptr<internal::State> state, internal::BlockIndex name,
+ internal::BlockIndex value)
+ : state_(std::move(state)), name_index_(name), value_index_(value) {}
+
+ // Reference to the state containing this property.
+ std::shared_ptr<internal::State> state_;
+
+ // Index of the name block in the state.
+ internal::BlockIndex name_index_;
+
+ // Index of the value block in the state.
+ internal::BlockIndex value_index_;
+};
+
+} // namespace internal
+
+using IntProperty = internal::NumericProperty<int64_t>;
+using UintProperty = internal::NumericProperty<uint64_t>;
+using DoubleProperty = internal::NumericProperty<double>;
+using BoolProperty = internal::Property<bool>;
+
+using IntArray = internal::ArrayValue<int64_t>;
+using UintArray = internal::ArrayValue<uint64_t>;
+using DoubleArray = internal::ArrayValue<double>;
+
+using LinearIntHistogram = internal::LinearHistogram<int64_t>;
+using LinearUintHistogram = internal::LinearHistogram<uint64_t>;
+using LinearDoubleHistogram = internal::LinearHistogram<double>;
+
+using ExponentialIntHistogram = internal::ExponentialHistogram<int64_t>;
+using ExponentialUintHistogram = internal::ExponentialHistogram<uint64_t>;
+using ExponentialDoubleHistogram = internal::ExponentialHistogram<double>;
+
+using StringProperty = internal::Property<std::string>;
+using ByteVectorProperty = internal::Property<std::vector<uint8_t>>;
+
+// Links specify a location that can be read as a continuation of an Inspect hierarchy.
+class Link final {
+ public:
+ // Construct a default link.
+ Link() = default;
+ ~Link();
+
+ // Allow moving, disallow copying.
+ Link(const Link& other) = delete;
+ Link(Link&& other) = default;
+ Link& operator=(const Link& other) = delete;
+ Link& operator=(Link&& other) = default;
+
+ // Return true if this node is stored in a buffer. False otherwise.
+ explicit operator bool() { return state_ != nullptr; }
+
+ private:
+ friend class ::inspect::internal::State;
+ Link(std::shared_ptr<internal::State> state, internal::BlockIndex name,
+ internal::BlockIndex value, internal::BlockIndex content)
+ : state_(std::move(state)), name_index_(name), value_index_(value), content_index_(content) {}
+
+ // Reference to the state containing this value.
+ std::shared_ptr<internal::State> state_;
+
+ // Index of the name block in the state.
+ internal::BlockIndex name_index_;
+
+ // Index of the value block in the state.
+ internal::BlockIndex value_index_;
+
+ // Index of the content block in the state.
+ internal::BlockIndex content_index_;
+};
+
+// A LazyNode has a value that is dynamically set by a callback.
+class LazyNode final {
+ public:
+ // Construct a default LazyNode.
+ LazyNode() = default;
+ ~LazyNode();
+
+ // Allow moving, disallow copying.
+ LazyNode(const LazyNode& other) = delete;
+ LazyNode(LazyNode&& other) = default;
+ LazyNode& operator=(const LazyNode& other) = delete;
+ LazyNode& operator=(LazyNode&& other) = default;
+
+ // Return true if this value is represented in a buffer. False otherwise.
+ explicit operator bool() { return state_ != nullptr; }
+
+ private:
+ friend class ::inspect::internal::State;
+ LazyNode(std::shared_ptr<internal::State> state, std::string content_value, Link link)
+ : state_(std::move(state)),
+ content_value_(std::move(content_value)),
+ link_(std::move(link)) {}
+
+ // Reference to the state containing this value.
+ std::shared_ptr<internal::State> state_;
+
+ // The value stored in the contents of the Link for this node. Used as a key for removal when
+ // deleted.
+ std::string content_value_;
+
+ // The Link node that references this LazyNode.
+ Link link_;
+};
+
+// A node under which properties, metrics, and other nodes may be nested.
+// All methods wrap the corresponding functionality on |State|.
+class Node final {
+ public:
+ // Construct a default node. Operations on this node are
+ // no-ops.
+ Node() = default;
+ ~Node();
+
+ // Allow moving, disallow copying.
+ Node(const Node& other) = delete;
+ Node(Node&& other) = default;
+ Node& operator=(const Node& other) = delete;
+ Node& operator=(Node&& other) noexcept;
+
+ // Create a new |Node| with the given name that is a child of this node.
+ // If this node is not stored in a buffer, the created node will
+ // also not be stored in a buffer.
+ Node CreateChild(const std::string& name) __WARN_UNUSED_RESULT;
+
+ // Same as CreateChild, but emplaces the value in the given container.
+ //
+ // The type of |list| must have method emplace(Node).
+ // inspect::ValueList is recommended for most use cases.
+ template <typename T>
+ void CreateChild(const std::string& name, T* list) {
+ list->emplace(CreateChild(name));
+ }
+
+ // Create a new |IntProperty| with the given name that is a child of this node.
+ // If this node is not stored in a buffer, the created metric will
+ // also not be stored in a buffer.
+ IntProperty CreateInt(const std::string& name, int64_t value) __WARN_UNUSED_RESULT;
+
+ // Same as CreateInt, but emplaces the value in the given container.
+ //
+ // The type of |list| must have method emplace(IntProperty).
+ // inspect::ValueList is recommended for most use cases.
+ template <typename T>
+ void CreateInt(const std::string& name, int64_t value, T* list) {
+ list->emplace(CreateInt(name, value));
+ }
+
+ // Create a new |UintProperty| with the given name that is a child of this node.
+ // If this node is not stored in a buffer, the created metric will
+ // also not be stored in a buffer.
+ UintProperty CreateUint(const std::string& name, uint64_t value) __WARN_UNUSED_RESULT;
+
+ // Same as CreateUint, but emplaces the value in the given container.
+ //
+ // The type of |list| must have method emplace(UintProperty).
+ // inspect::ValueList is recommended for most use cases.
+ template <typename T>
+ void CreateUint(const std::string& name, uint64_t value, T* list) {
+ list->emplace(CreateUint(name, value));
+ }
+
+ // Create a new |DoubleProperty| with the given name that is a child of this node.
+ // If this node is not stored in a buffer, the created metric will
+ // also not be stored in a buffer.
+ DoubleProperty CreateDouble(const std::string& name, double value) __WARN_UNUSED_RESULT;
+
+ // Same as CreateDouble, but emplaces the value in the given container.
+ //
+ // The type of |list| must have method emplace(DoubleProperty).
+ // inspect::ValueList is recommended for most use cases.
+ template <typename T>
+ void CreateDouble(const std::string& name, double value, T* list) {
+ list->emplace(CreateDouble(name, value));
+ }
+
+ // Create a new |BoolProperty| with the given name that is a child of this node.
+ // If this node is not stored in a buffer, the created metric will
+ // also not be stored in a buffer.
+ BoolProperty CreateBool(const std::string& name, bool value) __WARN_UNUSED_RESULT;
+
+ // Same as CreateBool, but emplaces the value in the given container.
+ //
+ // The type of |list| must have method emplace(BoolProperty).
+ // inspect::ValueList is recommended for most use cases.
+ template <typename T>
+ void CreateBool(const std::string& name, bool value, T* list) {
+ list->emplace(CreateBool(name, value));
+ }
+
+ // Create a new |StringProperty| with the given name and value that is a child of this node.
+ // If this node is not stored in a buffer, the created property will
+ // also not be stored in a buffer.
+ StringProperty CreateString(const std::string& name,
+ const std::string& value) __WARN_UNUSED_RESULT;
+
+ // Same as CreateString, but emplaces the value in the given container.
+ //
+ // The type of |list| must have method emplace(StringProperty).
+ // inspect::ValueList is recommended for most use cases.
+ template <typename T>
+ void CreateString(const std::string& name, const std::string& value, T* list) {
+ list->emplace(CreateString(name, value));
+ }
+
+ // Create a new |ByteVectorProperty| with the given name and value that is a child of this node.
+ // If this node is not stored in a buffer, the created property will
+ // also not be stored in a buffer.
+ ByteVectorProperty CreateByteVector(const std::string& name,
+ const std::vector<uint8_t>& value) __WARN_UNUSED_RESULT;
+
+ // Same as CreateByteVector, but emplaces the value in the given container.
+ //
+ // The type of |list| must have method emplace(ByteVectorProperty).
+ // inspect::ValueList is recommended for most use cases.
+ template <typename T>
+ void CreateByteVector(const std::string& name, const std::vector<uint8_t>& value, T* list) {
+ list->emplace(CreateByteVector(name, value));
+ }
+
+ // Create a new |IntArray| with the given name and slots that is a child of this node.
+ // If this node is not stored in a buffer, the created value will
+ // also not be stored in a buffer.
+ IntArray CreateIntArray(const std::string& name, size_t slots) __WARN_UNUSED_RESULT;
+
+ // Create a new |UintArray| with the given name and slots that is a child of this node.
+ // If this node is not stored in a buffer, the created value will
+ // also not be stored in a buffer.
+ UintArray CreateUintArray(const std::string& name, size_t slots) __WARN_UNUSED_RESULT;
+
+ // Create a new |DoubleArray| with the given name and slots that is a child of this node.
+ // If this node is not stored in a buffer, the created value will
+ // also not be stored in a buffer.
+ DoubleArray CreateDoubleArray(const std::string& name, size_t slots) __WARN_UNUSED_RESULT;
+
+ // Create a new |LinearIntHistogram| with the given name and format that is a child of this
+ // node. If this node is not stored in a buffer, the created value will also not be stored in
+ // a buffer.
+ LinearIntHistogram CreateLinearIntHistogram(const std::string& name, int64_t floor,
+ int64_t step_size,
+ size_t buckets) __WARN_UNUSED_RESULT;
+
+ // Create a new |LinearUintHistogram| with the given name and format that is a child of this
+ // node. If this node is not stored in a buffer, the created value will also not be stored in
+ // a buffer.
+ LinearUintHistogram CreateLinearUintHistogram(const std::string& name, uint64_t floor,
+ uint64_t step_size,
+ size_t buckets) __WARN_UNUSED_RESULT;
+
+ // Create a new |LinearDoubleHistogram| with the given name and format that is a child of this
+ // node. If this node is not stored in a buffer, the created value will also not be stored in
+ // a buffer.
+ LinearDoubleHistogram CreateLinearDoubleHistogram(const std::string& name, double floor,
+ double step_size,
+ size_t buckets) __WARN_UNUSED_RESULT;
+
+ // Create a new |ExponentialIntHistogram| with the given name and format that is a child of this
+ // node. If this node is not stored in a buffer, the created value will also not be stored in
+ // a buffer.
+ ExponentialIntHistogram CreateExponentialIntHistogram(const std::string& name, int64_t floor,
+ int64_t initial_step,
+ int64_t step_multiplier,
+ size_t buckets) __WARN_UNUSED_RESULT;
+
+ // Create a new |ExponentialUintHistogram| with the given name and format that is a child of this
+ // node. If this node is not stored in a buffer, the created value will also not be stored in
+ // a buffer.
+ ExponentialUintHistogram CreateExponentialUintHistogram(const std::string& name, uint64_t floor,
+ uint64_t initial_step,
+ uint64_t step_multiplier,
+ size_t buckets) __WARN_UNUSED_RESULT;
+
+ // Create a new |ExponentialDoubleHistogram| with the given name and format that is a child of
+ // this node. If this node is not stored in a buffer, the created value will also not be
+ // stored in a buffer.
+ ExponentialDoubleHistogram CreateExponentialDoubleHistogram(const std::string& name, double floor,
+ double initial_step,
+ double step_multiplier,
+ size_t buckets) __WARN_UNUSED_RESULT;
+
+ // Create a new |LazyNode| with the given name that is populated by the given callback on demand.
+ //
+ // The passed |callback| will live as long as the returned LazyNode, and will not be called
+ // concurrently by multiple threads.
+ //
+ // For example:
+ // auto a = root.CreateChild("a");
+ // a.CreateLazyNode("b", [] {
+ // Inspector insp;
+ // ValueList values;
+ // insp.GetRoot().CreateInt("val", 2, &values);
+ // return fit::make_ok_result(insp);
+ // });
+ //
+ // Output:
+ // root:
+ // a:
+ // b:
+ // val = 2
+ LazyNode CreateLazyNode(const std::string& name,
+ LazyNodeCallbackFn callback) __WARN_UNUSED_RESULT;
+
+ // Same as CreateLazyNode, but emplaces the value in the given container.
+ //
+ // The type of |list| must have method emplace(LazyNode).
+ // inspect::ValueList is recommended for most use cases.
+ template <typename F, typename T>
+ void CreateLazyNode(const std::string& name, F callback, T* list) {
+ list->emplace(CreateLazyNode(name, std::move(callback)));
+ }
+
+ // Create a new |LazyNode| whose children and properties are added to this node on demand.
+ //
+ // The passed |callback| will live as long as the returned LazyNode, and will not be called
+ // concurrently by multiple threads.
+ //
+ // The name is only used if inflating the tree callback fails.
+ //
+ // WARNING: It is the caller's responsibility to avoid name collisions with other properties
+ // on this node.
+ //
+ // For example:
+ // auto a = root.CreateChild("a");
+ // a.CreateLazy("b", [] {
+ // Inspector insp;
+ // ValueList values;
+ // insp.GetRoot().CreateInt("val", 2).enlist(&values);
+ // return fit::make_ok_promise(insp);
+ // });
+ //
+ // Output:
+ // root:
+ // a:
+ // val = 2
+ //
+ // Alternatively:
+ //
+ // a.CreateLazyNode("b", [] {
+ // return fit::make_error_promise();
+ // });
+ //
+ // Possible output:
+ // root:
+ // a:
+ // b [Failed to open link]
+ LazyNode CreateLazyValues(const std::string& name,
+ LazyNodeCallbackFn callback) __WARN_UNUSED_RESULT;
+
+ // Same as CreateLazyValues, but emplaces the value in the given container.
+ //
+ // The type of |list| must have method emplace(LazyNode).
+ // inspect::ValueList is recommended for most use cases.
+ template <typename F, typename T>
+ void CreateLazyValues(const std::string& name, F callback, T* list) {
+ list->emplace(CreateLazyValues(name, std::move(callback)));
+ }
+
+ // Create a new |LazyNode| whose children and properties are added to this node on demand.
+ // Return true if this node is stored in a buffer. False otherwise.
+ explicit operator bool() { return state_ != nullptr; }
+
+ // Create a unique name for children of this node.
+ //
+ // The returned strings are guaranteed to be at least unique within the context of this Node.
+ std::string UniqueName(const std::string& prefix);
+
+ private:
+ friend class ::inspect::internal::State;
+ Node(std::shared_ptr<internal::State> state, internal::BlockIndex name,
+ internal::BlockIndex value)
+ : state_(std::move(state)), name_index_(name), value_index_(value) {}
+
+ // Reference to the state containing this metric.
+ std::shared_ptr<internal::State> state_;
+
+ // Index of the name block in the state.
+ internal::BlockIndex name_index_;
+
+ // Index of the value block in the state.
+ internal::BlockIndex value_index_;
+};
+
+} // namespace inspect
+
+#endif // LIB_INSPECT_CPP_VMO_TYPES_H_
diff --git a/third_party/fuchsia-sdk/pkg/inspect/inspector.cc b/third_party/fuchsia-sdk/pkg/inspect/inspector.cc
new file mode 100644
index 0000000..92a7d0d
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/inspect/inspector.cc
@@ -0,0 +1,101 @@
+// Copyright 2018 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.
+
+#include <lib/fit/result.h>
+#include <lib/inspect/cpp/inspect.h>
+#include <lib/inspect/cpp/vmo/heap.h>
+#include <lib/inspect/cpp/vmo/state.h>
+#include <lib/inspect/cpp/vmo/types.h>
+
+#include <sstream>
+
+using inspect::internal::Heap;
+using inspect::internal::State;
+
+namespace inspect {
+
+namespace {
+const InspectSettings kDefaultInspectSettings = {.maximum_size = 256 * 1024};
+} // namespace
+
+Inspector::Inspector() : Inspector(kDefaultInspectSettings) {}
+
+Inspector::Inspector(const InspectSettings& settings)
+ : root_(std::make_shared<Node>()), value_list_(std::make_shared<ValueList>()) {
+ if (settings.maximum_size == 0) {
+ return;
+ }
+
+ state_ = State::CreateWithSize(settings.maximum_size);
+ if (!state_) {
+ return;
+ }
+
+ *root_ = state_->CreateRootNode();
+}
+
+Inspector::Inspector(zx::vmo vmo)
+ : root_(std::make_shared<Node>()), value_list_(std::make_shared<ValueList>()) {
+ size_t size;
+
+ zx_status_t status;
+ if (ZX_OK != (status = vmo.get_size(&size))) {
+ return;
+ }
+
+ if (size == 0) {
+ // VMO cannot be zero size.
+ return;
+ }
+
+ // Decommit all pages, reducing memory usage of the VMO and zeroing it.
+ if (ZX_OK != (status = vmo.op_range(ZX_VMO_OP_DECOMMIT, 0, size, nullptr, 0))) {
+ return;
+ }
+
+ state_ = State::Create(std::make_unique<Heap>(std::move(vmo)));
+ if (!state_) {
+ return;
+ }
+
+ *root_ = state_->CreateRootNode();
+}
+
+zx::vmo Inspector::DuplicateVmo() const {
+ zx::vmo ret;
+
+ if (state_) {
+ state_->DuplicateVmo(&ret);
+ }
+
+ return ret;
+}
+
+zx::vmo Inspector::CopyVmo() const {
+ zx::vmo ret;
+
+ state_->Copy(&ret);
+
+ return ret;
+}
+
+std::vector<uint8_t> Inspector::CopyBytes() const {
+ std::vector<uint8_t> ret;
+ state_->CopyBytes(&ret);
+ return ret;
+}
+
+Node& Inspector::GetRoot() const { return *root_; }
+
+std::vector<std::string> Inspector::GetChildNames() const { return state_->GetLinkNames(); }
+
+fit::promise<Inspector> Inspector::OpenChild(const std::string& child_name) const {
+ return state_->CallLinkCallback(child_name);
+}
+
+namespace internal {
+std::shared_ptr<State> GetState(const Inspector* inspector) { return inspector->state_; }
+} // namespace internal
+
+} // namespace inspect
diff --git a/third_party/fuchsia-sdk/pkg/inspect/meta.json b/third_party/fuchsia-sdk/pkg/inspect/meta.json
new file mode 100644
index 0000000..8578db6
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/inspect/meta.json
@@ -0,0 +1,41 @@
+{
+ "banjo_deps": [],
+ "deps": [
+ "async-default",
+ "fdio",
+ "async",
+ "fit",
+ "zx"
+ ],
+ "fidl_deps": [],
+ "headers": [
+ "pkg/inspect/include/lib/inspect/cpp/inspect.h",
+ "pkg/inspect/include/lib/inspect/cpp/inspector.h",
+ "pkg/inspect/include/lib/inspect/cpp/hierarchy.h",
+ "pkg/inspect/include/lib/inspect/cpp/reader.h",
+ "pkg/inspect/include/lib/inspect/cpp/health.h",
+ "pkg/inspect/include/lib/inspect/cpp/value_list.h",
+ "pkg/inspect/include/lib/inspect/cpp/vmo/state.h",
+ "pkg/inspect/include/lib/inspect/cpp/vmo/types.h",
+ "pkg/inspect/include/lib/inspect/cpp/vmo/block.h",
+ "pkg/inspect/include/lib/inspect/cpp/vmo/heap.h",
+ "pkg/inspect/include/lib/inspect/cpp/vmo/limits.h",
+ "pkg/inspect/include/lib/inspect/cpp/vmo/scanner.h",
+ "pkg/inspect/include/lib/inspect/cpp/vmo/snapshot.h"
+ ],
+ "include_dir": "pkg/inspect/include",
+ "name": "inspect",
+ "root": "pkg/inspect",
+ "sources": [
+ "pkg/inspect/health.cc",
+ "pkg/inspect/hierarchy.cc",
+ "pkg/inspect/inspector.cc",
+ "pkg/inspect/reader.cc",
+ "pkg/inspect/vmo/heap.cc",
+ "pkg/inspect/vmo/scanner.cc",
+ "pkg/inspect/vmo/snapshot.cc",
+ "pkg/inspect/vmo/state.cc",
+ "pkg/inspect/vmo/types.cc"
+ ],
+ "type": "cc_source_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/inspect/reader.cc b/third_party/fuchsia-sdk/pkg/inspect/reader.cc
new file mode 100644
index 0000000..20f5ae6
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/inspect/reader.cc
@@ -0,0 +1,536 @@
+// 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.
+
+#include <lib/fit/optional.h>
+#include <lib/inspect/cpp/reader.h>
+#include <lib/inspect/cpp/vmo/block.h>
+#include <lib/inspect/cpp/vmo/scanner.h>
+#include <lib/inspect/cpp/vmo/snapshot.h>
+
+#include <iterator>
+#include <set>
+#include <stack>
+#include <unordered_map>
+
+using inspect::internal::BlockIndex;
+using inspect::internal::SnapshotTree;
+
+namespace inspect {
+
+namespace {
+
+// Traverses the given hierarchy and passes pointers to any hierarchy containing a link to the
+// callback.
+//
+// The callback is called before the passed hierarchy is traversed into, so it may be modified in
+// the context of the callback.
+void VisitHierarchiesWithLink(Hierarchy* root, fit::function<void(Hierarchy*)> callback) {
+ root->Visit([&](const std::vector<std::string>& path, Hierarchy* hierarchy) {
+ if (!hierarchy->node().links().empty()) {
+ callback(hierarchy);
+ }
+ return true;
+ });
+}
+
+// Iteratively snapshot individual inspectors and then snapshot the children of those inspectors,
+// collecting the results in a single SnapshotTree.
+//
+// Consistency of individual Snapshots is guaranteed.
+//
+// Child Snapshots are guaranteed only to be taken consistently after their parent Snapshot.
+//
+// Between the initial Snapshot and reading lazy children, it is possible that the lazy child was
+// deleted. In this case, the child snapshot will be missing.
+fit::promise<SnapshotTree> SnapshotTreeFromInspector(Inspector insp) {
+ SnapshotTree ret;
+ if (ZX_OK != Snapshot::Create(insp.DuplicateVmo(), &ret.snapshot)) {
+ return fit::make_result_promise<SnapshotTree>(fit::error());
+ }
+
+ // Sequence all promises to ensure depth-first traversal. Otherwise traversal may cause
+ // all children for a Snapshot to be instantiated simultaneously.
+ fit::sequencer seq;
+ std::vector<fit::promise<SnapshotTree>> promises;
+ auto child_names = insp.GetChildNames();
+ for (const auto& child_name : child_names) {
+ promises.emplace_back(
+ insp.OpenChild(child_name)
+ .and_then([](Inspector& insp) { return SnapshotTreeFromInspector(std::move(insp)); })
+ .wrap_with(seq));
+ }
+
+ return fit::join_promise_vector(std::move(promises))
+ .and_then([ret = std::move(ret), names = std::move(child_names)](
+ std::vector<fit::result<SnapshotTree>>& children) mutable
+ -> fit::result<SnapshotTree> {
+ ZX_ASSERT(names.size() == children.size());
+
+ for (size_t i = 0; i < names.size(); i++) {
+ if (children[i].is_ok()) {
+ ret.children.emplace(std::move(names[i]), children[i].take_value());
+ }
+ }
+
+ return fit::ok(std::move(ret));
+ });
+}
+
+} // namespace
+
+namespace internal {
+
+// A ParsedNode contains parsed information for a node.
+// It is built iteratively as children and values are discovered.
+//
+// A ParsedNode is valid only if it has been initialized with a name and
+// parent index (which happens when its OBJECT_VALUE block is read).
+//
+// A ParsedNode is "complete" when the number of children in the parsed
+// hierarchy matches an expected count. At this point the Hierarchy may be
+// removed and the ParsedNode discarded.
+struct ParsedNode {
+ // The node hierarchy being parsed out of the buffer.
+ // Propertys and properties are parsed into here as they are read.
+ Hierarchy hierarchy;
+
+ // The number of children expected for this node.
+ // The node is considered "complete" once the number of children in the
+ // hierarchy matches this count.
+ size_t children_count = 0;
+
+ // The index of the parent, only valid if this node is initialized.
+ BlockIndex parent;
+
+ // Initializes the stored node with the given name and parent.
+ void InitializeNode(std::string name, BlockIndex new_parent) {
+ hierarchy.node_ptr()->set_name(std::move(name));
+ parent = new_parent;
+ initialized_ = true;
+ }
+
+ explicit operator bool() { return initialized_; }
+
+ bool is_complete() { return hierarchy.children().size() == children_count; }
+
+ private:
+ bool initialized_ = false;
+};
+
+// The |Reader| supports reading the contents of a |Snapshot|.
+// This class constructs a hierarchy of nodes contained in the snapshot
+// if the snapshot is valid.
+class Reader {
+ public:
+ Reader(Snapshot snapshot) : snapshot_(std::move(snapshot)) {}
+
+ // Read the contents of the snapshot and return the root node.
+ fit::result<Hierarchy> Read();
+
+ private:
+ // Gets a pointer to the ParsedNode for the given index. A new ParsedObject
+ // is created if one did not exist previously for the index.
+ ParsedNode* GetOrCreate(BlockIndex index);
+
+ void InnerScanBlocks();
+
+ // Initialize an Object for the given BlockIndex.
+ void InnerCreateObject(BlockIndex index, const Block* block);
+
+ // Parse a numeric property block and attach it to the given parent.
+ void InnerParseNumericProperty(ParsedNode* parent, const Block* block);
+
+ // Parse a property block and attach it to the given parent.
+ void InnerParseProperty(ParsedNode* parent, const Block* block);
+
+ // Parse a link block and attach it to the given parent.
+ void InnerParseLink(ParsedNode* parent, const Block* block);
+
+ // Helper to interpret the given block as a NAME block and return a
+ // copy of the name contents.
+ fit::optional<std::string> GetAndValidateName(BlockIndex index);
+
+ // Contents of the read VMO.
+ Snapshot snapshot_;
+
+ // Map of block index to the parsed node being constructed for that address.
+ std::unordered_map<BlockIndex, ParsedNode> parsed_nodes_;
+};
+
+fit::optional<std::string> Reader::GetAndValidateName(BlockIndex index) {
+ const Block* block = internal::GetBlock(&snapshot_, index);
+ if (!block) {
+ return {};
+ }
+
+ size_t capacity = PayloadCapacity(GetOrder(block));
+ auto len = NameBlockFields::Length::Get<size_t>(block->header);
+ // Do not parse the name if the declared length is greater than what the block can hold.
+ if (len > capacity) {
+ return {};
+ }
+
+ return std::string(block->payload_ptr(), len);
+}
+
+void Reader::InnerScanBlocks() {
+ ScanBlocks(snapshot_.data(), snapshot_.size(), [this](BlockIndex index, const Block* block) {
+ BlockType type = GetType(block);
+ if (index == 0) {
+ if (type != BlockType::kHeader) {
+ return false;
+ }
+ } else if (type == BlockType::kNodeValue) {
+ // This block defines an Object, use the value to fill out the name of
+ // the ParsedNode.
+ InnerCreateObject(index, block);
+ } else if (type == BlockType::kIntValue || type == BlockType::kUintValue ||
+ type == BlockType::kDoubleValue || type == BlockType::kArrayValue ||
+ type == BlockType::kBoolValue) {
+ // This block defines a numeric property for an Object, parse the
+ // property into the properties field of the ParsedNode.
+ auto parent_index = ValueBlockFields::ParentIndex::Get<BlockIndex>(block->header);
+ InnerParseNumericProperty(GetOrCreate(parent_index), block);
+ } else if (type == BlockType::kBufferValue) {
+ // This block defines a property for an Object, parse the property
+ // into the properties field of the ParsedNode.
+ auto parent_index = ValueBlockFields::ParentIndex::Get<BlockIndex>(block->header);
+ InnerParseProperty(GetOrCreate(parent_index), block);
+ } else if (type == BlockType::kLinkValue) {
+ // This block defines a link to an adjacent hierarchy stored outside the currently parsed one.
+ // For now we parse and store the contents of the link with the NodeValue, and we will handle
+ // merging trees in a separate step.
+ auto parent_index = ValueBlockFields::ParentIndex::Get<BlockIndex>(block->header);
+ InnerParseLink(GetOrCreate(parent_index), block);
+ }
+
+ return true;
+ });
+}
+
+fit::result<Hierarchy> Reader::Read() {
+ if (!snapshot_) {
+ // Snapshot is invalid, return an error.
+ return fit::error();
+ }
+
+ // Initialize the implicit root node, which uses index 0.
+ ParsedNode root;
+ root.InitializeNode("root", 0);
+ parsed_nodes_.emplace(0, std::move(root));
+
+ // Scan blocks into the parsed_node map. This creates ParsedNodes with
+ // properties and an accurate count of the number of expected
+ // children. ParsedNodes with a valid OBJECT_VALUE block are initialized
+ // with a name and parent index.
+ InnerScanBlocks();
+
+ // Stack of completed nodes to process. Entries consist of the completed
+ // Hierarchy and the block index of their parent.
+ std::stack<std::pair<Hierarchy, BlockIndex>> complete_nodes;
+
+ // Iterate over the map of parsed nodes and find those nodes that are
+ // already "complete." These nodes are moved to the complete_nodes map for
+ // bottom-up processing.
+ for (auto it = parsed_nodes_.begin(); it != parsed_nodes_.end();) {
+ if (!it->second) {
+ // The node is not valid, ignore.
+ it = parsed_nodes_.erase(it);
+ continue;
+ }
+
+ if (it->second.is_complete()) {
+ if (it->first == 0) {
+ // The root is complete, return it.
+ return fit::ok(std::move(it->second.hierarchy));
+ }
+
+ // The node is valid and complete, push it onto the stack.
+ complete_nodes.push(std::make_pair(std::move(it->second.hierarchy), it->second.parent));
+ it = parsed_nodes_.erase(it);
+ continue;
+ }
+
+ ++it;
+ }
+
+ // Construct a valid hierarchy from the bottom up by attaching completed
+ // nodes to their parent node. Once a parent becomes complete, add it to
+ // the stack to recursively bubble the completed children towards the root.
+ while (!complete_nodes.empty()) {
+ auto obj = std::move(complete_nodes.top());
+ complete_nodes.pop();
+
+ // Get the parent node, which was created during block scanning.
+ auto it = parsed_nodes_.find(obj.second);
+ if (it == parsed_nodes_.end()) {
+ // Parent node did not exist, ignore this node.
+ continue;
+ }
+ auto* parent = &it->second;
+ parent->hierarchy.add_child(std::move(obj.first));
+ if (parent->is_complete()) {
+ if (obj.second == 0) {
+ // This was the last node that needed to be added to the root to complete it.
+ // Return the root.
+ return fit::ok(std::move(parent->hierarchy));
+ }
+
+ // The parent node is now complete, push it onto the stack.
+ complete_nodes.push(std::make_pair(std::move(parent->hierarchy), parent->parent));
+ parsed_nodes_.erase(it);
+ }
+ }
+
+ // We processed all completed nodes but could not find a complete root,
+ // return an error.
+ return fit::error();
+}
+
+ParsedNode* Reader::GetOrCreate(BlockIndex index) {
+ return &parsed_nodes_.emplace(index, ParsedNode()).first->second;
+}
+
+ArrayDisplayFormat ArrayBlockFormatToDisplay(ArrayBlockFormat format) {
+ switch (format) {
+ case ArrayBlockFormat::kLinearHistogram:
+ return ArrayDisplayFormat::kLinearHistogram;
+ case ArrayBlockFormat::kExponentialHistogram:
+ return ArrayDisplayFormat::kExponentialHistogram;
+ default:
+ return ArrayDisplayFormat::kFlat;
+ }
+}
+
+void Reader::InnerParseNumericProperty(ParsedNode* parent, const Block* block) {
+ auto name = GetAndValidateName(ValueBlockFields::NameIndex::Get<size_t>(block->header));
+ if (!name.has_value()) {
+ return;
+ }
+
+ auto* parent_node = parent->hierarchy.node_ptr();
+
+ BlockType type = GetType(block);
+ switch (type) {
+ case BlockType::kIntValue:
+ parent_node->add_property(
+ PropertyValue(std::move(name.value()), IntPropertyValue(block->payload.i64)));
+ return;
+ case BlockType::kUintValue:
+ parent_node->add_property(
+ PropertyValue(std::move(name.value()), UintPropertyValue(block->payload.u64)));
+ return;
+ case BlockType::kDoubleValue:
+ parent_node->add_property(
+ PropertyValue(std::move(name.value()), DoublePropertyValue(block->payload.f64)));
+ return;
+ case BlockType::kBoolValue:
+ parent_node->add_property(
+ PropertyValue(std::move(name.value()), BoolPropertyValue(block->payload.u64)));
+ return;
+ case BlockType::kArrayValue: {
+ auto entry_type = ArrayBlockPayload::EntryType::Get<BlockType>(block->payload.u64);
+ auto count = ArrayBlockPayload::Count::Get<uint8_t>(block->payload.u64);
+ if (GetArraySlot<const int64_t>(block, count - 1) == nullptr) {
+ // Block does not store the entire array.
+ return;
+ }
+
+ auto array_format = ArrayBlockFormatToDisplay(
+ ArrayBlockPayload::Flags::Get<ArrayBlockFormat>(block->payload.u64));
+
+ if (entry_type == BlockType::kIntValue) {
+ std::vector<int64_t> values;
+ std::copy(GetArraySlot<const int64_t>(block, 0), GetArraySlot<const int64_t>(block, count),
+ std::back_inserter(values));
+ parent_node->add_property(
+ PropertyValue(std::move(name.value()), IntArrayValue(std::move(values), array_format)));
+ } else if (entry_type == BlockType::kUintValue) {
+ std::vector<uint64_t> values;
+ std::copy(GetArraySlot<const uint64_t>(block, 0),
+ GetArraySlot<const uint64_t>(block, count), std::back_inserter(values));
+ parent_node->add_property(PropertyValue(std::move(name.value()),
+ UintArrayValue(std::move(values), array_format)));
+ } else if (entry_type == BlockType::kDoubleValue) {
+ std::vector<double> values;
+ std::copy(GetArraySlot<const double>(block, 0), GetArraySlot<const double>(block, count),
+ std::back_inserter(values));
+ parent_node->add_property(PropertyValue(std::move(name.value()),
+ DoubleArrayValue(std::move(values), array_format)));
+ }
+ return;
+ }
+ default:
+ return;
+ }
+}
+
+void Reader::InnerParseProperty(ParsedNode* parent, const Block* block) {
+ auto name = GetAndValidateName(ValueBlockFields::NameIndex::Get<size_t>(block->header));
+ if (!name.has_value()) {
+ return;
+ }
+
+ // Do not allow reading more bytes than exist in the buffer for any property. This safeguards
+ // against cycles and excessive memory usage.
+ size_t remaining_length = std::min(
+ snapshot_.size(), PropertyBlockPayload::TotalLength::Get<size_t>(block->payload.u64));
+ size_t current_offset = 0;
+ std::vector<uint8_t> buf;
+
+ BlockIndex cur_extent = PropertyBlockPayload::ExtentIndex::Get<BlockIndex>(block->payload.u64);
+ auto* extent = internal::GetBlock(&snapshot_, cur_extent);
+ while (remaining_length > 0) {
+ if (!extent || GetType(extent) != BlockType::kExtent) {
+ break;
+ }
+ size_t len = std::min(remaining_length, PayloadCapacity(GetOrder(extent)));
+ buf.insert(buf.end(), extent->payload_ptr(), extent->payload_ptr() + len);
+ remaining_length -= len;
+ current_offset += len;
+
+ BlockIndex next_extent = ExtentBlockFields::NextExtentIndex::Get<BlockIndex>(extent->header);
+
+ extent = internal::GetBlock(&snapshot_, next_extent);
+ }
+
+ auto* parent_node = parent->hierarchy.node_ptr();
+ if (PropertyBlockPayload::Flags::Get<uint8_t>(block->payload.u64) &
+ static_cast<uint8_t>(PropertyBlockFormat::kBinary)) {
+ parent_node->add_property(
+ inspect::PropertyValue(std::move(name.value()), inspect::ByteVectorPropertyValue(buf)));
+ } else {
+ parent_node->add_property(
+ inspect::PropertyValue(std::move(name.value()),
+ inspect::StringPropertyValue(std::string(buf.begin(), buf.end()))));
+ }
+}
+
+void Reader::InnerParseLink(ParsedNode* parent, const Block* block) {
+ auto name = GetAndValidateName(ValueBlockFields::NameIndex::Get<size_t>(block->header));
+ if (name->empty()) {
+ return;
+ }
+
+ auto content =
+ GetAndValidateName(LinkBlockPayload::ContentIndex::Get<size_t>(block->payload.u64));
+ if (content->empty()) {
+ return;
+ }
+
+ LinkDisposition disposition;
+ switch (LinkBlockPayload::Flags::Get<LinkBlockDisposition>(block->payload.u64)) {
+ case LinkBlockDisposition::kChild:
+ disposition = LinkDisposition::kChild;
+ break;
+ case LinkBlockDisposition::kInline:
+ disposition = LinkDisposition::kInline;
+ break;
+ }
+
+ parent->hierarchy.node_ptr()->add_link(
+ LinkValue(std::move(name.value()), std::move(content.value()), disposition));
+}
+
+void Reader::InnerCreateObject(BlockIndex index, const Block* block) {
+ auto name = GetAndValidateName(ValueBlockFields::NameIndex::Get<BlockIndex>(block->header));
+ if (!name.has_value()) {
+ return;
+ }
+ auto* parsed_node = GetOrCreate(index);
+ auto parent_index = ValueBlockFields::ParentIndex::Get<BlockIndex>(block->header);
+ parsed_node->InitializeNode(std::move(name.value()), parent_index);
+ if (parent_index != index) {
+ // Only link to a parent if the parent can be valid (not index 0).
+ auto* parent = GetOrCreate(parent_index);
+ parent->children_count += 1;
+ }
+}
+
+fit::result<Hierarchy> ReadFromSnapshotTree(const SnapshotTree& tree) {
+ auto read_result = internal::Reader(tree.snapshot).Read();
+ if (!read_result.is_ok()) {
+ return read_result;
+ }
+
+ auto ret = read_result.take_value();
+
+ VisitHierarchiesWithLink(&ret, [&](Hierarchy* cur) {
+ for (const auto& link : cur->node().links()) {
+ auto it = tree.children.find(link.content());
+ if (it == tree.children.end()) {
+ cur->add_missing_value(MissingValueReason::kLinkNotFound, link.name());
+ continue;
+ }
+
+ // TODO(crjohns): Remove recursion, or limit depth.
+ auto next_result = ReadFromSnapshotTree(it->second);
+ if (!next_result.is_ok()) {
+ cur->add_missing_value(MissingValueReason::kLinkHierarchyParseFailure, link.name());
+ continue;
+ }
+
+ if (link.disposition() == LinkDisposition::kChild) {
+ // The linked hierarchy is a child of this node, add it to the list of children.
+ next_result.value().node_ptr()->set_name(link.name());
+ cur->add_child(next_result.take_value());
+ } else if (link.disposition() == LinkDisposition::kInline) {
+ // The linked hierarchy is meant to have its contents inlined into this node.
+ auto next = next_result.take_value();
+
+ // Move properties into this node.
+ for (auto& prop : next.node_ptr()->take_properties()) {
+ cur->node_ptr()->add_property(std::move(prop));
+ }
+
+ // Move children into this node.
+ for (auto& child : next.take_children()) {
+ cur->add_child(std::move(child));
+ }
+
+ // Copy missing values.
+ for (const auto& missing : next.missing_values()) {
+ cur->add_missing_value(missing.reason, missing.name);
+ }
+
+ // There will be no further links that have not already been processed, since we recursively
+ // get the hierarchy from a SnapshotTree.
+ } else {
+ cur->add_missing_value(MissingValueReason::kLinkInvalid, link.name());
+ }
+ }
+ });
+
+ return fit::ok(std::move(ret));
+}
+
+} // namespace internal
+
+fit::result<Hierarchy> ReadFromSnapshot(Snapshot snapshot) {
+ internal::Reader reader(std::move(snapshot));
+ return reader.Read();
+}
+
+fit::result<Hierarchy> ReadFromVmo(const zx::vmo& vmo) {
+ inspect::Snapshot snapshot;
+ if (inspect::Snapshot::Create(std::move(vmo), &snapshot) != ZX_OK) {
+ return fit::error();
+ }
+ return ReadFromSnapshot(std::move(snapshot));
+}
+
+fit::result<Hierarchy> ReadFromBuffer(std::vector<uint8_t> buffer) {
+ inspect::Snapshot snapshot;
+ if (inspect::Snapshot::Create(std::move(buffer), &snapshot) != ZX_OK) {
+ // TODO(CF-865): Best-effort read of invalid snapshots.
+ return fit::error();
+ }
+ return ReadFromSnapshot(std::move(snapshot));
+}
+
+fit::promise<Hierarchy> ReadFromInspector(Inspector inspector) {
+ return SnapshotTreeFromInspector(std::move(inspector)).and_then(internal::ReadFromSnapshotTree);
+}
+
+} // namespace inspect
diff --git a/third_party/fuchsia-sdk/pkg/inspect/vmo/heap.cc b/third_party/fuchsia-sdk/pkg/inspect/vmo/heap.cc
new file mode 100644
index 0000000..29b18d6
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/inspect/vmo/heap.cc
@@ -0,0 +1,209 @@
+// Copyright 2018 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.
+
+#include <lib/inspect/cpp/vmo/heap.h>
+#include <zircon/process.h>
+
+namespace inspect {
+namespace internal {
+
+namespace {
+// Get the "buddy" for a given |Block|. Buddies may be merged together if they are both free.
+constexpr BlockIndex Buddy(BlockIndex block, BlockOrder block_order) {
+ // XOR index of the block by its size (in kMinOrderSize blocks) to get the index of its
+ // buddy.
+ return block ^ IndexForOffset(OrderToSize(block_order));
+}
+
+} // namespace
+
+Heap::Heap(zx::vmo vmo) : vmo_(std::move(vmo)) {
+ ZX_ASSERT(ZX_OK == vmo_.get_size(&max_size_));
+ ZX_ASSERT(max_size_ > 0);
+ ZX_ASSERT(ZX_OK == zx_vmar_map(zx_vmar_root_self(), ZX_VM_PERM_READ | ZX_VM_PERM_WRITE, 0,
+ vmo_.get(), 0, max_size_, &buffer_addr_));
+
+ Extend(kMinVmoSize);
+}
+
+Heap::~Heap() {
+ zx_vmar_unmap(zx_vmar_root_self(), buffer_addr_, max_size_);
+ ZX_DEBUG_ASSERT_MSG(num_allocated_blocks_ == 0, "There are still %lu outstanding blocks",
+ num_allocated_blocks_);
+}
+
+const zx::vmo& Heap::GetVmo() const { return vmo_; }
+
+zx_status_t Heap::Allocate(size_t min_size, BlockIndex* out_block) {
+ ZX_DEBUG_ASSERT_MSG(min_size >= sizeof(Block), "Block allocation size %lu is too small",
+ min_size);
+ const BlockOrder min_fit_order = FitOrder(min_size);
+ ZX_DEBUG_ASSERT_MSG(min_fit_order < kNumOrders, "Order %u is greater than maximum order %lu",
+ min_fit_order, kNumOrders - 1);
+ if (min_fit_order >= kNumOrders) {
+ return ZX_ERR_INVALID_ARGS;
+ }
+
+ // Iterate through the orders until we find a free block with order >=
+ // what is needed.
+ BlockOrder next_order = kNumOrders;
+ for (BlockOrder i = min_fit_order; i < kNumOrders; i++) {
+ if (IsFreeBlock(free_blocks_[i], i)) {
+ next_order = i;
+ break;
+ }
+ }
+
+ // If no free block is found, extend the VMO and use one of the newly
+ // created free blocks.
+ if (next_order == kNumOrders) {
+ zx_status_t status;
+ status = Extend(cur_size_ * 2);
+ if (status != ZX_OK) {
+ return status;
+ }
+ next_order = kNumOrders - 1;
+ ZX_ASSERT(IsFreeBlock(free_blocks_[kNumOrders - 1], kNumOrders - 1));
+ }
+
+ // Once a free block is found, split it repeatedly until it is the
+ // right size.
+ BlockIndex next_block_index = free_blocks_[next_order];
+ while (GetOrder(GetBlock(next_block_index)) > min_fit_order) {
+ if (!SplitBlock(next_block_index)) {
+ return ZX_ERR_INTERNAL;
+ }
+ }
+
+ // Remove the block from the free list, clear, and reserve it.
+ RemoveFree(next_block_index);
+ auto* next_block = GetBlock(next_block_index);
+
+ next_block->header = BlockFields::Order::Make(GetOrder(next_block)) |
+ BlockFields::Type::Make(BlockType::kReserved);
+
+ *out_block = next_block_index;
+ ++num_allocated_blocks_;
+ return ZX_OK;
+}
+
+void Heap::Free(BlockIndex block_index) {
+ auto* block = GetBlock(block_index);
+ BlockIndex buddy_index = Buddy(block_index, GetOrder(block));
+ auto* buddy = GetBlock(buddy_index);
+
+ // Repeatedly merge buddies of the freed block until the buddy is
+ // not free or we hit the maximum block size.
+ while (GetType(buddy) == BlockType::kFree && GetOrder(block) < kNumOrders - 1 &&
+ GetOrder(block) == GetOrder(buddy)) {
+ RemoveFree(buddy_index);
+ if (buddy < block) {
+ // We must always merge into the lower index block.
+ // If the buddy of the block is a lower index, we need to swap
+ // index and pointers.
+ std::swap(block, buddy);
+ std::swap(block_index, buddy_index);
+ }
+ BlockFields::Order::Set(&block->header, GetOrder(block) + 1);
+ buddy_index = Buddy(block_index, GetOrder(block));
+ buddy = GetBlock(buddy_index);
+ }
+
+ // Complete freeing the block by linking it onto the free list.
+ block->header = BlockFields::Order::Make(GetOrder(block)) |
+ BlockFields::Type::Make(BlockType::kFree) |
+ FreeBlockFields::NextFreeBlock::Make(free_blocks_[GetOrder(block)]);
+ free_blocks_[GetOrder(block)] = block_index;
+ --num_allocated_blocks_;
+}
+
+bool Heap::SplitBlock(BlockIndex block) {
+ RemoveFree(block);
+ auto* cur = GetBlock(block);
+ BlockOrder order = GetOrder(cur);
+ ZX_DEBUG_ASSERT_MSG(order < kNumOrders, "Order on block is invalid");
+ if (order >= kNumOrders) {
+ return false;
+ }
+
+ // Lower the order of the original block, then find its new buddy.
+ // Both the original block and the new buddy need to be added
+ // onto the free list of the new order.
+ BlockIndex buddy_index = Buddy(block, order - 1);
+ auto* buddy = GetBlock(buddy_index);
+ cur->header = BlockFields::Order::Make(order - 1) | BlockFields::Type::Make(BlockType::kFree) |
+ FreeBlockFields::NextFreeBlock::Make(buddy_index);
+
+ buddy->header = BlockFields::Order::Make(order - 1) | BlockFields::Type::Make(BlockType::kFree) |
+ FreeBlockFields::NextFreeBlock::Make(free_blocks_[order - 1]);
+
+ free_blocks_[order - 1] = block;
+
+ return true;
+}
+
+bool Heap::RemoveFree(BlockIndex block) {
+ auto* to_remove = GetBlock(block);
+ BlockOrder order = GetOrder(to_remove);
+ ZX_DEBUG_ASSERT_MSG(order < kNumOrders, "Order %u on block %lu is invalid", order, block);
+ if (order >= kNumOrders) {
+ return false;
+ }
+
+ // If the block we are removing is at the head of the list,
+ // immediately unlink it and return.
+ BlockIndex next = free_blocks_[order];
+ if (next == block) {
+ free_blocks_[order] = FreeBlockFields::NextFreeBlock::Get<size_t>(to_remove->header);
+ return true;
+ }
+
+ // Look through the free list until we find the position for the block,
+ // then unlink it.
+ while (IsFreeBlock(next, order)) {
+ auto* cur = GetBlock(next);
+ next = FreeBlockFields::NextFreeBlock::Get<size_t>(cur->header);
+ if (next == block) {
+ FreeBlockFields::NextFreeBlock::Set(
+ &cur->header, FreeBlockFields::NextFreeBlock::Get<size_t>(to_remove->header));
+ return true;
+ }
+ }
+
+ return false;
+}
+
+zx_status_t Heap::Extend(size_t new_size) {
+ if (cur_size_ == max_size_ && new_size > max_size_) {
+ return ZX_ERR_NO_MEMORY;
+ }
+ new_size = std::min(max_size_, new_size);
+
+ if (cur_size_ >= new_size) {
+ return ZX_OK;
+ }
+
+ size_t min_index = IndexForOffset(cur_size_);
+ size_t last_index = free_blocks_[kNumOrders - 1];
+ // Ensure we start on an index at a page boundary.
+ // Convert each new max order block to a free block in descending
+ // order on the free list.
+ size_t cur_index = IndexForOffset(new_size - new_size % kMinVmoSize);
+ do {
+ cur_index -= IndexForOffset(kMaxOrderSize);
+ auto* block = GetBlock(cur_index);
+ block->header = BlockFields::Order::Make(kNumOrders - 1) |
+ BlockFields::Type::Make(BlockType::kFree) |
+ FreeBlockFields::NextFreeBlock::Make(last_index);
+ last_index = cur_index;
+ } while (cur_index > min_index);
+
+ free_blocks_[kNumOrders - 1] = last_index;
+
+ cur_size_ = new_size;
+ return ZX_OK;
+}
+
+} // namespace internal
+} // namespace inspect
diff --git a/third_party/fuchsia-sdk/pkg/inspect/vmo/scanner.cc b/third_party/fuchsia-sdk/pkg/inspect/vmo/scanner.cc
new file mode 100644
index 0000000..bdb480c
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/inspect/vmo/scanner.cc
@@ -0,0 +1,40 @@
+// 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.
+
+#include <lib/inspect/cpp/vmo/limits.h>
+#include <lib/inspect/cpp/vmo/scanner.h>
+
+namespace inspect {
+namespace internal {
+
+zx_status_t ScanBlocks(const uint8_t* buffer, size_t size,
+ fit::function<bool(BlockIndex, const Block*)> callback) {
+ size_t offset = 0;
+ while (offset < size) {
+ auto* block = reinterpret_cast<const Block*>(buffer + offset);
+ if (size - offset < sizeof(Block)) {
+ // Block header does not fit in remaining space.
+ return ZX_ERR_OUT_OF_RANGE;
+ }
+ BlockOrder order = GetOrder(block);
+ if (order > kMaxOrderShift) {
+ return ZX_ERR_OUT_OF_RANGE;
+ }
+ if (size - offset < OrderToSize(order)) {
+ // Block header specifies an order that is too large to fit
+ // in the remainder of the buffer.
+ return ZX_ERR_OUT_OF_RANGE;
+ }
+
+ if (!callback(IndexForOffset(offset), block)) {
+ return ZX_OK;
+ }
+ offset += OrderToSize(order);
+ }
+
+ return ZX_OK;
+}
+
+} // namespace internal
+} // namespace inspect
diff --git a/third_party/fuchsia-sdk/pkg/inspect/vmo/snapshot.cc b/third_party/fuchsia-sdk/pkg/inspect/vmo/snapshot.cc
new file mode 100644
index 0000000..cef0e7b
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/inspect/vmo/snapshot.cc
@@ -0,0 +1,164 @@
+// 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.
+
+#include <lib/inspect/cpp/vmo/block.h>
+#include <lib/inspect/cpp/vmo/snapshot.h>
+#include <zircon/assert.h>
+
+using inspect::internal::Block;
+using inspect::internal::BlockIndex;
+using inspect::internal::IndexForOffset;
+using inspect::internal::kMinOrderSize;
+
+namespace inspect {
+
+Snapshot::Snapshot(std::vector<uint8_t> buffer)
+ : buffer_(std::make_shared<std::vector<uint8_t>>(std::move(buffer))) {}
+
+zx_status_t Snapshot::Create(std::vector<uint8_t> buffer, Snapshot* out_snapshot) {
+ ZX_ASSERT(out_snapshot);
+
+ if (buffer.size() < kMinOrderSize) {
+ return ZX_ERR_INVALID_ARGS;
+ }
+
+ // A buffer does not have concurrent writers or observers, so we don't use
+ // this.
+ uint64_t unused;
+ // Verify that the buffer can, in fact, be parsed as a snapshot.
+ zx_status_t status = Snapshot::ParseHeader(buffer.data(), &unused);
+ if (status != ZX_OK) {
+ return status;
+ }
+ *out_snapshot = Snapshot(std::move(buffer));
+ if (!*out_snapshot) {
+ return ZX_ERR_INTERNAL;
+ }
+ return ZX_OK;
+}
+
+zx_status_t Snapshot::Create(const zx::vmo& vmo, Snapshot* out_snapshot) {
+ return Snapshot::Create(std::move(vmo), kDefaultOptions, out_snapshot);
+}
+
+zx_status_t Snapshot::Create(const zx::vmo& vmo, Options options, Snapshot* out_snapshot) {
+ return Snapshot::Create(std::move(vmo), std::move(options), nullptr, out_snapshot);
+}
+
+zx_status_t Snapshot::Create(const zx::vmo& vmo, Options options, ReadObserver read_observer,
+ Snapshot* out_snapshot) {
+ size_t tries_left = options.read_attempts;
+
+ zx_status_t status;
+ std::vector<uint8_t> buffer;
+
+ while (tries_left-- > 0) {
+ size_t size;
+ status = vmo.get_size(&size);
+ if (status != ZX_OK) {
+ return status;
+ }
+ if (size < sizeof(Block)) {
+ return ZX_ERR_OUT_OF_RANGE;
+ }
+ if (buffer.size() != size) {
+ buffer.resize(size);
+ }
+
+ status = Snapshot::Read(vmo, sizeof(Block), buffer.data());
+ if (status != ZX_OK) {
+ return status;
+ }
+ if (read_observer) {
+ read_observer(buffer.data(), sizeof(Block));
+ }
+
+ uint64_t generation;
+ status = Snapshot::ParseHeader(buffer.data(), &generation);
+ if (status != ZX_OK) {
+ return status;
+ }
+
+ if (!options.skip_consistency_check && generation % 2 != 0) {
+ continue;
+ }
+
+ status = Snapshot::Read(vmo, size, buffer.data());
+ if (status != ZX_OK) {
+ return status;
+ }
+ if (read_observer) {
+ read_observer(buffer.data(), size);
+ }
+
+ // Read the header out of the buffer again,
+ std::vector<uint8_t> new_header;
+ new_header.resize(sizeof(Block));
+ status = Snapshot::Read(vmo, new_header.size(), new_header.data());
+ if (status != ZX_OK) {
+ return status;
+ }
+ if (read_observer) {
+ read_observer(new_header.data(), new_header.size());
+ }
+
+ uint64_t new_generation;
+ status = Snapshot::ParseHeader(new_header.data(), &new_generation);
+ if (status != ZX_OK) {
+ return status;
+ }
+ if (!options.skip_consistency_check && generation != new_generation) {
+ continue;
+ }
+
+ size_t new_size;
+ if (vmo.get_size(&new_size) != ZX_OK) {
+ return ZX_ERR_INTERNAL;
+ }
+ if (new_size != size) {
+ continue;
+ }
+
+ *out_snapshot = Snapshot(std::move(buffer));
+
+ return ZX_OK;
+ }
+
+ return ZX_ERR_INTERNAL;
+}
+
+zx_status_t Snapshot::Read(const zx::vmo& vmo, size_t size, uint8_t* buffer) {
+ memset(buffer, 0, size);
+ return vmo.read(buffer, 0, size);
+}
+
+zx_status_t Snapshot::ParseHeader(uint8_t* buffer, uint64_t* out_generation_count) {
+ auto* block = reinterpret_cast<Block*>(buffer);
+ if (memcmp(&block->header_data[4], internal::kMagicNumber, 4) != 0) {
+ return ZX_ERR_INTERNAL;
+ }
+ *out_generation_count = block->payload.u64;
+ return ZX_OK;
+}
+
+namespace internal {
+const Block* GetBlock(const Snapshot* snapshot, BlockIndex index) {
+ // Check that the block's index fits in the snapshot.
+ // This means that the whole first 16 bytes of the block are valid to read.
+ if (index >= IndexForOffset(snapshot->size())) {
+ return nullptr;
+ }
+ const auto* ret = reinterpret_cast<const Block*>(snapshot->data() + index * kMinOrderSize);
+
+ // Check that the entire declared size of the block fits in the snapshot.
+ auto size = OrderToSize(GetOrder(ret));
+ if (index * kMinOrderSize + size > snapshot->size()) {
+ return nullptr;
+ }
+
+ return ret;
+}
+} // namespace internal
+
+} // namespace inspect
diff --git a/third_party/fuchsia-sdk/pkg/inspect/vmo/state.cc b/third_party/fuchsia-sdk/pkg/inspect/vmo/state.cc
new file mode 100644
index 0000000..25546db
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/inspect/vmo/state.cc
@@ -0,0 +1,987 @@
+// Copyright 2018 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.
+
+#include <lib/fit/bridge.h>
+#include <lib/fit/sequencer.h>
+#include <lib/inspect/cpp/inspect.h>
+#include <lib/inspect/cpp/vmo/block.h>
+#include <lib/inspect/cpp/vmo/state.h>
+
+#include <functional>
+#include <sstream>
+
+namespace inspect {
+namespace internal {
+
+namespace {
+// Helper class to support RAII locking of the generation count.
+class AutoGenerationIncrement final {
+ public:
+ AutoGenerationIncrement(BlockIndex target, Heap* heap);
+ ~AutoGenerationIncrement();
+
+ // Disallow copy assign and move.
+ AutoGenerationIncrement(AutoGenerationIncrement&&) = delete;
+ AutoGenerationIncrement(const AutoGenerationIncrement&) = delete;
+ AutoGenerationIncrement& operator=(AutoGenerationIncrement&&) = delete;
+ AutoGenerationIncrement& operator=(const AutoGenerationIncrement&) = delete;
+
+ private:
+ // Acquire the generation count lock.
+ // This consists of atomically incrementing the count using
+ // acquire-release ordering, ensuring readers see this increment before
+ // any changes to the buffer.
+ void Acquire(Block* block);
+
+ // Release the generation count lock.
+ // This consists of atomically incrementing the count using release
+ // ordering, ensuring readers see this increment after all changes to
+ // the buffer are committed.
+ void Release(Block* block);
+
+ BlockIndex target_;
+ Heap* heap_;
+};
+
+AutoGenerationIncrement ::AutoGenerationIncrement(BlockIndex target, Heap* heap)
+ : target_(target), heap_(heap) {
+ Acquire(heap_->GetBlock(target_));
+}
+AutoGenerationIncrement::~AutoGenerationIncrement() { Release(heap_->GetBlock(target_)); }
+
+void AutoGenerationIncrement ::Acquire(Block* block) {
+ uint64_t* ptr = &block->payload.u64;
+ __atomic_fetch_add(ptr, 1, std::memory_order_acq_rel);
+}
+
+void AutoGenerationIncrement::Release(Block* block) {
+ uint64_t* ptr = &block->payload.u64;
+ __atomic_fetch_add(ptr, 1, std::memory_order_release);
+}
+
+} // namespace
+
+template <typename NumericType, typename WrapperType, BlockType BlockTypeValue>
+WrapperType State::InnerCreateArray(const std::string& name, BlockIndex parent, size_t slots,
+ ArrayBlockFormat format) {
+ size_t block_size_needed = slots * sizeof(NumericType) + kMinOrderSize;
+ ZX_DEBUG_ASSERT_MSG(block_size_needed <= kMaxOrderSize,
+ "The requested array size cannot fit in a block");
+ if (block_size_needed > kMaxOrderSize) {
+ return WrapperType();
+ }
+
+ std::lock_guard<std::mutex> lock(mutex_);
+ AutoGenerationIncrement gen(header_, heap_.get());
+
+ BlockIndex name_index, value_index;
+ zx_status_t status;
+ status = InnerCreateValue(name, BlockType::kArrayValue, parent, &name_index, &value_index,
+ block_size_needed);
+ if (status != ZX_OK) {
+ return WrapperType();
+ }
+
+ auto* block = heap_->GetBlock(value_index);
+ block->payload.u64 = ArrayBlockPayload::EntryType::Make(BlockTypeValue) |
+ ArrayBlockPayload::Flags::Make(format) |
+ ArrayBlockPayload::Count::Make(slots);
+
+ return WrapperType(weak_self_ptr_.lock(), name_index, value_index);
+}
+
+template <typename NumericType, typename WrapperType, BlockType BlockTypeValue>
+void State::InnerSetArray(WrapperType* metric, size_t index, NumericType value) {
+ ZX_ASSERT(metric->state_.get() == this);
+ std::lock_guard<std::mutex> lock(mutex_);
+ AutoGenerationIncrement gen(header_, heap_.get());
+
+ auto* block = heap_->GetBlock(metric->value_index_);
+ ZX_ASSERT(GetType(block) == BlockType::kArrayValue);
+ auto entry_type = ArrayBlockPayload::EntryType::Get<BlockType>(block->payload.u64);
+ ZX_ASSERT(entry_type == BlockTypeValue);
+ auto* slot = GetArraySlot<NumericType>(block, index);
+ if (slot != nullptr) {
+ *slot = value;
+ }
+}
+
+template <typename NumericType, typename WrapperType, BlockType BlockTypeValue, typename Operation>
+void State::InnerOperationArray(WrapperType* metric, size_t index, NumericType value) {
+ ZX_ASSERT(metric->state_.get() == this);
+ std::lock_guard<std::mutex> lock(mutex_);
+ AutoGenerationIncrement gen(header_, heap_.get());
+
+ auto* block = heap_->GetBlock(metric->value_index_);
+ ZX_ASSERT(GetType(block) == BlockType::kArrayValue);
+ auto entry_type = ArrayBlockPayload::EntryType::Get<BlockType>(block->payload.u64);
+ ZX_ASSERT(entry_type == BlockTypeValue);
+ auto* slot = GetArraySlot<NumericType>(block, index);
+ if (slot != nullptr) {
+ *slot = Operation()(*slot, value);
+ }
+}
+
+template <typename WrapperType>
+void State::InnerFreeArray(WrapperType* value) {
+ ZX_DEBUG_ASSERT_MSG(value->state_.get() == this, "Array being freed from the wrong state");
+ if (value->state_.get() != this) {
+ return;
+ }
+
+ std::lock_guard<std::mutex> lock(mutex_);
+ AutoGenerationIncrement gen(header_, heap_.get());
+
+ DecrementParentRefcount(value->value_index_);
+
+ heap_->Free(value->name_index_);
+ heap_->Free(value->value_index_);
+ value->state_ = nullptr;
+}
+
+std::shared_ptr<State> State::Create(std::unique_ptr<Heap> heap) {
+ BlockIndex header;
+ if (heap->Allocate(sizeof(Block), &header) != ZX_OK) {
+ return nullptr;
+ }
+
+ ZX_DEBUG_ASSERT_MSG(header == 0, "Header must be at index 0");
+ if (header != 0) {
+ return nullptr;
+ }
+
+ auto* block = heap->GetBlock(header);
+ block->header = HeaderBlockFields::Order::Make(GetOrder(block)) |
+ HeaderBlockFields::Type::Make(BlockType::kHeader) |
+ HeaderBlockFields::Version::Make(kVersion);
+ memcpy(&block->header_data[4], kMagicNumber, 4);
+ block->payload.u64 = 0;
+
+ std::shared_ptr<State> ret(new State(std::move(heap), header));
+ ret->weak_self_ptr_ = ret;
+ return ret;
+}
+
+std::shared_ptr<State> State::CreateWithSize(size_t size) {
+ zx::vmo vmo;
+ if (size == 0 || ZX_OK != zx::vmo::create(size, 0, &vmo)) {
+ return nullptr;
+ }
+ return State::Create(std::make_unique<Heap>(std::move(vmo)));
+}
+
+State::~State() { heap_->Free(header_); }
+
+const zx::vmo& State::GetVmo() const {
+ std::lock_guard<std::mutex> lock(mutex_);
+ return heap_->GetVmo();
+}
+
+bool State::DuplicateVmo(zx::vmo* vmo) const {
+ std::lock_guard<std::mutex> lock(mutex_);
+ return ZX_OK == heap_->GetVmo().duplicate(ZX_RIGHTS_BASIC | ZX_RIGHT_READ | ZX_RIGHT_MAP, vmo);
+}
+
+bool State::Copy(zx::vmo* vmo) const {
+ std::lock_guard<std::mutex> lock(mutex_);
+
+ size_t size = heap_->size();
+ if (zx::vmo::create(size, 0, vmo) != ZX_OK) {
+ return false;
+ }
+
+ if (vmo->write(heap_->data(), 0, size) != ZX_OK) {
+ return false;
+ }
+
+ return true;
+}
+
+bool State::CopyBytes(std::vector<uint8_t>* out) const {
+ std::lock_guard<std::mutex> lock(mutex_);
+
+ size_t size = heap_->size();
+ if (size == 0) {
+ return false;
+ }
+
+ out->resize(size);
+ memcpy(out->data(), heap_->data(), size);
+
+ return true;
+}
+
+IntProperty State::CreateIntProperty(const std::string& name, BlockIndex parent, int64_t value) {
+ std::lock_guard<std::mutex> lock(mutex_);
+ AutoGenerationIncrement gen(header_, heap_.get());
+
+ BlockIndex name_index, value_index;
+ zx_status_t status;
+ status = InnerCreateValue(name, BlockType::kIntValue, parent, &name_index, &value_index);
+ if (status != ZX_OK) {
+ return IntProperty();
+ }
+
+ auto* block = heap_->GetBlock(value_index);
+ block->payload.i64 = value;
+
+ return IntProperty(weak_self_ptr_.lock(), name_index, value_index);
+}
+
+UintProperty State::CreateUintProperty(const std::string& name, BlockIndex parent, uint64_t value) {
+ std::lock_guard<std::mutex> lock(mutex_);
+ AutoGenerationIncrement gen(header_, heap_.get());
+
+ BlockIndex name_index, value_index;
+ zx_status_t status;
+ status = InnerCreateValue(name, BlockType::kUintValue, parent, &name_index, &value_index);
+ if (status != ZX_OK) {
+ return UintProperty();
+ }
+
+ auto* block = heap_->GetBlock(value_index);
+ block->payload.u64 = value;
+
+ return UintProperty(weak_self_ptr_.lock(), name_index, value_index);
+}
+
+DoubleProperty State::CreateDoubleProperty(const std::string& name, BlockIndex parent,
+ double value) {
+ std::lock_guard<std::mutex> lock(mutex_);
+ AutoGenerationIncrement gen(header_, heap_.get());
+
+ BlockIndex name_index, value_index;
+ zx_status_t status;
+ status = InnerCreateValue(name, BlockType::kDoubleValue, parent, &name_index, &value_index);
+ if (status != ZX_OK) {
+ return DoubleProperty();
+ }
+
+ auto* block = heap_->GetBlock(value_index);
+ block->payload.f64 = value;
+
+ return DoubleProperty(weak_self_ptr_.lock(), name_index, value_index);
+}
+
+BoolProperty State::CreateBoolProperty(const std::string& name, BlockIndex parent, bool value) {
+ std::lock_guard<std::mutex> lock(mutex_);
+ AutoGenerationIncrement gen(header_, heap_.get());
+
+ BlockIndex name_index, value_index;
+ zx_status_t status;
+ status = InnerCreateValue(name, BlockType::kBoolValue, parent, &name_index, &value_index);
+ if (status != ZX_OK) {
+ return BoolProperty();
+ }
+
+ auto* block = heap_->GetBlock(value_index);
+ block->payload.u64 = value;
+ return BoolProperty(weak_self_ptr_.lock(), name_index, value_index);
+}
+
+IntArray State::CreateIntArray(const std::string& name, BlockIndex parent, size_t slots,
+ ArrayBlockFormat format) {
+ return InnerCreateArray<int64_t, IntArray, BlockType::kIntValue>(name, parent, slots, format);
+}
+
+UintArray State::CreateUintArray(const std::string& name, BlockIndex parent, size_t slots,
+ ArrayBlockFormat format) {
+ return InnerCreateArray<uint64_t, UintArray, BlockType::kUintValue>(name, parent, slots, format);
+}
+
+DoubleArray State::CreateDoubleArray(const std::string& name, BlockIndex parent, size_t slots,
+ ArrayBlockFormat format) {
+ return InnerCreateArray<double, DoubleArray, BlockType::kDoubleValue>(name, parent, slots,
+ format);
+}
+
+template <typename WrapperType, typename ValueType>
+WrapperType State::InnerCreateProperty(const std::string& name, BlockIndex parent,
+ const char* value, size_t length,
+ PropertyBlockFormat format) {
+ std::lock_guard<std::mutex> lock(mutex_);
+ AutoGenerationIncrement gen(header_, heap_.get());
+
+ BlockIndex name_index, value_index;
+ zx_status_t status;
+ status = InnerCreateValue(name, BlockType::kBufferValue, parent, &name_index, &value_index);
+ if (status != ZX_OK) {
+ return WrapperType();
+ }
+ auto* block = heap_->GetBlock(value_index);
+ block->payload.u64 = PropertyBlockPayload::Flags::Make(format);
+ status = InnerSetStringExtents(value_index, value, length);
+ if (status != ZX_OK) {
+ heap_->Free(name_index);
+ heap_->Free(value_index);
+ return WrapperType();
+ }
+
+ return WrapperType(weak_self_ptr_.lock(), name_index, value_index);
+}
+
+StringProperty State::CreateStringProperty(const std::string& name, BlockIndex parent,
+ const std::string& value) {
+ return InnerCreateProperty<StringProperty, std::string>(
+ name, parent, value.data(), value.length(), PropertyBlockFormat::kUtf8);
+}
+
+ByteVectorProperty State::CreateByteVectorProperty(const std::string& name, BlockIndex parent,
+ const std::vector<uint8_t>& value) {
+ return InnerCreateProperty<ByteVectorProperty, std::vector<uint8_t>>(
+ name, parent, reinterpret_cast<const char*>(value.data()), value.size(),
+ PropertyBlockFormat::kBinary);
+}
+
+Link State::CreateLink(const std::string& name, BlockIndex parent, const std::string& content,
+ LinkBlockDisposition disposition) {
+ std::lock_guard<std::mutex> lock(mutex_);
+ AutoGenerationIncrement gen(header_, heap_.get());
+
+ BlockIndex name_index, value_index, content_index;
+ zx_status_t status;
+ status = InnerCreateValue(name, BlockType::kLinkValue, parent, &name_index, &value_index);
+ if (status != ZX_OK) {
+ return Link();
+ }
+
+ status = CreateName(content, &content_index);
+ if (status != ZX_OK) {
+ DecrementParentRefcount(value_index);
+ heap_->Free(name_index);
+ heap_->Free(value_index);
+ return Link();
+ }
+
+ auto* block = heap_->GetBlock(value_index);
+
+ block->payload.u64 = LinkBlockPayload::ContentIndex::Make(content_index) |
+ LinkBlockPayload::Flags::Make(disposition);
+
+ return Link(weak_self_ptr_.lock(), name_index, value_index, content_index);
+}
+
+Node State::CreateRootNode() {
+ std::lock_guard<std::mutex> lock(mutex_);
+ return Node(weak_self_ptr_.lock(), 0, 0);
+}
+
+LazyNode State::InnerCreateLazyLink(const std::string& name, BlockIndex parent,
+ LazyNodeCallbackFn callback, LinkBlockDisposition disposition) {
+ auto content = UniqueLinkName(name);
+ auto link = CreateLink(name, parent, content, disposition);
+
+ {
+ std::lock_guard<std::mutex> lock(mutex_);
+
+ link_callbacks_.emplace(content, LazyNodeCallbackHolder(std::move(callback)));
+
+ return LazyNode(weak_self_ptr_.lock(), std::move(content), std::move(link));
+ }
+}
+
+LazyNode State::CreateLazyNode(const std::string& name, BlockIndex parent,
+ LazyNodeCallbackFn callback) {
+ return InnerCreateLazyLink(name, parent, std::move(callback), LinkBlockDisposition::kChild);
+}
+
+LazyNode State::CreateLazyValues(const std::string& name, BlockIndex parent,
+ LazyNodeCallbackFn callback) {
+ return InnerCreateLazyLink(name, parent, std::move(callback), LinkBlockDisposition::kInline);
+}
+
+Node State::CreateNode(const std::string& name, BlockIndex parent) {
+ std::lock_guard<std::mutex> lock(mutex_);
+ AutoGenerationIncrement gen(header_, heap_.get());
+
+ BlockIndex name_index, value_index;
+ zx_status_t status;
+ status = InnerCreateValue(name, BlockType::kNodeValue, parent, &name_index, &value_index);
+ if (status != ZX_OK) {
+ return Node();
+ }
+
+ return Node(weak_self_ptr_.lock(), name_index, value_index);
+}
+
+void State::SetIntProperty(IntProperty* metric, int64_t value) {
+ ZX_ASSERT(metric->state_.get() == this);
+ std::lock_guard<std::mutex> lock(mutex_);
+ AutoGenerationIncrement gen(header_, heap_.get());
+
+ auto* block = heap_->GetBlock(metric->value_index_);
+ ZX_DEBUG_ASSERT_MSG(GetType(block) == BlockType::kIntValue, "Expected int metric, got %d",
+ static_cast<int>(GetType(block)));
+ block->payload.i64 = value;
+}
+
+void State::SetUintProperty(UintProperty* metric, uint64_t value) {
+ ZX_ASSERT(metric->state_.get() == this);
+
+ std::lock_guard<std::mutex> lock(mutex_);
+ AutoGenerationIncrement gen(header_, heap_.get());
+
+ auto* block = heap_->GetBlock(metric->value_index_);
+ ZX_DEBUG_ASSERT_MSG(GetType(block) == BlockType::kUintValue, "Expected uint metric, got %d",
+ static_cast<int>(GetType(block)));
+ block->payload.u64 = value;
+}
+
+void State::SetDoubleProperty(DoubleProperty* metric, double value) {
+ ZX_ASSERT(metric->state_.get() == this);
+
+ std::lock_guard<std::mutex> lock(mutex_);
+ AutoGenerationIncrement gen(header_, heap_.get());
+
+ auto* block = heap_->GetBlock(metric->value_index_);
+ ZX_DEBUG_ASSERT_MSG(GetType(block) == BlockType::kDoubleValue, "Expected double metric, got %d",
+ static_cast<int>(GetType(block)));
+ block->payload.f64 = value;
+}
+
+void State::SetBoolProperty(BoolProperty* metric, bool value) {
+ ZX_ASSERT(metric->state_.get() == this);
+ std::lock_guard<std::mutex> lock(mutex_);
+ AutoGenerationIncrement gen(header_, heap_.get());
+
+ auto* block = heap_->GetBlock(metric->value_index_);
+ ZX_DEBUG_ASSERT_MSG(GetType(block) == BlockType::kBoolValue, "Expected bool metric, got %d",
+ static_cast<int>(GetType(block)));
+ block->payload.u64 = value;
+}
+
+void State::SetIntArray(IntArray* array, size_t index, int64_t value) {
+ InnerSetArray<int64_t, IntArray, BlockType::kIntValue>(array, index, value);
+}
+
+void State::SetUintArray(UintArray* array, size_t index, uint64_t value) {
+ InnerSetArray<uint64_t, UintArray, BlockType::kUintValue>(array, index, value);
+}
+
+void State::SetDoubleArray(DoubleArray* array, size_t index, double value) {
+ InnerSetArray<double, DoubleArray, BlockType::kDoubleValue>(array, index, value);
+}
+
+void State::AddIntProperty(IntProperty* metric, int64_t value) {
+ ZX_ASSERT(metric->state_.get() == this);
+
+ std::lock_guard<std::mutex> lock(mutex_);
+ AutoGenerationIncrement gen(header_, heap_.get());
+
+ auto* block = heap_->GetBlock(metric->value_index_);
+ ZX_DEBUG_ASSERT_MSG(GetType(block) == BlockType::kIntValue, "Expected int metric, got %d",
+ static_cast<int>(GetType(block)));
+ block->payload.i64 += value;
+}
+
+void State::AddUintProperty(UintProperty* metric, uint64_t value) {
+ ZX_ASSERT(metric->state_.get() == this);
+
+ std::lock_guard<std::mutex> lock(mutex_);
+ AutoGenerationIncrement gen(header_, heap_.get());
+
+ auto* block = heap_->GetBlock(metric->value_index_);
+ ZX_DEBUG_ASSERT_MSG(GetType(block) == BlockType::kUintValue, "Expected uint metric, got %d",
+ static_cast<int>(GetType(block)));
+ block->payload.u64 += value;
+}
+
+void State::AddDoubleProperty(DoubleProperty* metric, double value) {
+ ZX_ASSERT(metric->state_.get() == this);
+
+ std::lock_guard<std::mutex> lock(mutex_);
+ AutoGenerationIncrement gen(header_, heap_.get());
+
+ auto* block = heap_->GetBlock(metric->value_index_);
+ ZX_DEBUG_ASSERT_MSG(GetType(block) == BlockType::kDoubleValue, "Expected double metric, got %d",
+ static_cast<int>(GetType(block)));
+ block->payload.f64 += value;
+}
+
+void State::SubtractIntProperty(IntProperty* metric, int64_t value) {
+ ZX_ASSERT(metric->state_.get() == this);
+
+ std::lock_guard<std::mutex> lock(mutex_);
+ AutoGenerationIncrement gen(header_, heap_.get());
+
+ auto* block = heap_->GetBlock(metric->value_index_);
+ ZX_DEBUG_ASSERT_MSG(GetType(block) == BlockType::kIntValue, "Expected int metric, got %d",
+ static_cast<int>(GetType(block)));
+ block->payload.i64 -= value;
+}
+
+void State::SubtractUintProperty(UintProperty* metric, uint64_t value) {
+ ZX_ASSERT(metric->state_.get() == this);
+
+ std::lock_guard<std::mutex> lock(mutex_);
+ AutoGenerationIncrement gen(header_, heap_.get());
+
+ auto* block = heap_->GetBlock(metric->value_index_);
+ ZX_DEBUG_ASSERT_MSG(GetType(block) == BlockType::kUintValue, "Expected uint metric, got %d",
+ static_cast<int>(GetType(block)));
+ block->payload.u64 -= value;
+}
+
+void State::SubtractDoubleProperty(DoubleProperty* metric, double value) {
+ ZX_ASSERT(metric->state_.get() == this);
+
+ std::lock_guard<std::mutex> lock(mutex_);
+ AutoGenerationIncrement gen(header_, heap_.get());
+
+ auto* block = heap_->GetBlock(metric->value_index_);
+ ZX_DEBUG_ASSERT_MSG(GetType(block) == BlockType::kDoubleValue, "Expected double metric, got %d",
+ static_cast<int>(GetType(block)));
+ block->payload.f64 -= value;
+}
+
+void State::AddIntArray(IntArray* array, size_t index, int64_t value) {
+ InnerOperationArray<int64_t, IntArray, BlockType::kIntValue, std::plus<int64_t>>(array, index,
+ value);
+}
+
+void State::SubtractIntArray(IntArray* array, size_t index, int64_t value) {
+ InnerOperationArray<int64_t, IntArray, BlockType::kIntValue, std::minus<int64_t>>(array, index,
+ value);
+}
+
+void State::AddUintArray(UintArray* array, size_t index, uint64_t value) {
+ InnerOperationArray<uint64_t, UintArray, BlockType::kUintValue, std::plus<uint64_t>>(array, index,
+ value);
+}
+
+void State::SubtractUintArray(UintArray* array, size_t index, uint64_t value) {
+ InnerOperationArray<uint64_t, UintArray, BlockType::kUintValue, std::minus<uint64_t>>(
+ array, index, value);
+}
+
+void State::AddDoubleArray(DoubleArray* array, size_t index, double value) {
+ InnerOperationArray<double, DoubleArray, BlockType::kDoubleValue, std::plus<double>>(array, index,
+ value);
+}
+
+void State::SubtractDoubleArray(DoubleArray* array, size_t index, double value) {
+ InnerOperationArray<double, DoubleArray, BlockType::kDoubleValue, std::minus<double>>(
+ array, index, value);
+}
+
+template <typename WrapperType>
+void State::InnerSetProperty(WrapperType* property, const char* value, size_t length) {
+ ZX_ASSERT(property->state_.get() == this);
+
+ std::lock_guard<std::mutex> lock(mutex_);
+ AutoGenerationIncrement gen(header_, heap_.get());
+
+ InnerSetStringExtents(property->value_index_, value, length);
+}
+
+void State::SetStringProperty(StringProperty* property, const std::string& value) {
+ InnerSetProperty(property, value.data(), value.size());
+}
+
+void State::SetByteVectorProperty(ByteVectorProperty* property, const std::vector<uint8_t>& value) {
+ InnerSetProperty(property, reinterpret_cast<const char*>(value.data()), value.size());
+}
+
+void State::DecrementParentRefcount(BlockIndex value_index) {
+ Block* value = heap_->GetBlock(value_index);
+ ZX_ASSERT(value);
+
+ BlockIndex parent_index = ValueBlockFields::ParentIndex::Get<BlockIndex>(value->header);
+ Block* parent;
+ while ((parent = heap_->GetBlock(parent_index)) != nullptr) {
+ ZX_ASSERT(parent);
+ switch (GetType(parent)) {
+ case BlockType::kHeader:
+ return;
+ case BlockType::kNodeValue:
+ // Stop decrementing parent refcounts when we observe a live object.
+ ZX_ASSERT(parent->payload.u64 != 0);
+ --parent->payload.u64;
+ return;
+ case BlockType::kTombstone:
+ ZX_ASSERT(parent->payload.u64 != 0);
+ if (--parent->payload.u64 == 0) {
+ // The tombstone parent is no longer referenced and can be deleted.
+ // Continue decrementing refcounts.
+ BlockIndex next_parent_index =
+ ValueBlockFields::ParentIndex::Get<BlockIndex>(parent->header);
+ heap_->Free(ValueBlockFields::NameIndex::Get<BlockIndex>(parent->header));
+ heap_->Free(parent_index);
+ parent_index = next_parent_index;
+ break;
+ }
+ // The tombstone parent is still referenced. Done decrementing refcounts.
+ return;
+ default:
+ ZX_DEBUG_ASSERT_MSG(false, "Invalid parent type %u",
+ static_cast<uint32_t>(GetType(parent)));
+ return;
+ }
+ }
+}
+
+void State::FreeIntProperty(IntProperty* metric) {
+ ZX_DEBUG_ASSERT_MSG(metric->state_.get() == this, "Property being freed from the wrong state");
+ if (metric->state_.get() != this) {
+ return;
+ }
+
+ std::lock_guard<std::mutex> lock(mutex_);
+ AutoGenerationIncrement gen(header_, heap_.get());
+
+ DecrementParentRefcount(metric->value_index_);
+
+ heap_->Free(metric->name_index_);
+ heap_->Free(metric->value_index_);
+ metric->state_ = nullptr;
+}
+
+void State::FreeUintProperty(UintProperty* metric) {
+ ZX_DEBUG_ASSERT_MSG(metric->state_.get() == this, "Property being freed from the wrong state");
+ if (metric->state_.get() != this) {
+ return;
+ }
+
+ std::lock_guard<std::mutex> lock(mutex_);
+ AutoGenerationIncrement gen(header_, heap_.get());
+
+ DecrementParentRefcount(metric->value_index_);
+
+ heap_->Free(metric->name_index_);
+ heap_->Free(metric->value_index_);
+ metric->state_ = nullptr;
+}
+
+void State::FreeDoubleProperty(DoubleProperty* metric) {
+ ZX_DEBUG_ASSERT_MSG(metric->state_.get() == this, "Property being freed from the wrong state");
+ if (metric->state_.get() != this) {
+ return;
+ }
+
+ std::lock_guard<std::mutex> lock(mutex_);
+ AutoGenerationIncrement gen(header_, heap_.get());
+
+ DecrementParentRefcount(metric->value_index_);
+
+ heap_->Free(metric->name_index_);
+ heap_->Free(metric->value_index_);
+ metric->state_ = nullptr;
+}
+
+void State::FreeBoolProperty(BoolProperty* metric) {
+ ZX_DEBUG_ASSERT_MSG(metric->state_.get() == this, "Property being freed from wrong state");
+ if (metric->state_.get() != this) {
+ return;
+ }
+
+ std::lock_guard<std::mutex> lock(mutex_);
+ AutoGenerationIncrement gen(header_, heap_.get());
+
+ DecrementParentRefcount(metric->value_index_);
+
+ heap_->Free(metric->name_index_);
+ heap_->Free(metric->value_index_);
+ metric->state_ = nullptr;
+}
+
+void State::FreeIntArray(IntArray* array) { InnerFreeArray<IntArray>(array); }
+
+void State::FreeUintArray(UintArray* array) { InnerFreeArray<UintArray>(array); }
+
+void State::FreeDoubleArray(DoubleArray* array) { InnerFreeArray<DoubleArray>(array); }
+
+template <typename WrapperType>
+void State::InnerFreePropertyWithExtents(WrapperType* property) {
+ ZX_DEBUG_ASSERT_MSG(property->state_.get() == this, "Property being freed from the wrong state");
+ if (property->state_.get() != this) {
+ return;
+ }
+
+ std::lock_guard<std::mutex> lock(mutex_);
+ AutoGenerationIncrement gen(header_, heap_.get());
+
+ DecrementParentRefcount(property->value_index_);
+
+ InnerFreeStringExtents(property->value_index_);
+
+ heap_->Free(property->name_index_);
+ heap_->Free(property->value_index_);
+ property->state_ = nullptr;
+}
+
+void State::FreeStringProperty(StringProperty* property) { InnerFreePropertyWithExtents(property); }
+
+void State::FreeByteVectorProperty(ByteVectorProperty* property) {
+ InnerFreePropertyWithExtents(property);
+}
+
+void State::FreeLink(Link* link) {
+ ZX_DEBUG_ASSERT_MSG(link->state_.get() == this, "Link being freed from the wrong state");
+ if (link->state_.get() != this) {
+ return;
+ }
+
+ std::lock_guard<std::mutex> lock(mutex_);
+ AutoGenerationIncrement gen(header_, heap_.get());
+
+ DecrementParentRefcount(link->value_index_);
+
+ heap_->Free(link->name_index_);
+ heap_->Free(link->value_index_);
+ heap_->Free(link->content_index_);
+ link->state_ = nullptr;
+}
+
+void State::FreeNode(Node* object) {
+ ZX_DEBUG_ASSERT_MSG(object->state_.get() == this, "Node being freed from the wrong state");
+ if (object->state_.get() != this) {
+ return;
+ }
+
+ if (object->value_index_ == 0) {
+ // This is a special "root" node, it cannot be deleted.
+ return;
+ }
+
+ std::lock_guard<std::mutex> lock(mutex_);
+ AutoGenerationIncrement gen(header_, heap_.get());
+
+ auto* block = heap_->GetBlock(object->value_index_);
+ if (block) {
+ if (block->payload.u64 == 0) {
+ // Actually free the block, decrementing parent refcounts.
+ DecrementParentRefcount(object->value_index_);
+ // Node has no refs, free it.
+ heap_->Free(object->name_index_);
+ heap_->Free(object->value_index_);
+ } else {
+ // Node has refs, change type to tombstone so it can be removed
+ // when the last ref is gone.
+ ValueBlockFields::Type::Set(&block->header, static_cast<uint64_t>(BlockType::kTombstone));
+ }
+ }
+}
+
+void State::FreeLazyNode(LazyNode* object) {
+ ZX_DEBUG_ASSERT_MSG(object->state_.get() == this, "Node being freed from the wrong state");
+ if (object->state_.get() != this) {
+ return;
+ }
+
+ // Free the contained link, which removes the reference to the value in the map.
+ FreeLink(&object->link_);
+
+ LazyNodeCallbackHolder holder;
+
+ {
+ // Separately lock the current state, and remove the callback for this lazy node.
+ std::lock_guard<std::mutex> lock(mutex_);
+ auto it = link_callbacks_.find(object->content_value_);
+ if (it != link_callbacks_.end()) {
+ holder = it->second;
+ link_callbacks_.erase(it);
+ }
+ object->state_ = nullptr;
+ }
+
+ // Cancel the Holder without State locked. This avoids a deadlock in which we could be locking the
+ // holder with the state lock held, meanwhile the callback itself is modifying state (with holder
+ // locked).
+ //
+ // At this point in time, the LazyNode is still *live* and the callback may be getting executed.
+ // Following this cancel call, the LazyNode is no longer live and the callback will never be
+ // called again.
+ holder.cancel();
+}
+
+std::vector<std::string> State::GetLinkNames() const {
+ std::lock_guard<std::mutex> lock(mutex_);
+ std::vector<std::string> ret;
+ for (const auto& entry : link_callbacks_) {
+ ret.push_back(entry.first);
+ }
+ return ret;
+}
+
+fit::promise<Inspector> State::CallLinkCallback(const std::string& name) {
+ LazyNodeCallbackHolder holder;
+
+ {
+ std::lock_guard<std::mutex> lock(mutex_);
+ auto it = link_callbacks_.find(name);
+ if (it == link_callbacks_.end()) {
+ return fit::make_result_promise<Inspector>(fit::error());
+ }
+ // Copy out the holder.
+ holder = it->second;
+ }
+
+ // Call the callback.
+ // This occurs without state locked, but deletion of the LazyNode synchronizes on the internal
+ // mutex in the Holder. If the LazyNode is deleted before this call, the callback will not be
+ // executed. If the LazyNode is being deleted concurrent with this call, it will be delayed until
+ // after the callback returns.
+ return holder.call();
+}
+
+zx_status_t State::InnerCreateValue(const std::string& name, BlockType type,
+ BlockIndex parent_index, BlockIndex* out_name,
+ BlockIndex* out_value, size_t min_size_required) {
+ BlockIndex value_index, name_index;
+ zx_status_t status;
+ status = heap_->Allocate(min_size_required, &value_index);
+ if (status != ZX_OK) {
+ return status;
+ }
+
+ status = CreateName(name, &name_index);
+ if (status != ZX_OK) {
+ heap_->Free(value_index);
+ return status;
+ }
+
+ auto* block = heap_->GetBlock(value_index);
+ block->header = ValueBlockFields::Order::Make(GetOrder(block)) |
+ ValueBlockFields::Type::Make(type) |
+ ValueBlockFields::ParentIndex::Make(parent_index) |
+ ValueBlockFields::NameIndex::Make(name_index);
+ memset(&block->payload, 0, min_size_required - sizeof(block->header));
+
+ // Increment the parent refcount.
+ Block* parent = heap_->GetBlock(parent_index);
+ ZX_DEBUG_ASSERT_MSG(parent, "Index %lu is invalid", parent_index);
+ // In release mode, do cleanup if parent is invalid.
+ BlockType parent_type = (parent) ? GetType(parent) : BlockType::kFree;
+ switch (parent_type) {
+ case BlockType::kHeader:
+ break;
+ case BlockType::kNodeValue:
+ case BlockType::kTombstone:
+ // Increment refcount.
+ parent->payload.u64++;
+ break;
+ default:
+ ZX_DEBUG_ASSERT_MSG(false, "Invalid parent block type %u for 0x%lx",
+ static_cast<uint32_t>(GetType(parent)), parent_index);
+ heap_->Free(name_index);
+ heap_->Free(value_index);
+ return ZX_ERR_INVALID_ARGS;
+ }
+
+ *out_name = name_index;
+ *out_value = value_index;
+ return ZX_OK;
+}
+
+void State::InnerFreeStringExtents(BlockIndex string_index) {
+ auto* str = heap_->GetBlock(string_index);
+ if (!str || GetType(str) != BlockType::kBufferValue) {
+ return;
+ }
+
+ auto extent_index = PropertyBlockPayload::ExtentIndex::Get<BlockIndex>(str->payload.u64);
+ auto* extent = heap_->GetBlock(extent_index);
+ while (IsExtent(extent)) {
+ auto next_extent = ExtentBlockFields::NextExtentIndex::Get<BlockIndex>(extent->header);
+ heap_->Free(extent_index);
+ extent_index = next_extent;
+ extent = heap_->GetBlock(extent_index);
+ }
+
+ // Leave the string value allocated (and empty).
+ str->payload.u64 = PropertyBlockPayload::TotalLength::Make(0) |
+ PropertyBlockPayload::ExtentIndex::Make(0) |
+ PropertyBlockPayload::Flags::Make(
+ PropertyBlockPayload::Flags::Get<uint8_t>(str->payload.u64));
+}
+
+zx_status_t State::InnerSetStringExtents(BlockIndex string_index, const char* value,
+ size_t length) {
+ InnerFreeStringExtents(string_index);
+
+ auto* block = heap_->GetBlock(string_index);
+
+ if (length == 0) {
+ // The extent index is 0 if no extents were needed (the value is empty).
+ block->payload.u64 = PropertyBlockPayload::TotalLength::Make(length) |
+ PropertyBlockPayload::ExtentIndex::Make(0) |
+ PropertyBlockPayload::Flags::Make(
+ PropertyBlockPayload::Flags::Get<uint8_t>(block->payload.u64));
+ return ZX_OK;
+ }
+
+ BlockIndex extent_index;
+ zx_status_t status;
+ status = heap_->Allocate(std::min(kMaxOrderSize, BlockSizeForPayload(length)), &extent_index);
+ if (status != ZX_OK) {
+ return status;
+ }
+
+ block->payload.u64 = PropertyBlockPayload::TotalLength::Make(length) |
+ PropertyBlockPayload::ExtentIndex::Make(extent_index) |
+ PropertyBlockPayload::Flags::Make(
+ PropertyBlockPayload::Flags::Get<uint8_t>(block->payload.u64));
+
+ // Thread the value through extents, creating new extents as needed.
+ size_t offset = 0;
+ while (offset < length) {
+ auto* extent = heap_->GetBlock(extent_index);
+
+ extent->header = ExtentBlockFields::Order::Make(GetOrder(extent)) |
+ ExtentBlockFields::Type::Make(BlockType::kExtent) |
+ ExtentBlockFields::NextExtentIndex::Make(0);
+
+ size_t len = std::min(PayloadCapacity(GetOrder(extent)), length - offset);
+ memcpy(extent->payload.data, value + offset, len);
+ offset += len;
+
+ if (offset < length) {
+ status = heap_->Allocate(std::min(kMaxOrderSize, BlockSizeForPayload(length - offset)),
+ &extent_index);
+ if (status != ZX_OK) {
+ InnerFreeStringExtents(string_index);
+ return status;
+ }
+ ExtentBlockFields::NextExtentIndex::Set(&extent->header, extent_index);
+ }
+ }
+
+ return ZX_OK;
+}
+
+std::string State::UniqueLinkName(const std::string& prefix) {
+ return prefix + "-" +
+ std::to_string(next_unique_link_number_.fetch_add(1, std::memory_order_relaxed));
+}
+
+zx_status_t State::CreateName(const std::string& name, BlockIndex* out) {
+ ZX_DEBUG_ASSERT_MSG(name.size() <= kMaxPayloadSize, "Name too long (length is %lu)", name.size());
+ if (name.size() > kMaxPayloadSize) {
+ return ZX_ERR_INVALID_ARGS;
+ }
+
+ zx_status_t status;
+ status = heap_->Allocate(BlockSizeForPayload(name.size()), out);
+ if (status != ZX_OK) {
+ return status;
+ }
+
+ auto* block = heap_->GetBlock(*out);
+ block->header = NameBlockFields::Order::Make(GetOrder(block)) |
+ NameBlockFields::Type::Make(BlockType::kName) |
+ NameBlockFields::Length::Make(name.size());
+ memset(block->payload.data, 0, PayloadCapacity(GetOrder(block)));
+ memcpy(block->payload.data, name.data(), name.size());
+ return ZX_OK;
+}
+
+std::string State::UniqueName(const std::string& prefix) {
+ std::ostringstream out;
+ uint64_t value = next_unique_id_.fetch_add(1, std::memory_order_relaxed);
+ out << prefix << "0x" << std::hex << value;
+ return out.str();
+}
+
+} // namespace internal
+} // namespace inspect
diff --git a/third_party/fuchsia-sdk/pkg/inspect/vmo/types.cc b/third_party/fuchsia-sdk/pkg/inspect/vmo/types.cc
new file mode 100644
index 0000000..15fcd43
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/inspect/vmo/types.cc
@@ -0,0 +1,474 @@
+// Copyright 2018 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.
+
+#include <lib/inspect/cpp/inspect.h>
+
+using inspect::internal::ArrayBlockFormat;
+
+namespace inspect {
+
+template <>
+internal::NumericProperty<int64_t>::~NumericProperty<int64_t>() {
+ if (state_) {
+ state_->FreeIntProperty(this);
+ }
+}
+
+template <>
+internal::NumericProperty<int64_t>& internal::NumericProperty<int64_t>::operator=(
+ internal::NumericProperty<int64_t>&& other) noexcept {
+ if (state_) {
+ state_->FreeIntProperty(this);
+ }
+ state_ = std::move(other.state_);
+ name_index_ = other.name_index_;
+ value_index_ = other.value_index_;
+ return *this;
+}
+
+template <>
+void internal::NumericProperty<int64_t>::Set(int64_t value) {
+ if (state_) {
+ state_->SetIntProperty(this, value);
+ }
+}
+
+template <>
+void internal::NumericProperty<int64_t>::Add(int64_t value) {
+ if (state_) {
+ state_->AddIntProperty(this, value);
+ }
+}
+
+template <>
+void internal::NumericProperty<int64_t>::Subtract(int64_t value) {
+ if (state_) {
+ state_->SubtractIntProperty(this, value);
+ }
+}
+
+template <>
+internal::NumericProperty<uint64_t>::~NumericProperty<uint64_t>() {
+ if (state_) {
+ state_->FreeUintProperty(this);
+ }
+}
+
+template <>
+internal::NumericProperty<uint64_t>& internal::NumericProperty<uint64_t>::operator=(
+ internal::NumericProperty<uint64_t>&& other) noexcept {
+ if (state_) {
+ state_->FreeUintProperty(this);
+ }
+ state_ = std::move(other.state_);
+ name_index_ = std::move(other.name_index_);
+ value_index_ = std::move(other.value_index_);
+ return *this;
+}
+
+template <>
+void internal::NumericProperty<uint64_t>::Set(uint64_t value) {
+ if (state_) {
+ state_->SetUintProperty(this, value);
+ }
+}
+
+template <>
+void internal::NumericProperty<uint64_t>::Add(uint64_t value) {
+ if (state_) {
+ state_->AddUintProperty(this, value);
+ }
+}
+
+template <>
+void internal::NumericProperty<uint64_t>::Subtract(uint64_t value) {
+ if (state_) {
+ state_->SubtractUintProperty(this, value);
+ }
+}
+
+template <>
+internal::NumericProperty<double>::~NumericProperty<double>() {
+ if (state_) {
+ state_->FreeDoubleProperty(this);
+ }
+}
+
+template <>
+internal::NumericProperty<double>& internal::NumericProperty<double>::operator=(
+ internal::NumericProperty<double>&& other) noexcept {
+ if (state_) {
+ state_->FreeDoubleProperty(this);
+ }
+ state_ = std::move(other.state_);
+ name_index_ = std::move(other.name_index_);
+ value_index_ = std::move(other.value_index_);
+ return *this;
+}
+
+template <>
+void internal::NumericProperty<double>::Set(double value) {
+ if (state_) {
+ state_->SetDoubleProperty(this, value);
+ }
+}
+
+template <>
+void internal::NumericProperty<double>::Add(double value) {
+ if (state_) {
+ state_->AddDoubleProperty(this, value);
+ }
+}
+
+template <>
+void internal::NumericProperty<double>::Subtract(double value) {
+ if (state_) {
+ state_->SubtractDoubleProperty(this, value);
+ }
+}
+
+template <>
+internal::ArrayValue<int64_t>::~ArrayValue<int64_t>() {
+ if (state_) {
+ state_->FreeIntArray(this);
+ }
+}
+
+template <>
+internal::ArrayValue<int64_t>& internal::ArrayValue<int64_t>::operator=(
+ internal::ArrayValue<int64_t>&& other) noexcept {
+ if (state_) {
+ state_->FreeIntArray(this);
+ }
+ state_ = std::move(other.state_);
+ name_index_ = std::move(other.name_index_);
+ value_index_ = std::move(other.value_index_);
+ return *this;
+}
+
+template <>
+void internal::ArrayValue<int64_t>::Set(size_t index, int64_t value) {
+ if (state_) {
+ state_->SetIntArray(this, index, value);
+ }
+}
+
+template <>
+void internal::ArrayValue<int64_t>::Add(size_t index, int64_t value) {
+ if (state_) {
+ state_->AddIntArray(this, index, value);
+ }
+}
+
+template <>
+void internal::ArrayValue<int64_t>::Subtract(size_t index, int64_t value) {
+ if (state_) {
+ state_->SubtractIntArray(this, index, value);
+ }
+}
+
+template <>
+internal::ArrayValue<uint64_t>::~ArrayValue<uint64_t>() {
+ if (state_) {
+ state_->FreeUintArray(this);
+ }
+}
+
+template <>
+internal::ArrayValue<uint64_t>& internal::ArrayValue<uint64_t>::operator=(
+ internal::ArrayValue<uint64_t>&& other) noexcept {
+ if (state_) {
+ state_->FreeUintArray(this);
+ }
+ state_ = std::move(other.state_);
+ name_index_ = std::move(other.name_index_);
+ value_index_ = std::move(other.value_index_);
+ return *this;
+}
+
+template <>
+void internal::ArrayValue<uint64_t>::Set(size_t index, uint64_t value) {
+ if (state_) {
+ state_->SetUintArray(this, index, value);
+ }
+}
+
+template <>
+void internal::ArrayValue<uint64_t>::Add(size_t index, uint64_t value) {
+ if (state_) {
+ state_->AddUintArray(this, index, value);
+ }
+}
+
+template <>
+void internal::ArrayValue<uint64_t>::Subtract(size_t index, uint64_t value) {
+ if (state_) {
+ state_->SubtractUintArray(this, index, value);
+ }
+}
+
+template <>
+internal::ArrayValue<double>::~ArrayValue<double>() {
+ if (state_) {
+ state_->FreeDoubleArray(this);
+ }
+}
+
+template <>
+internal::ArrayValue<double>& internal::ArrayValue<double>::operator=(
+ internal::ArrayValue<double>&& other) noexcept {
+ if (state_) {
+ state_->FreeDoubleArray(this);
+ }
+ state_ = std::move(other.state_);
+ name_index_ = std::move(other.name_index_);
+ value_index_ = std::move(other.value_index_);
+ return *this;
+}
+
+template <>
+void internal::ArrayValue<double>::Set(size_t index, double value) {
+ if (state_) {
+ state_->SetDoubleArray(this, index, value);
+ }
+}
+
+template <>
+void internal::ArrayValue<double>::Add(size_t index, double value) {
+ if (state_) {
+ state_->AddDoubleArray(this, index, value);
+ }
+}
+
+template <>
+void internal::ArrayValue<double>::Subtract(size_t index, double value) {
+ if (state_) {
+ state_->SubtractDoubleArray(this, index, value);
+ }
+}
+
+#define PROPERTY_METHODS(NAME, TYPE) \
+ template <> \
+ internal::Property<TYPE>::~Property() { \
+ if (state_) { \
+ state_->Free##NAME##Property(this); \
+ } \
+ } \
+ \
+ template <> \
+ internal::Property<TYPE>& internal::Property<TYPE>::operator=(Property&& other) noexcept { \
+ if (state_) { \
+ state_->Free##NAME##Property(this); \
+ } \
+ state_ = std::move(other.state_); \
+ name_index_ = other.name_index_; \
+ value_index_ = other.value_index_; \
+ return *this; \
+ } \
+ \
+ template <> \
+ void internal::Property<TYPE>::Set(const TYPE& value) { \
+ if (state_) { \
+ state_->Set##NAME##Property(this, value); \
+ } \
+ }
+
+PROPERTY_METHODS(String, std::string)
+PROPERTY_METHODS(ByteVector, std::vector<uint8_t>)
+PROPERTY_METHODS(Bool, bool)
+
+Node::~Node() {
+ if (state_) {
+ state_->FreeNode(this);
+ }
+}
+
+Node& Node::operator=(Node&& other) noexcept {
+ if (state_) {
+ state_->FreeNode(this);
+ }
+ state_ = std::move(other.state_);
+ name_index_ = std::move(other.name_index_);
+ value_index_ = std::move(other.value_index_);
+ return *this;
+}
+
+Node Node::CreateChild(const std::string& name) {
+ if (state_) {
+ return state_->CreateNode(name, value_index_);
+ }
+ return Node();
+}
+
+IntProperty Node::CreateInt(const std::string& name, int64_t value) {
+ if (state_) {
+ return state_->CreateIntProperty(name, value_index_, value);
+ }
+ return IntProperty();
+}
+
+UintProperty Node::CreateUint(const std::string& name, uint64_t value) {
+ if (state_) {
+ return state_->CreateUintProperty(name, value_index_, value);
+ }
+ return UintProperty();
+}
+
+DoubleProperty Node::CreateDouble(const std::string& name, double value) {
+ if (state_) {
+ return state_->CreateDoubleProperty(name, value_index_, value);
+ }
+ return DoubleProperty();
+}
+
+BoolProperty Node::CreateBool(const std::string& name, bool value) {
+ if (state_) {
+ return state_->CreateBoolProperty(name, value_index_, value);
+ }
+ return BoolProperty();
+}
+
+StringProperty Node::CreateString(const std::string& name, const std::string& value) {
+ if (state_) {
+ return state_->CreateStringProperty(name, value_index_, value);
+ }
+ return StringProperty();
+}
+
+ByteVectorProperty Node::CreateByteVector(const std::string& name,
+ const std::vector<uint8_t>& value) {
+ if (state_) {
+ return state_->CreateByteVectorProperty(name, value_index_, value);
+ }
+ return ByteVectorProperty();
+}
+
+IntArray Node::CreateIntArray(const std::string& name, size_t slots) {
+ if (state_) {
+ return state_->CreateIntArray(name, value_index_, slots, ArrayBlockFormat::kDefault);
+ }
+ return IntArray();
+}
+
+UintArray Node::CreateUintArray(const std::string& name, size_t slots) {
+ if (state_) {
+ return state_->CreateUintArray(name, value_index_, slots, ArrayBlockFormat::kDefault);
+ }
+ return UintArray();
+}
+
+DoubleArray Node::CreateDoubleArray(const std::string& name, size_t slots) {
+ if (state_) {
+ return state_->CreateDoubleArray(name, value_index_, slots, ArrayBlockFormat::kDefault);
+ }
+ return DoubleArray();
+}
+
+namespace {
+const size_t kExtraSlotsForLinearHistogram = 4;
+const size_t kExtraSlotsForExponentialHistogram = 5;
+} // namespace
+
+LinearIntHistogram Node::CreateLinearIntHistogram(const std::string& name, int64_t floor,
+ int64_t step_size, size_t buckets) {
+ if (state_) {
+ const size_t slots = buckets + kExtraSlotsForLinearHistogram;
+ auto array =
+ state_->CreateIntArray(name, value_index_, slots, ArrayBlockFormat::kLinearHistogram);
+ return LinearIntHistogram(floor, step_size, slots, std::move(array));
+ }
+ return LinearIntHistogram();
+}
+
+LinearUintHistogram Node::CreateLinearUintHistogram(const std::string& name, uint64_t floor,
+ uint64_t step_size, size_t buckets) {
+ if (state_) {
+ const size_t slots = buckets + kExtraSlotsForLinearHistogram;
+ auto array =
+ state_->CreateUintArray(name, value_index_, slots, ArrayBlockFormat::kLinearHistogram);
+ return LinearUintHistogram(floor, step_size, slots, std::move(array));
+ }
+ return LinearUintHistogram();
+}
+
+LinearDoubleHistogram Node::CreateLinearDoubleHistogram(const std::string& name, double floor,
+ double step_size, size_t buckets) {
+ if (state_) {
+ const size_t slots = buckets + kExtraSlotsForLinearHistogram;
+ auto array =
+ state_->CreateDoubleArray(name, value_index_, slots, ArrayBlockFormat::kLinearHistogram);
+ return LinearDoubleHistogram(floor, step_size, slots, std::move(array));
+ }
+ return LinearDoubleHistogram();
+}
+
+ExponentialIntHistogram Node::CreateExponentialIntHistogram(const std::string& name, int64_t floor,
+ int64_t initial_step,
+ int64_t step_multiplier,
+ size_t buckets) {
+ if (state_) {
+ const size_t slots = buckets + kExtraSlotsForExponentialHistogram;
+ auto array =
+ state_->CreateIntArray(name, value_index_, slots, ArrayBlockFormat::kExponentialHistogram);
+ return ExponentialIntHistogram(floor, initial_step, step_multiplier, slots, std::move(array));
+ }
+ return ExponentialIntHistogram();
+}
+
+ExponentialUintHistogram Node::CreateExponentialUintHistogram(const std::string& name,
+ uint64_t floor, uint64_t initial_step,
+ uint64_t step_multiplier,
+ size_t buckets) {
+ if (state_) {
+ const size_t slots = buckets + kExtraSlotsForExponentialHistogram;
+ auto array =
+ state_->CreateUintArray(name, value_index_, slots, ArrayBlockFormat::kExponentialHistogram);
+ return ExponentialUintHistogram(floor, initial_step, step_multiplier, slots, std::move(array));
+ }
+ return ExponentialUintHistogram();
+}
+
+ExponentialDoubleHistogram Node::CreateExponentialDoubleHistogram(const std::string& name,
+ double floor, double initial_step,
+ double step_multiplier,
+ size_t buckets) {
+ if (state_) {
+ const size_t slots = buckets + kExtraSlotsForExponentialHistogram;
+ auto array = state_->CreateDoubleArray(name, value_index_, slots,
+ ArrayBlockFormat::kExponentialHistogram);
+ return ExponentialDoubleHistogram(floor, initial_step, step_multiplier, slots,
+ std::move(array));
+ }
+ return ExponentialDoubleHistogram();
+}
+
+std::string Node::UniqueName(const std::string& prefix) { return state_->UniqueName(prefix); }
+
+LazyNode Node::CreateLazyNode(const std::string& name, LazyNodeCallbackFn callback) {
+ if (state_) {
+ return state_->CreateLazyNode(name, value_index_, std::move(callback));
+ }
+ return LazyNode();
+}
+
+LazyNode Node::CreateLazyValues(const std::string& name, LazyNodeCallbackFn callback) {
+ if (state_) {
+ return state_->CreateLazyValues(name, value_index_, std::move(callback));
+ }
+ return LazyNode();
+}
+
+Link::~Link() {
+ if (state_) {
+ state_->FreeLink(this);
+ }
+}
+
+LazyNode::~LazyNode() {
+ if (state_) {
+ state_->FreeLazyNode(this);
+ }
+}
+
+} // namespace inspect
diff --git a/third_party/fuchsia-sdk/pkg/inspect_service_cpp/BUILD.gn b/third_party/fuchsia-sdk/pkg/inspect_service_cpp/BUILD.gn
new file mode 100644
index 0000000..57d0ac6
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/inspect_service_cpp/BUILD.gn
@@ -0,0 +1,30 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("inspect_service_cpp") {
+ sources = [
+ "reader.cc",
+ "service.cc",
+ "include/lib/inspect/service/cpp/reader.h",
+ "include/lib/inspect/service/cpp/service.h",
+ ]
+ include_dirs = [ "include" ]
+ public_deps = [
+ "../../fidl/fuchsia.inspect",
+ "../async-cpp",
+ "../inspect",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":inspect_service_cpp",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/inspect_service_cpp/include/lib/inspect/service/cpp/reader.h b/third_party/fuchsia-sdk/pkg/inspect_service_cpp/include/lib/inspect/service/cpp/reader.h
new file mode 100644
index 0000000..3f8e013
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/inspect_service_cpp/include/lib/inspect/service/cpp/reader.h
@@ -0,0 +1,33 @@
+// 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.
+
+#ifndef LIB_INSPECT_SERVICE_CPP_READER_H_
+#define LIB_INSPECT_SERVICE_CPP_READER_H_
+
+#include <fuchsia/inspect/cpp/fidl.h>
+#include <lib/fit/promise.h>
+#include <lib/inspect/cpp/hierarchy.h>
+
+namespace inspect {
+
+// Read all of the child names from a TreeNameIterator into a vector.
+//
+// This function continually calls GetNext on the iterator until all child names have been returned.
+//
+// Returns a promise for the vector of child names names.
+fit::promise<std::vector<std::string>> ReadAllChildNames(
+ fuchsia::inspect::TreeNameIteratorPtr iterator);
+
+// Read a full inspect::Hierarchy from a fuchsia.inspect.Tree.
+//
+// fuchsia.inspect.Tree provides lookup support for Link nodes stored in a hierarchy. This function
+// uses the protocol to lookup linked data as needed to create a complete view of the entire tree,
+// including dynamically generated subtrees.
+//
+// Returns a promise for the hierarchy parsed from the Tree.
+fit::promise<Hierarchy> ReadFromTree(fuchsia::inspect::TreePtr tree);
+
+} // namespace inspect
+
+#endif // LIB_INSPECT_SERVICE_CPP_READER_H_
diff --git a/third_party/fuchsia-sdk/pkg/inspect_service_cpp/include/lib/inspect/service/cpp/service.h b/third_party/fuchsia-sdk/pkg/inspect_service_cpp/include/lib/inspect/service/cpp/service.h
new file mode 100644
index 0000000..6cba1ea
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/inspect_service_cpp/include/lib/inspect/service/cpp/service.h
@@ -0,0 +1,22 @@
+// 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.
+
+#ifndef LIB_INSPECT_SERVICE_CPP_SERVICE_H_
+#define LIB_INSPECT_SERVICE_CPP_SERVICE_H_
+
+#include <fuchsia/inspect/cpp/fidl.h>
+#include <lib/inspect/cpp/inspect.h>
+
+namespace inspect {
+
+// Returns a handler for fuchsia.inspect.Tree connections on the given Inspector.
+//
+// This is meant to be used to construct a vfs::Service Node to serve the given Inspector as a
+// fuchsia.inspect.Tree.
+fidl::InterfaceRequestHandler<fuchsia::inspect::Tree> MakeTreeHandler(
+ const inspect::Inspector* inspector, async_dispatcher_t* dispatcher = nullptr);
+
+} // namespace inspect
+
+#endif // LIB_INSPECT_SERVICE_CPP_SERVICE_H_
diff --git a/third_party/fuchsia-sdk/pkg/inspect_service_cpp/meta.json b/third_party/fuchsia-sdk/pkg/inspect_service_cpp/meta.json
new file mode 100644
index 0000000..3f765e8
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/inspect_service_cpp/meta.json
@@ -0,0 +1,22 @@
+{
+ "banjo_deps": [],
+ "deps": [
+ "async-cpp",
+ "inspect"
+ ],
+ "fidl_deps": [
+ "fuchsia.inspect"
+ ],
+ "headers": [
+ "pkg/inspect_service_cpp/include/lib/inspect/service/cpp/reader.h",
+ "pkg/inspect_service_cpp/include/lib/inspect/service/cpp/service.h"
+ ],
+ "include_dir": "pkg/inspect_service_cpp/include",
+ "name": "inspect_service_cpp",
+ "root": "pkg/inspect_service_cpp",
+ "sources": [
+ "pkg/inspect_service_cpp/reader.cc",
+ "pkg/inspect_service_cpp/service.cc"
+ ],
+ "type": "cc_source_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/inspect_service_cpp/reader.cc b/third_party/fuchsia-sdk/pkg/inspect_service_cpp/reader.cc
new file mode 100644
index 0000000..001ca34
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/inspect_service_cpp/reader.cc
@@ -0,0 +1,93 @@
+// 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.
+
+#include <lib/fit/bridge.h>
+#include <lib/inspect/cpp/reader.h>
+#include <lib/inspect/service/cpp/reader.h>
+
+using inspect::internal::SnapshotTree;
+
+namespace inspect {
+
+namespace {
+fit::promise<SnapshotTree> SnapshotTreeFromTree(fuchsia::inspect::TreePtr tree) {
+ fit::bridge<fuchsia::inspect::TreeContent> content_bridge;
+ fuchsia::inspect::TreeNameIteratorPtr child_ptr;
+ tree->GetContent(content_bridge.completer.bind());
+ tree->ListChildNames(child_ptr.NewRequest());
+ return fit::join_promises(content_bridge.consumer.promise_or(fit::error()),
+ ReadAllChildNames(std::move(child_ptr)))
+ .and_then([tree = std::move(tree)](
+ std::tuple<fit::result<fuchsia::inspect::TreeContent>,
+ fit::result<std::vector<std::string>>>& result) mutable
+ -> fit::promise<SnapshotTree> {
+ auto& content = std::get<0>(result);
+ auto& children = std::get<1>(result);
+
+ SnapshotTree ret;
+ if (!content.is_ok() || !children.is_ok() ||
+ Snapshot::Create(content.take_value().buffer().vmo, &ret.snapshot)) {
+ return fit::make_result_promise<SnapshotTree>(fit::error());
+ }
+
+ // Sequence all child reads for depth-first traversal.
+ fit::sequencer seq;
+ std::vector<fit::promise<SnapshotTree>> child_promises;
+ for (const auto& child_name : children.value()) {
+ fuchsia::inspect::TreePtr child_ptr;
+ tree->OpenChild(child_name, child_ptr.NewRequest());
+ child_promises.emplace_back(SnapshotTreeFromTree(std::move(child_ptr)).wrap_with(seq));
+ }
+
+ return join_promise_vector(std::move(child_promises))
+ .and_then(
+ [ret = std::move(ret), tree = std::move(tree), children = children.take_value()](
+ std::vector<fit::result<SnapshotTree>>& results) mutable {
+ ZX_ASSERT(children.size() == results.size());
+
+ for (size_t i = 0; i < results.size(); i++) {
+ if (results[i].is_ok()) {
+ ret.children.emplace(std::move(children[i]), results[i].take_value());
+ }
+ }
+
+ return fit::ok(std::move(ret));
+ });
+
+ return fit::make_result_promise<SnapshotTree>(fit::error());
+ });
+}
+} // namespace
+
+fit::promise<std::vector<std::string>> ReadAllChildNames(
+ fuchsia::inspect::TreeNameIteratorPtr iterator) {
+ fit::bridge<std::vector<std::string>> bridge;
+
+ iterator->GetNext(bridge.completer.bind());
+
+ return bridge.consumer.promise_or(fit::error())
+ .then([it = std::move(iterator)](fit::result<std::vector<std::string>>& result) mutable
+ -> fit::promise<std::vector<std::string>> {
+ if (!result.is_ok() || result.value().size() == 0) {
+ return fit::make_ok_promise(std::vector<std::string>());
+ }
+
+ return ReadAllChildNames(std::move(it))
+ .then(
+ [ret = result.take_value()](fit::result<std::vector<std::string>>& result) mutable {
+ if (result.is_ok()) {
+ for (auto& v : result.take_value()) {
+ ret.emplace_back(std::move(v));
+ }
+ }
+ return fit::make_ok_promise(std::move(ret));
+ });
+ });
+}
+
+fit::promise<Hierarchy> ReadFromTree(fuchsia::inspect::TreePtr tree) {
+ return SnapshotTreeFromTree(std::move(tree)).and_then(internal::ReadFromSnapshotTree);
+}
+
+} // namespace inspect
diff --git a/third_party/fuchsia-sdk/pkg/inspect_service_cpp/service.cc b/third_party/fuchsia-sdk/pkg/inspect_service_cpp/service.cc
new file mode 100644
index 0000000..b08c934
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/inspect_service_cpp/service.cc
@@ -0,0 +1,122 @@
+// 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.
+
+#include <lib/async/cpp/executor.h>
+#include <lib/async/default.h>
+#include <lib/fidl/cpp/binding_set.h>
+#include <lib/fidl/cpp/event_sender.h>
+#include <lib/inspect/cpp/inspect.h>
+#include <lib/inspect/service/cpp/service.h>
+
+#include <set>
+
+namespace inspect {
+
+namespace {
+
+class InspectTreeNameListService final : public fuchsia::inspect::TreeNameIterator {
+ public:
+ InspectTreeNameListService(std::vector<std::string> names,
+ fit::function<void(InspectTreeNameListService*)> done_callback)
+ : names_(std::move(names)), done_callback_(std::move(done_callback)) {}
+
+ void GetNext(GetNextCallback callback) override {
+ std::vector<std::string> ret;
+ size_t i = 0;
+ for (; i < fuchsia::inspect::MAX_TREE_NAME_LIST_SIZE && name_offset_ < names_.size(); i++) {
+ ret.emplace_back(std::move(names_[name_offset_]));
+ name_offset_++;
+ }
+
+ callback(std::move(ret));
+
+ // Close the connection only if the response was empty. We respond with an empty vector to let
+ // the client know we will be disconnecting.
+ if (i == 0) {
+ done_callback_(this);
+ }
+ }
+
+ private:
+ size_t name_offset_ = 0;
+ std::vector<std::string> names_;
+
+ fit::function<void(InspectTreeNameListService*)> done_callback_;
+};
+
+class InspectTreeService final : public fuchsia::inspect::Tree {
+ public:
+ InspectTreeService(Inspector inspector, async_dispatcher_t* dispatcher,
+ fit::function<void(InspectTreeService*)> closer)
+ : inspector_(std::move(inspector)), executor_(dispatcher), closer_(std::move(closer)) {}
+
+ // Cannot be moved or copied.
+ InspectTreeService(const InspectTreeService&) = delete;
+ InspectTreeService(InspectTreeService&&) = delete;
+ InspectTreeService& operator=(InspectTreeService&&) = delete;
+ InspectTreeService& operator=(const InspectTreeService&) = delete;
+
+ void GetContent(GetContentCallback callback) override {
+ fuchsia::inspect::TreeContent ret;
+ fuchsia::mem::Buffer buffer;
+ buffer.vmo = inspector_.DuplicateVmo();
+ buffer.vmo.get_size(&buffer.size);
+ ret.set_buffer(std::move(buffer));
+ callback(std::move(ret));
+ }
+
+ void ListChildNames(fidl::InterfaceRequest<fuchsia::inspect::TreeNameIterator> request) override {
+ auto names = inspector_.GetChildNames();
+ auto service = std::make_unique<InspectTreeNameListService>(
+ std::move(names),
+ [this](InspectTreeNameListService* ptr) { name_list_bindings_.RemoveBinding(ptr); });
+ name_list_bindings_.AddBinding(std::move(service), std::move(request), executor_.dispatcher());
+ }
+
+ void OpenChild(std::string child_name,
+ fidl::InterfaceRequest<fuchsia::inspect::Tree> request) override {
+ executor_.schedule_task(
+ inspector_.OpenChild(std::move(child_name))
+ .and_then([this, request = std::move(request)](Inspector& inspector) mutable {
+ auto child = std::unique_ptr<InspectTreeService>(new InspectTreeService(
+ std::move(inspector), executor_.dispatcher(),
+ [this](InspectTreeService* ptr) { child_bindings_.RemoveBinding(ptr); }));
+ child_bindings_.AddBinding(std::move(child), std::move(request));
+ }));
+ }
+
+ private:
+ Inspector inspector_;
+
+ async::Executor executor_;
+ fidl::BindingSet<fuchsia::inspect::Tree, std::unique_ptr<InspectTreeService>> child_bindings_;
+ fidl::BindingSet<fuchsia::inspect::TreeNameIterator, std::unique_ptr<InspectTreeNameListService>>
+ name_list_bindings_;
+
+ // Calling this function unbinds the given service and destroys it immediately.
+ fit::function<void(InspectTreeService*)> closer_;
+};
+} // namespace
+
+fidl::InterfaceRequestHandler<fuchsia::inspect::Tree> MakeTreeHandler(
+ const inspect::Inspector* inspector, async_dispatcher_t* dispatcher) {
+ if (dispatcher == nullptr) {
+ dispatcher = async_get_default_dispatcher();
+ ZX_ASSERT(dispatcher);
+ }
+
+ auto bindings = std::make_unique<
+ fidl::BindingSet<fuchsia::inspect::Tree, std::unique_ptr<InspectTreeService>>>();
+ return [bindings = std::move(bindings), dispatcher,
+ inspector](fidl::InterfaceRequest<fuchsia::inspect::Tree> request) mutable {
+ bindings->AddBinding(std::make_unique<InspectTreeService>(
+ *inspector, dispatcher,
+ [binding_ptr = bindings.get()](InspectTreeService* ptr) {
+ binding_ptr->RemoveBinding(ptr);
+ }),
+ std::move(request));
+ };
+}
+
+} // namespace inspect
diff --git a/third_party/fuchsia-sdk/pkg/media_cpp/BUILD.gn b/third_party/fuchsia-sdk/pkg/media_cpp/BUILD.gn
new file mode 100644
index 0000000..1ea1c84
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/media_cpp/BUILD.gn
@@ -0,0 +1,27 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("media_cpp") {
+ sources = [
+ "type_converters.cc",
+ "include/lib/media/cpp/type_converters.h",
+ ]
+ include_dirs = [ "include" ]
+ public_deps = [
+ "../../fidl/fuchsia.media",
+ "../media_cpp_no_converters",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":media_cpp",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/media_cpp/include/lib/media/cpp/type_converters.h b/third_party/fuchsia-sdk/pkg/media_cpp/include/lib/media/cpp/type_converters.h
new file mode 100644
index 0000000..ed8741c
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/media_cpp/include/lib/media/cpp/type_converters.h
@@ -0,0 +1,26 @@
+// Copyright 2018 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.
+
+#ifndef LIB_MEDIA_CPP_TYPE_CONVERTERS_H_
+#define LIB_MEDIA_CPP_TYPE_CONVERTERS_H_
+
+#include <fuchsia/media/cpp/fidl.h>
+#include <lib/fidl/cpp/type_converter.h>
+#include <lib/media/cpp/timeline_function.h>
+
+namespace fidl {
+
+template <>
+struct TypeConverter<fuchsia::media::TimelineFunction, media::TimelineFunction> {
+ static fuchsia::media::TimelineFunction Convert(const media::TimelineFunction& value);
+};
+
+template <>
+struct TypeConverter<media::TimelineFunction, fuchsia::media::TimelineFunction> {
+ static media::TimelineFunction Convert(const fuchsia::media::TimelineFunction& value);
+};
+
+} // namespace fidl
+
+#endif // LIB_MEDIA_CPP_TYPE_CONVERTERS_H_
diff --git a/third_party/fuchsia-sdk/pkg/media_cpp/meta.json b/third_party/fuchsia-sdk/pkg/media_cpp/meta.json
new file mode 100644
index 0000000..217d1d2
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/media_cpp/meta.json
@@ -0,0 +1,19 @@
+{
+ "banjo_deps": [],
+ "deps": [
+ "media_cpp_no_converters"
+ ],
+ "fidl_deps": [
+ "fuchsia.media"
+ ],
+ "headers": [
+ "pkg/media_cpp/include/lib/media/cpp/type_converters.h"
+ ],
+ "include_dir": "pkg/media_cpp/include",
+ "name": "media_cpp",
+ "root": "pkg/media_cpp",
+ "sources": [
+ "pkg/media_cpp/type_converters.cc"
+ ],
+ "type": "cc_source_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/media_cpp/type_converters.cc b/third_party/fuchsia-sdk/pkg/media_cpp/type_converters.cc
new file mode 100644
index 0000000..ef9070d
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/media_cpp/type_converters.cc
@@ -0,0 +1,29 @@
+// Copyright 2018 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.
+
+#include <lib/media/cpp/type_converters.h>
+
+namespace fidl {
+
+// static
+fuchsia::media::TimelineFunction
+TypeConverter<fuchsia::media::TimelineFunction, media::TimelineFunction>::Convert(
+ const media::TimelineFunction& value) {
+ fuchsia::media::TimelineFunction result;
+ result.subject_time = value.subject_time();
+ result.reference_time = value.reference_time();
+ result.subject_delta = value.subject_delta();
+ result.reference_delta = value.reference_delta();
+ return result;
+}
+
+// static
+media::TimelineFunction
+TypeConverter<media::TimelineFunction, fuchsia::media::TimelineFunction>::Convert(
+ const fuchsia::media::TimelineFunction& value) {
+ return media::TimelineFunction(value.subject_time, value.reference_time, value.subject_delta,
+ value.reference_delta);
+}
+
+} // namespace fidl
diff --git a/third_party/fuchsia-sdk/pkg/media_cpp_no_converters/BUILD.gn b/third_party/fuchsia-sdk/pkg/media_cpp_no_converters/BUILD.gn
new file mode 100644
index 0000000..45ab8b7
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/media_cpp_no_converters/BUILD.gn
@@ -0,0 +1,27 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("media_cpp_no_converters") {
+ sources = [
+ "timeline_function.cc",
+ "timeline_rate.cc",
+ "include/lib/media/cpp/timeline_function.h",
+ "include/lib/media/cpp/timeline_rate.h",
+ ]
+ include_dirs = [ "include" ]
+ public_deps = [
+ ]
+}
+
+group("all"){
+ deps = [
+ ":media_cpp_no_converters",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/media_cpp_no_converters/include/lib/media/cpp/timeline_function.h b/third_party/fuchsia-sdk/pkg/media_cpp_no_converters/include/lib/media/cpp/timeline_function.h
new file mode 100644
index 0000000..424f419
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/media_cpp_no_converters/include/lib/media/cpp/timeline_function.h
@@ -0,0 +1,116 @@
+// Copyright 2016 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.
+
+#ifndef LIB_MEDIA_CPP_TIMELINE_FUNCTION_H_
+#define LIB_MEDIA_CPP_TIMELINE_FUNCTION_H_
+
+#include <zircon/assert.h>
+
+#include <lib/media/cpp/timeline_rate.h>
+
+namespace media {
+
+// TODO(dalesat): Consider always allowing inexact results.
+
+// A linear function from int64_t to int64_t with non-negative slope that
+// translates reference timeline values into subject timeline values (the
+// 'subject' being the timeline that's represented by the function). The
+// representation is in point-slope form. The point is represented as two
+// int64_t time values (subject_time, reference_time), and the slope (rate) is
+// represented as a TimelineRate, the ratio of two uint32_t values
+// (subject_delta / reference_delta).
+class TimelineFunction final {
+ public:
+ // Applies a timeline function.
+ static int64_t Apply(int64_t subject_time, int64_t reference_time,
+ TimelineRate rate, // subject_delta / reference_delta
+ int64_t reference_input);
+
+ // Applies the inverse of a timeline function.
+ static int64_t ApplyInverse(int64_t subject_time, int64_t reference_time,
+ TimelineRate rate, // subject_delta / reference_delta
+ int64_t subject_input) {
+ ZX_DEBUG_ASSERT(rate.reference_delta() != 0u);
+ return Apply(reference_time, subject_time, rate.Inverse(), subject_input);
+ }
+
+ // Composes two timeline functions B->C and A->B producing A->C. If exact is
+ // true, DCHECKs on loss of precision.
+ static TimelineFunction Compose(const TimelineFunction& bc, const TimelineFunction& ab,
+ bool exact = true);
+
+ TimelineFunction() : subject_time_(0), reference_time_(0) {}
+
+ TimelineFunction(int64_t subject_time, int64_t reference_time, uint32_t subject_delta,
+ uint32_t reference_delta)
+ : subject_time_(subject_time),
+ reference_time_(reference_time),
+ rate_(subject_delta, reference_delta) {}
+
+ TimelineFunction(int64_t subject_time, int64_t reference_time, TimelineRate rate)
+ : subject_time_(subject_time), reference_time_(reference_time), rate_(rate) {}
+
+ explicit TimelineFunction(TimelineRate rate)
+ : subject_time_(0), reference_time_(0), rate_(rate) {}
+
+ // Determines whether this |TimelineFunction| is invertible.
+ bool invertible() const { return rate_.invertible(); }
+
+ // Applies the function. Returns TimelineRate::kOverflow on overflow.
+ int64_t Apply(int64_t reference_input) const {
+ return Apply(subject_time_, reference_time_, rate_, reference_input);
+ }
+
+ // Applies the inverse of the function. Returns TimelineRate::kOverflow on
+ // overflow.
+ int64_t ApplyInverse(int64_t subject_input) const {
+ ZX_DEBUG_ASSERT(rate_.reference_delta() != 0u);
+ return ApplyInverse(subject_time_, reference_time_, rate_, subject_input);
+ }
+
+ // Applies the function. Returns TimelineRate::kOverflow on overflow.
+ int64_t operator()(int64_t reference_input) const { return Apply(reference_input); }
+
+ // Returns a timeline function that is the inverse if this timeline function.
+ TimelineFunction Inverse() const {
+ ZX_DEBUG_ASSERT(rate_.reference_delta() != 0u);
+ return TimelineFunction(reference_time_, subject_time_, rate_.Inverse());
+ }
+
+ int64_t subject_time() const { return subject_time_; }
+
+ int64_t reference_time() const { return reference_time_; }
+
+ const TimelineRate& rate() const { return rate_; }
+
+ uint32_t subject_delta() const { return rate_.subject_delta(); }
+
+ uint32_t reference_delta() const { return rate_.reference_delta(); }
+
+ private:
+ int64_t subject_time_;
+ int64_t reference_time_;
+ TimelineRate rate_; // subject_delta / reference_delta
+};
+
+// Tests two timeline functions for equality. Equality requires equal basis
+// values.
+inline bool operator==(const TimelineFunction& a, const TimelineFunction& b) {
+ return a.subject_time() == b.subject_time() && a.reference_time() == b.reference_time() &&
+ a.rate() == b.rate();
+}
+
+// Tests two timeline functions for inequality. Equality requires equal basis
+// values.
+inline bool operator!=(const TimelineFunction& a, const TimelineFunction& b) { return !(a == b); }
+
+// Composes two timeline functions B->C and A->B producing A->C. DCHECKs on
+// loss of precision.
+inline TimelineFunction operator*(const TimelineFunction& bc, const TimelineFunction& ab) {
+ return TimelineFunction::Compose(bc, ab);
+}
+
+} // namespace media
+
+#endif // LIB_MEDIA_CPP_TIMELINE_FUNCTION_H_
diff --git a/third_party/fuchsia-sdk/pkg/media_cpp_no_converters/include/lib/media/cpp/timeline_rate.h b/third_party/fuchsia-sdk/pkg/media_cpp_no_converters/include/lib/media/cpp/timeline_rate.h
new file mode 100644
index 0000000..f970326
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/media_cpp_no_converters/include/lib/media/cpp/timeline_rate.h
@@ -0,0 +1,152 @@
+// Copyright 2016 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.
+
+#ifndef LIB_MEDIA_CPP_TIMELINE_RATE_H_
+#define LIB_MEDIA_CPP_TIMELINE_RATE_H_
+
+#include <stdint.h>
+#include <zircon/assert.h>
+
+#include <limits>
+
+namespace media {
+
+// TODO(dalesat): Consider always allowing inexact results.
+
+// Expresses the relative rate of a timeline as the ratio between two uint32_t
+// values subject_delta / reference_delta. "subject" refers to the timeline
+// whose rate is being represented, and "reference" refers to the timeline
+// relative to which the rate is expressed.
+class TimelineRate final {
+ public:
+ // Used to indicate overflow of scaling operations.
+ static constexpr int64_t kOverflow = std::numeric_limits<int64_t>::max();
+
+ // Zero as a TimelineRate.
+ static const TimelineRate Zero;
+
+ // Nanoseconds (subject) per second (reference) as a TimelineRate.
+ static const TimelineRate NsPerSecond;
+
+ // Reduces the ratio of *subject_delta and *reference_delta.
+ static void Reduce(uint32_t* subject_delta, uint32_t* reference_delta);
+
+ // Produces the product of the rates. If exact is true, DCHECKs on loss of
+ // precision.
+ static void Product(uint32_t a_subject_delta, uint32_t a_reference_delta,
+ uint32_t b_subject_delta, uint32_t b_reference_delta,
+ uint32_t* product_subject_delta, uint32_t* product_reference_delta,
+ bool exact = true);
+
+ // Produces the product of the rates and the int64_t as an int64_t. Returns
+ // kOverflow on overflow.
+ static int64_t Scale(int64_t value, uint32_t subject_delta, uint32_t reference_delta);
+
+ // Returns the product of the rates. If exact is true, DCHECKs on loss of
+ // precision.
+ static TimelineRate Product(TimelineRate a, TimelineRate b, bool exact = true) {
+ uint32_t result_subject_delta;
+ uint32_t result_reference_delta;
+ Product(a.subject_delta(), a.reference_delta(), b.subject_delta(), b.reference_delta(),
+ &result_subject_delta, &result_reference_delta, exact);
+ return TimelineRate(result_subject_delta, result_reference_delta);
+ }
+
+ TimelineRate() : subject_delta_(0), reference_delta_(1) {}
+
+ explicit TimelineRate(uint32_t subject_delta)
+ : subject_delta_(subject_delta), reference_delta_(1) {}
+
+ explicit TimelineRate(float rate_as_float)
+ : subject_delta_(rate_as_float > 1.0f ? kFloatFactor
+ : static_cast<uint32_t>(kFloatFactor * rate_as_float)),
+ reference_delta_(rate_as_float > 1.0f ? static_cast<uint32_t>(kFloatFactor / rate_as_float)
+ : kFloatFactor) {
+ // The expressions above are intended to provide good precision for
+ // 'reasonable' playback rate values (say in the range 0.0 to 4.0). The
+ // expressions always produce a ratio of kFloatFactor and a number smaller
+ // than kFloatFactor. kFloatFactor's value was chosen because floats have
+ // a 23-bit mantissa, and operations with a larger factor would sacrifice
+ // precision.
+ ZX_DEBUG_ASSERT(rate_as_float >= 0.0f);
+ Reduce(&subject_delta_, &reference_delta_);
+ }
+
+ TimelineRate(uint32_t subject_delta, uint32_t reference_delta)
+ : subject_delta_(subject_delta), reference_delta_(reference_delta) {
+ ZX_DEBUG_ASSERT(reference_delta != 0);
+ Reduce(&subject_delta_, &reference_delta_);
+ }
+
+ // Determines whether this |TimelineRate| is invertible.
+ bool invertible() const { return subject_delta_ != 0; }
+
+ // Returns the inverse of the rate. DCHECKs if the subject_delta of this
+ // rate is zero.
+ TimelineRate Inverse() const {
+ ZX_DEBUG_ASSERT(subject_delta_ != 0);
+
+ // Note: TimelineRates should be always be in their reduced form. Because
+ // of this, we do not want to invoke the subject/reference constructor
+ // (which will attempt to reduce the ratio). Instead, use the default
+ // constructor and just swap subject/reference.
+ TimelineRate ret;
+ ret.subject_delta_ = reference_delta_;
+ ret.reference_delta_ = subject_delta_;
+ return ret;
+ }
+
+ // Scales the value by this rate. Returns kOverflow on overflow.
+ int64_t Scale(int64_t value) const { return Scale(value, subject_delta_, reference_delta_); }
+
+ // Scales the value by the inverse of this rate.
+ int64_t ScaleInverse(int64_t value) const {
+ return Scale(value, reference_delta_, subject_delta_);
+ }
+
+ uint32_t subject_delta() const { return subject_delta_; }
+ uint32_t reference_delta() const { return reference_delta_; }
+
+ private:
+ // A multiplier for float-to-TimelineRate conversions chosen because floats
+ // have a 23-bit mantissa.
+ static constexpr uint32_t kFloatFactor = 1ul << 23;
+
+ uint32_t subject_delta_;
+ uint32_t reference_delta_;
+};
+
+// Tests two rates for equality.
+inline bool operator==(TimelineRate a, TimelineRate b) {
+ return a.subject_delta() == b.subject_delta() && a.reference_delta() == b.reference_delta();
+}
+
+// Tests two rates for inequality.
+inline bool operator!=(TimelineRate a, TimelineRate b) { return !(a == b); }
+
+// Returns the ratio of the two rates. DCHECKs on loss of precision.
+inline TimelineRate operator/(TimelineRate a, TimelineRate b) {
+ return TimelineRate::Product(a, b.Inverse());
+}
+
+// Returns the product of the two rates. DCHECKs on loss of precision.
+inline TimelineRate operator*(TimelineRate a, TimelineRate b) {
+ return TimelineRate::Product(a, b);
+}
+
+// Returns the product of the rate and the int64_t. Returns kOverflow on
+// overflow.
+inline int64_t operator*(TimelineRate a, int64_t b) { return a.Scale(b); }
+
+// Returns the product of the rate and the int64_t. Returns kOverflow on
+// overflow.
+inline int64_t operator*(int64_t a, TimelineRate b) { return b.Scale(a); }
+
+// Returns the the int64_t divided by the rate. Returns kOverflow on
+// overflow.
+inline int64_t operator/(int64_t a, TimelineRate b) { return b.ScaleInverse(a); }
+
+} // namespace media
+
+#endif // LIB_MEDIA_CPP_TIMELINE_RATE_H_
diff --git a/third_party/fuchsia-sdk/pkg/media_cpp_no_converters/meta.json b/third_party/fuchsia-sdk/pkg/media_cpp_no_converters/meta.json
new file mode 100644
index 0000000..4931059
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/media_cpp_no_converters/meta.json
@@ -0,0 +1,17 @@
+{
+ "banjo_deps": [],
+ "deps": [],
+ "fidl_deps": [],
+ "headers": [
+ "pkg/media_cpp_no_converters/include/lib/media/cpp/timeline_function.h",
+ "pkg/media_cpp_no_converters/include/lib/media/cpp/timeline_rate.h"
+ ],
+ "include_dir": "pkg/media_cpp_no_converters/include",
+ "name": "media_cpp_no_converters",
+ "root": "pkg/media_cpp_no_converters",
+ "sources": [
+ "pkg/media_cpp_no_converters/timeline_function.cc",
+ "pkg/media_cpp_no_converters/timeline_rate.cc"
+ ],
+ "type": "cc_source_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/media_cpp_no_converters/timeline_function.cc b/third_party/fuchsia-sdk/pkg/media_cpp_no_converters/timeline_function.cc
new file mode 100644
index 0000000..72a9a1f
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/media_cpp_no_converters/timeline_function.cc
@@ -0,0 +1,31 @@
+// Copyright 2016 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.
+
+#include <lib/media/cpp/timeline_function.h>
+
+#include <limits>
+#include <utility>
+
+namespace media {
+
+// static
+int64_t TimelineFunction::Apply(int64_t subject_time, int64_t reference_time,
+ TimelineRate rate, // subject_delta / reference_delta
+ int64_t reference_input) {
+ return rate.Scale(reference_input - reference_time) + subject_time;
+}
+
+// static
+TimelineFunction TimelineFunction::Compose(const TimelineFunction& bc, const TimelineFunction& ab,
+ bool exact) {
+ // TODO(dalesat): Improve this implementation.
+ // This particular approach to composing two timeline functions compromises
+ // range and accuracy (in some cases) for simplicity. It should be replaced
+ // with something that provides maximum range and accuracy without adding a
+ // lot of runtime cost.
+ return TimelineFunction(bc.Apply(ab.subject_time()), ab.reference_time(),
+ TimelineRate::Product(ab.rate(), bc.rate(), exact));
+}
+
+} // namespace media
diff --git a/third_party/fuchsia-sdk/pkg/media_cpp_no_converters/timeline_rate.cc b/third_party/fuchsia-sdk/pkg/media_cpp_no_converters/timeline_rate.cc
new file mode 100644
index 0000000..a1a0a37
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/media_cpp_no_converters/timeline_rate.cc
@@ -0,0 +1,226 @@
+// Copyright 2016 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.
+
+#include <lib/media/cpp/timeline_rate.h>
+
+#include <zircon/assert.h>
+
+#include <limits>
+#include <utility>
+
+namespace media {
+
+namespace {
+
+// Calculates the greatest common denominator (factor) of two values.
+template <typename T>
+T BinaryGcd(T a, T b) {
+ if (a == 0) {
+ return b;
+ }
+
+ if (b == 0) {
+ return a;
+ }
+
+ // Remove and count the common factors of 2.
+ uint8_t twos;
+ for (twos = 0; ((a | b) & 1) == 0; ++twos) {
+ a >>= 1;
+ b >>= 1;
+ }
+
+ // Get rid of the non-common factors of 2 in a. a is non-zero, so this
+ // terminates.
+ while ((a & 1) == 0) {
+ a >>= 1;
+ }
+
+ do {
+ // Get rid of the non-common factors of 2 in b. b is non-zero, so this
+ // terminates.
+ while ((b & 1) == 0) {
+ b >>= 1;
+ }
+
+ // Apply the Euclid subtraction method.
+ if (a > b) {
+ std::swap(a, b);
+ }
+
+ b = b - a;
+ } while (b != 0);
+
+ // Multiply in the common factors of two.
+ return a << twos;
+}
+
+// Reduces the ratio of *numerator and *denominator.
+template <typename T>
+void ReduceRatio(T* numerator, T* denominator) {
+ ZX_DEBUG_ASSERT(numerator != nullptr);
+ ZX_DEBUG_ASSERT(denominator != nullptr);
+ ZX_DEBUG_ASSERT(*denominator != 0);
+
+ T gcd = BinaryGcd(*numerator, *denominator);
+
+ if (gcd == 0) {
+ *denominator = 1;
+ return;
+ }
+
+ if (gcd == 1) {
+ return;
+ }
+
+ *numerator = *numerator / gcd;
+ *denominator = *denominator / gcd;
+}
+
+template void ReduceRatio<uint64_t>(uint64_t* numerator, uint64_t* denominator);
+template void ReduceRatio<uint32_t>(uint32_t* numerator, uint32_t* denominator);
+
+// Scales a uint64_t value by the ratio of two uint32_t values. If round_up is
+// true, the result is rounded up rather than down. overflow is set to indicate
+// overflow.
+uint64_t ScaleUInt64(uint64_t value, uint32_t subject_delta, uint32_t reference_delta,
+ bool round_up, bool* overflow) {
+ ZX_DEBUG_ASSERT(reference_delta != 0u);
+ ZX_DEBUG_ASSERT(overflow != nullptr);
+
+ constexpr uint64_t kLow32Bits = 0xffffffffu;
+ constexpr uint64_t kHigh32Bits = kLow32Bits << 32u;
+
+ // high and low are the product of the subject_delta and the high and low
+ // halves
+ // (respectively) of value.
+ uint64_t high = subject_delta * (value >> 32u);
+ uint64_t low = subject_delta * (value & kLow32Bits);
+ // Ignoring overflow and remainder, the result we want is:
+ // ((high << 32) + low) / reference_delta.
+
+ // Move the high end of low into the low end of high.
+ high += low >> 32u;
+ low = low & kLow32Bits;
+ // Ignoring overflow and remainder, the result we want is still:
+ // ((high << 32) + low) / reference_delta.
+
+ // When we divide high by reference_delta, there'll be a remainder. Make
+ // that the high end of low, which is currently all zeroes.
+ low |= (high % reference_delta) << 32u;
+
+ // Determine if we need to round up when we're done:
+ round_up = round_up && (low % reference_delta) != 0;
+
+ // Do the division.
+ high /= reference_delta;
+ low /= reference_delta;
+
+ // If high's top 32 bits aren't all zero, we have overflow.
+ if (high & kHigh32Bits) {
+ *overflow = true;
+ return 0;
+ }
+
+ uint64_t result = (high << 32u) | low;
+ if (round_up) {
+ if (result == std::numeric_limits<int64_t>::max()) {
+ *overflow = true;
+ return 0;
+ }
+ ++result;
+ }
+
+ *overflow = false;
+ return result;
+}
+
+} // namespace
+
+// static
+const TimelineRate TimelineRate::Zero = TimelineRate(0, 1);
+
+// static
+const TimelineRate TimelineRate::NsPerSecond = TimelineRate(1000000000L, 1);
+
+// static
+void TimelineRate::Reduce(uint32_t* subject_delta, uint32_t* reference_delta) {
+ ReduceRatio(subject_delta, reference_delta);
+}
+
+// static
+void TimelineRate::Product(uint32_t a_subject_delta, uint32_t a_reference_delta,
+ uint32_t b_subject_delta, uint32_t b_reference_delta,
+ uint32_t* product_subject_delta, uint32_t* product_reference_delta,
+ bool exact) {
+ ZX_DEBUG_ASSERT(a_reference_delta != 0);
+ ZX_DEBUG_ASSERT(b_reference_delta != 0);
+ ZX_DEBUG_ASSERT(product_subject_delta != nullptr);
+ ZX_DEBUG_ASSERT(product_reference_delta != nullptr);
+
+ uint64_t subject_delta = static_cast<uint64_t>(a_subject_delta) * b_subject_delta;
+ uint64_t reference_delta = static_cast<uint64_t>(a_reference_delta) * b_reference_delta;
+
+ ReduceRatio(&subject_delta, &reference_delta);
+
+ if (subject_delta > std::numeric_limits<uint32_t>::max() ||
+ reference_delta > std::numeric_limits<uint32_t>::max()) {
+ ZX_DEBUG_ASSERT(!exact);
+
+ do {
+ subject_delta >>= 1;
+ reference_delta >>= 1;
+ } while (subject_delta > std::numeric_limits<uint32_t>::max() ||
+ reference_delta > std::numeric_limits<uint32_t>::max());
+
+ if (reference_delta == 0) {
+ // Product is larger than we can represent. Return the largest value we
+ // can represent.
+ *product_subject_delta = std::numeric_limits<uint32_t>::max();
+ *product_reference_delta = 1;
+ return;
+ }
+ }
+
+ *product_subject_delta = static_cast<uint32_t>(subject_delta);
+ *product_reference_delta = static_cast<uint32_t>(reference_delta);
+}
+
+// static
+int64_t TimelineRate::Scale(int64_t value, uint32_t subject_delta, uint32_t reference_delta) {
+ static constexpr uint64_t abs_of_min_int64 =
+ static_cast<uint64_t>(std::numeric_limits<int64_t>::max()) + 1;
+
+ ZX_DEBUG_ASSERT(reference_delta != 0u);
+
+ bool overflow;
+
+ uint64_t abs_result;
+
+ if (value >= 0) {
+ abs_result =
+ ScaleUInt64(static_cast<uint64_t>(value), subject_delta, reference_delta, false, &overflow);
+ } else if (value == std::numeric_limits<int64_t>::min()) {
+ abs_result = ScaleUInt64(abs_of_min_int64, subject_delta, reference_delta, true, &overflow);
+ } else {
+ abs_result =
+ ScaleUInt64(static_cast<uint64_t>(-value), subject_delta, reference_delta, true, &overflow);
+ }
+
+ if (overflow) {
+ return TimelineRate::kOverflow;
+ }
+
+ // Make sure we won't overflow when we cast to int64_t.
+ if (abs_result > static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) {
+ if (value < 0 && abs_result == abs_of_min_int64) {
+ return std::numeric_limits<int64_t>::min();
+ }
+ return TimelineRate::kOverflow;
+ }
+
+ return value >= 0 ? static_cast<int64_t>(abs_result) : -static_cast<int64_t>(abs_result);
+}
+
+} // namespace media
diff --git a/third_party/fuchsia-sdk/pkg/memfs/BUILD.gn b/third_party/fuchsia-sdk/pkg/memfs/BUILD.gn
new file mode 100644
index 0000000..2850f2c
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/memfs/BUILD.gn
@@ -0,0 +1,29 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("memfs") {
+ shared_libs = [ "memfs" ]
+
+ deps = [
+ "../async",
+ "../fit",
+ "../sync",
+ ]
+ sources = [
+ "include/lib/memfs/memfs.h",
+ ]
+ include_dirs = [ "include" ]
+}
+
+group("all"){
+ deps = [
+ ":memfs",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/memfs/include/lib/memfs/memfs.h b/third_party/fuchsia-sdk/pkg/memfs/include/lib/memfs/memfs.h
new file mode 100644
index 0000000..c9bcdf9
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/memfs/include/lib/memfs/memfs.h
@@ -0,0 +1,71 @@
+// Copyright 2017 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.
+
+#ifndef LIB_MEMFS_MEMFS_H_
+#define LIB_MEMFS_MEMFS_H_
+
+#include <lib/async/dispatcher.h>
+#include <lib/sync/completion.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+typedef struct memfs_filesystem memfs_filesystem_t;
+
+// Given an async dispatcher, create an in-memory filesystem.
+//
+// The number of pages in this memfs is bounded by the amount of
+// available physical memory.
+//
+// Returns the MemFS filesystem object in |out_fs|. This object
+// must be freed by memfs_free_filesystem.
+//
+// Returns a handle to the root directory in |out_root|.
+__EXPORT zx_status_t memfs_create_filesystem(async_dispatcher_t* dispatcher,
+ memfs_filesystem_t** out_fs, zx_handle_t* out_root);
+
+// Frees a MemFS filesystem, unmounting any sub-filesystems that
+// may exist.
+//
+// Requires that the async handler dispatcher provided to
+// |memfs_create_filesystem| still be running.
+//
+// Signals the optional argument |unmounted| when memfs has torn down.
+__EXPORT void memfs_free_filesystem(memfs_filesystem_t* fs, sync_completion_t* unmounted);
+
+// Creates an in-memory filesystem and installs it into the local namespace at
+// the given path.
+//
+// Operations on the filesystem are serviced by the given async dispatcher.
+//
+// Returns the MemFS filesystem object in |out_fs|. This object may be freed by
+// memfs_uninstall_unsafe. See memfs_uninstall_unsafe for how to avoid use-after-free bugs when
+// freeing that memory.
+//
+// The number of pages in this memfs is bounded by the amount of
+// available physical memory.
+//
+// Returns |ZX_ERR_ALREADY_EXISTS| if |path| already exists in the namespace for
+// this process.
+__EXPORT zx_status_t memfs_install_at(async_dispatcher_t* dispatcher, const char* path,
+ memfs_filesystem_t** out_fs);
+
+// Removes the in-memory filesystem |fs| installed into the local namespace at |path|.
+//
+// If there are pending operations on the file system, uninstalling the file system can result in a
+// use-after-free. To avoid this problem, the caller must shutdown the async_dispatcher_t passed to
+// memfs_install_at before calling memfs_uninstall_unsafe.
+//
+// Typically, memfs_uninstall_unsafe is only useful in unit tests where the caller has complete
+// control over all pending operations. In production code, prefer to clean up by exiting the
+// process.
+//
+// On error, |fs| is not freed. Errors may include all errors from fdio_ns_unbind and
+// fdio_ns_get_installed.
+__EXPORT zx_status_t memfs_uninstall_unsafe(memfs_filesystem_t* fs, const char* path);
+
+__END_CDECLS
+
+#endif // LIB_MEMFS_MEMFS_H_
diff --git a/third_party/fuchsia-sdk/pkg/memfs/meta.json b/third_party/fuchsia-sdk/pkg/memfs/meta.json
new file mode 100644
index 0000000..6e3038a
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/memfs/meta.json
@@ -0,0 +1,29 @@
+{
+ "binaries": {
+ "arm64": {
+ "debug": ".build-id/4c/570772eef1424d.debug",
+ "dist": "arch/arm64/dist/libmemfs.so",
+ "dist_path": "lib/libmemfs.so",
+ "link": "arch/arm64/lib/libmemfs.so"
+ },
+ "x64": {
+ "debug": ".build-id/fd/0aaad880fd8e81.debug",
+ "dist": "arch/x64/dist/libmemfs.so",
+ "dist_path": "lib/libmemfs.so",
+ "link": "arch/x64/lib/libmemfs.so"
+ }
+ },
+ "deps": [
+ "async",
+ "fit",
+ "sync"
+ ],
+ "format": "shared",
+ "headers": [
+ "pkg/memfs/include/lib/memfs/memfs.h"
+ ],
+ "include_dir": "pkg/memfs/include",
+ "name": "memfs",
+ "root": "pkg/memfs",
+ "type": "cc_prebuilt_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/modular_cpp/BUILD.gn b/third_party/fuchsia-sdk/pkg/modular_cpp/BUILD.gn
new file mode 100644
index 0000000..ff12110
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/modular_cpp/BUILD.gn
@@ -0,0 +1,29 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("modular_cpp") {
+ sources = [
+ "agent.cc",
+ "include/lib/modular/cpp/agent.h",
+ ]
+ include_dirs = [ "include" ]
+ public_deps = [
+ "../../fidl/fuchsia.modular",
+ "../../fidl/fuchsia.sys",
+ "../fidl_cpp",
+ "../sys_cpp",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":modular_cpp",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/modular_cpp/agent.cc b/third_party/fuchsia-sdk/pkg/modular_cpp/agent.cc
new file mode 100644
index 0000000..4ce693b
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/modular_cpp/agent.cc
@@ -0,0 +1,49 @@
+// 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.
+
+#include <lib/modular/cpp/agent.h>
+
+namespace modular {
+
+Agent::Agent(std::shared_ptr<sys::OutgoingDirectory> publish_dir, fit::closure on_terminate)
+ : publish_dir_(std::move(publish_dir)), on_terminate_(std::move(on_terminate)) {
+ publish_dir_->AddPublicService<fuchsia::modular::Agent>(agent_bindings_.GetHandler(this));
+ publish_dir_->AddPublicService<fuchsia::modular::Lifecycle>(lifecycle_bindings_.GetHandler(this));
+}
+
+Agent::~Agent() = default;
+
+// |fuchsia::modular::Agent|
+void Agent::Connect(
+ std::string requestor_id,
+ fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> outgoing_services_request) {
+ agent_service_provider_bindings_.AddBinding(this, std::move(outgoing_services_request));
+}
+
+// |fuchsia::sys::ServiceProvider|
+void Agent::ConnectToService(std::string service_name, zx::channel request) {
+ auto it = service_name_to_handler_.find(service_name);
+ if (it != service_name_to_handler_.end()) {
+ it->second(std::move(request));
+ }
+}
+
+// |fuchsia::modular::Lifecycle|
+void Agent::Terminate() {
+ // Unpublish Agent interfaces.
+ publish_dir_->RemovePublicService<fuchsia::modular::Agent>();
+ publish_dir_->RemovePublicService<fuchsia::modular::Lifecycle>();
+
+ // Stop processing further requests.
+ agent_bindings_.CloseAll();
+ lifecycle_bindings_.CloseAll();
+ agent_service_provider_bindings_.CloseAll();
+
+ // Move |on_terminate_| onto the stack to make it re-entrant. This allows the supplied
+ // |on_terminate_| to destroy this Agent instance while still making its state accessible.
+ auto on_terminate = std::move(on_terminate_);
+ on_terminate();
+}
+
+} // namespace modular
diff --git a/third_party/fuchsia-sdk/pkg/modular_cpp/include/lib/modular/cpp/agent.h b/third_party/fuchsia-sdk/pkg/modular_cpp/include/lib/modular/cpp/agent.h
new file mode 100644
index 0000000..d77c93c
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/modular_cpp/include/lib/modular/cpp/agent.h
@@ -0,0 +1,109 @@
+// 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.
+
+#ifndef LIB_MODULAR_CPP_AGENT_H_
+#define LIB_MODULAR_CPP_AGENT_H_
+
+#include <fuchsia/modular/cpp/fidl.h>
+#include <fuchsia/sys/cpp/fidl.h>
+#include <lib/async/cpp/task.h>
+#include <lib/async/default.h>
+#include <lib/fidl/cpp/binding_set.h>
+#include <lib/fidl/cpp/interface_request.h>
+#include <lib/sys/cpp/outgoing_directory.h>
+
+#include <memory>
+#include <unordered_map>
+
+namespace modular {
+
+// Agent is a utility class for implementing an Agent. This utility provides a mechanism to publish
+// the Agent interface and participate in Modular lifecycle.
+//
+// Example:
+// ========
+//
+// class MyAgentServiceImpl : public MyAgentService {
+// public:
+// // |MyAgentService|
+// void MyAgentMethod() override {};
+// };
+//
+// int main(int argc, const char** argv) {
+// async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
+// auto context = sys::ComponentContext::Create();
+//
+// MyAgentServiceImpl my_service;
+// fidl::BindingSet<MyAgentService> my_service_bindings;
+//
+// modular::Agent agent(context->outgoing(),
+// [&loop] { /* on terminate */
+// loop.Quit();
+// });
+// agent.AddService<MyAgentService>(my_service_bindings_.GetHandler(&my_service));
+//
+// loop.Run();
+// return 0;
+// }
+class Agent final : fuchsia::modular::Agent,
+ fuchsia::modular::Lifecycle,
+ fuchsia::sys::ServiceProvider {
+ public:
+ // Publishes the |fuchsia.modular.Agent| and |fuchsia.modular.Lifecycle| interfaces over the
+ // |publish_dir| directory. When a Terminate signal is received, these interfaces are unpublished
+ // and the supplied |on_terminate| is called.
+ //
+ // |on_terminate| must not be null. |on_terminate| may destroy
+ Agent(std::shared_ptr<sys::OutgoingDirectory> publish_dir, fit::closure on_terminate);
+
+ ~Agent() override;
+
+ Agent(const Agent&) = delete;
+ Agent(Agent&&) = delete;
+ void operator=(const Agent&) = delete;
+ void operator=(Agent&&) = delete;
+
+ // Adds the specified interface to the set of published agent interfaces.
+ //
+ // Adds a supported service with the given |service_name|, using the given
+ // |request_handler|. |request_handler| should
+ // remain valid for the lifetime of this object.
+ template <typename Interface>
+ void AddService(fidl::InterfaceRequestHandler<Interface> request_handler,
+ std::string service_name = Interface::Name_) {
+ service_name_to_handler_[service_name] = [request_handler =
+ std::move(request_handler)](zx::channel req) {
+ request_handler(fidl::InterfaceRequest<Interface>(std::move(req)));
+ };
+ }
+
+ private:
+ // |fuchsia::modular::Agent|
+ void Connect(
+ std::string requestor_id,
+ fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> outgoing_services_request) override;
+
+ // |fuchsia::sys::ServiceProvider|
+ void ConnectToService(std::string service_name, zx::channel request) override;
+
+ // |fuchsia::modular::Lifecycle|
+ void Terminate() override;
+
+ // This directory is where Agent & Lifecycle interfaeces are published.
+ std::shared_ptr<sys::OutgoingDirectory> publish_dir_;
+ fit::closure on_terminate_;
+
+ fidl::BindingSet<fuchsia::modular::Agent> agent_bindings_;
+ fidl::BindingSet<fuchsia::modular::Lifecycle> lifecycle_bindings_;
+
+ fidl::BindingSet<fuchsia::sys::ServiceProvider> agent_service_provider_bindings_;
+
+ // A mapping of `service name -> service connection handle` which is inflated using
+ // AddService<>().
+ std::unordered_map<std::string, fit::function<void(zx::channel)>> service_name_to_handler_;
+};
+
+} // namespace modular
+
+#endif // LIB_MODULAR_CPP_AGENT_H_
diff --git a/third_party/fuchsia-sdk/pkg/modular_cpp/meta.json b/third_party/fuchsia-sdk/pkg/modular_cpp/meta.json
new file mode 100644
index 0000000..8aaa39e
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/modular_cpp/meta.json
@@ -0,0 +1,21 @@
+{
+ "banjo_deps": [],
+ "deps": [
+ "fidl_cpp",
+ "sys_cpp"
+ ],
+ "fidl_deps": [
+ "fuchsia.modular",
+ "fuchsia.sys"
+ ],
+ "headers": [
+ "pkg/modular_cpp/include/lib/modular/cpp/agent.h"
+ ],
+ "include_dir": "pkg/modular_cpp/include",
+ "name": "modular_cpp",
+ "root": "pkg/modular_cpp",
+ "sources": [
+ "pkg/modular_cpp/agent.cc"
+ ],
+ "type": "cc_source_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/modular_testing_cpp/BUILD.gn b/third_party/fuchsia-sdk/pkg/modular_testing_cpp/BUILD.gn
new file mode 100644
index 0000000..8ab93c7
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/modular_testing_cpp/BUILD.gn
@@ -0,0 +1,37 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("modular_testing_cpp") {
+ sources = [
+ "fake_agent.cc",
+ "fake_component.cc",
+ "test_harness_builder.cc",
+ "test_harness_launcher.cc",
+ "include/lib/modular/testing/cpp/fake_agent.h",
+ "include/lib/modular/testing/cpp/fake_component.h",
+ "include/lib/modular/testing/cpp/test_harness_builder.h",
+ "include/lib/modular/testing/cpp/test_harness_launcher.h",
+ ]
+ include_dirs = [ "include" ]
+ public_deps = [
+ "../../fidl/fuchsia.modular",
+ "../../fidl/fuchsia.modular.testing",
+ "../async-loop-cpp",
+ "../async-loop-default",
+ "../modular_cpp",
+ "../sys_cpp",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":modular_testing_cpp",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/modular_testing_cpp/fake_agent.cc b/third_party/fuchsia-sdk/pkg/modular_testing_cpp/fake_agent.cc
new file mode 100644
index 0000000..18d26a3
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/modular_testing_cpp/fake_agent.cc
@@ -0,0 +1,50 @@
+// 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.
+
+#include <lib/modular/testing/cpp/fake_agent.h>
+
+namespace modular_testing {
+
+FakeAgent::FakeAgent(FakeComponent::Args args) : FakeComponent(std::move(args)) {}
+
+FakeAgent::~FakeAgent() = default;
+
+// static
+std::unique_ptr<FakeAgent> FakeAgent::CreateWithDefaultOptions() {
+ return std::make_unique<FakeAgent>(modular_testing::FakeComponent::Args{
+ .url = modular_testing::TestHarnessBuilder::GenerateFakeUrl(),
+ .sandbox_services = FakeAgent::GetDefaultSandboxServices()});
+}
+
+// static
+std::vector<std::string> FakeAgent::GetDefaultSandboxServices() {
+ return {fuchsia::modular::ComponentContext::Name_, fuchsia::modular::AgentContext::Name_};
+}
+
+// |modular_testing::FakeComponent|
+void FakeAgent::OnCreate(fuchsia::sys::StartupInfo startup_info) {
+ FakeComponent::OnCreate(std::move(startup_info));
+
+ component_context()->svc()->Connect(modular_component_context_.NewRequest());
+ component_context()->svc()->Connect(agent_context_.NewRequest());
+
+ agent_ = std::make_unique<modular::Agent>(component_context()->outgoing(),
+ /* on_terminate */
+ [this] {
+ Exit(0);
+ // |OnDestroy| is invoked at this point.
+ });
+ FlushAddAgentServiceIfRunning();
+}
+
+void FakeAgent::FlushAddAgentServiceIfRunning() {
+ if (is_running()) {
+ for (auto& call : buffered_add_agent_service_calls_) {
+ call();
+ }
+ buffered_add_agent_service_calls_.clear();
+ }
+}
+
+} // namespace modular_testing
diff --git a/third_party/fuchsia-sdk/pkg/modular_testing_cpp/fake_component.cc b/third_party/fuchsia-sdk/pkg/modular_testing_cpp/fake_component.cc
new file mode 100644
index 0000000..beeae45
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/modular_testing_cpp/fake_component.cc
@@ -0,0 +1,76 @@
+// 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.
+
+#include <lib/modular/testing/cpp/fake_component.h>
+
+namespace modular_testing {
+namespace {
+constexpr char kServiceRootPath[] = "/svc";
+
+std::unique_ptr<sys::ComponentContext> CreateComponentContext(
+ fuchsia::sys::StartupInfo* startup_info, async_dispatcher_t* dispatcher) {
+ fuchsia::sys::FlatNamespace& flat = startup_info->flat_namespace;
+ if (flat.paths.size() != flat.directories.size()) {
+ return nullptr;
+ }
+
+ zx::channel service_root;
+ for (size_t i = 0; i < flat.paths.size(); ++i) {
+ if (flat.paths.at(i) == kServiceRootPath) {
+ service_root = std::move(flat.directories.at(i));
+ break;
+ }
+ }
+
+ return std::make_unique<sys::ComponentContext>(
+ std::make_unique<sys::ServiceDirectory>(std::move(service_root)),
+ std::move(startup_info->launch_info.directory_request), dispatcher);
+}
+} // namespace
+
+FakeComponent::FakeComponent(Args args) : args_(std::move(args)) {}
+FakeComponent::~FakeComponent() = default;
+
+modular_testing::TestHarnessBuilder::InterceptOptions FakeComponent::BuildInterceptOptions(
+ async_dispatcher_t* dispatcher) {
+ modular_testing::TestHarnessBuilder::InterceptOptions options;
+ options.url = args_.url;
+ options.sandbox_services = args_.sandbox_services;
+ options.launch_handler =
+ [this, dispatcher](fuchsia::sys::StartupInfo startup_info,
+ fidl::InterfaceHandle<fuchsia::modular::testing::InterceptedComponent>
+ intercepted_component) {
+ intercepted_component_ptr_.Bind(std::move(intercepted_component), dispatcher);
+ intercepted_component_ptr_.events().OnKill = [this] {
+ component_context_.reset();
+ OnDestroy();
+ };
+
+ component_context_ = CreateComponentContext(&startup_info, dispatcher);
+ component_context_->outgoing()->AddPublicService(
+ lifecycle_bindings_.GetHandler(this, dispatcher));
+
+ OnCreate(std::move(startup_info));
+ };
+
+ return options;
+}
+
+std::string FakeComponent::url() const { return args_.url; }
+bool FakeComponent::is_running() const { return !!component_context_; }
+
+sys::ComponentContext* FakeComponent::component_context() { return component_context_.get(); }
+const sys::ComponentContext* FakeComponent::component_context() const {
+ return component_context_.get();
+}
+
+void FakeComponent::Exit(int64_t exit_code, fuchsia::sys::TerminationReason reason) {
+ if (intercepted_component_ptr_) {
+ intercepted_component_ptr_->Exit(exit_code, reason);
+ }
+}
+
+void FakeComponent::Terminate() { Exit(0); }
+
+} // namespace modular_testing
diff --git a/third_party/fuchsia-sdk/pkg/modular_testing_cpp/include/lib/modular/testing/cpp/fake_agent.h b/third_party/fuchsia-sdk/pkg/modular_testing_cpp/include/lib/modular/testing/cpp/fake_agent.h
new file mode 100644
index 0000000..27e5810
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/modular_testing_cpp/include/lib/modular/testing/cpp/fake_agent.h
@@ -0,0 +1,96 @@
+// 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.
+
+#ifndef LIB_MODULAR_TESTING_CPP_FAKE_AGENT_H_
+#define LIB_MODULAR_TESTING_CPP_FAKE_AGENT_H_
+
+#include <fuchsia/modular/cpp/fidl.h>
+#include <fuchsia/modular/testing/cpp/fidl.h>
+#include <lib/modular/cpp/agent.h>
+#include <lib/modular/testing/cpp/fake_component.h>
+
+namespace modular_testing {
+
+// FakeAgent is a utility class for intercepting Agent components. This class is designed to be used
+// alongside modular_testing::TestHarnessBuilder::InterceptComponent(). Clients may instantiate this
+// class directly, or sub-class and override OnCreate() and OnDestroy().
+//
+// USAGE:
+// ======
+// * Pass BuildInterceptOptions() to TestHarnessBuilder::InterceptComponent() to route the
+// component's launch to this instance.
+// * Use is_running() to determine if the agent is running.
+// * Use AddAgentService<>() to publish agent services.
+// * Use component_context() to connect to incoming services, and add public services.
+//
+// EXAMPLE:
+// ========
+// ..
+// modular_testing::TestHarnessBuilder builder;
+// auto fake_agent = modular_testing::FakeAgent::CreateWithDefaultOptions();
+// builder.InterceptComponent(fake_agent.BuildInterceptOptions());
+// builder.BuildAndRun(test_harness());
+// ..
+class FakeAgent : public FakeComponent {
+ public:
+ FakeAgent() = delete;
+ explicit FakeAgent(FakeComponent::Args args);
+
+ FakeAgent(const FakeAgent&) = delete;
+ FakeAgent(FakeAgent&&) = delete;
+ void operator=(const FakeAgent&) = delete;
+ void operator=(FakeAgent&&) = delete;
+
+ ~FakeAgent() override;
+
+ // Instantiates a FakeAgent with a randomly generated URL, default sandbox services (see
+ // GetDefaultSandboxServices()).
+ static std::unique_ptr<FakeAgent> CreateWithDefaultOptions();
+
+ // Returns the default list of services (capabilities) an agent expects in its namespace.
+ // This method is useful when setting up an agent for interception.
+ //
+ // Default services:
+ // * fuchsia.modular.ComponentContext
+ // * fuchsia.modular.AgentContext
+ static std::vector<std::string> GetDefaultSandboxServices();
+
+ // Returns the agent's |fuchsia::modular::ComponentContext|.
+ fuchsia::modular::ComponentContext* modular_component_context() {
+ return modular_component_context_.get();
+ }
+
+ // Returns the agent's |fuchsia::modular::AgentContext|.
+ fuchsia::modular::AgentContext* agent_context() { return agent_context_.get(); }
+
+ // Adds a service to the service namespace which is exposed to clients
+ // connecting to the agent.
+ template <typename Interface>
+ void AddAgentService(fidl::InterfaceRequestHandler<Interface> handler) {
+ // Buffer the AddAgentService calls until the agent is actually launched.
+ buffered_add_agent_service_calls_.push_back([this, handler = std::move(handler)]() mutable {
+ agent_->AddService<Interface>(std::move(handler));
+ });
+
+ FlushAddAgentServiceIfRunning();
+ }
+
+ private:
+ // |FakeComponent|
+ void OnCreate(fuchsia::sys::StartupInfo startup_info) override;
+
+ // Process the pending AddAgentService() calls which were buffered until is_running() == true.
+ void FlushAddAgentServiceIfRunning();
+
+ fuchsia::modular::ComponentContextPtr modular_component_context_;
+ fuchsia::modular::AgentContextPtr agent_context_;
+
+ std::vector<fit::closure> buffered_add_agent_service_calls_;
+
+ std::unique_ptr<modular::Agent> agent_;
+};
+
+} // namespace modular_testing
+
+#endif // LIB_MODULAR_TESTING_CPP_FAKE_AGENT_H_
diff --git a/third_party/fuchsia-sdk/pkg/modular_testing_cpp/include/lib/modular/testing/cpp/fake_component.h b/third_party/fuchsia-sdk/pkg/modular_testing_cpp/include/lib/modular/testing/cpp/fake_component.h
new file mode 100644
index 0000000..569cb72
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/modular_testing_cpp/include/lib/modular/testing/cpp/fake_component.h
@@ -0,0 +1,121 @@
+// 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.
+
+#ifndef LIB_MODULAR_TESTING_CPP_FAKE_COMPONENT_H_
+#define LIB_MODULAR_TESTING_CPP_FAKE_COMPONENT_H_
+
+#include <lib/fidl/cpp/binding_set.h>
+#include <lib/modular/testing/cpp/test_harness_builder.h>
+#include <lib/sys/cpp/component_context.h>
+
+namespace modular_testing {
+
+// FakeComponent is a utility class for intercepting modular components. This class is
+// designed to be used alongside the modular_testing::TestHarnessBuilder::Intercept*() methods.
+// Clients may instantiate this class directly, or sub-class and override OnCreate() and
+// OnDestroy().
+//
+// See |modular_testing::FakeAgent| for intercepting a modular Agent.
+//
+// USAGE:
+// ======
+// * Pass BuildInterceptOptions() to TestHarnessBuilder::InterceptComponent() to route the
+// component's launch to this instance.
+// * Use is_running() to determine if the component is running.
+// * Use component_context() to connect to incoming services, and add public services.
+//
+// EXAMPLE:
+// ========
+// ..
+// modular_testing::TestHarnessBuilder builder;
+// modular_testing::FakeComponent fake_component(
+// {.url = modular_testing::TestHarnessBuilder::GenerateFakeUrl()});
+// builder.InterceptComponent(fake_component.BuildInterceptOptions());
+// builder.BuildAndRun(test_harness());
+// ..
+class FakeComponent : fuchsia::modular::Lifecycle {
+ public:
+ struct Args {
+ // Required.
+ //
+ // The URL of this component.
+ std::string url;
+
+ // Optional.
+ std::vector<std::string> sandbox_services;
+ };
+
+ FakeComponent() = delete;
+ explicit FakeComponent(Args args);
+
+ FakeComponent(const FakeComponent&) = delete;
+ FakeComponent(FakeComponent&&) = delete;
+ void operator=(const FakeComponent&) = delete;
+ void operator=(FakeComponent&&) = delete;
+
+ ~FakeComponent() override;
+
+ // Constructs an InterceptOptions struct using the FakeComponent::Args supplied to this instance.
+ //
+ // The constructed launch handler takes care of triggering OnCreate() on launch, OnDestroy() on
+ // destruction.
+ //
+ // |dispatcher| is used for serving the component's outgoing directory and dispatching
+ // |OnDestroy()|. A value of |nullptr| will use the current thread's dispatcher.
+ modular_testing::TestHarnessBuilder::InterceptOptions BuildInterceptOptions(
+ async_dispatcher_t* dispatcher = nullptr);
+
+ // Returns the URL assigned to this component; see |Args::url|.
+ std::string url() const;
+
+ // Returns true if the component was launched by the component manager and
+ // has not yet been destroyed.
+ bool is_running() const;
+
+ // Returns the ComponentContext for the running component.
+ //
+ // Requires: is_running()
+ sys::ComponentContext* component_context();
+ const sys::ComponentContext* component_context() const;
+
+ // Instructs the component manager that this component is exiting. See
+ // documentation for fuchsia.sys.TerminationReason for more details.
+ //
+ // Requires: is_running()
+ void Exit(int64_t exit_code,
+ fuchsia::sys::TerminationReason reason = fuchsia::sys::TerminationReason::EXITED);
+
+ protected:
+ // Called when the component is created. The directory handles for "/svc" in
+ // |startup_info.flat_namespace| and that for
+ // |startup_info.launch_info.directory_request| will be invalid: they are
+ // both consumed in the construction of |component_context_|.
+ //
+ // Clients may override this to be notified of create as well as to consume
+ // remaining |startup_info.flat_namespace| entries.
+ virtual void OnCreate(fuchsia::sys::StartupInfo startup_info) {}
+
+ // Called when |intercepted_componet_ptr_|'s OnKill event is dispatched.
+ //
+ // Clients may override this to be notifed of component destruction.
+ virtual void OnDestroy() {}
+
+ // Called when this component receives a fuchsia.modular.Lifecycle/Terminate(). This object will
+ // |Exit()| when Terminate() is received.
+ //
+ // |fuchsia::modular::Lifecycle|
+ void Terminate() override;
+
+ private:
+ Args args_;
+
+ fuchsia::modular::testing::InterceptedComponentPtr intercepted_component_ptr_;
+ std::unique_ptr<sys::ComponentContext> component_context_;
+
+ fidl::BindingSet<fuchsia::modular::Lifecycle> lifecycle_bindings_;
+};
+
+} // namespace modular_testing
+
+#endif // LIB_MODULAR_TESTING_CPP_FAKE_COMPONENT_H_
diff --git a/third_party/fuchsia-sdk/pkg/modular_testing_cpp/include/lib/modular/testing/cpp/test_harness_builder.h b/third_party/fuchsia-sdk/pkg/modular_testing_cpp/include/lib/modular/testing/cpp/test_harness_builder.h
new file mode 100644
index 0000000..a4b2cb3
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/modular_testing_cpp/include/lib/modular/testing/cpp/test_harness_builder.h
@@ -0,0 +1,199 @@
+// 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.
+
+#ifndef LIB_MODULAR_TESTING_CPP_TEST_HARNESS_BUILDER_H_
+#define LIB_MODULAR_TESTING_CPP_TEST_HARNESS_BUILDER_H_
+
+#include <fuchsia/modular/testing/cpp/fidl.h>
+#include <lib/sys/cpp/service_directory.h>
+#include <lib/vfs/cpp/pseudo_dir.h>
+#include <lib/vfs/cpp/service.h>
+
+namespace modular_testing {
+
+// TestHarnessBuilder is a utility for building a
+// |fuchsia.modular.testing.TestHarnessSpec|. This utility provides methods for
+// hosting environment services and routing intercepted components.
+//
+//
+// SAMPLE USAGE:
+//
+// #include <lib/modular/testing/cpp/fake_component.h>
+// #include <lib/modular/testing/cpp/test_harness_builder.h>
+// #include <lib/modular/testing/cpp/test_harness_launcher.h>
+//
+// class MyTest : gtest::RealLoopFixture {};
+//
+// TEST_F(MyTest, TestOne) {
+// modular_testing::TestHarnessLauncher test_harness_launcher;
+// modular_testing::TestHarnessBuilder builder;
+//
+// // Instruct the test harness to intercept the launch of a new component
+// // within the test harness environment. Specify that the component should
+// // include foo.Service within its component manifest.
+// modular_testing::FakeComponent component(
+// {.url = modular_testing::TestHarnessBuilder::GenerateFakeUrl(),
+// .sandbox_services = {"foo.Service"}});
+// builder.InterceptComponent(component.BuildInterceptOptions());
+//
+// // Start an instance of the modular runtime in the test harness
+// // environment. As soon as |component_url| is created in
+// // this environment |component.on_create| is triggered.
+// builder.BuildAndRun(test_harness_launcher.test_harness());
+//
+// // ... do something that would cause |component_url| to be created ...
+// RunLoopUntil([&] { return component.is_running(); });
+//
+// foo::ServicePtr service_ptr;
+// component.component_context()->svc()->Connect(service_ptr.NewRequest());
+//
+// // ...
+// }
+class TestHarnessBuilder final {
+ public:
+ using LaunchHandler =
+ fit::function<void(fuchsia::sys::StartupInfo startup_info,
+ fidl::InterfaceHandle<fuchsia::modular::testing::InterceptedComponent>
+ intercepted_component)>;
+
+ struct InterceptOptions {
+ // The URL of the component to intercept. Use GenerateFakeUrl() to create a
+ // random valid URL.
+ //
+ // Required: Must not be empty.
+ std::string url;
+
+ // A list of service names to populate the component's manifest
+ // sandbox.services JSON property
+ //
+ // Optional.
+ std::vector<std::string> sandbox_services;
+
+ // Called when this component is launched.
+ //
+ // Required.
+ LaunchHandler launch_handler;
+ };
+
+ // Builds on top of an empty |fuchsia.modular.testing.TestHarnessSpec|.
+ TestHarnessBuilder();
+ // Builds on top of the supplied |spec|.
+ explicit TestHarnessBuilder(fuchsia::modular::testing::TestHarnessSpec spec);
+
+ // Movable.
+ TestHarnessBuilder(TestHarnessBuilder&&) = default;
+ TestHarnessBuilder& operator=(TestHarnessBuilder&&) = default;
+ // Not copyable.
+ TestHarnessBuilder(const TestHarnessBuilder&) = delete;
+ TestHarnessBuilder& operator=(const TestHarnessBuilder&) = delete;
+
+ // Builds the underlying TestHarnessSpec and issues a |TestHarness/Run()|.
+ // Binds an OnNewComponent event handler to the supplied |test_harness| to
+ // route the Intercept*() calls issued below.
+ //
+ // Can only be called once.
+ void BuildAndRun(const fuchsia::modular::testing::TestHarnessPtr& test_harness);
+
+ // Amends the TestHarnessSpec to include interception instructions specified by
+ // |options|.
+ TestHarnessBuilder& InterceptComponent(InterceptOptions options);
+
+ // Convenience variant of InterceptComponent() which sets the base shell URL
+ // in the ModularConfig to |options.url|.
+ TestHarnessBuilder& InterceptBaseShell(InterceptOptions options);
+
+ // DEPRECATED. Please use the variant above.
+ [[deprecated]] TestHarnessBuilder& InterceptBaseShell(LaunchHandler, InterceptOptions options);
+
+ // Convenience variant of InterceptComponent() which adds a session shell URL
+ // to the ModularConfig for |options.url|.
+ TestHarnessBuilder& InterceptSessionShell(InterceptOptions options);
+
+ // Convenience variant of InterceptComponent() which sets the story shell URL
+ // in the ModularConfig to |options.url|.
+ TestHarnessBuilder& InterceptStoryShell(InterceptOptions options);
+
+ // Make a service named |service_name| available in the test harness
+ // environment. |connector| is called every time a client requests to
+ // establish a new connection. This service is hosted for as long as this
+ // TestHarnessBuilder object is kept alive.
+ TestHarnessBuilder& AddService(const std::string& service_name,
+ vfs::Service::Connector connector);
+
+ // Make the templated |Interface| service available in the test harness
+ // environment. |request_handler| is called every time a client requests to
+ // establish a new connection. This service is hosted for as long as this
+ // TestHarnessBuilder object is kept alive.
+ template <typename Interface>
+ TestHarnessBuilder& AddService(fidl::InterfaceRequestHandler<Interface> request_handler) {
+ return AddService(Interface::Name_,
+ [request_handler = std::move(request_handler)](
+ zx::channel request, async_dispatcher_t* dispatcher) mutable {
+ request_handler(fidl::InterfaceRequest<Interface>(std::move(request)));
+ });
+ }
+
+ // Make the specified |service_name| available in the test harness
+ // environment. The service is provided by |component_url|, which is
+ // launched and kept alive for the duration of the test harness environment.
+ // See |TestHarnessSpec.env_services.services_from_components| for more
+ // details.
+ TestHarnessBuilder& AddServiceFromComponent(const std::string& service_name,
+ const std::string& component_url);
+
+ // Make the templated service available in the test harness environment.
+ // The service is provided by the given |component_url|, which is launched and
+ // kept alive for the duration of the test harness environment. See
+ // |TestHarnessSpec.env_services.services_from_components| for more details.
+ template <typename Interface>
+ TestHarnessBuilder& AddServiceFromComponent(const std::string& component_url) {
+ return AddServiceFromComponent(Interface::Name_, component_url);
+ }
+
+ // Make the specified |service_name| from |services| available in the test
+ // harness environment. |services| and the service are both kept alive for the
+ // duration of this builder object's life time.
+ TestHarnessBuilder& AddServiceFromServiceDirectory(
+ const std::string& service_name, std::shared_ptr<sys::ServiceDirectory> services);
+
+ // Make the templated service from |services| available in the test
+ // harness environment. |services| and the service are both kept alive for the
+ // duration of this builder object's life time.
+ template <typename Interface>
+ TestHarnessBuilder& AddServiceFromServiceDirectory(
+ std::shared_ptr<sys::ServiceDirectory> services) {
+ return AddServiceFromServiceDirectory(Interface::Name_, std::move(services));
+ }
+
+ // Returns a generated fake URL. Subsequent calls to this method will generate
+ // a different URL. If |name| is provided, adds its contents to the component
+ // name. Non alpha-num characters (a-zA-Z0-9) are stripped.
+ static std::string GenerateFakeUrl(std::string name = "");
+
+ private:
+ // Takes the TestHarnessSpec built so far with the builder functions below.
+ //
+ // Can only be called once.
+ fuchsia::modular::testing::TestHarnessSpec BuildSpec();
+
+ // Builds a router function which routes calls to the various handlers
+ // provided to Intercept*() variants. Intended to be used as the handler for
+ // TestHarness.events.OnNewComponent
+ //
+ // Can only be called once.
+ LaunchHandler BuildOnNewComponentHandler();
+
+ fuchsia::modular::testing::TestHarnessSpec spec_;
+
+ // Map from url to handler to be called when that url's component
+ // is created and intercepted.
+ std::map<std::string, LaunchHandler> handlers_;
+
+ // Hosts services injected using AddService() and InheritService().
+ std::unique_ptr<vfs::PseudoDir> env_services_;
+};
+
+} // namespace modular_testing
+
+#endif // LIB_MODULAR_TESTING_CPP_TEST_HARNESS_BUILDER_H_
diff --git a/third_party/fuchsia-sdk/pkg/modular_testing_cpp/include/lib/modular/testing/cpp/test_harness_launcher.h b/third_party/fuchsia-sdk/pkg/modular_testing_cpp/include/lib/modular/testing/cpp/test_harness_launcher.h
new file mode 100644
index 0000000..bd13d86
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/modular_testing_cpp/include/lib/modular/testing/cpp/test_harness_launcher.h
@@ -0,0 +1,50 @@
+// 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.
+
+#ifndef LIB_MODULAR_TESTING_CPP_TEST_HARNESS_LAUNCHER_H_
+#define LIB_MODULAR_TESTING_CPP_TEST_HARNESS_LAUNCHER_H_
+
+#include <fuchsia/modular/testing/cpp/fidl.h>
+#include <fuchsia/sys/cpp/fidl.h>
+#include <lib/async-loop/cpp/loop.h>
+#include <lib/async-loop/default.h>
+#include <lib/sys/cpp/service_directory.h>
+
+namespace modular_testing {
+
+// TestHarnessLauncher launches and manages an instance of the modular test
+// harness component. Use this class to acquire an instance of the
+// |fuchsia.modular.TestHarness| service.
+class TestHarnessLauncher final {
+ public:
+ // Launches the modular test harness component.
+ explicit TestHarnessLauncher(fuchsia::sys::LauncherPtr launcher);
+
+ // Blocks the current thread until the modular test harness component is
+ // destroyed.
+ ~TestHarnessLauncher();
+
+ // Not copyable.
+ TestHarnessLauncher(const TestHarnessLauncher&) = delete;
+ TestHarnessLauncher& operator=(const TestHarnessLauncher&) = delete;
+
+ fuchsia::modular::testing::TestHarnessPtr& test_harness() { return test_harness_; }
+
+ private:
+ // This async loop is launched in a separate thread, and hosts |test_harness_ctrl_|. When
+ // |test_harness_ctrl_| is closed, this loop exits and unblocks the destructor.
+ async::Loop test_harness_loop_;
+
+ std::shared_ptr<sys::ServiceDirectory> test_harness_svc_;
+
+ fuchsia::sys::ComponentControllerPtr
+ test_harness_ctrl_; // Bound to |test_harness_loop_|'s dispatcher.
+
+ fuchsia::modular::testing::TestHarnessPtr test_harness_;
+ fuchsia::modular::LifecyclePtr lifecycle_;
+};
+
+} // namespace modular_testing
+
+#endif // LIB_MODULAR_TESTING_CPP_TEST_HARNESS_LAUNCHER_H_
diff --git a/third_party/fuchsia-sdk/pkg/modular_testing_cpp/meta.json b/third_party/fuchsia-sdk/pkg/modular_testing_cpp/meta.json
new file mode 100644
index 0000000..5e5d0f1
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/modular_testing_cpp/meta.json
@@ -0,0 +1,29 @@
+{
+ "banjo_deps": [],
+ "deps": [
+ "modular_cpp",
+ "sys_cpp",
+ "async-loop-cpp",
+ "async-loop-default"
+ ],
+ "fidl_deps": [
+ "fuchsia.modular",
+ "fuchsia.modular.testing"
+ ],
+ "headers": [
+ "pkg/modular_testing_cpp/include/lib/modular/testing/cpp/fake_agent.h",
+ "pkg/modular_testing_cpp/include/lib/modular/testing/cpp/fake_component.h",
+ "pkg/modular_testing_cpp/include/lib/modular/testing/cpp/test_harness_builder.h",
+ "pkg/modular_testing_cpp/include/lib/modular/testing/cpp/test_harness_launcher.h"
+ ],
+ "include_dir": "pkg/modular_testing_cpp/include",
+ "name": "modular_testing_cpp",
+ "root": "pkg/modular_testing_cpp",
+ "sources": [
+ "pkg/modular_testing_cpp/fake_agent.cc",
+ "pkg/modular_testing_cpp/fake_component.cc",
+ "pkg/modular_testing_cpp/test_harness_builder.cc",
+ "pkg/modular_testing_cpp/test_harness_launcher.cc"
+ ],
+ "type": "cc_source_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/modular_testing_cpp/test_harness_builder.cc b/third_party/fuchsia-sdk/pkg/modular_testing_cpp/test_harness_builder.cc
new file mode 100644
index 0000000..ad09c3d
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/modular_testing_cpp/test_harness_builder.cc
@@ -0,0 +1,186 @@
+// 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.
+
+#include <lib/modular/testing/cpp/test_harness_builder.h>
+
+#include <sstream>
+
+namespace modular_testing {
+namespace {
+
+std::string StringsToCSV(const std::vector<std::string>& strings) {
+ std::stringstream csv;
+ for (size_t i = 0; i < strings.size(); i++) {
+ if (i != 0) {
+ csv << ",";
+ }
+ csv << "\"" << strings[i] << "\"";
+ }
+ return csv.str();
+}
+
+std::string BuildExtraCmx(const TestHarnessBuilder::InterceptOptions& options) {
+ std::stringstream ss;
+ ss << R"({
+ "sandbox": {
+ "services": [
+ )";
+ ss << StringsToCSV(options.sandbox_services);
+ ss << R"(
+ ]
+ }
+ })";
+ return ss.str();
+}
+
+bool BufferFromString(std::string str, fuchsia::mem::Buffer* buffer) {
+ ZX_ASSERT(buffer != nullptr);
+ uint64_t num_bytes = str.size();
+ zx::vmo vmo;
+ zx_status_t status = zx::vmo::create(num_bytes, 0u, &vmo);
+ if (status < 0) {
+ return false;
+ }
+
+ if (num_bytes > 0) {
+ status = vmo.write(str.data(), 0, num_bytes);
+ if (status < 0) {
+ return false;
+ }
+ }
+
+ buffer->vmo = std::move(vmo);
+ buffer->size = num_bytes;
+ return true;
+}
+
+} // namespace
+
+TestHarnessBuilder::TestHarnessBuilder(fuchsia::modular::testing::TestHarnessSpec spec)
+ : spec_(std::move(spec)), env_services_(new vfs::PseudoDir) {}
+
+TestHarnessBuilder::TestHarnessBuilder()
+ : TestHarnessBuilder(fuchsia::modular::testing::TestHarnessSpec()) {}
+
+fuchsia::modular::testing::TestHarnessSpec TestHarnessBuilder::BuildSpec() {
+ fuchsia::io::DirectoryPtr dir;
+ // This directory must be READABLE *and* WRITABLE, otherwise service
+ // connections fail.
+ env_services_->Serve(fuchsia::io::OPEN_RIGHT_READABLE | fuchsia::io::OPEN_RIGHT_WRITABLE,
+ dir.NewRequest().TakeChannel());
+ spec_.mutable_env_services()->set_service_dir(dir.Unbind().TakeChannel());
+ return std::move(spec_);
+}
+
+TestHarnessBuilder::LaunchHandler TestHarnessBuilder::BuildOnNewComponentHandler() {
+ return [handlers = std::move(handlers_)](
+ fuchsia::sys::StartupInfo startup_info,
+ fidl::InterfaceHandle<fuchsia::modular::testing::InterceptedComponent> component) {
+ auto it = handlers.find(startup_info.launch_info.url);
+ if (it == handlers.end()) {
+ ZX_ASSERT_MSG(false, "Unexpected component URL: %s", startup_info.launch_info.url.c_str());
+ }
+
+ it->second(std::move(startup_info), component.Bind());
+ };
+}
+
+void TestHarnessBuilder::BuildAndRun(
+ const fuchsia::modular::testing::TestHarnessPtr& test_harness) {
+ test_harness.events().OnNewComponent = BuildOnNewComponentHandler();
+ test_harness->Run(BuildSpec());
+}
+
+TestHarnessBuilder& TestHarnessBuilder::InterceptComponent(InterceptOptions options) {
+ ZX_ASSERT(options.launch_handler);
+ ZX_ASSERT(!options.url.empty());
+
+ fuchsia::modular::testing::InterceptSpec intercept_spec;
+ intercept_spec.set_component_url(options.url);
+ auto extra_cmx_contents = BuildExtraCmx(options);
+ if (!extra_cmx_contents.empty()) {
+ ZX_ASSERT(BufferFromString(extra_cmx_contents, intercept_spec.mutable_extra_cmx_contents()));
+ }
+ spec_.mutable_components_to_intercept()->push_back(std::move(intercept_spec));
+
+ handlers_.insert(std::make_pair(options.url, std::move(options.launch_handler)));
+ return *this;
+}
+
+TestHarnessBuilder& TestHarnessBuilder::InterceptBaseShell(InterceptOptions options) {
+ spec_.mutable_basemgr_config()->mutable_base_shell()->mutable_app_config()->set_url(options.url);
+ InterceptComponent(std::move(options));
+ return *this;
+}
+
+TestHarnessBuilder& TestHarnessBuilder::InterceptBaseShell(LaunchHandler handler,
+ InterceptOptions options) {
+ options.launch_handler = std::move(handler);
+ return InterceptBaseShell(std::move(options));
+}
+
+TestHarnessBuilder& TestHarnessBuilder::InterceptSessionShell(InterceptOptions options) {
+ fuchsia::modular::session::SessionShellMapEntry entry;
+ entry.mutable_config()->mutable_app_config()->set_url(options.url);
+ spec_.mutable_basemgr_config()->mutable_session_shell_map()->push_back(std::move(entry));
+ InterceptComponent(std::move(options));
+ return *this;
+}
+
+TestHarnessBuilder& TestHarnessBuilder::InterceptStoryShell(InterceptOptions options) {
+ spec_.mutable_basemgr_config()->mutable_story_shell()->mutable_app_config()->set_url(options.url);
+ InterceptComponent(std::move(options));
+ return *this;
+}
+
+TestHarnessBuilder& TestHarnessBuilder::AddService(const std::string& service_name,
+ vfs::Service::Connector connector) {
+ env_services_->AddEntry(service_name, std::make_unique<vfs::Service>(std::move(connector)));
+ return *this;
+}
+
+TestHarnessBuilder& TestHarnessBuilder::AddServiceFromComponent(const std::string& service_name,
+ const std::string& component_url) {
+ fuchsia::modular::testing::ComponentService svc;
+ svc.name = service_name;
+ svc.url = component_url;
+ spec_.mutable_env_services()->mutable_services_from_components()->push_back(std::move(svc));
+ return *this;
+}
+
+TestHarnessBuilder& TestHarnessBuilder::AddServiceFromServiceDirectory(
+ const std::string& service_name, std::shared_ptr<sys::ServiceDirectory> services) {
+ return AddService(service_name, [service_name, services](zx::channel request,
+ async_dispatcher_t* dispatcher) mutable {
+ services->Connect(service_name, std::move(request));
+ });
+}
+
+// static
+std::string TestHarnessBuilder::GenerateFakeUrl(std::string name) {
+ name.erase(std::remove_if(name.begin(), name.end(),
+ [](auto const& c) -> bool { return !std::isalnum(c); }),
+ name.end());
+
+ uint32_t random_number = 0;
+ zx_cprng_draw(&random_number, sizeof random_number);
+ std::string rand_str = std::to_string(random_number);
+
+ // Since we cannot depend on utlitites outside of the stdlib and SDK, here
+ // is a quick way to format a string safely.
+ std::string url;
+ url = "fuchsia-pkg://example.com/GENERATED_URL_";
+ url += rand_str;
+ url += "#meta/GENERATED_URL_";
+ if (!name.empty()) {
+ url += name;
+ url += "_";
+ }
+ url += rand_str;
+ url += ".cmx";
+
+ return url;
+}
+
+} // namespace modular_testing
diff --git a/third_party/fuchsia-sdk/pkg/modular_testing_cpp/test_harness_launcher.cc b/third_party/fuchsia-sdk/pkg/modular_testing_cpp/test_harness_launcher.cc
new file mode 100644
index 0000000..34ec3a6
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/modular_testing_cpp/test_harness_launcher.cc
@@ -0,0 +1,52 @@
+// 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.
+
+#include <lib/async/cpp/task.h>
+#include <lib/modular/testing/cpp/test_harness_launcher.h>
+
+namespace modular_testing {
+namespace {
+constexpr char kTestHarnessUrl[] =
+ "fuchsia-pkg://fuchsia.com/modular_test_harness#meta/"
+ "modular_test_harness.cmx";
+constexpr zx::duration kTerminateTimeout = zx::sec(10);
+} // namespace
+
+TestHarnessLauncher::TestHarnessLauncher(fuchsia::sys::LauncherPtr launcher)
+ : test_harness_loop_(&kAsyncLoopConfigNoAttachToCurrentThread) {
+ test_harness_loop_.StartThread();
+
+ fuchsia::sys::LaunchInfo launch_info;
+ launch_info.url = kTestHarnessUrl;
+ test_harness_svc_ = sys::ServiceDirectory::CreateWithRequest(&launch_info.directory_request);
+
+ // Bind |test_harness_ctrl_| to |test_harness_loop_|, so that its error handler is
+ // dispatched even while this thread is blocked in the destructor.
+ launcher->CreateComponent(std::move(launch_info),
+ test_harness_ctrl_.NewRequest(test_harness_loop_.dispatcher()));
+
+ test_harness_svc_->Connect(test_harness_.NewRequest());
+ test_harness_svc_->Connect(lifecycle_.NewRequest());
+
+ test_harness_ctrl_.set_error_handler([this](zx_status_t) { test_harness_loop_.Quit(); });
+}
+
+TestHarnessLauncher::~TestHarnessLauncher() {
+ if (lifecycle_) {
+ lifecycle_->Terminate();
+ // Upon Lifecycle/Terminate(), the modular test harness will ask basemgr to terminate, and
+ // force-kill it if it doesn't terminate after some time.
+
+ // In case |lifecycle_| is closed by the test harness component but the error handler hasn't
+ // been dispatched yet, we kick off a timer to kill the test harness component.
+ async::PostDelayedTask(
+ test_harness_loop_.dispatcher(), [this] { test_harness_ctrl_->Kill(); }, kTerminateTimeout);
+ } else {
+ async::PostTask(test_harness_loop_.dispatcher(), [this] { test_harness_ctrl_->Kill(); });
+ }
+
+ test_harness_loop_.JoinThreads();
+}
+
+} // namespace modular_testing
diff --git a/third_party/fuchsia-sdk/pkg/scenic_cpp/BUILD.gn b/third_party/fuchsia-sdk/pkg/scenic_cpp/BUILD.gn
new file mode 100644
index 0000000..340ad70
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/scenic_cpp/BUILD.gn
@@ -0,0 +1,45 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("scenic_cpp") {
+ sources = [
+ "commands.cc",
+ "commands_sizing.cc",
+ "resources.cc",
+ "session.cc",
+ "view_ref_pair.cc",
+ "view_token_pair.cc",
+ "include/lib/ui/scenic/cpp/commands.h",
+ "include/lib/ui/scenic/cpp/commands_sizing.h",
+ "include/lib/ui/scenic/cpp/id.h",
+ "include/lib/ui/scenic/cpp/resources.h",
+ "include/lib/ui/scenic/cpp/session.h",
+ "include/lib/ui/scenic/cpp/view_ref_pair.h",
+ "include/lib/ui/scenic/cpp/view_token_pair.h",
+ ]
+ include_dirs = [ "include" ]
+ public_deps = [
+ "../../fidl/fuchsia.images",
+ "../../fidl/fuchsia.ui.gfx",
+ "../../fidl/fuchsia.ui.scenic",
+ "../../fidl/fuchsia.ui.views",
+ "../fidl_cpp",
+ "../fit",
+ "../images_cpp",
+ "../syslog",
+ "../zx",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":scenic_cpp",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/scenic_cpp/commands.cc b/third_party/fuchsia-sdk/pkg/scenic_cpp/commands.cc
new file mode 100644
index 0000000..9a5870b
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/scenic_cpp/commands.cc
@@ -0,0 +1,1430 @@
+// Copyright 2017 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.
+
+#include <lib/ui/scenic/cpp/commands.h>
+#include <lib/ui/scenic/cpp/view_ref_pair.h>
+#include <zircon/assert.h>
+
+#include <array>
+#include <cstddef>
+
+namespace {
+
+template <size_t N, class T>
+std::array<T, N> ToStdArray(const T* c_arr) {
+ std::array<T, N> result;
+ std::copy(c_arr, c_arr + N, std::begin(result));
+ return result;
+}
+
+} // namespace
+
+namespace scenic {
+
+fuchsia::ui::scenic::Command NewCommand(fuchsia::ui::gfx::Command command) {
+ fuchsia::ui::scenic::Command scenic_command;
+ scenic_command.set_gfx(std::move(command));
+ return scenic_command;
+}
+
+fuchsia::ui::scenic::Command NewCommand(fuchsia::ui::input::Command command) {
+ fuchsia::ui::scenic::Command scenic_command;
+ scenic_command.set_input(std::move(command));
+ return scenic_command;
+}
+
+// Helper function for all resource creation functions.
+fuchsia::ui::gfx::Command NewCreateResourceCmd(uint32_t id,
+ fuchsia::ui::gfx::ResourceArgs resource) {
+ fuchsia::ui::gfx::CreateResourceCmd create_resource;
+ create_resource.id = id;
+ create_resource.resource = std::move(resource);
+
+ fuchsia::ui::gfx::Command command;
+ command.set_create_resource(std::move(create_resource));
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewCreateMemoryCmd(uint32_t id, zx::vmo vmo, uint64_t allocation_size,
+ fuchsia::images::MemoryType memory_type) {
+ fuchsia::ui::gfx::MemoryArgs memory;
+ memory.vmo = std::move(vmo);
+ memory.allocation_size = allocation_size;
+ memory.memory_type = memory_type;
+
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_memory(std::move(memory));
+
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewCreateImageCmd(uint32_t id, uint32_t memory_id, uint32_t memory_offset,
+ fuchsia::images::ImageInfo info) {
+ fuchsia::ui::gfx::ImageArgs image;
+ image.memory_id = memory_id;
+ image.memory_offset = memory_offset;
+ image.info = info;
+
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_image(image);
+
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewCreateImagePipeCmd(
+ uint32_t id, fidl::InterfaceRequest<fuchsia::images::ImagePipe> request) {
+ fuchsia::ui::gfx::ImagePipeArgs image_pipe;
+ image_pipe.image_pipe_request = std::move(request);
+
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_image_pipe(std::move(image_pipe));
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewCreateImagePipe2Cmd(
+ uint32_t id, fidl::InterfaceRequest<fuchsia::images::ImagePipe2> request) {
+ fuchsia::ui::gfx::ImagePipe2Args image_pipe;
+ image_pipe.image_pipe_request = std::move(request);
+
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_image_pipe2(std::move(image_pipe));
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewCreateImageCmd(uint32_t id, uint32_t memory_id, uint32_t memory_offset,
+ fuchsia::images::PixelFormat format,
+ fuchsia::images::ColorSpace color_space,
+ fuchsia::images::Tiling tiling, uint32_t width,
+ uint32_t height, uint32_t stride) {
+ fuchsia::images::ImageInfo info;
+ info.pixel_format = format;
+ info.color_space = color_space;
+ info.tiling = tiling;
+ info.width = width;
+ info.height = height;
+ info.stride = stride;
+ return NewCreateImageCmd(id, memory_id, memory_offset, info);
+}
+
+fuchsia::ui::gfx::Command NewCreateBufferCmd(uint32_t id, uint32_t memory_id,
+ uint32_t memory_offset, uint32_t num_bytes) {
+ fuchsia::ui::gfx::BufferArgs buffer;
+ buffer.memory_id = memory_id;
+ buffer.memory_offset = memory_offset;
+ buffer.num_bytes = num_bytes;
+
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_buffer(buffer);
+
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewCreateCompositorCmd(uint32_t id) {
+ fuchsia::ui::gfx::CompositorArgs compositor;
+
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_compositor(compositor);
+
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewCreateDisplayCompositorCmd(uint32_t id) {
+ fuchsia::ui::gfx::DisplayCompositorArgs display_compositor;
+
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_display_compositor(display_compositor);
+
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewCreateLayerStackCmd(uint32_t id) {
+ fuchsia::ui::gfx::LayerStackArgs layer_stack;
+
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_layer_stack(layer_stack);
+
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewCreateLayerCmd(uint32_t id) {
+ fuchsia::ui::gfx::LayerArgs layer;
+
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_layer(layer);
+
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewCreateSceneCmd(uint32_t id) {
+ fuchsia::ui::gfx::SceneArgs scene;
+
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_scene(scene);
+
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewCreateCameraCmd(uint32_t id, uint32_t scene_id) {
+ fuchsia::ui::gfx::CameraArgs camera;
+ camera.scene_id = scene_id;
+
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_camera(camera);
+
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewCreateStereoCameraCmd(uint32_t id, uint32_t scene_id) {
+ fuchsia::ui::gfx::StereoCameraArgs stereo_camera;
+ stereo_camera.scene_id = scene_id;
+
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_stereo_camera(stereo_camera);
+
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewCreateRendererCmd(uint32_t id) {
+ fuchsia::ui::gfx::RendererArgs renderer;
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_renderer(renderer);
+
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewCreateAmbientLightCmd(uint32_t id) {
+ fuchsia::ui::gfx::AmbientLightArgs ambient_light;
+
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_ambient_light(ambient_light);
+
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewCreateDirectionalLightCmd(uint32_t id) {
+ fuchsia::ui::gfx::DirectionalLightArgs directional_light;
+
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_directional_light(directional_light);
+
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewCreatePointLightCmd(uint32_t id) {
+ fuchsia::ui::gfx::PointLightArgs point_light;
+
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_point_light(point_light);
+
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewCreateCircleCmd(uint32_t id, float radius) {
+ fuchsia::ui::gfx::Value radius_value;
+ radius_value.set_vector1(radius);
+
+ fuchsia::ui::gfx::CircleArgs circle;
+ circle.radius = std::move(radius_value);
+
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_circle(std::move(circle));
+
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewCreateRectangleCmd(uint32_t id, float width, float height) {
+ fuchsia::ui::gfx::Value width_value;
+ width_value.set_vector1(width);
+
+ fuchsia::ui::gfx::Value height_value;
+ height_value.set_vector1(height);
+
+ fuchsia::ui::gfx::RectangleArgs rectangle;
+ rectangle.width = std::move(width_value);
+ rectangle.height = std::move(height_value);
+
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_rectangle(std::move(rectangle));
+
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewCreateRoundedRectangleCmd(uint32_t id, float width, float height,
+ float top_left_radius,
+ float top_right_radius,
+ float bottom_right_radius,
+ float bottom_left_radius) {
+ fuchsia::ui::gfx::Value width_value;
+ width_value.set_vector1(width);
+
+ fuchsia::ui::gfx::Value height_value;
+ height_value.set_vector1(height);
+
+ fuchsia::ui::gfx::Value top_left_radius_value;
+ top_left_radius_value.set_vector1(top_left_radius);
+
+ fuchsia::ui::gfx::Value top_right_radius_value;
+ top_right_radius_value.set_vector1(top_right_radius);
+
+ fuchsia::ui::gfx::Value bottom_right_radius_value;
+ bottom_right_radius_value.set_vector1(bottom_right_radius);
+
+ fuchsia::ui::gfx::Value bottom_left_radius_value;
+ bottom_left_radius_value.set_vector1(bottom_left_radius);
+
+ fuchsia::ui::gfx::RoundedRectangleArgs rectangle;
+ rectangle.width = std::move(width_value);
+ rectangle.height = std::move(height_value);
+ rectangle.top_left_radius = std::move(top_left_radius_value);
+ rectangle.top_right_radius = std::move(top_right_radius_value);
+ rectangle.bottom_right_radius = std::move(bottom_right_radius_value);
+ rectangle.bottom_left_radius = std::move(bottom_left_radius_value);
+
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_rounded_rectangle(std::move(rectangle));
+
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewCreateVarCircleCmd(uint32_t id, uint32_t radius_var_id) {
+ fuchsia::ui::gfx::Value radius_value;
+ radius_value.set_variable_id(radius_var_id);
+
+ fuchsia::ui::gfx::CircleArgs circle;
+ circle.radius = std::move(radius_value);
+
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_circle(std::move(circle));
+
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewCreateVarRectangleCmd(uint32_t id, uint32_t width_var_id,
+ uint32_t height_var_id) {
+ fuchsia::ui::gfx::Value width_value;
+ width_value.set_variable_id(width_var_id);
+
+ fuchsia::ui::gfx::Value height_value;
+ height_value.set_variable_id(height_var_id);
+
+ fuchsia::ui::gfx::RectangleArgs rectangle;
+ rectangle.width = std::move(width_value);
+ rectangle.height = std::move(height_value);
+
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_rectangle(std::move(rectangle));
+
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewCreateVarRoundedRectangleCmd(uint32_t id, uint32_t width_var_id,
+ uint32_t height_var_id,
+ uint32_t top_left_radius_var_id,
+ uint32_t top_right_radius_var_id,
+ uint32_t bottom_left_radius_var_id,
+ uint32_t bottom_right_radius_var_id) {
+ fuchsia::ui::gfx::Value width_value;
+ width_value.set_variable_id(width_var_id);
+
+ fuchsia::ui::gfx::Value height_value;
+ height_value.set_variable_id(height_var_id);
+
+ fuchsia::ui::gfx::Value top_left_radius_value;
+ top_left_radius_value.set_variable_id(top_left_radius_var_id);
+
+ fuchsia::ui::gfx::Value top_right_radius_value;
+ top_right_radius_value.set_variable_id(top_right_radius_var_id);
+
+ fuchsia::ui::gfx::Value bottom_left_radius_value;
+ bottom_left_radius_value.set_variable_id(bottom_left_radius_var_id);
+
+ fuchsia::ui::gfx::Value bottom_right_radius_value;
+ bottom_right_radius_value.set_variable_id(bottom_right_radius_var_id);
+
+ fuchsia::ui::gfx::RoundedRectangleArgs rectangle;
+ rectangle.width = std::move(width_value);
+ rectangle.height = std::move(height_value);
+ rectangle.top_left_radius = std::move(top_left_radius_value);
+ rectangle.top_right_radius = std::move(top_right_radius_value);
+ rectangle.bottom_left_radius = std::move(bottom_left_radius_value);
+ rectangle.bottom_right_radius = std::move(bottom_right_radius_value);
+
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_rounded_rectangle(std::move(rectangle));
+
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewCreateMeshCmd(uint32_t id) {
+ fuchsia::ui::gfx::MeshArgs mesh;
+
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_mesh(mesh);
+
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewCreateMaterialCmd(uint32_t id) {
+ fuchsia::ui::gfx::MaterialArgs material;
+
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_material(material);
+
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewCreateClipNodeCmd(uint32_t id) {
+ fuchsia::ui::gfx::ClipNodeArgs node;
+
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_clip_node(node);
+
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewCreateEntityNodeCmd(uint32_t id) {
+ fuchsia::ui::gfx::EntityNodeArgs node;
+
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_entity_node(node);
+
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewCreateOpacityNodeCmdHACK(uint32_t id) {
+ fuchsia::ui::gfx::OpacityNodeArgsHACK node;
+
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_opacity_node(node);
+
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewCreateShapeNodeCmd(uint32_t id) {
+ fuchsia::ui::gfx::ShapeNodeArgs node;
+
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_shape_node(node);
+
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewCreateViewCmd(uint32_t id, fuchsia::ui::views::ViewToken token,
+ const fit::optional<std::string>& debug_name) {
+ ZX_DEBUG_ASSERT(token.value);
+
+ scenic::ViewRefPair ref_pair = scenic::ViewRefPair::New();
+
+ fuchsia::ui::gfx::ViewArgs3 view;
+ view.token = std::move(token);
+ view.control_ref = std::move(ref_pair.control_ref);
+ view.view_ref = std::move(ref_pair.view_ref);
+ view.debug_name = debug_name ? fidl::StringPtr(*debug_name) : fit::nullopt;
+
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_view3(std::move(view));
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewCreateViewCmd(uint32_t id, fuchsia::ui::views::ViewToken token,
+ fuchsia::ui::views::ViewRefControl control_ref,
+ fuchsia::ui::views::ViewRef view_ref,
+ const fit::optional<std::string>& debug_name) {
+ ZX_DEBUG_ASSERT(token.value);
+
+ fuchsia::ui::gfx::ViewArgs3 view;
+ view.token = std::move(token);
+ view.control_ref = std::move(control_ref);
+ view.view_ref = std::move(view_ref);
+ view.debug_name = debug_name ? fidl::StringPtr(*debug_name) : fit::nullopt;
+
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_view3(std::move(view));
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewCreateViewHolderCmd(uint32_t id,
+ fuchsia::ui::views::ViewHolderToken token,
+ const fit::optional<std::string>& debug_name) {
+ ZX_DEBUG_ASSERT(token.value);
+
+ fuchsia::ui::gfx::ViewHolderArgs view_holder;
+ view_holder.token = std::move(token);
+ view_holder.debug_name = debug_name ? fidl::StringPtr(*debug_name) : fit::nullopt;
+
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_view_holder(std::move(view_holder));
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewCreateVariableCmd(uint32_t id, fuchsia::ui::gfx::Value value) {
+ fuchsia::ui::gfx::VariableArgs variable;
+ switch (value.Which()) {
+ case ::fuchsia::ui::gfx::Value::Tag::kVector1:
+ variable.type = fuchsia::ui::gfx::ValueType::kVector1;
+ break;
+ case ::fuchsia::ui::gfx::Value::Tag::kVector2:
+ variable.type = fuchsia::ui::gfx::ValueType::kVector2;
+ break;
+ case ::fuchsia::ui::gfx::Value::Tag::kVector3:
+ variable.type = fuchsia::ui::gfx::ValueType::kVector3;
+ break;
+ case ::fuchsia::ui::gfx::Value::Tag::kVector4:
+ variable.type = fuchsia::ui::gfx::ValueType::kVector4;
+ break;
+ case fuchsia::ui::gfx::Value::Tag::kMatrix4x4:
+ variable.type = fuchsia::ui::gfx::ValueType::kMatrix4;
+ break;
+ case fuchsia::ui::gfx::Value::Tag::kColorRgba:
+ variable.type = fuchsia::ui::gfx::ValueType::kColorRgba;
+ break;
+ case fuchsia::ui::gfx::Value::Tag::kColorRgb:
+ variable.type = fuchsia::ui::gfx::ValueType::kColorRgb;
+ break;
+ case fuchsia::ui::gfx::Value::Tag::kDegrees:
+ variable.type = fuchsia::ui::gfx::ValueType::kVector1;
+ break;
+ case fuchsia::ui::gfx::Value::Tag::kTransform:
+ variable.type = fuchsia::ui::gfx::ValueType::kFactoredTransform;
+ break;
+ case fuchsia::ui::gfx::Value::Tag::kQuaternion:
+ variable.type = fuchsia::ui::gfx::ValueType::kQuaternion;
+ break;
+ case fuchsia::ui::gfx::Value::Tag::kVariableId:
+ // A variable's initial value cannot be another variable.
+ // This is also an invalid case, thus fall through.
+ case fuchsia::ui::gfx::Value::Tag::Invalid:
+ return fuchsia::ui::gfx::Command();
+ }
+ variable.initial_value = std::move(value);
+
+ fuchsia::ui::gfx::ResourceArgs resource;
+ resource.set_variable(std::move(variable));
+
+ return NewCreateResourceCmd(id, std::move(resource));
+}
+
+fuchsia::ui::gfx::Command NewReleaseResourceCmd(uint32_t id) {
+ fuchsia::ui::gfx::ReleaseResourceCmd release_resource;
+ release_resource.id = id;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_release_resource(release_resource);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewExportResourceCmd(uint32_t resource_id, zx::eventpair export_token) {
+ ZX_DEBUG_ASSERT(export_token);
+
+ fuchsia::ui::gfx::ExportResourceCmdDeprecated export_resource;
+ export_resource.id = resource_id;
+ export_resource.token = std::move(export_token);
+
+ fuchsia::ui::gfx::Command command;
+ command.set_export_resource(std::move(export_resource));
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewImportResourceCmd(uint32_t resource_id,
+ fuchsia::ui::gfx::ImportSpec spec,
+ zx::eventpair import_token) {
+ ZX_DEBUG_ASSERT(import_token);
+
+ fuchsia::ui::gfx::ImportResourceCmdDeprecated import_resource;
+ import_resource.id = resource_id;
+ import_resource.token = std::move(import_token);
+ import_resource.spec = spec;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_import_resource(std::move(import_resource));
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewExportResourceCmdAsRequest(uint32_t resource_id,
+ zx::eventpair* out_import_token) {
+ ZX_DEBUG_ASSERT(out_import_token);
+ ZX_DEBUG_ASSERT(!*out_import_token);
+
+ zx::eventpair export_token;
+ zx_status_t status = zx::eventpair::create(0u, &export_token, out_import_token);
+ ZX_DEBUG_ASSERT_MSG(status == ZX_OK, "event pair create failed: status=%d", status);
+ return NewExportResourceCmd(resource_id, std::move(export_token));
+}
+
+fuchsia::ui::gfx::Command NewImportResourceCmdAsRequest(uint32_t resource_id,
+ fuchsia::ui::gfx::ImportSpec import_spec,
+ zx::eventpair* out_export_token) {
+ ZX_DEBUG_ASSERT(out_export_token);
+ ZX_DEBUG_ASSERT(!*out_export_token);
+
+ zx::eventpair import_token;
+ zx_status_t status = zx::eventpair::create(0u, &import_token, out_export_token);
+ ZX_DEBUG_ASSERT_MSG(status == ZX_OK, "event pair create failed: status=%d", status);
+ return NewImportResourceCmd(resource_id, import_spec, std::move(import_token));
+}
+
+fuchsia::ui::gfx::Command NewSetViewPropertiesCmd(uint32_t view_holder_id,
+ const std::array<float, 3>& bounding_box_min,
+ const std::array<float, 3>& bounding_box_max,
+ const std::array<float, 3>& inset_from_min,
+ const std::array<float, 3>& inset_from_max) {
+ fuchsia::ui::gfx::SetViewPropertiesCmd set_view_properties;
+ set_view_properties.view_holder_id = view_holder_id;
+ auto& props = set_view_properties.properties;
+ props.bounding_box.min = NewVector3(bounding_box_min);
+ props.bounding_box.max = NewVector3(bounding_box_max);
+ props.inset_from_min = NewVector3(inset_from_min);
+ props.inset_from_max = NewVector3(inset_from_max);
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_view_properties(set_view_properties);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetViewPropertiesCmd(uint32_t view_holder_id,
+ const fuchsia::ui::gfx::ViewProperties& props) {
+ fuchsia::ui::gfx::SetViewPropertiesCmd set_view_properties;
+ set_view_properties.view_holder_id = view_holder_id;
+ set_view_properties.properties = props;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_view_properties(set_view_properties);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewAddChildCmd(uint32_t node_id, uint32_t child_id) {
+ fuchsia::ui::gfx::AddChildCmd add_child;
+ add_child.node_id = node_id;
+ add_child.child_id = child_id;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_add_child(add_child);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewDetachCmd(uint32_t id) {
+ fuchsia::ui::gfx::DetachCmd detach;
+ detach.id = id;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_detach(detach);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewDetachChildrenCmd(uint32_t node_id) {
+ fuchsia::ui::gfx::DetachChildrenCmd detach_children;
+ detach_children.node_id = node_id;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_detach_children(detach_children);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetTranslationCmd(uint32_t node_id,
+ const std::array<float, 3>& translation) {
+ fuchsia::ui::gfx::SetTranslationCmd set_translation;
+ set_translation.id = node_id;
+ set_translation.value = NewVector3Value(translation);
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_translation(set_translation);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetTranslationCmd(uint32_t node_id, uint32_t variable_id) {
+ fuchsia::ui::gfx::SetTranslationCmd set_translation;
+ set_translation.id = node_id;
+ set_translation.value = NewVector3Value(variable_id);
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_translation(set_translation);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetScaleCmd(uint32_t node_id, const std::array<float, 3>& scale) {
+ fuchsia::ui::gfx::SetScaleCmd set_scale;
+ set_scale.id = node_id;
+ set_scale.value = NewVector3Value(scale);
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_scale(set_scale);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetScaleCmd(uint32_t node_id, uint32_t variable_id) {
+ fuchsia::ui::gfx::SetScaleCmd set_scale;
+ set_scale.id = node_id;
+ set_scale.value = NewVector3Value(variable_id);
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_scale(set_scale);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetRotationCmd(uint32_t node_id,
+ const std::array<float, 4>& quaternion) {
+ fuchsia::ui::gfx::SetRotationCmd set_rotation;
+ set_rotation.id = node_id;
+ set_rotation.value = NewQuaternionValue(quaternion);
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_rotation(set_rotation);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetRotationCmd(uint32_t node_id, uint32_t variable_id) {
+ fuchsia::ui::gfx::SetRotationCmd set_rotation;
+ set_rotation.id = node_id;
+ set_rotation.value = NewQuaternionValue(variable_id);
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_rotation(set_rotation);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetAnchorCmd(uint32_t node_id, const std::array<float, 3>& anchor) {
+ fuchsia::ui::gfx::SetAnchorCmd set_anchor;
+ set_anchor.id = node_id;
+ set_anchor.value = NewVector3Value(anchor);
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_anchor(set_anchor);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetAnchorCmd(uint32_t node_id, uint32_t variable_id) {
+ fuchsia::ui::gfx::SetAnchorCmd set_anchor;
+ set_anchor.id = node_id;
+ set_anchor.value = NewVector3Value(variable_id);
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_anchor(set_anchor);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetOpacityCmd(uint32_t node_id, float opacity) {
+ fuchsia::ui::gfx::SetOpacityCmd set_opacity;
+ set_opacity.node_id = node_id;
+ set_opacity.opacity = opacity;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_opacity(set_opacity);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetEnableDebugViewBoundsCmd(uint32_t view_id, bool enable) {
+ fuchsia::ui::gfx::SetEnableDebugViewBoundsCmd enable_cmd;
+ enable_cmd.view_id = view_id;
+ enable_cmd.enable = enable;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_enable_view_debug_bounds(enable_cmd);
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetViewHolderBoundsColorCmd(uint32_t view_holder_id, uint8_t red,
+ uint8_t green, uint8_t blue) {
+ fuchsia::ui::gfx::ColorRgbValue color;
+ color.value.red = red;
+ color.value.green = green;
+ color.value.blue = blue;
+
+ fuchsia::ui::gfx::SetViewHolderBoundsColorCmd bounds_color_cmd;
+ bounds_color_cmd.view_holder_id = view_holder_id;
+ bounds_color_cmd.color = color;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_view_holder_bounds_color(bounds_color_cmd);
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetDisplayColorConversionCmdHACK(
+ uint32_t compositor_id, const std::array<float, 3>& preoffsets,
+ const std::array<float, 3 * 3>& matrix, const std::array<float, 3>& postoffsets) {
+ fuchsia::ui::gfx::SetDisplayColorConversionCmdHACK color_conversion;
+ color_conversion.compositor_id = compositor_id;
+ color_conversion.preoffsets = preoffsets;
+ color_conversion.matrix = matrix;
+ color_conversion.postoffsets = postoffsets;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_display_color_conversion(color_conversion);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetDisplayRotationCmdHACK(uint32_t compositor_id,
+ uint32_t rotation_degrees) {
+ fuchsia::ui::gfx::SetDisplayRotationCmdHACK display_rotation;
+ display_rotation.compositor_id = compositor_id;
+ display_rotation.rotation_degrees = rotation_degrees;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_display_rotation(display_rotation);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSendSizeChangeHintCmdHACK(uint32_t node_id, float width_change_factor,
+ float height_change_factor) {
+ fuchsia::ui::gfx::SendSizeChangeHintCmdHACK send_size_change_hint;
+ send_size_change_hint.node_id = node_id;
+ send_size_change_hint.width_change_factor = width_change_factor;
+ send_size_change_hint.height_change_factor = height_change_factor;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_send_size_change_hint_hack(send_size_change_hint);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetShapeCmd(uint32_t node_id, uint32_t shape_id) {
+ fuchsia::ui::gfx::SetShapeCmd set_shape;
+ set_shape.node_id = node_id;
+ set_shape.shape_id = shape_id;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_shape(set_shape);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetMaterialCmd(uint32_t node_id, uint32_t material_id) {
+ fuchsia::ui::gfx::SetMaterialCmd set_material;
+ set_material.node_id = node_id;
+ set_material.material_id = material_id;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_material(set_material);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetClipCmd(uint32_t node_id, uint32_t clip_id, bool clip_to_self) {
+ fuchsia::ui::gfx::SetClipCmd set_clip;
+ set_clip.node_id = node_id;
+ set_clip.clip_id = clip_id;
+ set_clip.clip_to_self = clip_to_self;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_clip(set_clip);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetClipPlanesCmd(uint32_t node_id,
+ std::vector<fuchsia::ui::gfx::Plane3> planes) {
+ fuchsia::ui::gfx::SetClipPlanesCmd set_clip_planes;
+ set_clip_planes.node_id = node_id;
+ set_clip_planes.clip_planes = std::move(planes);
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_clip_planes(set_clip_planes);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetTagCmd(uint32_t node_id, uint32_t tag_value) {
+ fuchsia::ui::gfx::SetTagCmd set_tag;
+ set_tag.node_id = node_id;
+ set_tag.tag_value = tag_value;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_tag(set_tag);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetHitTestBehaviorCmd(
+ uint32_t node_id, fuchsia::ui::gfx::HitTestBehavior hit_test_behavior) {
+ fuchsia::ui::gfx::SetHitTestBehaviorCmd set_hit_test_behavior;
+ set_hit_test_behavior.node_id = node_id;
+ set_hit_test_behavior.hit_test_behavior = hit_test_behavior;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_hit_test_behavior(set_hit_test_behavior);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetCameraCmd(uint32_t renderer_id, uint32_t camera_id) {
+ fuchsia::ui::gfx::SetCameraCmd set_camera;
+ set_camera.renderer_id = renderer_id;
+ set_camera.camera_id = camera_id;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_camera(set_camera);
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetTextureCmd(uint32_t material_id, uint32_t texture_id) {
+ fuchsia::ui::gfx::SetTextureCmd set_texture;
+ set_texture.material_id = material_id;
+ set_texture.texture_id = texture_id;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_texture(set_texture);
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetColorCmd(uint32_t material_id, uint8_t red, uint8_t green,
+ uint8_t blue, uint8_t alpha) {
+ fuchsia::ui::gfx::ColorRgbaValue color;
+ color.value.red = red;
+ color.value.green = green;
+ color.value.blue = blue;
+ color.value.alpha = alpha;
+ color.variable_id = 0;
+ fuchsia::ui::gfx::SetColorCmd set_color;
+ set_color.material_id = material_id;
+ set_color.color = color;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_color(set_color);
+
+ return command;
+}
+
+fuchsia::ui::gfx::MeshVertexFormat NewMeshVertexFormat(fuchsia::ui::gfx::ValueType position_type,
+ fuchsia::ui::gfx::ValueType normal_type,
+ fuchsia::ui::gfx::ValueType tex_coord_type) {
+ fuchsia::ui::gfx::MeshVertexFormat vertex_format;
+ vertex_format.position_type = position_type;
+ vertex_format.normal_type = normal_type;
+ vertex_format.tex_coord_type = tex_coord_type;
+ return vertex_format;
+}
+
+fuchsia::ui::gfx::Command NewBindMeshBuffersCmd(
+ uint32_t mesh_id, uint32_t index_buffer_id, fuchsia::ui::gfx::MeshIndexFormat index_format,
+ uint64_t index_offset, uint32_t index_count, uint32_t vertex_buffer_id,
+ fuchsia::ui::gfx::MeshVertexFormat vertex_format, uint64_t vertex_offset, uint32_t vertex_count,
+ const std::array<float, 3>& bounding_box_min, const std::array<float, 3>& bounding_box_max) {
+ fuchsia::ui::gfx::BindMeshBuffersCmd bind_mesh_buffers;
+ bind_mesh_buffers.mesh_id = mesh_id;
+ bind_mesh_buffers.index_buffer_id = index_buffer_id;
+ bind_mesh_buffers.index_format = index_format;
+ bind_mesh_buffers.index_offset = index_offset;
+ bind_mesh_buffers.index_count = index_count;
+ bind_mesh_buffers.vertex_buffer_id = vertex_buffer_id;
+ bind_mesh_buffers.vertex_format = vertex_format;
+ bind_mesh_buffers.vertex_offset = vertex_offset;
+ bind_mesh_buffers.vertex_count = vertex_count;
+ auto& bbox = bind_mesh_buffers.bounding_box;
+ bbox.min.x = bounding_box_min[0];
+ bbox.min.y = bounding_box_min[1];
+ bbox.min.z = bounding_box_min[2];
+ bbox.max.x = bounding_box_max[0];
+ bbox.max.y = bounding_box_max[1];
+ bbox.max.z = bounding_box_max[2];
+
+ fuchsia::ui::gfx::Command command;
+ command.set_bind_mesh_buffers(bind_mesh_buffers);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewAddLayerCmd(uint32_t layer_stack_id, uint32_t layer_id) {
+ fuchsia::ui::gfx::AddLayerCmd add_layer;
+ add_layer.layer_stack_id = layer_stack_id;
+ add_layer.layer_id = layer_id;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_add_layer(add_layer);
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewRemoveLayerCmd(uint32_t layer_stack_id, uint32_t layer_id) {
+ fuchsia::ui::gfx::RemoveLayerCmd remove_layer;
+ remove_layer.layer_stack_id = layer_stack_id;
+ remove_layer.layer_id = layer_id;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_remove_layer(remove_layer);
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewRemoveAllLayersCmd(uint32_t layer_stack_id) {
+ fuchsia::ui::gfx::RemoveAllLayersCmd remove_all_layers;
+ remove_all_layers.layer_stack_id = layer_stack_id;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_remove_all_layers(remove_all_layers);
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetLayerStackCmd(uint32_t compositor_id, uint32_t layer_stack_id) {
+ fuchsia::ui::gfx::SetLayerStackCmd set_layer_stack;
+ set_layer_stack.compositor_id = compositor_id;
+ set_layer_stack.layer_stack_id = layer_stack_id;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_layer_stack(set_layer_stack);
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetRendererCmd(uint32_t layer_id, uint32_t renderer_id) {
+ fuchsia::ui::gfx::SetRendererCmd set_renderer;
+ set_renderer.layer_id = layer_id;
+ set_renderer.renderer_id = renderer_id;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_renderer(set_renderer);
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetRendererParamCmd(uint32_t renderer_id,
+ fuchsia::ui::gfx::RendererParam param) {
+ fuchsia::ui::gfx::SetRendererParamCmd param_command;
+ param_command.renderer_id = renderer_id;
+ param_command.param = std::move(param);
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_renderer_param(std::move(param_command));
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetSizeCmd(uint32_t node_id, const std::array<float, 2>& size) {
+ fuchsia::ui::gfx::SetSizeCmd set_size;
+ set_size.id = node_id;
+ auto& value = set_size.value.value;
+ value.x = size[0];
+ value.y = size[1];
+ set_size.value.variable_id = 0;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_size(set_size);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetCameraTransformCmd(uint32_t camera_id,
+ const std::array<float, 3>& eye_position,
+ const std::array<float, 3>& eye_look_at,
+ const std::array<float, 3>& eye_up) {
+ fuchsia::ui::gfx::SetCameraTransformCmd set_command;
+ set_command.camera_id = camera_id;
+ set_command.eye_position = NewVector3Value(eye_position);
+ set_command.eye_look_at = NewVector3Value(eye_look_at);
+ set_command.eye_up = NewVector3Value(eye_up);
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_camera_transform(set_command);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetCameraProjectionCmd(uint32_t camera_id, const float fovy) {
+ fuchsia::ui::gfx::SetCameraProjectionCmd set_command;
+ set_command.camera_id = camera_id;
+ set_command.fovy = NewFloatValue(fovy);
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_camera_projection(set_command);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetStereoCameraProjectionCmd(
+ uint32_t camera_id, const std::array<float, 4 * 4>& left_projection,
+ const std::array<float, 4 * 4>& right_projection) {
+ fuchsia::ui::gfx::SetStereoCameraProjectionCmd set_command;
+ set_command.camera_id = camera_id;
+ set_command.left_projection = NewMatrix4Value(left_projection);
+ set_command.right_projection = NewMatrix4Value(right_projection);
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_stereo_camera_projection(set_command);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetCameraClipSpaceTransformCmd(uint32_t camera_id, float x, float y,
+ float scale) {
+ fuchsia::ui::gfx::SetCameraClipSpaceTransformCmd set_command;
+ set_command.camera_id = camera_id;
+ set_command.translation = {x, y};
+ set_command.scale = scale;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_camera_clip_space_transform(set_command);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetCameraPoseBufferCmd(uint32_t camera_id, uint32_t buffer_id,
+ uint32_t num_entries, int64_t base_time,
+ uint64_t time_interval) {
+ fuchsia::ui::gfx::SetCameraPoseBufferCmd set_command;
+ set_command.camera_id = camera_id;
+ set_command.buffer_id = buffer_id;
+ set_command.num_entries = num_entries;
+ set_command.base_time = base_time;
+ set_command.time_interval = time_interval;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_camera_pose_buffer(set_command);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetCameraPoseBufferCmd(uint32_t camera_id, uint32_t buffer_id,
+ uint32_t num_entries, zx::time base_time,
+ zx::duration time_interval) {
+ return NewSetCameraPoseBufferCmd(camera_id, buffer_id, num_entries, base_time.get(),
+ time_interval.get());
+}
+
+fuchsia::ui::gfx::Command NewSetLightColorCmd(uint32_t light_id, const std::array<float, 3>& rgb) {
+ fuchsia::ui::gfx::SetLightColorCmd set_command;
+ set_command.light_id = light_id;
+ set_command.color = NewColorRgbValue(rgb[0], rgb[1], rgb[2]);
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_light_color(set_command);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetLightColorCmd(uint32_t light_id, uint32_t variable_id) {
+ fuchsia::ui::gfx::SetLightColorCmd set_command;
+ set_command.light_id = light_id;
+ set_command.color = NewColorRgbValue(variable_id);
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_light_color(set_command);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetLightDirectionCmd(uint32_t light_id,
+ const std::array<float, 3>& dir) {
+ fuchsia::ui::gfx::SetLightDirectionCmd set_command;
+ set_command.light_id = light_id;
+ set_command.direction = NewVector3Value(dir);
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_light_direction(set_command);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetLightDirectionCmd(uint32_t light_id, uint32_t variable_id) {
+ fuchsia::ui::gfx::SetLightDirectionCmd set_command;
+ set_command.light_id = light_id;
+ set_command.direction = NewVector3Value(variable_id);
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_light_direction(set_command);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetPointLightPositionCmd(uint32_t light_id,
+ const std::array<float, 3>& pos) {
+ fuchsia::ui::gfx::SetPointLightPositionCmd set_command;
+ set_command.light_id = light_id;
+ set_command.position = NewVector3Value(pos);
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_point_light_position(set_command);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetPointLightPositionCmd(uint32_t light_id, uint32_t variable_id) {
+ fuchsia::ui::gfx::SetPointLightPositionCmd set_command;
+ set_command.light_id = light_id;
+ set_command.position = NewVector3Value(variable_id);
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_point_light_position(set_command);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetPointLightFalloffCmd(uint32_t light_id, float falloff) {
+ fuchsia::ui::gfx::SetPointLightFalloffCmd set_command;
+ set_command.light_id = light_id;
+ set_command.falloff = NewFloatValue(falloff);
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_point_light_falloff(set_command);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewAddLightCmd(uint32_t scene_id, uint32_t light_id) {
+ fuchsia::ui::gfx::AddLightCmd add_light_command;
+ add_light_command.scene_id = scene_id;
+ add_light_command.light_id = light_id;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_add_light(add_light_command);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSceneAddAmbientLightCmd(uint32_t scene_id, uint32_t light_id) {
+ fuchsia::ui::gfx::SceneAddAmbientLightCmd add_light_command;
+ add_light_command.scene_id = scene_id;
+ add_light_command.light_id = light_id;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_scene__add_ambient_light(add_light_command);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSceneAddDirectionalLightCmd(uint32_t scene_id, uint32_t light_id) {
+ fuchsia::ui::gfx::SceneAddDirectionalLightCmd add_light_command;
+ add_light_command.scene_id = scene_id;
+ add_light_command.light_id = light_id;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_scene__add_directional_light(add_light_command);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSceneAddPointLightCmd(uint32_t scene_id, uint32_t light_id) {
+ fuchsia::ui::gfx::SceneAddPointLightCmd add_light_command;
+ add_light_command.scene_id = scene_id;
+ add_light_command.light_id = light_id;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_scene__add_point_light(add_light_command);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewDetachLightCmd(uint32_t light_id) {
+ fuchsia::ui::gfx::DetachLightCmd detach_light_command;
+ detach_light_command.light_id = light_id;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_detach_light(detach_light_command);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewDetachLightsCmd(uint32_t scene_id) {
+ fuchsia::ui::gfx::DetachLightsCmd detach_lights_command;
+ detach_lights_command.scene_id = scene_id;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_detach_lights(detach_lights_command);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetEventMaskCmd(uint32_t resource_id, uint32_t event_mask) {
+ fuchsia::ui::gfx::SetEventMaskCmd set_event_mask_command;
+ set_event_mask_command.id = resource_id;
+ set_event_mask_command.event_mask = event_mask;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_event_mask(set_event_mask_command);
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetLabelCmd(uint32_t resource_id, const std::string& label) {
+ fuchsia::ui::gfx::SetLabelCmd set_label_command;
+ set_label_command.id = resource_id;
+ set_label_command.label = label.substr(0, fuchsia::ui::gfx::kLabelMaxLength);
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_label(std::move(set_label_command));
+
+ return command;
+}
+
+fuchsia::ui::gfx::Command NewSetDisableClippingCmd(uint32_t renderer_id, bool disable_clipping) {
+ fuchsia::ui::gfx::SetDisableClippingCmd set_disable_clipping_command;
+ set_disable_clipping_command.renderer_id = renderer_id;
+ set_disable_clipping_command.disable_clipping = disable_clipping;
+
+ fuchsia::ui::gfx::Command command;
+ command.set_set_disable_clipping(set_disable_clipping_command);
+
+ return command;
+}
+
+fuchsia::ui::gfx::FloatValue NewFloatValue(float value) {
+ fuchsia::ui::gfx::FloatValue val;
+ val.variable_id = 0;
+ val.value = value;
+ return val;
+}
+
+fuchsia::ui::gfx::vec2 NewVector2(const std::array<float, 2>& value) {
+ fuchsia::ui::gfx::vec2 val;
+ val.x = value[0];
+ val.y = value[1];
+ return val;
+}
+
+fuchsia::ui::gfx::Vector2Value NewVector2Value(const std::array<float, 2> value) {
+ fuchsia::ui::gfx::Vector2Value val;
+ val.variable_id = 0;
+ val.value = NewVector2(value);
+ return val;
+}
+
+fuchsia::ui::gfx::Vector2Value NewVector2Value(uint32_t variable_id) {
+ fuchsia::ui::gfx::Vector2Value val;
+ val.variable_id = variable_id;
+ return val;
+}
+
+fuchsia::ui::gfx::vec3 NewVector3(const std::array<float, 3>& value) {
+ fuchsia::ui::gfx::vec3 val;
+ val.x = value[0];
+ val.y = value[1];
+ val.z = value[2];
+ return val;
+}
+
+fuchsia::ui::gfx::Vector3Value NewVector3Value(const std::array<float, 3>& value) {
+ fuchsia::ui::gfx::Vector3Value val;
+ val.variable_id = 0;
+ val.value = NewVector3(value);
+ return val;
+}
+
+fuchsia::ui::gfx::Vector3Value NewVector3Value(uint32_t variable_id) {
+ fuchsia::ui::gfx::Vector3Value val;
+ val.variable_id = variable_id;
+ return val;
+}
+
+fuchsia::ui::gfx::vec4 NewVector4(const std::array<float, 4>& value) {
+ fuchsia::ui::gfx::vec4 val;
+ val.x = value[0];
+ val.y = value[1];
+ val.z = value[2];
+ val.w = value[3];
+ return val;
+}
+
+fuchsia::ui::gfx::Vector4Value NewVector4Value(const std::array<float, 4>& value) {
+ fuchsia::ui::gfx::Vector4Value val;
+ val.variable_id = 0;
+ val.value = NewVector4(value);
+ return val;
+}
+
+fuchsia::ui::gfx::Vector4Value NewVector4Value(uint32_t variable_id) {
+ fuchsia::ui::gfx::Vector4Value val;
+ val.variable_id = variable_id;
+ return val;
+}
+
+fuchsia::ui::gfx::Quaternion NewQuaternion(const std::array<float, 4>& value) {
+ fuchsia::ui::gfx::Quaternion val;
+ val.x = value[0];
+ val.y = value[1];
+ val.z = value[2];
+ val.w = value[3];
+ return val;
+}
+
+fuchsia::ui::gfx::QuaternionValue NewQuaternionValue(const std::array<float, 4>& value) {
+ fuchsia::ui::gfx::QuaternionValue val;
+ val.variable_id = 0;
+ val.value = NewQuaternion(value);
+ return val;
+}
+
+fuchsia::ui::gfx::QuaternionValue NewQuaternionValue(uint32_t variable_id) {
+ fuchsia::ui::gfx::QuaternionValue val;
+ val.variable_id = variable_id;
+ return val;
+}
+
+fuchsia::ui::gfx::mat4 NewMatrix4(const std::array<float, 4 * 4>& matrix) {
+ fuchsia::ui::gfx::mat4 val;
+ for (size_t index = 0; index < 4 * 4; index++) {
+ val.matrix[index] = matrix[index];
+ }
+ return val;
+}
+
+fuchsia::ui::gfx::Matrix4Value NewMatrix4Value(const std::array<float, 4 * 4>& matrix) {
+ fuchsia::ui::gfx::Matrix4Value val;
+ val.variable_id = 0;
+ val.value = NewMatrix4(matrix);
+ return val;
+}
+
+fuchsia::ui::gfx::Matrix4Value NewMatrix4Value(uint32_t variable_id) {
+ fuchsia::ui::gfx::Matrix4Value val;
+ val.variable_id = variable_id;
+ return val;
+}
+
+fuchsia::ui::gfx::ColorRgbValue NewColorRgbValue(float red, float green, float blue) {
+ fuchsia::ui::gfx::ColorRgbValue val;
+ val.variable_id = 0;
+ auto& color = val.value;
+ color.red = red;
+ color.green = green;
+ color.blue = blue;
+
+ return val;
+}
+
+fuchsia::ui::gfx::ColorRgbValue NewColorRgbValue(uint32_t variable_id) {
+ fuchsia::ui::gfx::ColorRgbValue val;
+ val.variable_id = variable_id;
+
+ return val;
+}
+
+fuchsia::ui::gfx::ColorRgbaValue NewColorRgbaValue(const std::array<uint8_t, 4>& value) {
+ fuchsia::ui::gfx::ColorRgbaValue val;
+ val.variable_id = 0;
+ auto& color = val.value;
+ color.red = value[0];
+ color.green = value[1];
+ color.blue = value[2];
+ color.alpha = value[3];
+
+ return val;
+}
+
+fuchsia::ui::gfx::ColorRgbaValue NewColorRgbaValue(uint32_t variable_id) {
+ fuchsia::ui::gfx::ColorRgbaValue val;
+ val.variable_id = variable_id;
+
+ return val;
+}
+
+// TODO(mikejurka): this should be in an images util file
+bool ImageInfoEquals(const fuchsia::images::ImageInfo& a, const fuchsia::images::ImageInfo& b) {
+ return a.transform == b.transform && a.width == b.width && a.height == b.height &&
+ a.stride == b.stride && a.pixel_format == b.pixel_format &&
+ a.color_space == b.color_space && a.tiling == b.tiling && a.alpha_format == b.alpha_format;
+}
+
+} // namespace scenic
diff --git a/third_party/fuchsia-sdk/pkg/scenic_cpp/commands_sizing.cc b/third_party/fuchsia-sdk/pkg/scenic_cpp/commands_sizing.cc
new file mode 100644
index 0000000..b7d67f2
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/scenic_cpp/commands_sizing.cc
@@ -0,0 +1,1542 @@
+// File is automatically generated; do not modify.
+// See tools/fidl/measure-tape/README.md
+
+#include <lib/ui/scenic/cpp/commands_sizing.h>
+
+#include <fuchsia/images/cpp/fidl.h>
+#include <fuchsia/ui/gfx/cpp/fidl.h>
+#include <fuchsia/ui/input/cpp/fidl.h>
+#include <fuchsia/ui/scenic/cpp/fidl.h>
+#include <fuchsia/ui/views/cpp/fidl.h>
+#include <zircon/types.h>
+
+
+namespace measure_tape {
+namespace fuchsia {
+namespace ui {
+namespace scenic {
+
+namespace {
+
+class MeasuringTape {
+ public:
+ MeasuringTape() = default;
+
+ void Measure(const ::fuchsia::ui::scenic::Command& value) {
+ num_bytes_ += sizeof(fidl_xunion_t);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::scenic::Command& value) {
+ switch (value.Which()) {
+ case ::fuchsia::ui::scenic::Command::Tag::kGfx:
+ Measure(value.gfx());
+ break;
+ case ::fuchsia::ui::scenic::Command::Tag::kViews:
+ Measure(value.views());
+ break;
+ case ::fuchsia::ui::scenic::Command::Tag::kInput:
+ Measure(value.input());
+ break;
+ case ::fuchsia::ui::scenic::Command::Tag::Invalid:
+ MaxOut();
+ break;
+ }
+ }
+
+ void MeasureHandles(const ::fuchsia::ui::scenic::Command& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::Command& value) {
+ num_bytes_ += sizeof(fidl_xunion_t);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::Command& value) {
+ switch (value.Which()) {
+ case ::fuchsia::ui::gfx::Command::Tag::kCreateResource:
+ Measure(value.create_resource());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kReleaseResource:
+ Measure(value.release_resource());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kExportResource:
+ Measure(value.export_resource());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kImportResource:
+ Measure(value.import_resource());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetTag:
+ Measure(value.set_tag());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kDetach:
+ Measure(value.detach());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetTranslation:
+ Measure(value.set_translation());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetScale:
+ Measure(value.set_scale());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetRotation:
+ Measure(value.set_rotation());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetAnchor:
+ Measure(value.set_anchor());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetSize:
+ Measure(value.set_size());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetOpacity:
+ Measure(value.set_opacity());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSendSizeChangeHintHack:
+ Measure(value.send_size_change_hint_hack());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kAddChild:
+ Measure(value.add_child());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kAddPart:
+ Measure(value.add_part());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kDetachChildren:
+ Measure(value.detach_children());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetShape:
+ Measure(value.set_shape());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetMaterial:
+ Measure(value.set_material());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetClip:
+ Measure(value.set_clip());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetHitTestBehavior:
+ Measure(value.set_hit_test_behavior());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetViewProperties:
+ Measure(value.set_view_properties());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kTakeSnapshotCmd:
+ Measure(value.take_snapshot_cmd());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetCamera:
+ Measure(value.set_camera());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetCameraTransform:
+ Measure(value.set_camera_transform());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetCameraProjection:
+ Measure(value.set_camera_projection());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetStereoCameraProjection:
+ Measure(value.set_stereo_camera_projection());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetCameraPoseBuffer:
+ Measure(value.set_camera_pose_buffer());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetLightColor:
+ Measure(value.set_light_color());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetLightDirection:
+ Measure(value.set_light_direction());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kAddLight:
+ Measure(value.add_light());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kDetachLight:
+ Measure(value.detach_light());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kDetachLights:
+ Measure(value.detach_lights());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetTexture:
+ Measure(value.set_texture());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetColor:
+ Measure(value.set_color());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kBindMeshBuffers:
+ Measure(value.bind_mesh_buffers());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kAddLayer:
+ Measure(value.add_layer());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kRemoveLayer:
+ Measure(value.remove_layer());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kRemoveAllLayers:
+ Measure(value.remove_all_layers());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetLayerStack:
+ Measure(value.set_layer_stack());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetRenderer:
+ Measure(value.set_renderer());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetRendererParam:
+ Measure(value.set_renderer_param());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetEventMask:
+ Measure(value.set_event_mask());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetLabel:
+ Measure(value.set_label());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetDisableClipping:
+ Measure(value.set_disable_clipping());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetImportFocus:
+ Measure(value.set_import_focus());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetClipPlanes:
+ Measure(value.set_clip_planes());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetPointLightPosition:
+ Measure(value.set_point_light_position());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetPointLightFalloff:
+ Measure(value.set_point_light_falloff());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kScene_AddAmbientLight:
+ Measure(value.scene__add_ambient_light());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kScene_AddDirectionalLight:
+ Measure(value.scene__add_directional_light());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kScene_AddPointLight:
+ Measure(value.scene__add_point_light());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetDisplayColorConversion:
+ Measure(value.set_display_color_conversion());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetDisplayRotation:
+ Measure(value.set_display_rotation());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetEnableViewDebugBounds:
+ Measure(value.set_enable_view_debug_bounds());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetViewHolderBoundsColor:
+ Measure(value.set_view_holder_bounds_color());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::kSetCameraClipSpaceTransform:
+ Measure(value.set_camera_clip_space_transform());
+ break;
+ case ::fuchsia::ui::gfx::Command::Tag::Invalid:
+ MaxOut();
+ break;
+ }
+ }
+
+ void MeasureHandles(const ::fuchsia::ui::gfx::Command& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::views::Command& value) {
+ num_bytes_ += sizeof(fidl_xunion_t);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::views::Command& value) {
+ switch (value.Which()) {
+ case ::fuchsia::ui::views::Command::Tag::kEmpty:
+ num_bytes_ += 8;
+ break;
+ case ::fuchsia::ui::views::Command::Tag::Invalid:
+ MaxOut();
+ break;
+ }
+ }
+
+ void Measure(const ::fuchsia::ui::input::Command& value) {
+ num_bytes_ += sizeof(fidl_xunion_t);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::input::Command& value) {
+ switch (value.Which()) {
+ case ::fuchsia::ui::input::Command::Tag::kSendKeyboardInput:
+ Measure(value.send_keyboard_input());
+ break;
+ case ::fuchsia::ui::input::Command::Tag::kSendPointerInput:
+ Measure(value.send_pointer_input());
+ break;
+ case ::fuchsia::ui::input::Command::Tag::kSetHardKeyboardDelivery:
+ Measure(value.set_hard_keyboard_delivery());
+ break;
+ case ::fuchsia::ui::input::Command::Tag::kSetParallelDispatch:
+ Measure(value.set_parallel_dispatch());
+ break;
+ case ::fuchsia::ui::input::Command::Tag::Invalid:
+ MaxOut();
+ break;
+ }
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::CreateResourceCmd& value) {
+ num_bytes_ += FIDL_ALIGN(32);
+ MeasureHandles(value);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::CreateResourceCmd& value) {
+ MeasureOutOfLine(value.resource);
+ }
+
+ void MeasureHandles(const ::fuchsia::ui::gfx::CreateResourceCmd& value) {
+ MeasureHandles(value.resource);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::ReleaseResourceCmd& value) {
+ num_bytes_ += FIDL_ALIGN(4);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::ReleaseResourceCmd& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::ExportResourceCmdDeprecated& value) {
+ num_bytes_ += FIDL_ALIGN(8);
+ MeasureHandles(value);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::ExportResourceCmdDeprecated& value) {
+ }
+
+ void MeasureHandles(const ::fuchsia::ui::gfx::ExportResourceCmdDeprecated& value) {
+ num_handles_ += 1;
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::ImportResourceCmdDeprecated& value) {
+ num_bytes_ += FIDL_ALIGN(12);
+ MeasureHandles(value);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::ImportResourceCmdDeprecated& value) {
+ }
+
+ void MeasureHandles(const ::fuchsia::ui::gfx::ImportResourceCmdDeprecated& value) {
+ num_handles_ += 1;
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetTagCmd& value) {
+ num_bytes_ += FIDL_ALIGN(8);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetTagCmd& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::DetachCmd& value) {
+ num_bytes_ += FIDL_ALIGN(4);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::DetachCmd& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetTranslationCmd& value) {
+ num_bytes_ += FIDL_ALIGN(20);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetTranslationCmd& value) {
+ MeasureOutOfLine(value.value);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetScaleCmd& value) {
+ num_bytes_ += FIDL_ALIGN(20);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetScaleCmd& value) {
+ MeasureOutOfLine(value.value);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetRotationCmd& value) {
+ num_bytes_ += FIDL_ALIGN(24);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetRotationCmd& value) {
+ MeasureOutOfLine(value.value);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetAnchorCmd& value) {
+ num_bytes_ += FIDL_ALIGN(20);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetAnchorCmd& value) {
+ MeasureOutOfLine(value.value);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetSizeCmd& value) {
+ num_bytes_ += FIDL_ALIGN(16);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetSizeCmd& value) {
+ MeasureOutOfLine(value.value);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetOpacityCmd& value) {
+ num_bytes_ += FIDL_ALIGN(8);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetOpacityCmd& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SendSizeChangeHintCmdHACK& value) {
+ num_bytes_ += FIDL_ALIGN(12);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SendSizeChangeHintCmdHACK& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::AddChildCmd& value) {
+ num_bytes_ += FIDL_ALIGN(8);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::AddChildCmd& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::AddPartCmd& value) {
+ num_bytes_ += FIDL_ALIGN(8);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::AddPartCmd& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::DetachChildrenCmd& value) {
+ num_bytes_ += FIDL_ALIGN(4);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::DetachChildrenCmd& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetShapeCmd& value) {
+ num_bytes_ += FIDL_ALIGN(8);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetShapeCmd& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetMaterialCmd& value) {
+ num_bytes_ += FIDL_ALIGN(8);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetMaterialCmd& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetClipCmd& value) {
+ num_bytes_ += FIDL_ALIGN(12);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetClipCmd& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetHitTestBehaviorCmd& value) {
+ num_bytes_ += FIDL_ALIGN(8);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetHitTestBehaviorCmd& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetViewPropertiesCmd& value) {
+ num_bytes_ += FIDL_ALIGN(56);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetViewPropertiesCmd& value) {
+ MeasureOutOfLine(value.properties);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::TakeSnapshotCmdDEPRECATED& value) {
+ num_bytes_ += FIDL_ALIGN(8);
+ MeasureHandles(value);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::TakeSnapshotCmdDEPRECATED& value) {
+ }
+
+ void MeasureHandles(const ::fuchsia::ui::gfx::TakeSnapshotCmdDEPRECATED& value) {
+ num_handles_ += 1;
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetCameraCmd& value) {
+ num_bytes_ += FIDL_ALIGN(8);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetCameraCmd& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetCameraTransformCmd& value) {
+ num_bytes_ += FIDL_ALIGN(52);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetCameraTransformCmd& value) {
+ MeasureOutOfLine(value.eye_position);
+ MeasureOutOfLine(value.eye_look_at);
+ MeasureOutOfLine(value.eye_up);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetCameraProjectionCmd& value) {
+ num_bytes_ += FIDL_ALIGN(12);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetCameraProjectionCmd& value) {
+ MeasureOutOfLine(value.fovy);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetStereoCameraProjectionCmd& value) {
+ num_bytes_ += FIDL_ALIGN(140);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetStereoCameraProjectionCmd& value) {
+ MeasureOutOfLine(value.left_projection);
+ MeasureOutOfLine(value.right_projection);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetCameraPoseBufferCmd& value) {
+ num_bytes_ += FIDL_ALIGN(32);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetCameraPoseBufferCmd& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetLightColorCmd& value) {
+ num_bytes_ += FIDL_ALIGN(20);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetLightColorCmd& value) {
+ MeasureOutOfLine(value.color);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetLightDirectionCmd& value) {
+ num_bytes_ += FIDL_ALIGN(20);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetLightDirectionCmd& value) {
+ MeasureOutOfLine(value.direction);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::AddLightCmd& value) {
+ num_bytes_ += FIDL_ALIGN(8);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::AddLightCmd& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::DetachLightCmd& value) {
+ num_bytes_ += FIDL_ALIGN(4);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::DetachLightCmd& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::DetachLightsCmd& value) {
+ num_bytes_ += FIDL_ALIGN(4);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::DetachLightsCmd& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetTextureCmd& value) {
+ num_bytes_ += FIDL_ALIGN(8);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetTextureCmd& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetColorCmd& value) {
+ num_bytes_ += FIDL_ALIGN(12);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetColorCmd& value) {
+ MeasureOutOfLine(value.color);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::BindMeshBuffersCmd& value) {
+ num_bytes_ += FIDL_ALIGN(88);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::BindMeshBuffersCmd& value) {
+ MeasureOutOfLine(value.vertex_format);
+ MeasureOutOfLine(value.bounding_box);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::AddLayerCmd& value) {
+ num_bytes_ += FIDL_ALIGN(8);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::AddLayerCmd& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::RemoveLayerCmd& value) {
+ num_bytes_ += FIDL_ALIGN(8);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::RemoveLayerCmd& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::RemoveAllLayersCmd& value) {
+ num_bytes_ += FIDL_ALIGN(4);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::RemoveAllLayersCmd& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetLayerStackCmd& value) {
+ num_bytes_ += FIDL_ALIGN(8);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetLayerStackCmd& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetRendererCmd& value) {
+ num_bytes_ += FIDL_ALIGN(8);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetRendererCmd& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetRendererParamCmd& value) {
+ num_bytes_ += FIDL_ALIGN(32);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetRendererParamCmd& value) {
+ MeasureOutOfLine(value.param);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetEventMaskCmd& value) {
+ num_bytes_ += FIDL_ALIGN(8);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetEventMaskCmd& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetLabelCmd& value) {
+ num_bytes_ += FIDL_ALIGN(24);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetLabelCmd& value) {
+ num_bytes_ += FIDL_ALIGN(value.label.length());
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetDisableClippingCmd& value) {
+ num_bytes_ += FIDL_ALIGN(8);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetDisableClippingCmd& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetImportFocusCmdDEPRECATED& value) {
+ num_bytes_ += FIDL_ALIGN(1);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetImportFocusCmdDEPRECATED& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetClipPlanesCmd& value) {
+ num_bytes_ += FIDL_ALIGN(24);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetClipPlanesCmd& value) {
+ // TODO: vectors are not measured yet.
+ MaxOut();
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetPointLightPositionCmd& value) {
+ num_bytes_ += FIDL_ALIGN(20);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetPointLightPositionCmd& value) {
+ MeasureOutOfLine(value.position);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetPointLightFalloffCmd& value) {
+ num_bytes_ += FIDL_ALIGN(12);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetPointLightFalloffCmd& value) {
+ MeasureOutOfLine(value.falloff);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SceneAddAmbientLightCmd& value) {
+ num_bytes_ += FIDL_ALIGN(8);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SceneAddAmbientLightCmd& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SceneAddDirectionalLightCmd& value) {
+ num_bytes_ += FIDL_ALIGN(8);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SceneAddDirectionalLightCmd& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SceneAddPointLightCmd& value) {
+ num_bytes_ += FIDL_ALIGN(8);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SceneAddPointLightCmd& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetDisplayColorConversionCmdHACK& value) {
+ num_bytes_ += FIDL_ALIGN(64);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetDisplayColorConversionCmdHACK& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetDisplayRotationCmdHACK& value) {
+ num_bytes_ += FIDL_ALIGN(8);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetDisplayRotationCmdHACK& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetEnableDebugViewBoundsCmd& value) {
+ num_bytes_ += FIDL_ALIGN(8);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetEnableDebugViewBoundsCmd& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetViewHolderBoundsColorCmd& value) {
+ num_bytes_ += FIDL_ALIGN(20);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetViewHolderBoundsColorCmd& value) {
+ MeasureOutOfLine(value.color);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SetCameraClipSpaceTransformCmd& value) {
+ num_bytes_ += FIDL_ALIGN(16);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SetCameraClipSpaceTransformCmd& value) {
+ MeasureOutOfLine(value.translation);
+ }
+
+ void Measure(const ::fuchsia::ui::input::SendKeyboardInputCmd& value) {
+ num_bytes_ += FIDL_ALIGN(40);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::input::SendKeyboardInputCmd& value) {
+ MeasureOutOfLine(value.keyboard_event);
+ }
+
+ void Measure(const ::fuchsia::ui::input::SendPointerInputCmd& value) {
+ num_bytes_ += FIDL_ALIGN(56);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::input::SendPointerInputCmd& value) {
+ MeasureOutOfLine(value.pointer_event);
+ }
+
+ void Measure(const ::fuchsia::ui::input::SetHardKeyboardDeliveryCmd& value) {
+ num_bytes_ += FIDL_ALIGN(1);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::input::SetHardKeyboardDeliveryCmd& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::input::SetParallelDispatchCmd& value) {
+ num_bytes_ += FIDL_ALIGN(1);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::input::SetParallelDispatchCmd& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::ResourceArgs& value) {
+ num_bytes_ += sizeof(fidl_xunion_t);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::ResourceArgs& value) {
+ switch (value.Which()) {
+ case ::fuchsia::ui::gfx::ResourceArgs::Tag::kMemory:
+ Measure(value.memory());
+ break;
+ case ::fuchsia::ui::gfx::ResourceArgs::Tag::kImage:
+ Measure(value.image());
+ break;
+ case ::fuchsia::ui::gfx::ResourceArgs::Tag::kImagePipe:
+ Measure(value.image_pipe());
+ break;
+ case ::fuchsia::ui::gfx::ResourceArgs::Tag::kBuffer:
+ Measure(value.buffer());
+ break;
+ case ::fuchsia::ui::gfx::ResourceArgs::Tag::kView:
+ Measure(value.view());
+ break;
+ case ::fuchsia::ui::gfx::ResourceArgs::Tag::kViewHolder:
+ Measure(value.view_holder());
+ break;
+ case ::fuchsia::ui::gfx::ResourceArgs::Tag::kRectangle:
+ Measure(value.rectangle());
+ break;
+ case ::fuchsia::ui::gfx::ResourceArgs::Tag::kRoundedRectangle:
+ Measure(value.rounded_rectangle());
+ break;
+ case ::fuchsia::ui::gfx::ResourceArgs::Tag::kCircle:
+ Measure(value.circle());
+ break;
+ case ::fuchsia::ui::gfx::ResourceArgs::Tag::kMesh:
+ Measure(value.mesh());
+ break;
+ case ::fuchsia::ui::gfx::ResourceArgs::Tag::kShapeNode:
+ Measure(value.shape_node());
+ break;
+ case ::fuchsia::ui::gfx::ResourceArgs::Tag::kClipNode:
+ Measure(value.clip_node());
+ break;
+ case ::fuchsia::ui::gfx::ResourceArgs::Tag::kEntityNode:
+ Measure(value.entity_node());
+ break;
+ case ::fuchsia::ui::gfx::ResourceArgs::Tag::kOpacityNode:
+ Measure(value.opacity_node());
+ break;
+ case ::fuchsia::ui::gfx::ResourceArgs::Tag::kMaterial:
+ Measure(value.material());
+ break;
+ case ::fuchsia::ui::gfx::ResourceArgs::Tag::kCompositor:
+ Measure(value.compositor());
+ break;
+ case ::fuchsia::ui::gfx::ResourceArgs::Tag::kDisplayCompositor:
+ Measure(value.display_compositor());
+ break;
+ case ::fuchsia::ui::gfx::ResourceArgs::Tag::kImagePipeCompositor:
+ Measure(value.image_pipe_compositor());
+ break;
+ case ::fuchsia::ui::gfx::ResourceArgs::Tag::kLayerStack:
+ Measure(value.layer_stack());
+ break;
+ case ::fuchsia::ui::gfx::ResourceArgs::Tag::kLayer:
+ Measure(value.layer());
+ break;
+ case ::fuchsia::ui::gfx::ResourceArgs::Tag::kScene:
+ Measure(value.scene());
+ break;
+ case ::fuchsia::ui::gfx::ResourceArgs::Tag::kCamera:
+ Measure(value.camera());
+ break;
+ case ::fuchsia::ui::gfx::ResourceArgs::Tag::kStereoCamera:
+ Measure(value.stereo_camera());
+ break;
+ case ::fuchsia::ui::gfx::ResourceArgs::Tag::kRenderer:
+ Measure(value.renderer());
+ break;
+ case ::fuchsia::ui::gfx::ResourceArgs::Tag::kAmbientLight:
+ Measure(value.ambient_light());
+ break;
+ case ::fuchsia::ui::gfx::ResourceArgs::Tag::kDirectionalLight:
+ Measure(value.directional_light());
+ break;
+ case ::fuchsia::ui::gfx::ResourceArgs::Tag::kVariable:
+ Measure(value.variable());
+ break;
+ case ::fuchsia::ui::gfx::ResourceArgs::Tag::kPointLight:
+ Measure(value.point_light());
+ break;
+ case ::fuchsia::ui::gfx::ResourceArgs::Tag::kView3:
+ Measure(value.view3());
+ break;
+ case ::fuchsia::ui::gfx::ResourceArgs::Tag::kImagePipe2:
+ Measure(value.image_pipe2());
+ break;
+ case ::fuchsia::ui::gfx::ResourceArgs::Tag::Invalid:
+ MaxOut();
+ break;
+ }
+ }
+
+ void MeasureHandles(const ::fuchsia::ui::gfx::ResourceArgs& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::Vector3Value& value) {
+ num_bytes_ += FIDL_ALIGN(16);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::Vector3Value& value) {
+ MeasureOutOfLine(value.value);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::QuaternionValue& value) {
+ num_bytes_ += FIDL_ALIGN(20);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::QuaternionValue& value) {
+ MeasureOutOfLine(value.value);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::Vector2Value& value) {
+ num_bytes_ += FIDL_ALIGN(12);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::Vector2Value& value) {
+ MeasureOutOfLine(value.value);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::ViewProperties& value) {
+ num_bytes_ += FIDL_ALIGN(52);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::ViewProperties& value) {
+ MeasureOutOfLine(value.bounding_box);
+ MeasureOutOfLine(value.inset_from_min);
+ MeasureOutOfLine(value.inset_from_max);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::FloatValue& value) {
+ num_bytes_ += FIDL_ALIGN(8);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::FloatValue& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::Matrix4Value& value) {
+ num_bytes_ += FIDL_ALIGN(68);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::Matrix4Value& value) {
+ MeasureOutOfLine(value.value);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::ColorRgbValue& value) {
+ num_bytes_ += FIDL_ALIGN(16);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::ColorRgbValue& value) {
+ MeasureOutOfLine(value.value);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::ColorRgbaValue& value) {
+ num_bytes_ += FIDL_ALIGN(8);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::ColorRgbaValue& value) {
+ MeasureOutOfLine(value.value);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::MeshVertexFormat& value) {
+ num_bytes_ += FIDL_ALIGN(12);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::MeshVertexFormat& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::BoundingBox& value) {
+ num_bytes_ += FIDL_ALIGN(24);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::BoundingBox& value) {
+ MeasureOutOfLine(value.min);
+ MeasureOutOfLine(value.max);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::RendererParam& value) {
+ num_bytes_ += sizeof(fidl_xunion_t);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::RendererParam& value) {
+ switch (value.Which()) {
+ case ::fuchsia::ui::gfx::RendererParam::Tag::kShadowTechnique:
+ num_bytes_ += 8;
+ break;
+ case ::fuchsia::ui::gfx::RendererParam::Tag::kReserved:
+ num_bytes_ += 8;
+ break;
+ case ::fuchsia::ui::gfx::RendererParam::Tag::kEnableDebugging:
+ num_bytes_ += 8;
+ break;
+ case ::fuchsia::ui::gfx::RendererParam::Tag::Invalid:
+ MaxOut();
+ break;
+ }
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::vec2& value) {
+ num_bytes_ += FIDL_ALIGN(8);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::vec2& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::input::KeyboardEvent& value) {
+ num_bytes_ += FIDL_ALIGN(32);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::input::KeyboardEvent& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::input::PointerEvent& value) {
+ num_bytes_ += FIDL_ALIGN(48);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::input::PointerEvent& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::MemoryArgs& value) {
+ num_bytes_ += FIDL_ALIGN(24);
+ MeasureHandles(value);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::MemoryArgs& value) {
+ }
+
+ void MeasureHandles(const ::fuchsia::ui::gfx::MemoryArgs& value) {
+ num_handles_ += 1;
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::ImageArgs& value) {
+ num_bytes_ += FIDL_ALIGN(40);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::ImageArgs& value) {
+ MeasureOutOfLine(value.info);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::ImagePipeArgs& value) {
+ num_bytes_ += FIDL_ALIGN(4);
+ MeasureHandles(value);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::ImagePipeArgs& value) {
+ }
+
+ void MeasureHandles(const ::fuchsia::ui::gfx::ImagePipeArgs& value) {
+ num_handles_ += 1;
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::BufferArgs& value) {
+ num_bytes_ += FIDL_ALIGN(12);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::BufferArgs& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::ViewArgs& value) {
+ num_bytes_ += FIDL_ALIGN(24);
+ MeasureHandles(value);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::ViewArgs& value) {
+ MeasureOutOfLine(value.token);
+ if (value.debug_name) {
+ num_bytes_ += FIDL_ALIGN(value.debug_name->length());
+ }
+ }
+
+ void MeasureHandles(const ::fuchsia::ui::gfx::ViewArgs& value) {
+ MeasureHandles(value.token);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::ViewHolderArgs& value) {
+ num_bytes_ += FIDL_ALIGN(24);
+ MeasureHandles(value);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::ViewHolderArgs& value) {
+ MeasureOutOfLine(value.token);
+ if (value.debug_name) {
+ num_bytes_ += FIDL_ALIGN(value.debug_name->length());
+ }
+ }
+
+ void MeasureHandles(const ::fuchsia::ui::gfx::ViewHolderArgs& value) {
+ MeasureHandles(value.token);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::RectangleArgs& value) {
+ num_bytes_ += FIDL_ALIGN(48);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::RectangleArgs& value) {
+ MeasureOutOfLine(value.width);
+ MeasureOutOfLine(value.height);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::RoundedRectangleArgs& value) {
+ num_bytes_ += FIDL_ALIGN(144);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::RoundedRectangleArgs& value) {
+ MeasureOutOfLine(value.width);
+ MeasureOutOfLine(value.height);
+ MeasureOutOfLine(value.top_left_radius);
+ MeasureOutOfLine(value.top_right_radius);
+ MeasureOutOfLine(value.bottom_right_radius);
+ MeasureOutOfLine(value.bottom_left_radius);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::CircleArgs& value) {
+ num_bytes_ += FIDL_ALIGN(24);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::CircleArgs& value) {
+ MeasureOutOfLine(value.radius);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::MeshArgs& value) {
+ num_bytes_ += FIDL_ALIGN(1);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::MeshArgs& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::ShapeNodeArgs& value) {
+ num_bytes_ += FIDL_ALIGN(4);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::ShapeNodeArgs& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::ClipNodeArgs& value) {
+ num_bytes_ += FIDL_ALIGN(4);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::ClipNodeArgs& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::EntityNodeArgs& value) {
+ num_bytes_ += FIDL_ALIGN(4);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::EntityNodeArgs& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::OpacityNodeArgsHACK& value) {
+ num_bytes_ += FIDL_ALIGN(4);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::OpacityNodeArgsHACK& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::MaterialArgs& value) {
+ num_bytes_ += FIDL_ALIGN(4);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::MaterialArgs& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::CompositorArgs& value) {
+ num_bytes_ += FIDL_ALIGN(4);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::CompositorArgs& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::DisplayCompositorArgs& value) {
+ num_bytes_ += FIDL_ALIGN(4);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::DisplayCompositorArgs& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::ImagePipeCompositorArgs& value) {
+ num_bytes_ += FIDL_ALIGN(4);
+ MeasureHandles(value);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::ImagePipeCompositorArgs& value) {
+ }
+
+ void MeasureHandles(const ::fuchsia::ui::gfx::ImagePipeCompositorArgs& value) {
+ num_handles_ += 1;
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::LayerStackArgs& value) {
+ num_bytes_ += FIDL_ALIGN(4);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::LayerStackArgs& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::LayerArgs& value) {
+ num_bytes_ += FIDL_ALIGN(4);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::LayerArgs& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::SceneArgs& value) {
+ num_bytes_ += FIDL_ALIGN(4);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::SceneArgs& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::CameraArgs& value) {
+ num_bytes_ += FIDL_ALIGN(4);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::CameraArgs& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::StereoCameraArgs& value) {
+ num_bytes_ += FIDL_ALIGN(4);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::StereoCameraArgs& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::RendererArgs& value) {
+ num_bytes_ += FIDL_ALIGN(4);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::RendererArgs& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::AmbientLightArgs& value) {
+ num_bytes_ += FIDL_ALIGN(4);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::AmbientLightArgs& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::DirectionalLightArgs& value) {
+ num_bytes_ += FIDL_ALIGN(4);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::DirectionalLightArgs& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::VariableArgs& value) {
+ num_bytes_ += FIDL_ALIGN(32);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::VariableArgs& value) {
+ MeasureOutOfLine(value.initial_value);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::PointLightArgs& value) {
+ num_bytes_ += FIDL_ALIGN(4);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::PointLightArgs& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::ViewArgs3& value) {
+ num_bytes_ += FIDL_ALIGN(32);
+ MeasureHandles(value);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::ViewArgs3& value) {
+ MeasureOutOfLine(value.token);
+ MeasureOutOfLine(value.control_ref);
+ MeasureOutOfLine(value.view_ref);
+ if (value.debug_name) {
+ num_bytes_ += FIDL_ALIGN(value.debug_name->length());
+ }
+ }
+
+ void MeasureHandles(const ::fuchsia::ui::gfx::ViewArgs3& value) {
+ MeasureHandles(value.token);
+ MeasureHandles(value.control_ref);
+ MeasureHandles(value.view_ref);
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::ImagePipe2Args& value) {
+ num_bytes_ += FIDL_ALIGN(4);
+ MeasureHandles(value);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::ImagePipe2Args& value) {
+ }
+
+ void MeasureHandles(const ::fuchsia::ui::gfx::ImagePipe2Args& value) {
+ num_handles_ += 1;
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::vec3& value) {
+ num_bytes_ += FIDL_ALIGN(12);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::vec3& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::Quaternion& value) {
+ num_bytes_ += FIDL_ALIGN(16);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::Quaternion& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::mat4& value) {
+ num_bytes_ += FIDL_ALIGN(64);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::mat4& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::ColorRgb& value) {
+ num_bytes_ += FIDL_ALIGN(12);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::ColorRgb& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::ColorRgba& value) {
+ num_bytes_ += FIDL_ALIGN(4);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::ColorRgba& value) {
+ }
+
+ void Measure(const ::fuchsia::images::ImageInfo& value) {
+ num_bytes_ += FIDL_ALIGN(32);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::images::ImageInfo& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::views::ViewToken& value) {
+ num_bytes_ += FIDL_ALIGN(4);
+ MeasureHandles(value);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::views::ViewToken& value) {
+ }
+
+ void MeasureHandles(const ::fuchsia::ui::views::ViewToken& value) {
+ num_handles_ += 1;
+ }
+
+ void Measure(const ::fuchsia::ui::views::ViewHolderToken& value) {
+ num_bytes_ += FIDL_ALIGN(4);
+ MeasureHandles(value);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::views::ViewHolderToken& value) {
+ }
+
+ void MeasureHandles(const ::fuchsia::ui::views::ViewHolderToken& value) {
+ num_handles_ += 1;
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::Value& value) {
+ num_bytes_ += sizeof(fidl_xunion_t);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::Value& value) {
+ switch (value.Which()) {
+ case ::fuchsia::ui::gfx::Value::Tag::kVector1:
+ num_bytes_ += 8;
+ break;
+ case ::fuchsia::ui::gfx::Value::Tag::kVector2:
+ Measure(value.vector2());
+ break;
+ case ::fuchsia::ui::gfx::Value::Tag::kVector3:
+ Measure(value.vector3());
+ break;
+ case ::fuchsia::ui::gfx::Value::Tag::kVector4:
+ Measure(value.vector4());
+ break;
+ case ::fuchsia::ui::gfx::Value::Tag::kMatrix4x4:
+ Measure(value.matrix4x4());
+ break;
+ case ::fuchsia::ui::gfx::Value::Tag::kColorRgba:
+ Measure(value.color_rgba());
+ break;
+ case ::fuchsia::ui::gfx::Value::Tag::kColorRgb:
+ Measure(value.color_rgb());
+ break;
+ case ::fuchsia::ui::gfx::Value::Tag::kDegrees:
+ num_bytes_ += 8;
+ break;
+ case ::fuchsia::ui::gfx::Value::Tag::kQuaternion:
+ Measure(value.quaternion());
+ break;
+ case ::fuchsia::ui::gfx::Value::Tag::kTransform:
+ Measure(value.transform());
+ break;
+ case ::fuchsia::ui::gfx::Value::Tag::kVariableId:
+ num_bytes_ += 8;
+ break;
+ case ::fuchsia::ui::gfx::Value::Tag::Invalid:
+ MaxOut();
+ break;
+ }
+ }
+
+ void Measure(const ::fuchsia::ui::views::ViewRefControl& value) {
+ num_bytes_ += FIDL_ALIGN(4);
+ MeasureHandles(value);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::views::ViewRefControl& value) {
+ }
+
+ void MeasureHandles(const ::fuchsia::ui::views::ViewRefControl& value) {
+ num_handles_ += 1;
+ }
+
+ void Measure(const ::fuchsia::ui::views::ViewRef& value) {
+ num_bytes_ += FIDL_ALIGN(4);
+ MeasureHandles(value);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::views::ViewRef& value) {
+ }
+
+ void MeasureHandles(const ::fuchsia::ui::views::ViewRef& value) {
+ num_handles_ += 1;
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::vec4& value) {
+ num_bytes_ += FIDL_ALIGN(16);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::vec4& value) {
+ }
+
+ void Measure(const ::fuchsia::ui::gfx::FactoredTransform& value) {
+ num_bytes_ += FIDL_ALIGN(52);
+ MeasureOutOfLine(value);
+ }
+
+ void MeasureOutOfLine(const ::fuchsia::ui::gfx::FactoredTransform& value) {
+ MeasureOutOfLine(value.translation);
+ MeasureOutOfLine(value.scale);
+ MeasureOutOfLine(value.anchor);
+ MeasureOutOfLine(value.rotation);
+ }
+
+
+ Size Done() {
+ if (maxed_out_) {
+ return Size(ZX_CHANNEL_MAX_MSG_BYTES, ZX_CHANNEL_MAX_MSG_HANDLES);
+ }
+ return Size(num_bytes_, num_handles_);
+ }
+
+private:
+ void MaxOut() { maxed_out_ = true; }
+
+ bool maxed_out_ = false;
+ int64_t num_bytes_ = 0;
+ int64_t num_handles_ = 0;
+};
+
+} // namespace
+
+Size Measure(const ::fuchsia::ui::scenic::Command& value) {
+ MeasuringTape tape;
+ tape.Measure(value);
+ return tape.Done();
+}
+
+
+} // scenic
+} // ui
+} // fuchsia
+} // measure_tape
diff --git a/third_party/fuchsia-sdk/pkg/scenic_cpp/include/lib/ui/scenic/cpp/commands.h b/third_party/fuchsia-sdk/pkg/scenic_cpp/include/lib/ui/scenic/cpp/commands.h
new file mode 100644
index 0000000..48d4ee2
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/scenic_cpp/include/lib/ui/scenic/cpp/commands.h
@@ -0,0 +1,276 @@
+// Copyright 2017 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.
+
+#ifndef LIB_UI_SCENIC_CPP_COMMANDS_H_
+#define LIB_UI_SCENIC_CPP_COMMANDS_H_
+
+#include <fuchsia/images/cpp/fidl.h>
+#include <fuchsia/ui/gfx/cpp/fidl.h>
+#include <fuchsia/ui/scenic/cpp/fidl.h>
+#include <fuchsia/ui/views/cpp/fidl.h>
+#include <lib/zx/eventpair.h>
+#include <lib/zx/time.h>
+
+#include <string>
+
+namespace scenic {
+
+constexpr float kZeroesFloat3[3] = {0.f, 0.f, 0.f};
+constexpr float kOnesFloat3[3] = {1.f, 1.f, 1.f};
+// A quaterion that has no rotation.
+constexpr float kQuaternionDefault[4] = {0.f, 0.f, 0.f, 1.f};
+
+// Helper function for wrapping a GFX command as a Scenic command.
+fuchsia::ui::scenic::Command NewCommand(fuchsia::ui::gfx::Command command);
+
+// Helper function for wrapping an input command as a Scenic command.
+fuchsia::ui::scenic::Command NewCommand(fuchsia::ui::input::Command command);
+
+// Resource creation.
+fuchsia::ui::gfx::Command NewCreateMemoryCmd(uint32_t id, zx::vmo vmo, uint64_t allocation_size,
+ fuchsia::images::MemoryType memory_type);
+fuchsia::ui::gfx::Command NewCreateImageCmd(uint32_t id, uint32_t memory_id, uint32_t memory_offset,
+ fuchsia::images::ImageInfo info);
+fuchsia::ui::gfx::Command NewCreateImageCmd(uint32_t id, uint32_t memory_id, uint32_t memory_offset,
+ fuchsia::images::PixelFormat format,
+ fuchsia::images::ColorSpace color_space,
+ fuchsia::images::Tiling tiling, uint32_t width,
+ uint32_t height, uint32_t stride);
+fuchsia::ui::gfx::Command NewCreateImagePipeCmd(
+ uint32_t id, fidl::InterfaceRequest<fuchsia::images::ImagePipe> request);
+fuchsia::ui::gfx::Command NewCreateImagePipe2Cmd(
+ uint32_t id, fidl::InterfaceRequest<fuchsia::images::ImagePipe2> request);
+fuchsia::ui::gfx::Command NewCreateBufferCmd(uint32_t id, uint32_t memory_id,
+ uint32_t memory_offset, uint32_t num_bytes);
+
+fuchsia::ui::gfx::Command NewCreateCompositorCmd(uint32_t id);
+fuchsia::ui::gfx::Command NewCreateDisplayCompositorCmd(uint32_t id);
+fuchsia::ui::gfx::Command NewCreateLayerStackCmd(uint32_t id);
+fuchsia::ui::gfx::Command NewCreateLayerCmd(uint32_t id);
+
+fuchsia::ui::gfx::Command NewCreateSceneCmd(uint32_t id);
+fuchsia::ui::gfx::Command NewCreateCameraCmd(uint32_t id, uint32_t scene_id);
+fuchsia::ui::gfx::Command NewCreateStereoCameraCmd(uint32_t id, uint32_t scene_id);
+fuchsia::ui::gfx::Command NewCreateRendererCmd(uint32_t id);
+fuchsia::ui::gfx::Command NewCreateAmbientLightCmd(uint32_t id);
+fuchsia::ui::gfx::Command NewCreateDirectionalLightCmd(uint32_t id);
+fuchsia::ui::gfx::Command NewCreatePointLightCmd(uint32_t id);
+
+fuchsia::ui::gfx::Command NewCreateCircleCmd(uint32_t id, float radius);
+fuchsia::ui::gfx::Command NewCreateRectangleCmd(uint32_t id, float width, float height);
+fuchsia::ui::gfx::Command NewCreateRoundedRectangleCmd(uint32_t id, float width, float height,
+ float top_left_radius,
+ float top_right_radius,
+ float bottom_right_radius,
+ float bottom_left_radius);
+
+// Variant of NewCreateCircleCmd that uses a variable radius instead of a
+// constant one set at construction time.
+fuchsia::ui::gfx::Command NewCreateVarCircleCmd(uint32_t id, uint32_t radius_var_id);
+// Variant of NewCreateRectangleCmd that uses a variable width/height
+// instead of constant ones set at construction time.
+fuchsia::ui::gfx::Command NewCreateVarRectangleCmd(uint32_t id, uint32_t width_var_id,
+ uint32_t height_var_id);
+// Variant of NewCreateRoundedRectangleCmd that uses a variable
+// width/height/etc. instead of constant ones set at construction time.
+fuchsia::ui::gfx::Command NewCreateVarRoundedRectangleCmd(uint32_t id, uint32_t width_var_id,
+ uint32_t height_var_id,
+ uint32_t top_left_radius_var_id,
+ uint32_t top_right_radius_var_id,
+ uint32_t bottom_left_radius_var_id,
+ uint32_t bottom_right_radius_var_id);
+
+fuchsia::ui::gfx::Command NewCreateMeshCmd(uint32_t id);
+fuchsia::ui::gfx::Command NewCreateMaterialCmd(uint32_t id);
+fuchsia::ui::gfx::Command NewCreateClipNodeCmd(uint32_t id);
+fuchsia::ui::gfx::Command NewCreateEntityNodeCmd(uint32_t id);
+fuchsia::ui::gfx::Command NewCreateOpacityNodeCmdHACK(uint32_t id);
+fuchsia::ui::gfx::Command NewCreateShapeNodeCmd(uint32_t id);
+
+fuchsia::ui::gfx::Command NewCreateViewCmd(uint32_t id, fuchsia::ui::views::ViewToken token,
+ const fit::optional<std::string>& debug_name);
+fuchsia::ui::gfx::Command NewCreateViewCmd(uint32_t id, fuchsia::ui::views::ViewToken token,
+ fuchsia::ui::views::ViewRefControl control_ref,
+ fuchsia::ui::views::ViewRef view_ref,
+ const fit::optional<std::string>& debug_name);
+fuchsia::ui::gfx::Command NewCreateViewHolderCmd(uint32_t id,
+ fuchsia::ui::views::ViewHolderToken token,
+ const fit::optional<std::string>& debug_name);
+
+fuchsia::ui::gfx::Command NewCreateVariableCmd(uint32_t id, fuchsia::ui::gfx::Value value);
+
+fuchsia::ui::gfx::Command NewReleaseResourceCmd(uint32_t id);
+
+// Export & Import operations.
+fuchsia::ui::gfx::Command NewExportResourceCmd(uint32_t resource_id, zx::eventpair export_token);
+fuchsia::ui::gfx::Command NewImportResourceCmd(uint32_t resource_id,
+ fuchsia::ui::gfx::ImportSpec spec,
+ zx::eventpair import_token);
+
+// Exports the resource and returns an import token in |out_import_token|
+// which allows it to be imported into other sessions.
+fuchsia::ui::gfx::Command NewExportResourceCmdAsRequest(uint32_t resource_id,
+ zx::eventpair* out_import_token);
+
+// Imports the resource and returns an export token in |out_export_token|
+// by which another session can export a resource to associate with this import.
+fuchsia::ui::gfx::Command NewImportResourceCmdAsRequest(uint32_t resource_id,
+ fuchsia::ui::gfx::ImportSpec import_spec,
+ zx::eventpair* out_export_token);
+
+// View/ViewHolder commands.
+fuchsia::ui::gfx::Command NewSetViewPropertiesCmd(uint32_t view_holder_id,
+ const std::array<float, 3>& bounding_box_min,
+ const std::array<float, 3>& bounding_box_max,
+ const std::array<float, 3>& inset_from_min,
+ const std::array<float, 3>& inset_from_max);
+fuchsia::ui::gfx::Command NewSetViewPropertiesCmd(uint32_t view_holder_id,
+ const fuchsia::ui::gfx::ViewProperties& props);
+
+// Node operations.
+fuchsia::ui::gfx::Command NewAddChildCmd(uint32_t node_id, uint32_t child_id);
+fuchsia::ui::gfx::Command NewAddPartCmd(uint32_t node_id, uint32_t part_id);
+fuchsia::ui::gfx::Command NewDetachCmd(uint32_t node_id);
+fuchsia::ui::gfx::Command NewDetachChildrenCmd(uint32_t node_id);
+fuchsia::ui::gfx::Command NewSetTranslationCmd(uint32_t node_id,
+ const std::array<float, 3>& translation);
+fuchsia::ui::gfx::Command NewSetTranslationCmd(uint32_t node_id, uint32_t variable_id);
+fuchsia::ui::gfx::Command NewSetScaleCmd(uint32_t node_id, const std::array<float, 3>& scale);
+fuchsia::ui::gfx::Command NewSetScaleCmd(uint32_t node_id, uint32_t variable_id);
+fuchsia::ui::gfx::Command NewSetRotationCmd(uint32_t node_id,
+ const std::array<float, 4>& quaternion);
+fuchsia::ui::gfx::Command NewSetRotationCmd(uint32_t node_id, uint32_t variable_id);
+fuchsia::ui::gfx::Command NewSetAnchorCmd(uint32_t node_id, const std::array<float, 3>& anchor);
+fuchsia::ui::gfx::Command NewSetAnchorCmd(uint32_t node_id, uint32_t variable_id);
+
+fuchsia::ui::gfx::Command NewSetOpacityCmd(uint32_t node_id, float opacity);
+fuchsia::ui::gfx::Command NewSendSizeChangeHintCmdHACK(uint32_t node_id, float width_change_factor,
+ float height_change_factor);
+fuchsia::ui::gfx::Command NewSetShapeCmd(uint32_t node_id, uint32_t shape_id);
+fuchsia::ui::gfx::Command NewSetMaterialCmd(uint32_t node_id, uint32_t material_id);
+fuchsia::ui::gfx::Command NewSetClipCmd(uint32_t node_id, uint32_t clip_id, bool clip_to_self);
+fuchsia::ui::gfx::Command NewSetClipPlanesCmd(uint32_t node_id,
+ std::vector<fuchsia::ui::gfx::Plane3> planes);
+fuchsia::ui::gfx::Command NewSetTagCmd(uint32_t node_id, uint32_t tag_value);
+fuchsia::ui::gfx::Command NewSetHitTestBehaviorCmd(
+ uint32_t node_id, fuchsia::ui::gfx::HitTestBehavior hit_test_behavior);
+
+// Display Commands.
+fuchsia::ui::gfx::Command NewSetEnableDebugViewBoundsCmd(uint32_t view_id, bool enable);
+fuchsia::ui::gfx::Command NewSetViewHolderBoundsColorCmd(uint32_t view_holder_id, uint8_t red,
+ uint8_t green, uint8_t blue);
+
+fuchsia::ui::gfx::Command NewSetDisplayColorConversionCmdHACK(
+ uint32_t compositor_id, const std::array<float, 3>& preoffsets,
+ const std::array<float, 3 * 3>& matrix, const std::array<float, 3>& postoffsets);
+
+fuchsia::ui::gfx::Command NewSetDisplayRotationCmdHACK(uint32_t compositor_id,
+ uint32_t rotation_degrees);
+
+// Camera and lighting operations.
+
+fuchsia::ui::gfx::Command NewSetCameraCmd(uint32_t renderer_id, uint32_t camera_id);
+fuchsia::ui::gfx::Command NewSetCameraTransformCmd(uint32_t camera_id,
+ const std::array<float, 3>& eye_position,
+ const std::array<float, 3>& eye_look_at,
+ const std::array<float, 3>& eye_up);
+fuchsia::ui::gfx::Command NewSetCameraProjectionCmd(uint32_t camera_id, const float fovy);
+fuchsia::ui::gfx::Command NewSetCameraClipSpaceTransformCmd(uint32_t camera_id, float x, float y,
+ float scale);
+
+fuchsia::ui::gfx::Command NewSetCameraPoseBufferCmd(uint32_t camera_id, uint32_t buffer_id,
+ uint32_t num_entries, int64_t base_time,
+ uint64_t time_interval);
+
+// Overloaded |NewSetCameraPoseBufferCmd()| to support `zx::time` and `zx::duration`.
+fuchsia::ui::gfx::Command NewSetCameraPoseBufferCmd(uint32_t camera_id, uint32_t buffer_id,
+ uint32_t num_entries, zx::time base_time,
+ zx::duration time_interval);
+
+fuchsia::ui::gfx::Command NewSetStereoCameraProjectionCmd(
+ uint32_t camera_id, const std::array<float, 4 * 4>& left_projection,
+ const std::array<float, 4 * 4>& right_projection);
+
+fuchsia::ui::gfx::Command NewSetLightColorCmd(uint32_t light_id, const std::array<float, 3>& rgb);
+fuchsia::ui::gfx::Command NewSetLightColorCmd(uint32_t light_id, uint32_t variable_id);
+fuchsia::ui::gfx::Command NewSetLightDirectionCmd(uint32_t light_id,
+ const std::array<float, 3>& direction);
+fuchsia::ui::gfx::Command NewSetLightDirectionCmd(uint32_t light_id, uint32_t variable_id);
+fuchsia::ui::gfx::Command NewSetPointLightPositionCmd(uint32_t light_id,
+ const std::array<float, 3>& position);
+fuchsia::ui::gfx::Command NewSetPointLightPositionCmd(uint32_t light_id, uint32_t variable_id);
+fuchsia::ui::gfx::Command NewSetPointLightPositionCmd(uint32_t light_id,
+ const std::array<float, 3>& position);
+fuchsia::ui::gfx::Command NewSetPointLightFalloffCmd(uint32_t light_id, float falloff);
+fuchsia::ui::gfx::Command NewAddLightCmd(uint32_t scene_id, uint32_t light_id);
+fuchsia::ui::gfx::Command NewSceneAddAmbientLightCmd(uint32_t scene_id, uint32_t light_id);
+fuchsia::ui::gfx::Command NewSceneAddDirectionalLightCmd(uint32_t scene_id, uint32_t light_id);
+fuchsia::ui::gfx::Command NewSceneAddPointLightCmd(uint32_t scene_id, uint32_t light_id);
+fuchsia::ui::gfx::Command NewDetachLightCmd(uint32_t light_id);
+fuchsia::ui::gfx::Command NewDetachLightsCmd(uint32_t scene_id);
+
+// Material operations.
+fuchsia::ui::gfx::Command NewSetTextureCmd(uint32_t material_id, uint32_t texture_id);
+fuchsia::ui::gfx::Command NewSetColorCmd(uint32_t material_id, uint8_t red, uint8_t green,
+ uint8_t blue, uint8_t alpha);
+
+// Mesh operations.
+fuchsia::ui::gfx::MeshVertexFormat NewMeshVertexFormat(fuchsia::ui::gfx::ValueType position_type,
+ fuchsia::ui::gfx::ValueType normal_type,
+ fuchsia::ui::gfx::ValueType tex_coord_type);
+// These arguments are documented in commands.fidl; see BindMeshBuffersCmd.
+fuchsia::ui::gfx::Command NewBindMeshBuffersCmd(
+ uint32_t mesh_id, uint32_t index_buffer_id, fuchsia::ui::gfx::MeshIndexFormat index_format,
+ uint64_t index_offset, uint32_t index_count, uint32_t vertex_buffer_id,
+ fuchsia::ui::gfx::MeshVertexFormat vertex_format, uint64_t vertex_offset, uint32_t vertex_count,
+ const std::array<float, 3>& bounding_box_min, const std::array<float, 3>& bounding_box_max);
+
+// Layer / LayerStack / Compositor operations.
+fuchsia::ui::gfx::Command NewAddLayerCmd(uint32_t layer_stack_id, uint32_t layer_id);
+fuchsia::ui::gfx::Command NewRemoveLayerCmd(uint32_t layer_stack_id, uint32_t layer_id);
+fuchsia::ui::gfx::Command NewRemoveAllLayersCmd(uint32_t layer_stack_id);
+fuchsia::ui::gfx::Command NewSetLayerStackCmd(uint32_t compositor_id, uint32_t layer_stack_id);
+fuchsia::ui::gfx::Command NewSetRendererCmd(uint32_t layer_id, uint32_t renderer_id);
+fuchsia::ui::gfx::Command NewSetRendererParamCmd(uint32_t renderer_id,
+ fuchsia::ui::gfx::RendererParam param);
+fuchsia::ui::gfx::Command NewSetSizeCmd(uint32_t node_id, const std::array<float, 2>& size);
+
+// Event operations.
+fuchsia::ui::gfx::Command NewSetEventMaskCmd(uint32_t resource_id, uint32_t event_mask);
+
+// Diagnostic operations.
+fuchsia::ui::gfx::Command NewSetLabelCmd(uint32_t resource_id, const std::string& label);
+
+// Debugging operations.
+fuchsia::ui::gfx::Command NewSetDisableClippingCmd(uint32_t renderer_id, bool disable_clipping);
+
+// Basic types.
+// All functions with C-style array arguments are deprecated. Use the std::array version instead.
+fuchsia::ui::gfx::FloatValue NewFloatValue(float value);
+fuchsia::ui::gfx::Vector2Value NewVector2Value(const std::array<float, 2>& value);
+fuchsia::ui::gfx::Vector2Value NewVector2Value(uint32_t variable_id);
+fuchsia::ui::gfx::Vector3Value NewVector3Value(const std::array<float, 3>& value);
+fuchsia::ui::gfx::Vector3Value NewVector3Value(uint32_t variable_id);
+fuchsia::ui::gfx::Vector4Value NewVector4Value(const std::array<float, 4>& value);
+fuchsia::ui::gfx::Vector4Value NewVector4Value(uint32_t variable_id);
+fuchsia::ui::gfx::QuaternionValue NewQuaternionValue(const std::array<float, 4>& value);
+fuchsia::ui::gfx::QuaternionValue NewQuaternionValue(uint32_t variable_id);
+fuchsia::ui::gfx::Matrix4Value NewMatrix4Value(const std::array<float, 4 * 4>& matrix);
+fuchsia::ui::gfx::Matrix4Value NewMatrix4Value(uint32_t variable_id);
+fuchsia::ui::gfx::ColorRgbValue NewColorRgbValue(float red, float green, float blue);
+fuchsia::ui::gfx::ColorRgbValue NewColorRgbValue(uint32_t variable_id);
+fuchsia::ui::gfx::ColorRgbaValue NewColorRgbaValue(const std::array<uint8_t, 4>& value);
+fuchsia::ui::gfx::ColorRgbaValue NewColorRgbaValue(uint32_t variable_id);
+fuchsia::ui::gfx::QuaternionValue NewQuaternionValue(const std::array<float, 4>& value);
+fuchsia::ui::gfx::vec2 NewVector2(const std::array<float, 2>& value);
+fuchsia::ui::gfx::vec3 NewVector3(const std::array<float, 3>& value);
+fuchsia::ui::gfx::vec4 NewVector4(const std::array<float, 4>& value);
+
+// Utilities.
+
+bool ImageInfoEquals(const fuchsia::images::ImageInfo& a, const fuchsia::images::ImageInfo& b);
+
+} // namespace scenic
+
+#endif // LIB_UI_SCENIC_CPP_COMMANDS_H_
diff --git a/third_party/fuchsia-sdk/pkg/scenic_cpp/include/lib/ui/scenic/cpp/commands_sizing.h b/third_party/fuchsia-sdk/pkg/scenic_cpp/include/lib/ui/scenic/cpp/commands_sizing.h
new file mode 100644
index 0000000..98a0aa6
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/scenic_cpp/include/lib/ui/scenic/cpp/commands_sizing.h
@@ -0,0 +1,35 @@
+// File is automatically generated; do not modify.
+// See tools/fidl/measure-tape/README.md
+
+#ifndef LIB_UI_SCENIC_CPP_COMMANDS_SIZING_H_
+#define LIB_UI_SCENIC_CPP_COMMANDS_SIZING_H_
+
+#include <fuchsia/ui/scenic/cpp/fidl.h>
+
+
+namespace measure_tape {
+namespace fuchsia {
+namespace ui {
+namespace scenic {
+
+struct Size {
+ explicit Size(int64_t num_bytes, int64_t num_handles)
+ : num_bytes(num_bytes), num_handles(num_handles) {}
+
+ const int64_t num_bytes;
+ const int64_t num_handles;
+};
+
+// Helper function to measure ::fuchsia::ui::scenic::Command.
+//
+// In most cases, the size returned is a precise size. Otherwise, the size
+// returned is a safe upper-bound.
+Size Measure(const ::fuchsia::ui::scenic::Command& value);
+
+
+} // scenic
+} // ui
+} // fuchsia
+} // measure_tape
+
+#endif // LIB_UI_SCENIC_CPP_COMMANDS_SIZING_H_
diff --git a/third_party/fuchsia-sdk/pkg/scenic_cpp/include/lib/ui/scenic/cpp/id.h b/third_party/fuchsia-sdk/pkg/scenic_cpp/include/lib/ui/scenic/cpp/id.h
new file mode 100644
index 0000000..a500046
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/scenic_cpp/include/lib/ui/scenic/cpp/id.h
@@ -0,0 +1,17 @@
+// Copyright 2018 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.
+
+#ifndef LIB_UI_SCENIC_CPP_ID_H_
+#define LIB_UI_SCENIC_CPP_ID_H_
+
+#include <cstdint>
+
+namespace scenic {
+
+using SessionId = uint64_t;
+using ResourceId = uint32_t;
+
+} // namespace scenic
+
+#endif // LIB_UI_SCENIC_CPP_ID_H_
diff --git a/third_party/fuchsia-sdk/pkg/scenic_cpp/include/lib/ui/scenic/cpp/resources.h b/third_party/fuchsia-sdk/pkg/scenic_cpp/include/lib/ui/scenic/cpp/resources.h
new file mode 100644
index 0000000..99da011
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/scenic_cpp/include/lib/ui/scenic/cpp/resources.h
@@ -0,0 +1,640 @@
+// Copyright 2017 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.
+
+#ifndef LIB_UI_SCENIC_CPP_RESOURCES_H_
+#define LIB_UI_SCENIC_CPP_RESOURCES_H_
+
+#include <fuchsia/images/cpp/fidl.h>
+#include <fuchsia/ui/gfx/cpp/fidl.h>
+#include <fuchsia/ui/views/cpp/fidl.h>
+#include <lib/ui/scenic/cpp/session.h>
+#include <lib/zx/time.h>
+#include <zircon/assert.h>
+
+#include <array>
+
+namespace scenic {
+
+// Represents a resource in a session with a dynamically allocated id.
+// The resource is released from the session when this object is destroyed
+// but it may still be in use within the session if other resources reference
+// it.
+// This type cannot be instantiated, please see subclasses.
+class Resource {
+ public:
+ // Gets the session which owns this resource.
+ Session* session() const {
+ ZX_DEBUG_ASSERT(session_);
+ return session_;
+ }
+
+ // Gets the resource's id.
+ uint32_t id() const { return id_; }
+
+ // Exports the resource and associates it with |export_token|.
+ void Export(zx::eventpair export_token);
+
+ // Exports the resource and returns an import token in |out_import_token|
+ // which allows it to be imported into other sessions.
+ void ExportAsRequest(zx::eventpair* out_import_token);
+
+ // Sets which events a resource should deliver to the session listener.
+ void SetEventMask(uint32_t event_mask);
+
+ // Sets a label to help developers identify the purpose of the resource
+ // when using diagnostic tools.
+ void SetLabel(const std::string& label);
+
+ protected:
+ explicit Resource(Session* session);
+ Resource(Resource&& moved) noexcept;
+
+ Resource(const Resource&) = delete;
+ Resource& operator=(const Resource&) = delete;
+
+ virtual ~Resource();
+
+ private:
+ Session* const session_;
+ uint32_t const id_;
+};
+
+// Represents a memory resource in a session.
+// TODO(SCN-268): Make this class final, and add public move constructor.
+class Memory : public Resource {
+ public:
+ Memory(Session* session, zx::vmo vmo, uint64_t allocation_size,
+ fuchsia::images::MemoryType memory_type);
+ ~Memory();
+
+ // Gets the underlying VMO's memory type, indicating whether it represents
+ // host or GPU memory.
+ fuchsia::images::MemoryType memory_type() const { return memory_type_; }
+
+ protected:
+ Memory(Memory&& moved) noexcept;
+
+ private:
+ fuchsia::images::MemoryType const memory_type_;
+};
+
+// Represents an abstract shape resource in a session.
+// This type cannot be instantiated, please see subclasses.
+class Shape : public Resource {
+ protected:
+ explicit Shape(Session* session);
+ Shape(Shape&& moved) noexcept;
+ ~Shape();
+};
+
+// Represents a circle shape resource in a session.
+class Circle final : public Shape {
+ public:
+ Circle(Session* session, float radius);
+ Circle(Circle&& moved) noexcept;
+ ~Circle();
+};
+
+// Represents a rectangle shape resource in a session.
+class Rectangle final : public Shape {
+ public:
+ Rectangle(Session* session, float width, float height);
+ Rectangle(Rectangle&& moved) noexcept;
+ ~Rectangle();
+};
+
+// Represents a rounded rectangle shape resource in a session.
+class RoundedRectangle final : public Shape {
+ public:
+ RoundedRectangle(Session* session, float width, float height, float top_left_radius,
+ float top_right_radius, float bottom_right_radius, float bottom_left_radius);
+ RoundedRectangle(RoundedRectangle&& moved) noexcept;
+ ~RoundedRectangle();
+};
+
+// Represents an image resource in a session.
+// TODO(SCN-268): Make this class final, and add public move constructor.
+class Image : public Resource {
+ public:
+ // Creates an image resource bound to a session.
+ Image(const Memory& memory, off_t memory_offset, fuchsia::images::ImageInfo info);
+ Image(Session* session, uint32_t memory_id, off_t memory_offset, fuchsia::images::ImageInfo info);
+ ~Image();
+
+ // Returns the number of bytes needed to represent an image.
+ static size_t ComputeSize(const fuchsia::images::ImageInfo& image_info);
+
+ // Gets the byte offset of the image within its memory resource.
+ off_t memory_offset() const { return memory_offset_; }
+
+ // Gets information about the image's layout.
+ const fuchsia::images::ImageInfo& info() const { return info_; }
+
+ protected:
+ Image(Image&& moved) noexcept;
+
+ private:
+ off_t const memory_offset_;
+ fuchsia::images::ImageInfo const info_;
+};
+
+// Represents a buffer that is immutably bound to a range of a memory resource.
+class Buffer final : public Resource {
+ public:
+ Buffer(const Memory& memory, off_t memory_offset, size_t num_bytes);
+ Buffer(Session* session, uint32_t memory_id, off_t memory_offset, size_t num_bytes);
+ Buffer(Buffer&& moved) noexcept;
+ ~Buffer();
+};
+
+// Represents a mesh resource in a session. Before it can be rendered, it
+// must be bound to index and vertex arrays by calling the BindBuffers() method.
+class Mesh final : public Shape {
+ public:
+ Mesh(Session* session);
+ Mesh(Mesh&& moved) noexcept;
+
+ ~Mesh();
+
+ // These arguments are documented in commands.fidl; see
+ // BindMeshBuffersCmd.
+ void BindBuffers(const Buffer& index_buffer, fuchsia::ui::gfx::MeshIndexFormat index_format,
+ uint64_t index_offset, uint32_t index_count, const Buffer& vertex_buffer,
+ fuchsia::ui::gfx::MeshVertexFormat vertex_format, uint64_t vertex_offset,
+ uint32_t vertex_count, const std::array<float, 3>& bounding_box_min,
+ const std::array<float, 3>& bounding_box_max);
+};
+
+// Represents a material resource in a session.
+class Material final : public Resource {
+ public:
+ explicit Material(Session* session);
+ Material(Material&& moved) noexcept;
+ ~Material();
+
+ // Sets the material's texture.
+ void SetTexture(const Image& image) {
+ ZX_DEBUG_ASSERT(session() == image.session());
+ SetTexture(image.id());
+ }
+ void SetTexture(uint32_t image_id);
+
+ // Sets the material's color.
+ void SetColor(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha);
+};
+
+// Represents an abstract node resource in a session.
+// This type cannot be instantiated, please see subclasses.
+class Node : public Resource {
+ public:
+ // Sets the node's transform properties.
+ void SetTranslation(float tx, float ty, float tz) { SetTranslation({tx, ty, tz}); }
+
+ void SetTranslation(const std::array<float, 3>& translation);
+
+ void SetTranslation(uint32_t variable_id);
+
+ void SetScale(float sx, float sy, float sz) { SetScale({sx, sy, sz}); }
+ void SetScale(const std::array<float, 3>& scale);
+ void SetScale(uint32_t variable_id);
+ void SetRotation(float qi, float qj, float qk, float qw) { SetRotation({qi, qj, qk, qw}); }
+ void SetRotation(const std::array<float, 4>& quaternion);
+ void SetRotation(uint32_t variable_id);
+ void SetAnchor(float ax, float ay, float az) { SetAnchor({ax, ay, az}); }
+ void SetAnchor(const std::array<float, 3>& anchor);
+ void SetAnchor(uint32_t variable_id);
+
+ void SendSizeChangeHint(float width_change_factor, float height_change_factor);
+
+ // Sets the node's tag value.
+ void SetTag(uint32_t tag_value);
+
+ // Sets the node's hit test behavior.
+ void SetHitTestBehavior(fuchsia::ui::gfx::HitTestBehavior hit_test_behavior);
+
+ // Detaches the node from its parent.
+ void Detach();
+
+ protected:
+ explicit Node(Session* session);
+ Node(Node&& moved) noexcept;
+ ~Node();
+};
+
+// Represents an shape node resource in a session.
+class ShapeNode final : public Node {
+ public:
+ explicit ShapeNode(Session* session);
+ ShapeNode(ShapeNode&& moved) noexcept;
+ ~ShapeNode();
+
+ // Sets the shape that the shape node should draw.
+ void SetShape(const Shape& shape) {
+ ZX_DEBUG_ASSERT(session() == shape.session());
+ SetShape(shape.id());
+ }
+ void SetShape(uint32_t shape_id);
+
+ // Sets the material with which to draw the shape.
+ void SetMaterial(const Material& material) {
+ ZX_DEBUG_ASSERT(session() == material.session());
+ SetMaterial(material.id());
+ }
+ void SetMaterial(uint32_t material_id);
+};
+
+// Abstract base class for nodes which can have child nodes.
+// This type cannot be instantiated, please see subclasses.
+class ContainerNode : public Node {
+ public:
+ // Adds a child to the node.
+ void AddChild(const Node& child) {
+ ZX_DEBUG_ASSERT(session() == child.session());
+ AddChild(child.id());
+ }
+ void AddChild(uint32_t child_node_id);
+
+ // Detaches all children from the node.
+ void DetachChildren();
+
+ protected:
+ explicit ContainerNode(Session* session);
+ ContainerNode(ContainerNode&& moved) noexcept;
+ ~ContainerNode();
+};
+
+// Required by EntityNode::Attach().
+class ViewHolder;
+
+// Represents an entity node resource in a session.
+// TODO(SCN-268): Make this class final, and add public move constructor.
+class EntityNode : public ContainerNode {
+ public:
+ explicit EntityNode(Session* session);
+ EntityNode(EntityNode&& moved) noexcept;
+ ~EntityNode();
+
+ void SetClip(uint32_t clip_id, bool clip_to_self);
+ void SetClipPlanes(std::vector<fuchsia::ui::gfx::Plane3> planes);
+
+ // Deprecated(38480): use |AddChild| instead.
+ void Attach(const ViewHolder& view_holder);
+};
+
+// Represents an imported node resource in a session.
+// The imported node is initially created in an unbound state and must
+// be bound immediately after creation, prior to use.
+//
+// Deprecated(38480): use EntityNode instead or consider omitting.
+class ImportNode final : public ContainerNode {
+ public:
+ explicit ImportNode(Session* session);
+ ImportNode(ImportNode&& moved) noexcept;
+ ~ImportNode();
+
+ // Imports the node associated with |import_token|.
+ void Bind(zx::eventpair import_token);
+
+ // Imports the node and returns an export token in |out_export_token|
+ // by which another session can export a node to associate with this import.
+ void BindAsRequest(zx::eventpair* out_export_token);
+
+ // Returns true if the import has been bound.
+ bool is_bound() const { return is_bound_; }
+
+ void Attach(const ViewHolder& view_holder);
+
+ private:
+ bool is_bound_ = false;
+};
+
+/// Represents an attachment point for a subgraph within a larger scene graph.
+/// The |ViewHolder| can be attached to a Node as a child, and the contents of
+/// the linked |View| will become a child of the Node as well.
+///
+/// Each |ViewHolder| is linked to a paired |View| via a shared token pair.
+class ViewHolder final : public Node {
+ public:
+ ViewHolder(Session* session, zx::eventpair token, const std::string& debug_name);
+ ViewHolder(Session* session, fuchsia::ui::views::ViewHolderToken token,
+ const std::string& debug_name);
+ ViewHolder(ViewHolder&& moved) noexcept;
+ ~ViewHolder();
+
+ // Set properties of the attached view.
+
+ void SetViewProperties(float min_x, float min_y, float min_z, float max_x, float max_y,
+ float max_z, float in_min_x, float in_min_y, float in_min_z,
+ float in_max_x, float in_max_y, float in_max_z) {
+ SetViewProperties({min_x, min_y, min_z}, {max_x, max_y, max_z}, {in_min_x, in_min_y, in_min_z},
+ {in_max_x, in_max_y, in_max_z});
+ }
+ void SetViewProperties(const std::array<float, 3>& bounding_box_min,
+ const std::array<float, 3>& bounding_box_max,
+ const std::array<float, 3>& inset_from_min,
+ const std::array<float, 3>& inset_from_max);
+ void SetViewProperties(const fuchsia::ui::gfx::ViewProperties& props);
+
+ void SetDebugBoundsColor(uint8_t red, uint8_t green, uint8_t blue);
+};
+
+// Represents the root of a subgraph within a larger scene graph. |Node|s can
+// be attached to the |View| as children, and these |Node|s will have the
+// |View|s' coordinate transform applied to their own, in addition to being
+// clipped to the |View|s' bounding box.
+//
+// Each |View| is linked to an associated |ViewHolder| via a shared token pair.
+class View final : public Resource {
+ public:
+ View(Session* session, zx::eventpair token, const std::string& debug_name);
+ View(Session* session, fuchsia::ui::views::ViewToken token, const std::string& debug_name);
+ View(Session* session, fuchsia::ui::views::ViewToken token,
+ fuchsia::ui::views::ViewRefControl control_ref, fuchsia::ui::views::ViewRef view_ref,
+ const std::string& debug_name);
+ View(View&& moved) noexcept;
+ ~View();
+
+ void AddChild(const Node& child) const;
+ void DetachChild(const Node& child) const;
+
+ void enableDebugBounds(bool enable);
+};
+
+// Creates a node that clips the contents of its hierarchy to the specified clip
+// shape.
+class ClipNode final : public ContainerNode {
+ public:
+ explicit ClipNode(Session* session);
+ ClipNode(ClipNode&& moved) noexcept;
+ ~ClipNode();
+};
+
+// Creates a node that renders its hierarchy with the specified opacity.
+class OpacityNodeHACK final : public ContainerNode {
+ public:
+ explicit OpacityNodeHACK(Session* session);
+ OpacityNodeHACK(OpacityNodeHACK&& moved) noexcept;
+ ~OpacityNodeHACK();
+
+ // The opacity with which to render the contents of the hierarchy rooted at
+ // this node. The opacity values are clamped 0.0 to 1.0.
+ void SetOpacity(float opacity);
+};
+
+// A value that can be used in place of a constant value.
+class Variable final : public Resource {
+ public:
+ explicit Variable(Session* session, fuchsia::ui::gfx::Value initial_value);
+ Variable(Variable&& moved) noexcept;
+ ~Variable();
+};
+
+// Represents an abstract light resource in a session.
+// This type cannot be instantiated, please see subclasses.
+class Light : public Resource {
+ public:
+ // Sets the light's color.
+ void SetColor(float red, float green, float blue) { SetColor({red, green, blue}); }
+ void SetColor(const std::array<float, 3>& rgb);
+ void SetColor(uint32_t variable_id);
+
+ // Detach light from the scene it is attached to, if any.
+ void Detach();
+
+ protected:
+ explicit Light(Session* session);
+ Light(Light&& moved) noexcept;
+ ~Light();
+};
+
+// Represents a directional light resource in a session.
+class AmbientLight final : public Light {
+ public:
+ explicit AmbientLight(Session* session);
+ AmbientLight(AmbientLight&& moved) noexcept;
+ ~AmbientLight();
+};
+
+// Represents a directional light resource in a session.
+class DirectionalLight final : public Light {
+ public:
+ explicit DirectionalLight(Session* session);
+ DirectionalLight(DirectionalLight&& moved) noexcept;
+ ~DirectionalLight();
+
+ // Sets the light's direction.
+ void SetDirection(float dx, float dy, float dz) { SetDirection({dx, dy, dz}); }
+ void SetDirection(const std::array<float, 3>& direction);
+ void SetDirection(uint32_t variable_id);
+};
+
+// Represents a point light resource in a session.
+class PointLight final : public Light {
+ public:
+ explicit PointLight(Session* session);
+ PointLight(PointLight&& moved) noexcept;
+ ~PointLight();
+
+ // Sets the light's direction.
+ void SetPosition(float dx, float dy, float dz) { SetPosition({dx, dy, dz}); }
+ void SetPosition(const std::array<float, 3>& position);
+ void SetPosition(uint32_t variable_id);
+
+ // Set the light's falloff.
+ void SetFalloff(float falloff);
+};
+
+// Represents a scene resource in a session.
+class Scene final : public ContainerNode {
+ public:
+ explicit Scene(Session* session);
+ Scene(Scene&& moved) noexcept;
+ ~Scene();
+
+ void AddLight(const Light& light) {
+ ZX_DEBUG_ASSERT(session() == light.session());
+ AddLight(light.id());
+ }
+ void AddLight(uint32_t light_id);
+
+ void AddAmbientLight(const AmbientLight& light) {
+ ZX_DEBUG_ASSERT(session() == light.session());
+ AddAmbientLight(light.id());
+ }
+ void AddAmbientLight(uint32_t light_id);
+
+ void AddDirectionalLight(const DirectionalLight& light) {
+ ZX_DEBUG_ASSERT(session() == light.session());
+ AddDirectionalLight(light.id());
+ }
+ void AddDirectionalLight(uint32_t light_id);
+
+ void AddPointLight(const PointLight& light) {
+ ZX_DEBUG_ASSERT(session() == light.session());
+ AddPointLight(light.id());
+ }
+ void AddPointLight(uint32_t light_id);
+
+ void DetachLights();
+
+ private:
+ void Detach() = delete;
+};
+
+class CameraBase : public Resource {
+ public:
+ CameraBase(Session* session) : Resource(session) {}
+ CameraBase(CameraBase&& moved) noexcept : Resource(std::move(moved)) {}
+ ~CameraBase() {}
+ // Sets the camera's view parameters.
+ void SetTransform(const std::array<float, 3>& eye_position,
+ const std::array<float, 3>& eye_look_at, const std::array<float, 3>& eye_up);
+ // Sets the camera's 2-D clip-space transform. Translation is in Vulkan NDC ([-1, 1]^2), after
+ // scaling, so for example, under a scale of 3, (-3, -3) would translate to center the lower right
+ // corner, whereas (-2, -2) would align the lower right corner with that of the clipping volume.
+ // Scaling occurs on the x/y plane. z is unaffected.
+ void SetClipSpaceTransform(float x, float y, float scale);
+ // Sets the camera pose buffer
+ void SetPoseBuffer(const Buffer& buffer, uint32_t num_entries, int64_t base_time,
+ uint64_t time_interval);
+ // Overloaded version of |SetPoseBuffer()| using `zx::time` and `zx::duration`.
+ void SetPoseBuffer(const Buffer& buffer, uint32_t num_entries, zx::time base_time,
+ zx::duration time_interval);
+};
+
+// Represents a camera resource in a session.
+class Camera : public CameraBase {
+ public:
+ explicit Camera(const Scene& scene);
+ Camera(Session* session, uint32_t scene_id);
+ Camera(Camera&& moved) noexcept;
+ ~Camera();
+
+ // Sets the camera's projection parameters.
+ void SetProjection(const float fovy);
+};
+
+// Represents a StereoCamera resource in a session.
+class StereoCamera final : public CameraBase {
+ public:
+ explicit StereoCamera(const Scene& scene);
+ StereoCamera(Session* session, uint32_t scene_id);
+ StereoCamera(StereoCamera&& moved) noexcept;
+ ~StereoCamera();
+
+ // Sets the camera's projection parameters.
+ void SetStereoProjection(const std::array<float, 4 * 4>& left_projection,
+ const std::array<float, 4 * 4>& right_projection);
+};
+
+// Represents a renderer resource in a session.
+class Renderer final : public Resource {
+ public:
+ explicit Renderer(Session* session);
+ Renderer(Renderer&& moved) noexcept;
+ ~Renderer();
+
+ // Sets the camera whose view will be rendered.
+ void SetCamera(const Camera& camera) {
+ ZX_DEBUG_ASSERT(session() == camera.session());
+ SetCamera(camera.id());
+ }
+ void SetCamera(uint32_t camera_id);
+
+ void SetParam(fuchsia::ui::gfx::RendererParam param);
+
+ // Convenient wrapper for SetParam().
+ void SetShadowTechnique(fuchsia::ui::gfx::ShadowTechnique technique);
+
+ // Set whether clipping is disabled for this renderer.
+ // NOTE: disabling clipping only has a visual effect; hit-testing is not
+ // affected.
+ void SetDisableClipping(bool disable_clipping);
+
+ // Set whether debug visualization is enabled for this renderer.
+ void SetEnableDebugging(bool enable_debugging);
+};
+
+// Represents a layer resource in a session.
+class Layer final : public Resource {
+ public:
+ explicit Layer(Session* session);
+ Layer(Layer&& moved) noexcept;
+ ~Layer();
+
+ // Sets the layer's XY translation and Z-order.
+ void SetTranslation(float tx, float ty, float tz) { SetTranslation({tx, ty, tz}); }
+ void SetTranslation(const std::array<float, 3>& translation);
+
+ void SetSize(float width, float height) { SetSize({width, height}); }
+ void SetSize(const std::array<float, 2>& size);
+
+ void SetRenderer(const Renderer& renderer) {
+ ZX_DEBUG_ASSERT(session() == renderer.session());
+ SetRenderer(renderer.id());
+ }
+ void SetRenderer(uint32_t renderer_id);
+};
+
+// Represents a layer-stack resource in a session.
+class LayerStack final : public Resource {
+ public:
+ explicit LayerStack(Session* session);
+ LayerStack(LayerStack&& moved) noexcept;
+ ~LayerStack();
+
+ void AddLayer(const Layer& layer) {
+ ZX_DEBUG_ASSERT(session() == layer.session());
+ AddLayer(layer.id());
+ }
+ void AddLayer(uint32_t layer_id);
+ void RemoveLayer(const Layer& layer) {
+ ZX_DEBUG_ASSERT(session() == layer.session());
+ RemoveLayer(layer.id());
+ }
+ void RemoveLayer(uint32_t layer_id);
+ void RemoveAllLayers();
+};
+
+// Represents a display-compositor resource in a session.
+class DisplayCompositor final : public Resource {
+ public:
+ explicit DisplayCompositor(Session* session);
+ DisplayCompositor(DisplayCompositor&& moved) noexcept;
+ ~DisplayCompositor();
+
+ // Sets the layer-stack that is to be composited.
+ void SetLayerStack(const LayerStack& layer_stack) {
+ ZX_DEBUG_ASSERT(session() == layer_stack.session());
+ SetLayerStack(layer_stack.id());
+ }
+ void SetLayerStack(uint32_t layer_stack_id);
+
+ void SetColorConversion(const std::array<float, 3>& preoffsets,
+ const std::array<float, 3 * 3>& matrix,
+ const std::array<float, 3>& postoffsets);
+
+ void SetLayoutRotation(uint32_t rotation_degrees);
+};
+
+// Represents a display-less compositor resource in a session.
+class Compositor final : public Resource {
+ public:
+ explicit Compositor(Session* session);
+ Compositor(Compositor&& moved) noexcept;
+ ~Compositor();
+
+ // Sets the layer-stack that is to be composited.
+ void SetLayerStack(const LayerStack& layer_stack) {
+ ZX_DEBUG_ASSERT(session() == layer_stack.session());
+ SetLayerStack(layer_stack.id());
+ }
+ void SetLayerStack(uint32_t layer_stack_id);
+
+ void SetLayoutRotation(uint32_t rotation_degrees);
+};
+
+} // namespace scenic
+
+#endif // LIB_UI_SCENIC_CPP_RESOURCES_H_
diff --git a/third_party/fuchsia-sdk/pkg/scenic_cpp/include/lib/ui/scenic/cpp/session.h b/third_party/fuchsia-sdk/pkg/scenic_cpp/include/lib/ui/scenic/cpp/session.h
new file mode 100644
index 0000000..782a715
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/scenic_cpp/include/lib/ui/scenic/cpp/session.h
@@ -0,0 +1,192 @@
+// Copyright 2017 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.
+
+#ifndef LIB_UI_SCENIC_CPP_SESSION_H_
+#define LIB_UI_SCENIC_CPP_SESSION_H_
+
+#include <fuchsia/images/cpp/fidl.h>
+#include <fuchsia/ui/gfx/cpp/fidl.h>
+#include <fuchsia/ui/input/cpp/fidl.h>
+#include <fuchsia/ui/scenic/cpp/fidl.h>
+#include <fuchsia/ui/views/cpp/fidl.h>
+#include <lib/fidl/cpp/binding.h>
+#include <lib/fit/function.h>
+#include <lib/zx/event.h>
+#include <lib/zx/time.h>
+
+#include <utility>
+
+namespace scenic {
+
+// Records the number of bytes occupied by enqueue requests without any commands.
+//
+// As commands are accumulated, they are measured the number of bytes and handles
+// added to this base. See |Flush|, |commands_num_bytes_|, and
+// |commands_num_handles_|.
+constexpr int64_t kEnqueueRequestBaseNumBytes =
+ sizeof(fidl_message_header_t) + sizeof(fidl_vector_t);
+
+// Connect to Scenic and establish a new Session, as well as an InterfaceRequest
+// for a SessionListener that can be hooked up as desired.
+//
+// Callbacks will be run on the async dispatcher specified by |dispatcher|,
+// or the default dispatcher for the current thread if unspecified.
+using SessionPtrAndListenerRequest =
+ std::pair<fuchsia::ui::scenic::SessionPtr,
+ fidl::InterfaceRequest<fuchsia::ui::scenic::SessionListener>>;
+SessionPtrAndListenerRequest CreateScenicSessionPtrAndListenerRequest(
+ fuchsia::ui::scenic::Scenic* scenic, async_dispatcher_t* dispatcher = nullptr);
+
+// Wraps a Scenic session.
+// Maintains a queue of pending operations and assists with allocation of
+// resource ids.
+class Session : private fuchsia::ui::scenic::SessionListener {
+ public:
+ // Provides timing information about a presentation request which has
+ // been applied by the scene manager.
+ using PresentCallback = fit::function<void(fuchsia::images::PresentationInfo info)>;
+ // Provides immediate information about predicted future latch and presentation times.
+ using Present2Callback =
+ fit::function<void(fuchsia::scenic::scheduling::FuturePresentationTimes info)>;
+ // Provides immediate information about predicted future latch and presentation times.
+ using RequestPresentationTimesCallback =
+ fit::function<void(fuchsia::scenic::scheduling::FuturePresentationTimes info)>;
+
+ // Called when session events are received.
+ using EventHandler = fit::function<void(std::vector<fuchsia::ui::scenic::Event>)>;
+ // Called when one or more Present2s are presented.
+ using OnFramePresentedCallback =
+ fit::function<void(fuchsia::scenic::scheduling::FramePresentedInfo info)>;
+
+ // Wraps the provided session and session listener.
+ // The listener is optional.
+ //
+ // Callbacks for |session_listener| will be run on the async dispatcher
+ // specified by |dispatcher|, or the default dispatcher for the current thread
+ // if unspecified. Callbacks for |session| will be run on the dispatcher to
+ // which it was bound before being passed in.
+ explicit Session(
+ fuchsia::ui::scenic::SessionPtr session,
+ fidl::InterfaceRequest<fuchsia::ui::scenic::SessionListener> session_listener = nullptr,
+ async_dispatcher_t* dispatcher = nullptr);
+
+ // Creates a new session using the provided Scenic and binds the listener to
+ // this object. The Scenic itself is not retained after construction.
+ //
+ // Callbacks will be run on the async dispatcher specified by |dispatcher|, or
+ // the default dispatcher for the current thread if unspecified.
+ explicit Session(fuchsia::ui::scenic::Scenic* scenic, async_dispatcher_t* dispatcher = nullptr);
+ explicit Session(fuchsia::ui::scenic::Scenic* scenic,
+ fidl::InterfaceRequest<fuchsia::ui::views::Focuser> view_focuser,
+ async_dispatcher_t* dispatcher = nullptr);
+
+ // Callbacks for SessionListener will be run on the async dispatcher specified
+ // by |dispatcher|, or the default dispatcher for the current thread if
+ // unspecified. Callbacks for SesssionPtr will be run on the dispatcher to
+ // which it was bound before being passed in.
+ explicit Session(SessionPtrAndListenerRequest session_and_listener,
+ async_dispatcher_t* dispatcher = nullptr);
+
+ Session(const Session&) = delete;
+ Session& operator=(const Session&) = delete;
+
+ // Destroys the session.
+ // All resources must be released prior to destruction.
+ ~Session();
+
+ void set_error_handler(fit::function<void(zx_status_t)> closure) {
+ session_.set_error_handler(std::move(closure));
+ }
+
+ // Sets a callback which is invoked when events are received.
+ void set_event_handler(EventHandler event_handler) { event_handler_ = std::move(event_handler); }
+
+ // Sets the callback invoked when frames are presented.
+ void set_on_frame_presented_handler(OnFramePresentedCallback callback);
+
+ // Gets a pointer to the underlying session interface.
+ fuchsia::ui::scenic::Session* session() { return session_.get(); }
+
+ // Gets the next resource id which will be provided when |AllocResourceId| is
+ // called.
+ uint32_t next_resource_id() const { return next_resource_id_; }
+
+ // Allocates a new unique resource id.
+ uint32_t AllocResourceId();
+
+ // Enqueues an operation to release a resource.
+ void ReleaseResource(uint32_t resource_id);
+
+ // Enqueues an operation.
+ // The session will queue operations locally to batch submission of operations
+ // until |Flush()| or |Present()| is called.
+ void Enqueue(fuchsia::ui::scenic::Command command);
+ void Enqueue(fuchsia::ui::gfx::Command command);
+ void Enqueue(fuchsia::ui::input::Command command);
+
+ // Registers an acquire fence to be submitted during the subsequent call to
+ // |Present()|.
+ void EnqueueAcquireFence(zx::event fence);
+
+ // Registers a release fence to be submitted during the subsequent call to
+ // |Present()|.
+ void EnqueueReleaseFence(zx::event fence);
+
+ // Flushes queued operations to the session.
+ // Virtual for testing.
+ virtual void Flush();
+
+ // Presents all previously enqueued operations.
+ // Implicitly flushes all queued operations to the session.
+ // Invokes the callback when the scene manager applies the presentation.
+ void Present(uint64_t presentation_time, PresentCallback callback);
+
+ // Overloaded |Present()| using zx::time.
+ void Present(zx::time presentation_time, PresentCallback callback);
+
+ // Immediately invokes the callback, providing predicted information back to the client.
+ // Presents all previously enqueued operations.
+ // Implicitly flushes all queued operations to the session.
+ void Present2(zx_duration_t requested_presentation_time, zx_duration_t requested_prediction_span,
+ Present2Callback immediate_callback);
+
+ // Immediately invokes the callback, providing predicted information back to the client.
+ void RequestPresentationTimes(zx_duration_t requested_prediction_span,
+ RequestPresentationTimesCallback callback);
+
+ // Unbinds the internal SessionPtr; this allows moving this across threads.
+ void Unbind();
+
+ // Rebinds the Session interface internally; this must be called after a call
+ // to Unbind().
+ void Rebind();
+
+ void SetDebugName(const std::string& debug_name);
+
+protected:
+ std::vector<fuchsia::ui::scenic::Command> commands_;
+ int64_t commands_num_bytes_ = kEnqueueRequestBaseNumBytes;
+ int64_t commands_num_handles_ = 0;
+
+private:
+ // |fuchsia::ui::scenic::SessionListener|
+ void OnScenicError(std::string error) override;
+ void OnScenicEvent(std::vector<fuchsia::ui::scenic::Event> events) override;
+
+ fuchsia::ui::scenic::SessionPtr session_;
+ // |session_handle_| is stored only when |session_| is unbound/invalid.
+ fidl::InterfaceHandle<fuchsia::ui::scenic::Session> session_handle_;
+ uint32_t next_resource_id_ = 1u;
+ uint32_t resource_count_ = 0u;
+
+ std::vector<zx::event> acquire_fences_;
+ std::vector<zx::event> release_fences_;
+
+ EventHandler event_handler_;
+ fidl::Binding<fuchsia::ui::scenic::SessionListener> session_listener_binding_;
+};
+
+} // namespace scenic
+
+#endif // LIB_UI_SCENIC_CPP_SESSION_H_
diff --git a/third_party/fuchsia-sdk/pkg/scenic_cpp/include/lib/ui/scenic/cpp/view_ref_pair.h b/third_party/fuchsia-sdk/pkg/scenic_cpp/include/lib/ui/scenic/cpp/view_ref_pair.h
new file mode 100644
index 0000000..8ff7c3d
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/scenic_cpp/include/lib/ui/scenic/cpp/view_ref_pair.h
@@ -0,0 +1,24 @@
+// 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.
+
+#ifndef LIB_UI_SCENIC_CPP_VIEW_REF_PAIR_H_
+#define LIB_UI_SCENIC_CPP_VIEW_REF_PAIR_H_
+
+#include <fuchsia/ui/views/cpp/fidl.h>
+#include <lib/zx/eventpair.h>
+
+namespace scenic {
+
+struct ViewRefPair {
+ // Convenience function which allows clients to easily create a valid
+ // |ViewRef| / |ViewRefControl| pair for use with the |View| resource.
+ static ViewRefPair New();
+
+ fuchsia::ui::views::ViewRefControl control_ref;
+ fuchsia::ui::views::ViewRef view_ref;
+};
+
+} // namespace scenic
+
+#endif // LIB_UI_SCENIC_CPP_VIEW_REF_PAIR_H_
diff --git a/third_party/fuchsia-sdk/pkg/scenic_cpp/include/lib/ui/scenic/cpp/view_token_pair.h b/third_party/fuchsia-sdk/pkg/scenic_cpp/include/lib/ui/scenic/cpp/view_token_pair.h
new file mode 100644
index 0000000..d798c0a
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/scenic_cpp/include/lib/ui/scenic/cpp/view_token_pair.h
@@ -0,0 +1,39 @@
+// 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.
+
+#ifndef LIB_UI_SCENIC_CPP_VIEW_TOKEN_PAIR_H_
+#define LIB_UI_SCENIC_CPP_VIEW_TOKEN_PAIR_H_
+
+#include <fuchsia/ui/views/cpp/fidl.h>
+#include <lib/zx/eventpair.h>
+
+namespace scenic {
+
+struct ViewTokenPair {
+ // Convenience function which allows clients to easily create a valid
+ // |ViewToken| / |ViewHolderToken| pair for use with |View| / |ViewHolder|
+ // resources.
+ static ViewTokenPair New();
+
+ fuchsia::ui::views::ViewToken view_token;
+ fuchsia::ui::views::ViewHolderToken view_holder_token;
+};
+
+using ViewTokenStdPair =
+ std::pair<fuchsia::ui::views::ViewToken, fuchsia::ui::views::ViewHolderToken>;
+
+// Convenience function which allows clients to easily create a |ViewToken| /
+// |ViewHolderToken| pair for use with |View| resources.
+ViewTokenStdPair NewViewTokenPair();
+
+// Convenience functions which allow converting from raw eventpair-based tokens
+// easily.
+// TEMPORARY; for transition purposes only.
+// TODO(SCN-1287): Remove.
+fuchsia::ui::views::ViewToken ToViewToken(zx::eventpair raw_token);
+fuchsia::ui::views::ViewHolderToken ToViewHolderToken(zx::eventpair raw_token);
+
+} // namespace scenic
+
+#endif // LIB_UI_SCENIC_CPP_VIEW_TOKEN_PAIR_H_
diff --git a/third_party/fuchsia-sdk/pkg/scenic_cpp/meta.json b/third_party/fuchsia-sdk/pkg/scenic_cpp/meta.json
new file mode 100644
index 0000000..0f51030
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/scenic_cpp/meta.json
@@ -0,0 +1,37 @@
+{
+ "banjo_deps": [],
+ "deps": [
+ "fidl_cpp",
+ "images_cpp",
+ "fit",
+ "syslog",
+ "zx"
+ ],
+ "fidl_deps": [
+ "fuchsia.images",
+ "fuchsia.ui.gfx",
+ "fuchsia.ui.scenic",
+ "fuchsia.ui.views"
+ ],
+ "headers": [
+ "pkg/scenic_cpp/include/lib/ui/scenic/cpp/commands.h",
+ "pkg/scenic_cpp/include/lib/ui/scenic/cpp/commands_sizing.h",
+ "pkg/scenic_cpp/include/lib/ui/scenic/cpp/id.h",
+ "pkg/scenic_cpp/include/lib/ui/scenic/cpp/resources.h",
+ "pkg/scenic_cpp/include/lib/ui/scenic/cpp/session.h",
+ "pkg/scenic_cpp/include/lib/ui/scenic/cpp/view_ref_pair.h",
+ "pkg/scenic_cpp/include/lib/ui/scenic/cpp/view_token_pair.h"
+ ],
+ "include_dir": "pkg/scenic_cpp/include",
+ "name": "scenic_cpp",
+ "root": "pkg/scenic_cpp",
+ "sources": [
+ "pkg/scenic_cpp/commands.cc",
+ "pkg/scenic_cpp/commands_sizing.cc",
+ "pkg/scenic_cpp/resources.cc",
+ "pkg/scenic_cpp/session.cc",
+ "pkg/scenic_cpp/view_ref_pair.cc",
+ "pkg/scenic_cpp/view_token_pair.cc"
+ ],
+ "type": "cc_source_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/scenic_cpp/resources.cc b/third_party/fuchsia-sdk/pkg/scenic_cpp/resources.cc
new file mode 100644
index 0000000..b4ab859
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/scenic_cpp/resources.cc
@@ -0,0 +1,609 @@
+// Copyright 2017 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.
+
+#include <lib/images/cpp/images.h>
+#include <lib/ui/scenic/cpp/commands.h>
+#include <lib/ui/scenic/cpp/resources.h>
+#include <lib/ui/scenic/cpp/view_token_pair.h>
+
+#include <algorithm>
+
+namespace scenic {
+namespace {
+
+template <class T>
+constexpr const T& clamp(const T& v, const T& lo, const T& hi) {
+ return (v < lo) ? lo : (hi < v) ? hi : v;
+}
+
+} // namespace
+
+Resource::Resource(Session* session) : session_(session), id_(session->AllocResourceId()) {}
+
+Resource::Resource(Resource&& moved) noexcept : session_(moved.session_), id_(moved.id_) {
+ auto& moved_session = *const_cast<Session**>(&moved.session_);
+ auto& moved_id = *const_cast<uint32_t*>(&moved.id_);
+ moved_session = nullptr;
+ moved_id = 0;
+}
+
+Resource::~Resource() {
+ // If this resource was moved, it is not responsible for releasing the ID.
+ if (session_)
+ session_->ReleaseResource(id_);
+}
+
+void Resource::Export(zx::eventpair export_token) {
+ session_->Enqueue(NewExportResourceCmd(id(), std::move(export_token)));
+}
+
+void Resource::ExportAsRequest(zx::eventpair* out_import_token) {
+ session_->Enqueue(NewExportResourceCmdAsRequest(id(), out_import_token));
+}
+
+void Resource::SetEventMask(uint32_t event_mask) {
+ session_->Enqueue(NewSetEventMaskCmd(id(), event_mask));
+}
+
+void Resource::SetLabel(const std::string& label) {
+ session_->Enqueue(NewSetLabelCmd(id(), label));
+}
+
+Shape::Shape(Session* session) : Resource(session) {}
+
+Shape::Shape(Shape&& moved) noexcept : Resource(std::move(moved)) {}
+
+Shape::~Shape() = default;
+
+Circle::Circle(Session* session, float radius) : Shape(session) {
+ session->Enqueue(NewCreateCircleCmd(id(), radius));
+}
+
+Circle::Circle(Circle&& moved) noexcept : Shape(std::move(moved)) {}
+
+Circle::~Circle() = default;
+
+Rectangle::Rectangle(Session* session, float width, float height) : Shape(session) {
+ session->Enqueue(NewCreateRectangleCmd(id(), width, height));
+}
+
+Rectangle::Rectangle(Rectangle&& moved) noexcept : Shape(std::move(moved)) {}
+
+Rectangle::~Rectangle() = default;
+
+RoundedRectangle::RoundedRectangle(Session* session, float width, float height,
+ float top_left_radius, float top_right_radius,
+ float bottom_right_radius, float bottom_left_radius)
+ : Shape(session) {
+ session->Enqueue(NewCreateRoundedRectangleCmd(id(), width, height, top_left_radius,
+ top_right_radius, bottom_right_radius,
+ bottom_left_radius));
+}
+
+RoundedRectangle::RoundedRectangle(RoundedRectangle&& moved) noexcept : Shape(std::move(moved)) {}
+
+RoundedRectangle::~RoundedRectangle() = default;
+
+Image::Image(const Memory& memory, off_t memory_offset, fuchsia::images::ImageInfo info)
+ : Image(memory.session(), memory.id(), memory_offset, info) {}
+
+Image::Image(Session* session, uint32_t memory_id, off_t memory_offset,
+ fuchsia::images::ImageInfo info)
+ : Resource(session), memory_offset_(memory_offset), info_(info) {
+ session->Enqueue(NewCreateImageCmd(id(), memory_id, memory_offset_, info));
+}
+
+Image::Image(Image&& moved) noexcept
+ : Resource(std::move(moved)), memory_offset_(moved.memory_offset_), info_(moved.info_) {}
+
+Image::~Image() = default;
+
+size_t Image::ComputeSize(const fuchsia::images::ImageInfo& image_info) {
+ return images::ImageSize(image_info);
+}
+
+Buffer::Buffer(const Memory& memory, off_t memory_offset, size_t num_bytes)
+ : Buffer(memory.session(), memory.id(), memory_offset, num_bytes) {}
+
+Buffer::Buffer(Session* session, uint32_t memory_id, off_t memory_offset, size_t num_bytes)
+ : Resource(session) {
+ session->Enqueue(NewCreateBufferCmd(id(), memory_id, memory_offset, num_bytes));
+}
+
+Buffer::Buffer(Buffer&& moved) noexcept : Resource(std::move(moved)) {}
+
+Buffer::~Buffer() = default;
+
+Memory::Memory(Session* session, zx::vmo vmo, uint64_t allocation_size,
+ fuchsia::images::MemoryType memory_type)
+ : Resource(session), memory_type_(memory_type) {
+ session->Enqueue(NewCreateMemoryCmd(id(), std::move(vmo), allocation_size, memory_type));
+}
+
+Memory::Memory(Memory&& moved) noexcept
+ : Resource(std::move(moved)), memory_type_(moved.memory_type_) {}
+
+Memory::~Memory() = default;
+
+Mesh::Mesh(Session* session) : Shape(session) { session->Enqueue(NewCreateMeshCmd(id())); }
+
+Mesh::Mesh(Mesh&& moved) noexcept : Shape(std::move(moved)) {}
+
+Mesh::~Mesh() = default;
+
+void Mesh::BindBuffers(const Buffer& index_buffer, fuchsia::ui::gfx::MeshIndexFormat index_format,
+ uint64_t index_offset, uint32_t index_count, const Buffer& vertex_buffer,
+ fuchsia::ui::gfx::MeshVertexFormat vertex_format, uint64_t vertex_offset,
+ uint32_t vertex_count, const std::array<float, 3>& bounding_box_min,
+ const std::array<float, 3>& bounding_box_max) {
+ ZX_DEBUG_ASSERT(session() == index_buffer.session() && session() == vertex_buffer.session());
+ session()->Enqueue(NewBindMeshBuffersCmd(
+ id(), index_buffer.id(), index_format, index_offset, index_count, vertex_buffer.id(),
+ vertex_format, vertex_offset, vertex_count, bounding_box_min, bounding_box_max));
+}
+
+Material::Material(Session* session) : Resource(session) {
+ session->Enqueue(NewCreateMaterialCmd(id()));
+}
+
+Material::Material(Material&& moved) noexcept : Resource(std::move(moved)) {}
+
+Material::~Material() = default;
+
+void Material::SetTexture(uint32_t image_id) {
+ session()->Enqueue(NewSetTextureCmd(id(), image_id));
+}
+
+void Material::SetColor(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) {
+ session()->Enqueue(NewSetColorCmd(id(), red, green, blue, alpha));
+}
+
+Node::Node(Session* session) : Resource(session) {}
+
+Node::Node(Node&& moved) noexcept : Resource(std::move(moved)) {}
+
+Node::~Node() = default;
+
+void Node::SetTranslation(const std::array<float, 3>& translation) {
+ session()->Enqueue(NewSetTranslationCmd(id(), translation));
+}
+
+void Node::SetTranslation(uint32_t variable_id) {
+ session()->Enqueue(NewSetTranslationCmd(id(), variable_id));
+}
+
+void Node::SetScale(const std::array<float, 3>& scale) {
+ session()->Enqueue(NewSetScaleCmd(id(), scale));
+}
+void Node::SetScale(uint32_t variable_id) { session()->Enqueue(NewSetScaleCmd(id(), variable_id)); }
+
+void Node::SetRotation(const std::array<float, 4>& quaternion) {
+ session()->Enqueue(NewSetRotationCmd(id(), quaternion));
+}
+
+void Node::SetRotation(uint32_t variable_id) {
+ session()->Enqueue(NewSetRotationCmd(id(), variable_id));
+}
+
+void Node::SetAnchor(const std::array<float, 3>& anchor) {
+ session()->Enqueue(NewSetAnchorCmd(id(), anchor));
+}
+
+void Node::SetAnchor(uint32_t variable_id) {
+ session()->Enqueue(NewSetAnchorCmd(id(), variable_id));
+}
+
+void Node::SendSizeChangeHint(float width_change_factor, float height_change_factor) {
+ session()->Enqueue(NewSendSizeChangeHintCmdHACK(id(), width_change_factor, height_change_factor));
+}
+
+void Node::SetTag(uint32_t tag_value) { session()->Enqueue(NewSetTagCmd(id(), tag_value)); }
+
+void Node::SetHitTestBehavior(fuchsia::ui::gfx::HitTestBehavior hit_test_behavior) {
+ session()->Enqueue(NewSetHitTestBehaviorCmd(id(), hit_test_behavior));
+}
+
+void Node::Detach() { session()->Enqueue(NewDetachCmd(id())); }
+
+ShapeNode::ShapeNode(Session* session) : Node(session) {
+ session->Enqueue(NewCreateShapeNodeCmd(id()));
+}
+
+ShapeNode::ShapeNode(ShapeNode&& moved) noexcept : Node(std::move(moved)) {}
+
+ShapeNode::~ShapeNode() = default;
+
+void ShapeNode::SetShape(uint32_t shape_id) { session()->Enqueue(NewSetShapeCmd(id(), shape_id)); }
+
+void ShapeNode::SetMaterial(uint32_t material_id) {
+ session()->Enqueue(NewSetMaterialCmd(id(), material_id));
+}
+
+ContainerNode::ContainerNode(Session* session) : Node(session) {}
+
+ContainerNode::ContainerNode(ContainerNode&& moved) noexcept : Node(std::move(moved)) {}
+
+ContainerNode::~ContainerNode() = default;
+
+void ContainerNode::AddChild(uint32_t child_node_id) {
+ session()->Enqueue(NewAddChildCmd(id(), child_node_id));
+}
+
+void ContainerNode::DetachChildren() { session()->Enqueue(NewDetachChildrenCmd(id())); }
+
+EntityNode::EntityNode(Session* session) : ContainerNode(session) {
+ session->Enqueue(NewCreateEntityNodeCmd(id()));
+}
+
+EntityNode::EntityNode(EntityNode&& moved) noexcept : ContainerNode(std::move(moved)) {}
+
+EntityNode::~EntityNode() = default;
+
+void EntityNode::Attach(const ViewHolder& view_holder) { AddChild(view_holder); }
+
+void EntityNode::SetClip(uint32_t clip_id, bool clip_to_self) {
+ session()->Enqueue(NewSetClipCmd(id(), clip_id, clip_to_self));
+}
+
+void EntityNode::SetClipPlanes(std::vector<fuchsia::ui::gfx::Plane3> planes) {
+ session()->Enqueue(NewSetClipPlanesCmd(id(), std::move(planes)));
+}
+
+ImportNode::ImportNode(Session* session) : ContainerNode(session) {}
+
+ImportNode::ImportNode(ImportNode&& moved) noexcept : ContainerNode(std::move(moved)) {}
+
+ImportNode::~ImportNode() { ZX_DEBUG_ASSERT_MSG(is_bound_, "Import was never bound."); }
+
+void ImportNode::Bind(zx::eventpair import_token) {
+ ZX_DEBUG_ASSERT(!is_bound_);
+ session()->Enqueue(
+ NewImportResourceCmd(id(), fuchsia::ui::gfx::ImportSpec::NODE, std::move(import_token)));
+ is_bound_ = true;
+}
+
+void ImportNode::BindAsRequest(zx::eventpair* out_export_token) {
+ ZX_DEBUG_ASSERT(!is_bound_);
+ session()->Enqueue(
+ NewImportResourceCmdAsRequest(id(), fuchsia::ui::gfx::ImportSpec::NODE, out_export_token));
+ is_bound_ = true;
+}
+
+void ImportNode::Attach(const ViewHolder& view_holder) {
+ session()->Enqueue(NewAddChildCmd(id(), view_holder.id()));
+}
+
+ViewHolder::ViewHolder(Session* session, zx::eventpair token, const std::string& debug_name)
+ : Node(session) {
+ session->Enqueue(
+ NewCreateViewHolderCmd(id(), scenic::ToViewHolderToken(std::move(token)), debug_name));
+}
+
+ViewHolder::ViewHolder(Session* session, fuchsia::ui::views::ViewHolderToken token,
+ const std::string& debug_name)
+ : Node(session) {
+ session->Enqueue(NewCreateViewHolderCmd(id(), std::move(token), debug_name));
+}
+
+ViewHolder::ViewHolder(ViewHolder&& moved) noexcept : Node(std::move(moved)) {}
+
+ViewHolder::~ViewHolder() = default;
+
+void ViewHolder::SetViewProperties(const std::array<float, 3>& bounding_box_min,
+ const std::array<float, 3>& bounding_box_max,
+ const std::array<float, 3>& inset_from_min,
+ const std::array<float, 3>& inset_from_max) {
+ session()->Enqueue(NewSetViewPropertiesCmd(id(), bounding_box_min, bounding_box_max,
+ inset_from_min, inset_from_max));
+}
+void ViewHolder::SetViewProperties(const fuchsia::ui::gfx::ViewProperties& props) {
+ session()->Enqueue(NewSetViewPropertiesCmd(id(), props));
+}
+
+void ViewHolder::SetDebugBoundsColor(uint8_t red, uint8_t green, uint8_t blue) {
+ session()->Enqueue(NewSetViewHolderBoundsColorCmd(id(), red, green, blue));
+}
+
+View::View(Session* session, zx::eventpair token, const std::string& debug_name)
+ : Resource(session) {
+ session->Enqueue(NewCreateViewCmd(id(), scenic::ToViewToken(std::move(token)), debug_name));
+}
+
+View::View(Session* session, fuchsia::ui::views::ViewToken token, const std::string& debug_name)
+ : Resource(session) {
+ session->Enqueue(NewCreateViewCmd(id(), std::move(token), debug_name));
+}
+
+View::View(Session* session, fuchsia::ui::views::ViewToken token,
+ fuchsia::ui::views::ViewRefControl control_ref, fuchsia::ui::views::ViewRef view_ref,
+ const std::string& debug_name)
+ : Resource(session) {
+ session->Enqueue(NewCreateViewCmd(id(), std::move(token), std::move(control_ref),
+ std::move(view_ref), debug_name));
+}
+
+View::View(View&& moved) noexcept : Resource(std::move(moved)) {}
+
+View::~View() = default;
+
+void View::AddChild(const Node& child) const {
+ ZX_DEBUG_ASSERT(session() == child.session());
+ session()->Enqueue(NewAddChildCmd(id(), child.id()));
+}
+
+void View::DetachChild(const Node& child) const {
+ ZX_DEBUG_ASSERT(session() == child.session());
+ session()->Enqueue(NewDetachCmd(child.id()));
+}
+
+void View::enableDebugBounds(bool enable) {
+ session()->Enqueue(NewSetEnableDebugViewBoundsCmd(id(), enable));
+}
+
+ClipNode::ClipNode(Session* session) : ContainerNode(session) {
+ session->Enqueue(NewCreateClipNodeCmd(id()));
+}
+
+ClipNode::ClipNode(ClipNode&& moved) noexcept : ContainerNode(std::move(moved)) {}
+
+ClipNode::~ClipNode() = default;
+
+OpacityNodeHACK::OpacityNodeHACK(Session* session) : ContainerNode(session) {
+ session->Enqueue(NewCreateOpacityNodeCmdHACK(id()));
+}
+
+OpacityNodeHACK::OpacityNodeHACK(OpacityNodeHACK&& moved) noexcept
+ : ContainerNode(std::move(moved)) {}
+
+OpacityNodeHACK::~OpacityNodeHACK() = default;
+
+void OpacityNodeHACK::SetOpacity(float opacity) {
+ opacity = clamp(opacity, 0.f, 1.f);
+ session()->Enqueue(NewSetOpacityCmd(id(), opacity));
+}
+
+Variable::Variable(Session* session, fuchsia::ui::gfx::Value initial_value) : Resource(session) {
+ session->Enqueue(NewCreateVariableCmd(id(), std::move(initial_value)));
+}
+
+Variable::Variable(Variable&& moved) noexcept : Resource(std::move(moved)) {}
+
+Variable::~Variable() = default;
+
+Scene::Scene(Session* session) : ContainerNode(session) {
+ session->Enqueue(NewCreateSceneCmd(id()));
+}
+
+Scene::Scene(Scene&& moved) noexcept : ContainerNode(std::move(moved)) {}
+
+Scene::~Scene() = default;
+
+void Scene::AddLight(uint32_t light_id) { session()->Enqueue(NewAddLightCmd(id(), light_id)); }
+
+void Scene::AddAmbientLight(uint32_t light_id) {
+ session()->Enqueue(NewSceneAddAmbientLightCmd(id(), light_id));
+}
+
+void Scene::AddDirectionalLight(uint32_t light_id) {
+ session()->Enqueue(NewSceneAddDirectionalLightCmd(id(), light_id));
+}
+
+void Scene::AddPointLight(uint32_t light_id) {
+ session()->Enqueue(NewSceneAddPointLightCmd(id(), light_id));
+}
+
+void Scene::DetachLights() { session()->Enqueue(NewDetachLightsCmd(id())); }
+
+void CameraBase::SetTransform(const std::array<float, 3>& eye_position,
+ const std::array<float, 3>& eye_look_at,
+ const std::array<float, 3>& eye_up) {
+ session()->Enqueue(NewSetCameraTransformCmd(id(), eye_position, eye_look_at, eye_up));
+}
+
+void CameraBase::SetClipSpaceTransform(float x, float y, float scale) {
+ session()->Enqueue(NewSetCameraClipSpaceTransformCmd(id(), x, y, scale));
+}
+
+void CameraBase::SetPoseBuffer(const Buffer& buffer, uint32_t num_entries, int64_t base_time,
+ uint64_t time_interval) {
+ session()->Enqueue(
+ NewSetCameraPoseBufferCmd(id(), buffer.id(), num_entries, base_time, time_interval));
+}
+
+void CameraBase::SetPoseBuffer(const Buffer& buffer, uint32_t num_entries, zx::time base_time,
+ zx::duration time_interval) {
+ SetPoseBuffer(buffer, num_entries, base_time.get(), time_interval.get());
+}
+
+Camera::Camera(const Scene& scene) : Camera(scene.session(), scene.id()) {}
+
+Camera::Camera(Session* session, uint32_t scene_id) : CameraBase(session) {
+ session->Enqueue(NewCreateCameraCmd(id(), scene_id));
+}
+
+Camera::Camera(Camera&& moved) noexcept : CameraBase(std::move(moved)) {}
+
+Camera::~Camera() = default;
+
+void Camera::SetProjection(const float fovy) {
+ session()->Enqueue(NewSetCameraProjectionCmd(id(), fovy));
+}
+
+StereoCamera::StereoCamera(const Scene& scene) : StereoCamera(scene.session(), scene.id()) {}
+
+StereoCamera::StereoCamera(Session* session, uint32_t scene_id) : CameraBase(session) {
+ session->Enqueue(NewCreateStereoCameraCmd(id(), scene_id));
+}
+
+StereoCamera::StereoCamera(StereoCamera&& moved) noexcept : CameraBase(std::move(moved)) {}
+
+StereoCamera::~StereoCamera() = default;
+
+void StereoCamera::SetStereoProjection(const std::array<float, 4 * 4>& left_projection,
+ const std::array<float, 4 * 4>& right_projection) {
+ session()->Enqueue(NewSetStereoCameraProjectionCmd(id(), left_projection, right_projection));
+}
+
+Renderer::Renderer(Session* session) : Resource(session) {
+ session->Enqueue(NewCreateRendererCmd(id()));
+}
+
+Renderer::Renderer(Renderer&& moved) noexcept : Resource(std::move(moved)) {}
+
+Renderer::~Renderer() = default;
+
+void Renderer::SetCamera(uint32_t camera_id) {
+ session()->Enqueue(NewSetCameraCmd(id(), camera_id));
+}
+
+void Renderer::SetParam(fuchsia::ui::gfx::RendererParam param) {
+ session()->Enqueue(NewSetRendererParamCmd(id(), std::move(param)));
+}
+
+void Renderer::SetShadowTechnique(fuchsia::ui::gfx::ShadowTechnique technique) {
+ auto param = fuchsia::ui::gfx::RendererParam();
+ param.set_shadow_technique(technique);
+ SetParam(std::move(param));
+}
+
+void Renderer::SetDisableClipping(bool disable_clipping) {
+ session()->Enqueue(NewSetDisableClippingCmd(id(), disable_clipping));
+}
+
+void Renderer::SetEnableDebugging(bool enable_debugging) {
+ auto param = fuchsia::ui::gfx::RendererParam();
+ param.set_enable_debugging(enable_debugging);
+ SetParam(std::move(param));
+}
+
+Layer::Layer(Session* session) : Resource(session) { session->Enqueue(NewCreateLayerCmd(id())); }
+
+Layer::Layer(Layer&& moved) noexcept : Resource(std::move(moved)) {}
+
+Layer::~Layer() = default;
+
+void Layer::SetRenderer(uint32_t renderer_id) {
+ session()->Enqueue(NewSetRendererCmd(id(), renderer_id));
+}
+
+void Layer::SetSize(const std::array<float, 2>& size) {
+ session()->Enqueue(NewSetSizeCmd(id(), size));
+}
+
+LayerStack::LayerStack(Session* session) : Resource(session) {
+ session->Enqueue(NewCreateLayerStackCmd(id()));
+}
+
+LayerStack::LayerStack(LayerStack&& moved) noexcept : Resource(std::move(moved)) {}
+
+LayerStack::~LayerStack() = default;
+
+void LayerStack::AddLayer(uint32_t layer_id) { session()->Enqueue(NewAddLayerCmd(id(), layer_id)); }
+
+void LayerStack::RemoveLayer(uint32_t layer_id) {
+ session()->Enqueue(NewRemoveLayerCmd(id(), layer_id));
+}
+
+void LayerStack::RemoveAllLayers() { session()->Enqueue(NewRemoveAllLayersCmd(id())); }
+
+DisplayCompositor::DisplayCompositor(Session* session) : Resource(session) {
+ session->Enqueue(NewCreateDisplayCompositorCmd(id()));
+}
+
+DisplayCompositor::DisplayCompositor(DisplayCompositor&& moved) noexcept
+ : Resource(std::move(moved)) {}
+
+DisplayCompositor::~DisplayCompositor() = default;
+
+void DisplayCompositor::SetLayerStack(uint32_t layer_stack_id) {
+ session()->Enqueue(NewSetLayerStackCmd(id(), layer_stack_id));
+}
+
+void DisplayCompositor::SetColorConversion(const std::array<float, 3>& preoffsets,
+ const std::array<float, 3 * 3>& matrix,
+ const std::array<float, 3>& postoffsets) {
+ session()->Enqueue(NewSetDisplayColorConversionCmdHACK(id(), preoffsets, matrix, postoffsets));
+}
+
+void DisplayCompositor::SetLayoutRotation(uint32_t rotation_degrees) {
+ session()->Enqueue(NewSetDisplayRotationCmdHACK(id(), rotation_degrees));
+}
+
+Compositor::Compositor(Session* session) : Resource(session) {
+ session->Enqueue(NewCreateCompositorCmd(id()));
+}
+
+Compositor::Compositor(Compositor&& moved) noexcept : Resource(std::move(moved)) {}
+
+Compositor::~Compositor() = default;
+
+void Compositor::SetLayerStack(uint32_t layer_stack_id) {
+ session()->Enqueue(NewSetLayerStackCmd(id(), layer_stack_id));
+}
+
+void Compositor::SetLayoutRotation(uint32_t rotation_degrees) {
+ session()->Enqueue(NewSetDisplayRotationCmdHACK(id(), rotation_degrees));
+}
+
+Light::Light(Session* session) : Resource(session) {}
+
+Light::Light(Light&& moved) noexcept : Resource(std::move(moved)) {}
+
+Light::~Light() = default;
+
+void Light::SetColor(const std::array<float, 3>& rgb) {
+ session()->Enqueue(NewSetLightColorCmd(id(), rgb));
+}
+
+void Light::SetColor(uint32_t variable_id) {
+ session()->Enqueue(NewSetLightColorCmd(id(), variable_id));
+}
+
+void Light::Detach() { session()->Enqueue(NewDetachLightCmd(id())); }
+
+AmbientLight::AmbientLight(Session* session) : Light(session) {
+ session->Enqueue(NewCreateAmbientLightCmd(id()));
+}
+
+AmbientLight::AmbientLight(AmbientLight&& moved) noexcept : Light(std::move(moved)) {}
+
+AmbientLight::~AmbientLight() = default;
+
+DirectionalLight::DirectionalLight(Session* session) : Light(session) {
+ session->Enqueue(NewCreateDirectionalLightCmd(id()));
+}
+
+DirectionalLight::DirectionalLight(DirectionalLight&& moved) noexcept : Light(std::move(moved)) {}
+
+DirectionalLight::~DirectionalLight() = default;
+
+void DirectionalLight::SetDirection(const std::array<float, 3>& direction) {
+ session()->Enqueue(NewSetLightDirectionCmd(id(), direction));
+}
+
+void DirectionalLight::SetDirection(uint32_t variable_id) {
+ session()->Enqueue(NewSetLightDirectionCmd(id(), variable_id));
+}
+
+PointLight::PointLight(Session* session) : Light(session) {
+ session->Enqueue(NewCreatePointLightCmd(id()));
+}
+
+PointLight::PointLight(PointLight&& moved) noexcept : Light(std::move(moved)) {}
+
+PointLight::~PointLight() = default;
+
+void PointLight::SetPosition(const std::array<float, 3>& position) {
+ session()->Enqueue(NewSetPointLightPositionCmd(id(), position));
+}
+
+void PointLight::SetPosition(uint32_t variable_id) {
+ session()->Enqueue(NewSetPointLightPositionCmd(id(), variable_id));
+}
+
+void PointLight::SetFalloff(float falloff) {
+ session()->Enqueue(NewSetPointLightFalloffCmd(id(), falloff));
+}
+
+} // namespace scenic
diff --git a/third_party/fuchsia-sdk/pkg/scenic_cpp/session.cc b/third_party/fuchsia-sdk/pkg/scenic_cpp/session.cc
new file mode 100644
index 0000000..2b96153
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/scenic_cpp/session.cc
@@ -0,0 +1,182 @@
+// Copyright 2017 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.
+
+#include <lib/syslog/global.h>
+#include <lib/ui/scenic/cpp/commands.h>
+#include <lib/ui/scenic/cpp/commands_sizing.h>
+#include <lib/ui/scenic/cpp/session.h>
+#include <zircon/assert.h>
+
+namespace scenic {
+
+SessionPtrAndListenerRequest CreateScenicSessionPtrAndListenerRequest(
+ fuchsia::ui::scenic::Scenic* scenic, async_dispatcher_t* dispatcher) {
+ fuchsia::ui::scenic::SessionPtr session;
+ fidl::InterfaceHandle<fuchsia::ui::scenic::SessionListener> listener_handle;
+ auto listener_request = listener_handle.NewRequest();
+
+ scenic->CreateSession(session.NewRequest(dispatcher), std::move(listener_handle));
+
+ return {std::move(session), std::move(listener_request)};
+}
+
+Session::Session(fuchsia::ui::scenic::SessionPtr session,
+ fidl::InterfaceRequest<fuchsia::ui::scenic::SessionListener> session_listener,
+ async_dispatcher_t* dispatcher)
+ : session_(std::move(session)), session_listener_binding_(this) {
+ ZX_DEBUG_ASSERT(session_);
+ if (session_listener.is_valid())
+ session_listener_binding_.Bind(std::move(session_listener), dispatcher);
+}
+
+Session::Session(fuchsia::ui::scenic::Scenic* scenic, async_dispatcher_t* dispatcher)
+ : session_listener_binding_(this) {
+ ZX_DEBUG_ASSERT(scenic);
+ scenic->CreateSession(session_.NewRequest(dispatcher),
+ session_listener_binding_.NewBinding(dispatcher));
+}
+
+Session::Session(fuchsia::ui::scenic::Scenic* scenic,
+ fidl::InterfaceRequest<fuchsia::ui::views::Focuser> view_focuser,
+ async_dispatcher_t* dispatcher)
+ : session_listener_binding_(this) {
+ ZX_DEBUG_ASSERT(scenic);
+ scenic->CreateSession2(session_.NewRequest(dispatcher),
+ session_listener_binding_.NewBinding(dispatcher), std::move(view_focuser));
+}
+
+Session::Session(SessionPtrAndListenerRequest session_and_listener, async_dispatcher_t* dispatcher)
+ : Session(std::move(session_and_listener.first), std::move(session_and_listener.second),
+ dispatcher) {}
+
+Session::~Session() {
+ ZX_DEBUG_ASSERT_MSG(resource_count_ == 0, "Some resources outlived the session: %u",
+ resource_count_);
+}
+void Session::set_on_frame_presented_handler(OnFramePresentedCallback callback) {
+ session_.events().OnFramePresented = std::move(callback);
+}
+
+uint32_t Session::AllocResourceId() {
+ uint32_t resource_id = next_resource_id_++;
+ ZX_DEBUG_ASSERT(resource_id);
+ resource_count_++;
+ return resource_id;
+}
+
+void Session::ReleaseResource(uint32_t resource_id) {
+ resource_count_--;
+ Enqueue(NewReleaseResourceCmd(resource_id));
+}
+
+void Session::Enqueue(fuchsia::ui::gfx::Command command) {
+ Enqueue(NewCommand(std::move(command)));
+}
+
+void Session::Enqueue(fuchsia::ui::input::Command command) {
+ Enqueue(NewCommand(std::move(command)));
+}
+
+void Session::Enqueue(fuchsia::ui::scenic::Command command) {
+ auto size = measure_tape::fuchsia::ui::scenic::Measure(command);
+
+ // If we would go over caps by adding this command, flush the commands we have
+ // accumulated so far.
+ if (commands_.size() > 0 &&
+ (static_cast<int64_t>(ZX_CHANNEL_MAX_MSG_BYTES) < commands_num_bytes_ + size.num_bytes ||
+ static_cast<int64_t>(ZX_CHANNEL_MAX_MSG_HANDLES) < commands_num_handles_ + size.num_handles)) {
+ Flush();
+ }
+
+ commands_.push_back(std::move(command));
+ commands_num_bytes_ += size.num_bytes;
+ commands_num_handles_ += size.num_handles;
+
+ // Eagerly flush all input commands.
+ if (commands_.back().Which() == fuchsia::ui::scenic::Command::Tag::kInput) {
+ Flush();
+ }
+}
+
+void Session::EnqueueAcquireFence(zx::event fence) {
+ ZX_DEBUG_ASSERT(fence);
+ acquire_fences_.push_back(std::move(fence));
+}
+
+void Session::EnqueueReleaseFence(zx::event fence) {
+ ZX_DEBUG_ASSERT(fence);
+ release_fences_.push_back(std::move(fence));
+}
+
+void Session::Flush() {
+ if (!commands_.empty()) {
+ session_->Enqueue(std::move(commands_));
+
+ // After being moved, |commands_| is in a "valid but unspecified state";
+ // see http://en.cppreference.com/w/cpp/utility/move. Calling clear() makes
+ // it safe to continue using.
+ commands_.clear();
+ commands_num_bytes_ = kEnqueueRequestBaseNumBytes;
+ commands_num_handles_ = 0;
+ }
+}
+
+void Session::Present(uint64_t presentation_time, PresentCallback callback) {
+ ZX_DEBUG_ASSERT(session_);
+ Flush();
+
+ session_->Present(presentation_time, std::move(acquire_fences_), std::move(release_fences_),
+ std::move(callback));
+}
+
+void Session::Present(zx::time presentation_time, PresentCallback callback) {
+ Present(presentation_time.get(), std::move(callback));
+}
+
+void Session::Present2(zx_duration_t requested_presentation_time,
+ zx_duration_t requested_prediction_span,
+ Present2Callback immediate_callback) {
+ ZX_DEBUG_ASSERT(session_);
+ Flush();
+
+ fuchsia::ui::scenic::Present2Args args;
+ args.set_requested_presentation_time(requested_presentation_time);
+ args.set_release_fences(std::move(release_fences_));
+ args.set_acquire_fences(std::move(acquire_fences_));
+ args.set_requested_prediction_span(requested_prediction_span);
+
+ session_->Present2(std::move(args), std::move(immediate_callback));
+}
+
+void Session::RequestPresentationTimes(zx_duration_t requested_prediction_span,
+ RequestPresentationTimesCallback callback) {
+ session_->RequestPresentationTimes(requested_prediction_span, std::move(callback));
+}
+
+void Session::Unbind() {
+ ZX_DEBUG_ASSERT(session_);
+ ZX_DEBUG_ASSERT(!session_handle_);
+ session_handle_ = session_.Unbind();
+ session_ = nullptr;
+}
+
+void Session::Rebind() {
+ ZX_DEBUG_ASSERT(!session_);
+ ZX_DEBUG_ASSERT(session_handle_);
+ session_ = fuchsia::ui::scenic::SessionPtr(session_handle_.Bind());
+ session_handle_ = nullptr;
+}
+
+void Session::OnScenicError(std::string error) {
+ FX_LOGF(ERROR, nullptr, "Scenic Session in client: %s", error.c_str());
+}
+
+void Session::OnScenicEvent(std::vector<fuchsia::ui::scenic::Event> events) {
+ if (event_handler_)
+ event_handler_(std::move(events));
+}
+
+void Session::SetDebugName(const std::string& debug_name) { session_->SetDebugName(debug_name); }
+
+} // namespace scenic
diff --git a/third_party/fuchsia-sdk/pkg/scenic_cpp/view_ref_pair.cc b/third_party/fuchsia-sdk/pkg/scenic_cpp/view_ref_pair.cc
new file mode 100644
index 0000000..560910e
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/scenic_cpp/view_ref_pair.cc
@@ -0,0 +1,32 @@
+// 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.
+
+#include <lib/ui/scenic/cpp/view_ref_pair.h>
+#include <zircon/assert.h>
+
+namespace scenic {
+
+ViewRefPair ViewRefPair::New() {
+ ViewRefPair ref_pair;
+
+ auto status = zx::eventpair::create(/*options*/ 0u, &ref_pair.control_ref.reference,
+ &ref_pair.view_ref.reference);
+ // Assert even in non-debug builds, because eventpair creation can fail under
+ // normal operation. Failure can occur for example, if the job creation
+ // policy governing this process forbids eventpair creation.
+ //
+ // It is unlikely that a well-behaved Scenic client would crash here; if you
+ // hit this, it means something is very abnormal.
+ ZX_ASSERT(status == ZX_OK);
+
+ // Remove duplication from control_ref; Scenic requires it.
+ ref_pair.control_ref.reference.replace(ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
+ &ref_pair.control_ref.reference);
+
+ // Remove signaling from view_ref; Scenic requires it.
+ ref_pair.view_ref.reference.replace(ZX_RIGHTS_BASIC, &ref_pair.view_ref.reference);
+ return ref_pair;
+}
+
+} // namespace scenic
diff --git a/third_party/fuchsia-sdk/pkg/scenic_cpp/view_token_pair.cc b/third_party/fuchsia-sdk/pkg/scenic_cpp/view_token_pair.cc
new file mode 100644
index 0000000..9704ed2
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/scenic_cpp/view_token_pair.cc
@@ -0,0 +1,45 @@
+// Copyright 2018 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.
+
+#include <lib/ui/scenic/cpp/view_token_pair.h>
+#include <zircon/assert.h>
+
+namespace scenic {
+
+ViewTokenPair ViewTokenPair::New() {
+ ViewTokenPair token_pair;
+
+ auto status =
+ zx::eventpair::create(0u, &token_pair.view_token.value, &token_pair.view_holder_token.value);
+ // Assert even in non-debug builds, because eventpair creation can fail under
+ // normal operation. Failure can occur for example, if the job creation
+ // policy governing this process forbids eventpair creation.
+ //
+ // It is unlikely that a well-behaved Scenic client would crash here; if you
+ // hit this, it means something is very abnormal.
+ ZX_ASSERT(status == ZX_OK);
+
+ return token_pair;
+}
+
+ViewTokenStdPair NewViewTokenPair() {
+ auto token_pair = ViewTokenPair::New();
+
+ return ViewTokenStdPair(std::move(token_pair.view_token),
+ std::move(token_pair.view_holder_token));
+}
+
+fuchsia::ui::views::ViewToken ToViewToken(zx::eventpair raw_token) {
+ return fuchsia::ui::views::ViewToken({
+ .value = std::move(raw_token),
+ });
+}
+
+fuchsia::ui::views::ViewHolderToken ToViewHolderToken(zx::eventpair raw_token) {
+ return fuchsia::ui::views::ViewHolderToken({
+ .value = std::move(raw_token),
+ });
+}
+
+} // namespace scenic
diff --git a/third_party/fuchsia-sdk/pkg/svc/BUILD.gn b/third_party/fuchsia-sdk/pkg/svc/BUILD.gn
new file mode 100644
index 0000000..c947588
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/svc/BUILD.gn
@@ -0,0 +1,28 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("svc") {
+ shared_libs = [ "svc" ]
+
+ deps = [
+ "../async",
+ "../fdio",
+ ]
+ sources = [
+ "include/lib/svc/dir.h",
+ ]
+ include_dirs = [ "include" ]
+}
+
+group("all"){
+ deps = [
+ ":svc",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/svc/include/lib/svc/dir.h b/third_party/fuchsia-sdk/pkg/svc/include/lib/svc/dir.h
new file mode 100644
index 0000000..b11adb5
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/svc/include/lib/svc/dir.h
@@ -0,0 +1,57 @@
+// Copyright 2018 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.
+
+#ifndef LIB_SVC_DIR_H_
+#define LIB_SVC_DIR_H_
+
+#include <lib/async/dispatcher.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+typedef void(svc_connector_t)(void* context, const char* service_name, zx_handle_t service_request);
+
+typedef struct svc_dir svc_dir_t;
+
+__EXPORT zx_status_t svc_dir_create(async_dispatcher_t* dispatcher, zx_handle_t directory_request,
+ svc_dir_t** out_result);
+
+// Adds a service named |service_name| to the given |dir|.
+//
+// If |type| is non-NULL, the service will be published in a directory whose
+// name matches the |type|. If |type| is NULL, the service will be published in
+// the root directory.
+//
+// The most commonly used values for |type| are "svc", "debug", and "ctrl".
+// Services published under "svc" are made available to clients via
+// |fuchsia.sys.Lancher#CreateComponent|. The "debug" serivices are exposed via
+// the hub. The "ctrl" services are used by the core platform to communicate
+// with your program.
+//
+// When a client requests the service, |handler| will be called on the async_t
+// passed to |svc_dir_create|. The |context| will be passed to |handler| as its
+// first argument.
+//
+// This may fail in two ways. If an entry with the given
+// |service_name| already exists, this returns
+// ZX_ERR_ALREADY_EXISTS. If the provided |service_name| is invalid,
+// ZX_ERR_INVALID_ARGS is returned. Otherwise, this returns ZX_OK.
+__EXPORT zx_status_t svc_dir_add_service(svc_dir_t* dir, const char* type, const char* service_name,
+ void* context, svc_connector_t* handler);
+
+// Removes the service named |service_name| of type |type| from the
+// given |dir|. This reports a failure if the entry does not exist, by
+// returning ZX_ERR_NOT_FOUND. Otherwise, the service entry is
+// removed, and ZX_OK is returned.
+__EXPORT zx_status_t svc_dir_remove_service(svc_dir_t* dir, const char* type,
+ const char* service_name);
+
+// Destroy the provided directory. This currently cannot fail, and
+// returns ZX_OK.
+__EXPORT zx_status_t svc_dir_destroy(svc_dir_t* dir);
+
+__END_CDECLS
+
+#endif // LIB_SVC_DIR_H_
diff --git a/third_party/fuchsia-sdk/pkg/svc/meta.json b/third_party/fuchsia-sdk/pkg/svc/meta.json
new file mode 100644
index 0000000..40cd078
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/svc/meta.json
@@ -0,0 +1,28 @@
+{
+ "binaries": {
+ "arm64": {
+ "debug": ".build-id/94/49060f220c6b71.debug",
+ "dist": "arch/arm64/dist/libsvc.so",
+ "dist_path": "lib/libsvc.so",
+ "link": "arch/arm64/lib/libsvc.so"
+ },
+ "x64": {
+ "debug": ".build-id/7b/adfd381297bf6f.debug",
+ "dist": "arch/x64/dist/libsvc.so",
+ "dist_path": "lib/libsvc.so",
+ "link": "arch/x64/lib/libsvc.so"
+ }
+ },
+ "deps": [
+ "async",
+ "fdio"
+ ],
+ "format": "shared",
+ "headers": [
+ "pkg/svc/include/lib/svc/dir.h"
+ ],
+ "include_dir": "pkg/svc/include",
+ "name": "svc",
+ "root": "pkg/svc",
+ "type": "cc_prebuilt_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/sync/BUILD.gn b/third_party/fuchsia-sdk/pkg/sync/BUILD.gn
new file mode 100644
index 0000000..832a14f
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sync/BUILD.gn
@@ -0,0 +1,30 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("sync") {
+ static_libs = [ "sync" ]
+
+ deps = [
+ ]
+ sources = [
+ "include/lib/sync/completion.h",
+ "include/lib/sync/condition.h",
+ "include/lib/sync/internal/condition-template.h",
+ "include/lib/sync/internal/mutex-internal.h",
+ "include/lib/sync/mutex.h",
+ ]
+ include_dirs = [ "include" ]
+}
+
+group("all"){
+ deps = [
+ ":sync",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/sync/include/lib/sync/completion.h b/third_party/fuchsia-sdk/pkg/sync/include/lib/sync/completion.h
new file mode 100644
index 0000000..51af5c0
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sync/include/lib/sync/completion.h
@@ -0,0 +1,272 @@
+// Copyright 2016 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.
+
+#ifndef LIB_SYNC_COMPLETION_H_
+#define LIB_SYNC_COMPLETION_H_
+
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// sync_completion_t
+//
+// :: Overview ::
+//
+// sync_completion_t objects (henceforth, simply "completions") are lightweight
+// in-process events. Conceptually, a completion has an internal state of either
+// UNSIGNALED or SIGNALED. Threads in a process may alter this state, check the
+// state without blocking, or wait on the completion with an optional
+// timeout/deadline until it achieves the SIGNALED state. Completions are
+// currently implemented using Zircon futexes.
+//
+// :: Initialization ::
+//
+// Completions always start in the UNSIGNALED state. When used in C code, users
+// *must* explicitly initialize their completion's state using the
+// SYNC_COMPLETION_INIT preprocessor symbol. For example:
+//
+// ```
+// struct my_structure {
+// int32_t a_variable;
+// sync_completion_t a_completion;
+// };
+//
+// void init_my_structure(struct my_structure* s) {
+// s->a_variable = 0;
+// s->a_completion = SYNC_COMPLETION_INIT;
+// }
+// ```
+//
+// When used in C++ code, no explicit initialization steps are required. The
+// completion's structure will contain a default constructor which properly
+// initializes the completion's UNSIGNALED state.
+//
+// :: Operations ::
+//
+// The permitted operations on a completion are as follows.
+//
+// ++ sync_completion_wait ++
+// Block a thread with an optional relative timeout until the completion
+// achieves the signaled state. If the completion is already in the SIGNALED
+// state, the waiting thread will not block.
+//
+// ++ sync_completion_wait_deadline ++
+// Block a thread with an optional absolute deadline timeout until the
+// completion achieves the signaled state. If the completion is already in the
+// SIGNALED state, the waiting thread will not block.
+//
+// ++ sync_completion_signal ++
+// Change the internal state of a completion to SIGNALED, releasing any threads
+// which are currently waiting on it.
+//
+// ++ sync_completion_reset ++
+// Change the internal state of a completion to UNSIGNALED. See also `Avoid
+// "Strobing" Signals` (below) for some hazards related to the use of the reset
+// operation.
+//
+// ++ sync_completion_signaled ++
+// Observe the internal state of a completion, and return true if it is
+// SIGNALED, and false otherwise.
+//
+// :: No Spurious Wakeups ::
+//
+// sync_completion_wait() will *only* return:
+// ++ if the completion is signaled at some point by a call to
+// sync_completion_signal() (either before or after the call to
+// sync_completion_wait())
+// ++ or if the timeout occurs (if using timeouts)
+//
+// Implementation details:
+//
+// In general, futex-based concurrency algorithms can cause futex wakeups on
+// memory locations that have been deallocated (for example, the standard
+// algorithm for a mutex_unlock can do that). This means that futex-based
+// concurrency algorithms must be robust against spurious wakeups, because a
+// futex memory location may have been previously used, deallocated, and then
+// recycled.
+//
+// Completions guarantee that waiters will not suffer any spurious wakeups,
+// provided that the lifetime of the sync_completion_t instance is properly
+// respected. For example, pretend we have the following situation.
+//
+// ```
+// void thread_a() {
+// sync_completion_t C = SYNC_COMPLETION_INIT;
+// share_completion_with_thread_b(&C);
+// sync_completion_wait(&C, ZX_TIME_INFINITE);
+// }
+//
+// void thread_b() {
+// sync_completion_t* C = obtain_completion_from_thread_a();
+// sync_completion_signal(C);
+// }
+// ```
+//
+// The call to sync_completion_wait is guaranteed to not wake up spuriously,
+// even if an unrelated zx_futex_wake operation targeting the same memory
+// location happens to occur during the interactions between thread_a and
+// thread_b. This behavior **depends** on making sure that the life-cycle of C
+// is properly obeyed. After thread_b does sync_completion_signal(C), it must
+// not perform any further operations on C. Having signaled C, thread_b has
+// caused thread_a to unblock and begin the process of deallocating C. Any
+// operations performed on C after this point are racing with the deallocation
+// of C and might result in a use-after-free situation. While it is possible
+// that thread_b may still be in the call to sync_completion_signal when
+// thread_a unwinds and deallocates the completion, no reads or writes from or to
+// the completion's state will be made after this point, and the code is safe
+// provided that this is the final completion operation.
+//
+// :: Avoid "Strobing" Signals ::
+//
+// Users should avoid the pattern of "strobing" a signal operation.
+// Specifically, calling sync_completion_signal(C) immediately followed by
+// sync_completion_reset(C) is not guaranteed to wake up a waiter, even if the
+// user could prove that the waiter is waiting in the completion.
+//
+// Implementation details:
+//
+// The following is an example of a sequence which makes use of the strobe
+// pattern which can lead a missed event. It is based on specific details of
+// how sync_completion_t is implemented today, and should not be considered to
+// be the only way that a signal might end up getting missed, either now or in
+// the future. Again, user should always avoid this "strobing" pattern, it is
+// not guaranteed to wake a waiter.
+//
+// ```
+// global sync_completion_t C;
+//
+// Thread A:
+// 1) Wait on C with no timeout.
+// 2) Declare victory
+//
+// Thread B:
+// 1) Wait until thread A is blocked on completion C by polling Thread A's state
+// via zx_object_get_info.
+// 2) sync_completion_signal(C)
+// 3) sync_completion_reset(C)
+// 4) sync_completion_wait(C, timeout)
+// ```
+//
+// Step B.1 establishes the fact that (from thread B's perspective) thread A
+// managed to observe C in the UNSIGNALED state and join the internal futex wait
+// queue used to implement the completion_t. In the process, thread A sets the
+// completion_t's internal state to UNSIGNALED_WITH_WAITERS. The subsequent
+// signal/reset/wait operations (steps B.2-B.4), will release thread A from the
+// wait queue, but cycle the internal state of the completion_t through the
+// SIGNALED and UNSIGNALED states, and back again to the UNSIGNALED_WITH_WAITERS
+// state. If thread B manages to cycle the state all of the way back around to
+// UNSIGNALED_WITH_WAITERS before thread A manages to wake up, thread A will see
+// the state as UNSIGNALED_WITH_WAITERS and rejoin the wait queue thinking that
+// it had been woken by a spurious futex_wake.
+//
+// Once again, as a general rule the signal/reset pattern shown here should not
+// be used with sync_completion_t objects. It is considered to be racy and can
+// result in undesired behavior, no matter what steps are taken establish that A
+// is waiting before the signal/reset operations take place.
+//
+// :: Memory Ordering Semantics ::
+//
+// When a thread transitions the state of a completion from UNSIGNALED to
+// SIGNALED by calling sync_completion_signal, the operation provides the same
+// guarantees as an atomic modification of the completion state with Release
+// semantics. These guarantees do _not_ hold if the completion is already in
+// the SIGNALED state when the thread calls sync_completion_signal.
+//
+// When a thread returns from a sync_completion_wait operation with a status of
+// ZX_OK, the operation provides the same guarantees as having atomically
+// observed the completion state as being SIGNALED with Acquire semantics.
+// These guarantees do _not_ hold if the wait operation times out, or returns
+// any other error.
+//
+// The effects of these guarantees are that write operations to shared memory
+// performed by a thread may not be reordered beyond a signal operation which
+// successfully transitions a completion from UNSIGNALED to SIGNALED performed
+// by the same thread. Likewise, successful wait operations performed by a
+// thread against a completion guarantee that subsequent read operations
+// performed by that thread may not be reordered before the wait operation.
+//
+// Taken together, these guarantees make the following common pattern safe.
+//
+// ```
+// typedef struct {
+// uint32_t val;
+// sync_completion_t C;
+// } read_operation_t;
+//
+// void thread_a() {
+// read_operation_t Op;
+// Op.C = SYNC_COMPLETION_INIT;
+//
+// send_op_to_thread_b(&Op);
+// sync_completion_wait(&Op.C);
+// do_great_things_with_val(Op.val);
+// }
+//
+// void thread_b() {
+// while (true) {
+// read_operation_t* Op = obtain_read_op();
+// Op->val = compute_a_value_only_thread_b_can_compute();
+// sync_completion_signal(&Op->C);
+// }
+// }
+// ```
+//
+// Thread A is guaranteed to see the results written by thread B into the shared
+// Op.val member. The modifications performed by thread B may not be reordered
+// past the signal operation, and read operations performed by thread A may not
+// be moved before the wait operation.
+//
+
+__BEGIN_CDECLS
+
+typedef struct sync_completion {
+ zx_futex_t futex;
+
+#ifdef __cplusplus
+ sync_completion() : futex(0) {}
+#endif
+} sync_completion_t;
+
+#if !defined(__cplusplus)
+#define SYNC_COMPLETION_INIT ((sync_completion_t){0})
+#endif
+
+// Returns ZX_ERR_TIMED_OUT if timeout elapses, and ZX_OK if woken by
+// a call to sync_completion_signal or if the completion has already been
+// signaled.
+zx_status_t sync_completion_wait(sync_completion_t* completion, zx_duration_t timeout);
+
+// Returns ZX_ERR_TIMED_OUT if deadline elapses, and ZX_OK if woken by
+// a call to sync_completion_signal or if the completion has already been
+// signaled.
+zx_status_t sync_completion_wait_deadline(sync_completion_t* completion, zx_time_t deadline);
+
+// Awakens all waiters on the completion, and marks it as
+// signaled. Waits after this call but before a reset of the
+// completion will also see the signal and immediately return.
+void sync_completion_signal(sync_completion_t* completion);
+
+// Marks the completion as signaled, but doesn't awaken all waiters right away.
+// Instead, all waiters are requeued to the |requeue_target|, and the owner of
+// the |requeue_target| is set to |requeue_target_owner|, or to no one if
+// ZX_HANDLE_INVALID is passed.
+//
+// Waits after this call but before a reset of the completion will also see the
+// signal and immediately return.
+//
+// Intended to be used by libsync internally, e.g. the condition variable
+// implementation.
+void sync_completion_signal_requeue(sync_completion_t* completion, zx_futex_t* requeue_target,
+ zx_handle_t requeue_target_owner);
+
+// Resets the completion's signaled state to unsignaled.
+void sync_completion_reset(sync_completion_t* completion);
+
+// Returns true iff a completion has been signaled.
+bool sync_completion_signaled(sync_completion_t* completion);
+
+__END_CDECLS
+
+#endif // LIB_SYNC_COMPLETION_H_
diff --git a/third_party/fuchsia-sdk/pkg/sync/include/lib/sync/condition.h b/third_party/fuchsia-sdk/pkg/sync/include/lib/sync/condition.h
new file mode 100644
index 0000000..27e5457
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sync/include/lib/sync/condition.h
@@ -0,0 +1,99 @@
+// Copyright 2018 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.
+
+#ifndef LIB_SYNC_CONDITION_H_
+#define LIB_SYNC_CONDITION_H_
+
+#include <assert.h>
+#include <lib/sync/mutex.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// A condition variable that works with a sync_mutex_t
+typedef struct sync_condition {
+ int lock;
+ void* head;
+ void* tail;
+
+#ifdef __cplusplus
+ sync_condition() : lock(0), head(nullptr), tail(nullptr) {}
+#endif
+} sync_condition_t;
+
+static_assert(sizeof(((sync_condition_t*)0)->lock) == sizeof(sync_mutex_t),
+ "sync_condition lock storage must be the same size as sync_mutex_t");
+
+#if !defined(__cplusplus)
+#define SYNC_CONDITION_INIT ((sync_condition_t){0})
+#endif
+
+// Block until |condition| is signaled by sync_condition_signal()/sync_condition_broadcast(), or a
+// spurious wake up occurs.
+//
+// |mutex| must be in a locked state, and will be atomically unlocked for the duration of the wait,
+// then locked again before the function returns.
+void sync_condition_wait(sync_condition_t* condition, sync_mutex_t* mutex);
+
+// Block until |condition| is signaled by sync_condition_signal()/sync_condition_broadcast(), or a
+// spurious wake up or a timeout occurs.
+//
+// |mutex| must be in a locked state, and will be atomically unlocked for the duration of the wait,
+// then locked again before the function returns.
+//
+// ZX_TIME_INFINITE can be used for |deadline| to wait for an unlimited amount of time.
+//
+// Return value:
+// ZX_OK if |condition| was signaled or a spurious wake up occurred.
+// ZX_ERR_TIMED_OUT if the wait timed out.
+zx_status_t sync_condition_timedwait(sync_condition_t* condition, sync_mutex_t* mutex,
+ zx_time_t deadline);
+
+// Wake up one thread waiting for |condition|.
+//
+// If the woken thread was waiting on sync_condition_timedwait(), then it is guaranteed
+// to receive a ZX_OK return value even if a race with a timeout occurs. As an example
+// where this makes a difference, consider the following implementation of a multi-producer,
+// multi-consumer queue:
+//
+// Message* MessageQueue::DequeueTimeout(zx_time_t deadline) {
+// sync_mutex_lock(&mutex_);
+// for (;;) {
+// if (!list_.empty()) {
+// Message* msg = list_.front();
+// list_.pop_front();
+// sync_mutex_unlock(&mutex_);
+// return msg;
+// }
+// zx_status_t status = sync_condition_timedwait(&condition_, &mutex_, deadline);
+// if (status == ZX_ERR_TIMED_OUT) {
+// // Without the above guarantee, this would be a bug: a race between
+// // a timeout and a signal() would result in a missed wakeup.
+// // To fix that, we would need to recheck list_.empty() here, which
+// // is not obvious and would make the code more complex.
+// sync_mutex_unlock(&mutex_);
+// return nullptr;
+// }
+// }
+// }
+//
+// void MessageQueue::Enqueue(Message* msg) {
+// sync_mutex_lock(&mutex_);
+// list_.push_back(msg);
+// // Signal just one waiter. Assumes that any possible waiter will dequeue the message.
+// sync_condition_signal(&condvar_);
+// sync_mutex_unlock(&mutex_);
+// }
+//
+// Note that pthread does not seem to require this property, and in fact the current upstream
+// implementation of pthread_cond_timedwait() in MUSL does not have it.
+void sync_condition_signal(sync_condition_t* condition);
+
+// Wake up all threads that are currently waiting for |condition|.
+void sync_condition_broadcast(sync_condition_t* condition);
+
+__END_CDECLS
+
+#endif // LIB_SYNC_CONDITION_H_
diff --git a/third_party/fuchsia-sdk/pkg/sync/include/lib/sync/internal/condition-template.h b/third_party/fuchsia-sdk/pkg/sync/include/lib/sync/internal/condition-template.h
new file mode 100644
index 0000000..7a5506f
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sync/include/lib/sync/internal/condition-template.h
@@ -0,0 +1,294 @@
+// Copyright 2018 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.
+
+#ifndef LIB_SYNC_INTERNAL_CONDITION_TEMPLATE_H_
+#define LIB_SYNC_INTERNAL_CONDITION_TEMPLATE_H_
+
+#include <zircon/syscalls.h>
+#include <lib/sync/completion.h>
+#include <lib/sync/internal/mutex-internal.h>
+
+namespace condition_impl_internal {
+
+// A template implementation of a condition variable.
+// The algorithm is borrowed from MUSL.
+//
+// The 'Condition' struct must contain the following fields:
+// int lock;
+// void* head;
+// void* tail;
+//
+// The following struct template must be specialized for the mutex type 'Mutex'
+// in order to instantiate the template:
+template <typename Mutex>
+struct MutexOps {
+ // Return a pointer to the futex that backs the |mutex|
+ static zx_futex_t* get_futex(Mutex* mutex);
+
+ // Lock the |mutex|. If an error occurs while locking the mutex,
+ // ZX_ERR_BAD_STATE must be returned. An implementation-defined
+ // error code can be returned via |mutex_lock_err| if it's not null.
+ static zx_status_t lock(Mutex* mutex, int* mutex_lock_err);
+
+ // Similar to lock(), but also update the waiter information in the mutex.
+ // If the mutex implements waiter counting, then the count must be adjusted
+ // by |waiters_delta|. Otherwise, the mutex must be marked as potentially
+ // having waiters.
+ static zx_status_t lock_with_waiters(Mutex* mutex, int waiters_delta, int* mutex_lock_err);
+
+ // Unlock the mutex
+ static void unlock(Mutex* mutex);
+
+ // Requeue all of the memebrs waiting in |completion| to the futex backing |mutex|.
+ static void signal_requeue(sync_completion_t* completion, Mutex* mutex);
+};
+
+// Note that this library is used by libc, and as such needs to use
+// '_zx_' function names for syscalls and not the regular 'zx_' names.
+
+static inline void spin() {
+#if defined(__x86_64__)
+ __asm__ __volatile__("pause" : : : "memory");
+#elif defined(__aarch64__)
+ __atomic_thread_fence(__ATOMIC_SEQ_CST);
+#else
+#error Please define spin() for your architecture
+#endif
+}
+
+static inline bool cas(int* ptr, int* expected, int desired) {
+ return __atomic_compare_exchange_n(ptr, expected, desired, false, __ATOMIC_SEQ_CST,
+ __ATOMIC_SEQ_CST);
+}
+
+static inline void wait(int* futex, int current_value) {
+ int spins = 100;
+ while (spins--) {
+ if (__atomic_load_n(futex, __ATOMIC_SEQ_CST) == current_value) {
+ spin();
+ } else {
+ return;
+ }
+ }
+ while (__atomic_load_n(futex, __ATOMIC_SEQ_CST) == current_value) {
+ _zx_futex_wait(futex, current_value, ZX_HANDLE_INVALID, ZX_TIME_INFINITE);
+ }
+}
+
+enum {
+ WAITING,
+ SIGNALED,
+ LEAVING,
+};
+
+struct Waiter {
+ Waiter* prev = nullptr;
+ Waiter* next = nullptr;
+ int state = WAITING;
+ sync_completion_t ready;
+ int* notify = nullptr;
+};
+
+// Return value:
+// - ZX_OK if the condition variable was signaled;
+// - ZX_ERR_TIMED_OUT if deadline was reached;
+// - ZX_ERR_BAD_STATE if there was an error locking the mutex.
+// In this case, |mutex_lock_err|, if not null, will be populated with an error code
+// provided by the mutex implementation.
+template <typename Condition, typename Mutex>
+static inline zx_status_t timedwait(Condition* c, Mutex* mutex, zx_time_t deadline,
+ int* mutex_lock_err) __TA_NO_THREAD_SAFETY_ANALYSIS {
+ sync_mutex_lock(reinterpret_cast<sync_mutex_t*>(&c->lock));
+
+ Waiter node;
+
+ // Add our waiter node onto the condition's list. We add the node to the
+ // head of the list, but this is logically the end of the queue.
+ node.next = static_cast<Waiter*>(c->head);
+ c->head = &node;
+ if (!c->tail) {
+ c->tail = &node;
+ } else {
+ node.next->prev = &node;
+ }
+
+ sync_mutex_unlock(reinterpret_cast<sync_mutex_t*>(&c->lock));
+
+ MutexOps<Mutex>::unlock(mutex);
+
+ // Wait to be signaled. There are multiple ways this wait could finish:
+ // 1) After being woken by signal().
+ // 2) After being woken by a mutex unlock, after we were
+ // requeued from the condition's futex to the mutex's futex (by
+ // timedwait() in another thread).
+ // 3) After a timeout.
+ // In the original Linux version of this algorithm, this could also exit
+ // when interrupted by an asynchronous signal, but that does not apply on Zircon.
+ sync_completion_wait_deadline(&node.ready, deadline);
+
+ int oldstate = WAITING;
+ if (cas(&node.state, &oldstate, LEAVING)) {
+ // The wait timed out. So far, this thread was not signaled by
+ // signal() -- this thread was able to move state.node out of the
+ // WAITING state before any signal() call could do that.
+ //
+ // This thread must therefore remove the waiter node from the
+ // list itself.
+
+ // Access to cv object is valid because this waiter was not
+ // yet signaled and a new signal/broadcast cannot return
+ // after seeing a LEAVING waiter without getting notified
+ // via the futex notify below.
+
+ sync_mutex_lock(reinterpret_cast<sync_mutex_t*>(&c->lock));
+
+ // Remove our waiter node from the list.
+ if (c->head == &node) {
+ c->head = node.next;
+ } else if (node.prev) {
+ node.prev->next = node.next;
+ }
+
+ if (c->tail == &node) {
+ c->tail = node.prev;
+ } else if (node.next) {
+ node.next->prev = node.prev;
+ }
+
+ sync_mutex_unlock(reinterpret_cast<sync_mutex_t*>(&c->lock));
+
+ // It is possible that signal() saw our waiter node after we set
+ // node.state to LEAVING but before we removed the node from the
+ // list. If so, it will have set node.notify and will be waiting
+ // on it, and we need to wake it up.
+ //
+ // This is rather complex. An alternative would be to eliminate
+ // the |node.state| field and always claim |lock| if we could have
+ // got a timeout. However, that presumably has higher overhead
+ // (since it contends |lock| and involves more atomic ops).
+ if (node.notify) {
+ if (__atomic_fetch_add(node.notify, -1, __ATOMIC_SEQ_CST) == 1) {
+ _zx_futex_wake(node.notify, 1);
+ }
+ }
+
+ // We don't need lock_with_waiters() here: we haven't been signaled, and will
+ // never be since we managed to claim the state as LEAVING. This means that
+ // we could not have been woken up by unlock_requeue() + mutex unlock().
+ if (MutexOps<Mutex>::lock(mutex, mutex_lock_err) != ZX_OK) {
+ return ZX_ERR_BAD_STATE;
+ }
+ return ZX_ERR_TIMED_OUT;
+ }
+
+ // Since the CAS above failed, we have been signaled.
+ // It could still be the case that sync_completion_wait_deadline() above timed out,
+ // so we need to make sure to wait for the completion to control the wake order.
+ // If the completion has already been signaled, this will return immediately.
+ sync_completion_wait_deadline(&node.ready, ZX_TIME_INFINITE);
+
+ // By this point, our part of the waiter list cannot change further.
+ // It has been unlinked from the condition by signal().
+ // Any timed out waiters would have removed themselves from the list
+ // before signal() signaled the first node.ready in our list.
+ //
+ // It is therefore safe now to read node.next and node.prev without
+ // holding c->lock.
+
+ // As an optimization, we only update waiter count at the beginning and
+ // end of the signaled list.
+ int waiters_delta = 0;
+ if (!node.prev) {
+ waiters_delta++;
+ }
+ if (!node.next) {
+ waiters_delta--;
+ }
+
+ // We must leave the mutex in the "locked with waiters" state here
+ // (or adjust its waiter count, depending on the implementation).
+ // There are two reasons for that:
+ // 1) If we do the unlock_requeue() below, a condition waiter will be
+ // requeued to the mutex's futex. We need to ensure that it will
+ // be signaled by mutex unlock() in future.
+ // 2) If the current thread was woken via an unlock_requeue() +
+ // mutex unlock, there *might* be another thread waiting for
+ // the mutex after us in the queue. We need to ensure that it
+ // will be signaled by zxr_mutex_unlock() in future.
+ zx_status_t status = MutexOps<Mutex>::lock_with_waiters(mutex, waiters_delta, mutex_lock_err);
+
+ if (node.prev) {
+ // Signal the completion that's holding back the next waiter, and
+ // requeue it to the mutex so that it will be woken when the
+ // mutex is unlocked.
+ MutexOps<Mutex>::signal_requeue(&node.prev->ready, mutex);
+ }
+
+ // Even if the first call to sync_completion_wait_deadline() timed out,
+ // we still have been signaled. Thus we still return ZX_OK rather than
+ // ZX_ERR_TIMED_OUT. This provides the following guarantee: if multiple
+ // threads are waiting when signal() is called, at least one waiting
+ // thread will be woken *and* get a ZX_OK from timedwait() (unless there
+ // is an error locking the mutex). This property does not appear to be
+ // required by pthread condvars, although an analogous property is
+ // required for futex wake-ups. We also require this property for
+ // sync_condition_t.
+ return status;
+}
+
+// This will wake up to |n| threads that are waiting on the condition,
+// or all waiting threads if |n| is set to -1
+template <typename Condition>
+static inline void signal(Condition* c, int n) {
+ Waiter* p;
+ Waiter* first = nullptr;
+ int ref = 0;
+ int cur;
+
+ sync_mutex_lock(reinterpret_cast<sync_mutex_t*>(&c->lock));
+ for (p = static_cast<Waiter*>(c->tail); n && p; p = p->prev) {
+ int oldstate = WAITING;
+ if (!cas(&p->state, &oldstate, SIGNALED)) {
+ // This waiter timed out, and it marked itself as in the
+ // LEAVING state. However, it hasn't yet claimed |lock|
+ // (since we claimed the lock first) and so it hasn't yet
+ // removed itself from the list. We will wait for the waiter
+ // to remove itself from the list and to notify us of that.
+ __atomic_fetch_add(&ref, 1, __ATOMIC_SEQ_CST);
+ p->notify = &ref;
+ } else {
+ n--;
+ if (!first) {
+ first = p;
+ }
+ }
+ }
+ // Split the list, leaving any remainder on the cv.
+ if (p) {
+ if (p->next) {
+ p->next->prev = 0;
+ }
+ p->next = 0;
+ } else {
+ c->head = 0;
+ }
+ c->tail = p;
+ sync_mutex_unlock(reinterpret_cast<sync_mutex_t*>(&c->lock));
+
+ // Wait for any waiters in the LEAVING state to remove
+ // themselves from the list before returning or allowing
+ // signaled threads to proceed.
+ while ((cur = __atomic_load_n(&ref, __ATOMIC_SEQ_CST))) {
+ wait(&ref, cur);
+ }
+
+ // Allow first signaled waiter, if any, to proceed.
+ if (first) {
+ sync_completion_signal(&first->ready);
+ }
+}
+
+} // namespace condition_impl_internal
+
+#endif // LIB_SYNC_INTERNAL_CONDITION_TEMPLATE_H_
diff --git a/third_party/fuchsia-sdk/pkg/sync/include/lib/sync/internal/mutex-internal.h b/third_party/fuchsia-sdk/pkg/sync/include/lib/sync/internal/mutex-internal.h
new file mode 100644
index 0000000..9f33d99
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sync/include/lib/sync/internal/mutex-internal.h
@@ -0,0 +1,53 @@
+// 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.
+
+#ifndef LIB_SYNC_INTERNAL_MUTEX_INTERNAL_H_
+#define LIB_SYNC_INTERNAL_MUTEX_INTERNAL_H_
+
+#include <assert.h>
+#include <lib/sync/mutex.h>
+#include <zircon/process.h>
+#include <zircon/types.h>
+
+// The value of LIB_SYNC_MUTEX_UNLOCKED must be 0 to match C11's mtx.h and so
+// that mutexes can be allocated in BSS segments (zero-initialized data).
+//
+// Note that we use bit zero as the storage for our contested vs. unconstested
+// state, but the sense of the bit is negative instead of positive. IOW - a
+// contested mutex's state is encoded as the handle of the owning thread with
+// the LSB cleared (not set).
+#define LIB_SYNC_MUTEX_UNLOCKED ((zx_futex_storage_t)0)
+#define CONTESTED_BIT ((zx_futex_storage_t)1)
+
+static_assert(sizeof(zx_handle_t) <= sizeof(zx_futex_storage_t),
+ "mutex implementation requires futex storage to be "
+ "large enough to hold a zircon handle");
+
+static_assert((CONTESTED_BIT & ZX_HANDLE_FIXED_BITS_MASK) == CONTESTED_BIT,
+ "mutex implementation requires that it's contested state storage "
+ "bit be one of the zx_handle_t's guaranteed-to-be-one bits.");
+
+static_assert((~CONTESTED_BIT & ZX_HANDLE_FIXED_BITS_MASK) != 0,
+ "mutex implementation requires at least two guaranteed-to-be-one "
+ "bits in zx_handle_t's");
+
+static inline zx_futex_storage_t libsync_mutex_locked_and_uncontested(void) {
+ return ((zx_futex_storage_t)_zx_thread_self());
+}
+
+static inline bool libsync_mutex_is_contested(zx_futex_storage_t val) {
+ return ((val & CONTESTED_BIT) == 0);
+}
+
+static inline zx_futex_storage_t libsync_mutex_make_contested(zx_futex_storage_t val) {
+ return (val & ~CONTESTED_BIT);
+}
+
+static inline zx_handle_t libsync_mutex_make_owner_from_state(zx_futex_storage_t val) {
+ return (val != LIB_SYNC_MUTEX_UNLOCKED) ? (zx_handle_t)(val | CONTESTED_BIT) : ZX_HANDLE_INVALID;
+}
+
+#undef CONTESTED_BIT
+
+#endif // LIB_SYNC_INTERNAL_MUTEX_INTERNAL_H_
diff --git a/third_party/fuchsia-sdk/pkg/sync/include/lib/sync/mutex.h b/third_party/fuchsia-sdk/pkg/sync/include/lib/sync/mutex.h
new file mode 100644
index 0000000..b7c020b
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sync/include/lib/sync/mutex.h
@@ -0,0 +1,71 @@
+// Copyright 2018 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.
+
+#ifndef LIB_SYNC_MUTEX_H_
+#define LIB_SYNC_MUTEX_H_
+
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// An optimal, non-recursive mutex on Fuchsia.
+//
+// The |mutex_t| mutex in the standard library has several quirks in its design
+// that prevent it from being optimal. For example, the |mutex_t| interface
+// supports recursion, which adds a branch to |mutex_init| to check that the
+// client has not asked for recursion, and |mutex_timedlock| operates in
+// |struct timespec| rather than |zx_time_t|.
+//
+// |sync_mutex| resolves these issues.
+typedef struct __TA_CAPABILITY("mutex") sync_mutex {
+ zx_futex_t futex;
+
+#ifdef __cplusplus
+ sync_mutex() : futex(0) {}
+#endif
+} sync_mutex_t;
+
+#if !defined(__cplusplus)
+#define SYNC_MUTEX_INIT ((sync_mutex_t){0})
+#endif
+
+// Locks the mutex.
+//
+// The current thread will block until the mutex is acquired. The mutex is
+// non-recursive, which means attempting to lock a mutex that is already held by
+// this thread will deadlock.
+void sync_mutex_lock(sync_mutex_t* mutex) __TA_ACQUIRE(mutex);
+
+// Locks the mutex and mark the mutex as having a waiter.
+//
+// Similar to |sync_mutex_lock| but marks the mutex as having a waiter. Intended
+// to be used by the condition variable implementation.
+void sync_mutex_lock_with_waiter(sync_mutex_t* mutex) __TA_ACQUIRE(mutex);
+
+// Attempt to lock the mutex until |deadline|.
+//
+// The current thread will block until either the mutex is acquired or
+// |deadline| passes.
+//
+// |deadline| is expressed as an absolute time in the ZX_CLOCK_MONOTONIC
+// timebase.
+//
+// Returns |ZX_OK| if the lock is acquired, and |ZX_ERR_TIMED_OUT| if the
+// deadline passes.
+zx_status_t sync_mutex_timedlock(sync_mutex_t* mutex, zx_time_t deadline);
+
+// Attempts to lock the mutex without blocking.
+//
+// Returns |ZX_OK| if the lock is obtained, and |ZX_ERR_BAD_STATE| if not.
+zx_status_t sync_mutex_trylock(sync_mutex_t* mutex);
+
+// Unlocks the mutex.
+//
+// Does nothing if the mutex is already unlocked.
+void sync_mutex_unlock(sync_mutex_t* mutex) __TA_RELEASE(mutex);
+
+__END_CDECLS
+
+#endif // LIB_SYNC_MUTEX_H_
diff --git a/third_party/fuchsia-sdk/pkg/sync/meta.json b/third_party/fuchsia-sdk/pkg/sync/meta.json
new file mode 100644
index 0000000..04799a3
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sync/meta.json
@@ -0,0 +1,23 @@
+{
+ "binaries": {
+ "arm64": {
+ "link": "arch/arm64/lib/libsync.a"
+ },
+ "x64": {
+ "link": "arch/x64/lib/libsync.a"
+ }
+ },
+ "deps": [],
+ "format": "static",
+ "headers": [
+ "pkg/sync/include/lib/sync/internal/condition-template.h",
+ "pkg/sync/include/lib/sync/internal/mutex-internal.h",
+ "pkg/sync/include/lib/sync/completion.h",
+ "pkg/sync/include/lib/sync/condition.h",
+ "pkg/sync/include/lib/sync/mutex.h"
+ ],
+ "include_dir": "pkg/sync/include",
+ "name": "sync",
+ "root": "pkg/sync",
+ "type": "cc_prebuilt_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/sys_cpp/BUILD.gn b/third_party/fuchsia-sdk/pkg/sys_cpp/BUILD.gn
new file mode 100644
index 0000000..ec05d2a
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_cpp/BUILD.gn
@@ -0,0 +1,39 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("sys_cpp") {
+ sources = [
+ "component_context.cc",
+ "file_descriptor.cc",
+ "outgoing_directory.cc",
+ "service_directory.cc",
+ "termination_reason.cc",
+ "include/lib/sys/cpp/component_context.h",
+ "include/lib/sys/cpp/file_descriptor.h",
+ "include/lib/sys/cpp/outgoing_directory.h",
+ "include/lib/sys/cpp/service_directory.h",
+ "include/lib/sys/cpp/termination_reason.h",
+ ]
+ include_dirs = [ "include" ]
+ public_deps = [
+ "../../fidl/fuchsia.io",
+ "../../fidl/fuchsia.sys",
+ "../fit",
+ "../sys_service_cpp",
+ "../vfs_cpp",
+ "../zx",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":sys_cpp",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/sys_cpp/component_context.cc b/third_party/fuchsia-sdk/pkg/sys_cpp/component_context.cc
new file mode 100644
index 0000000..de4ed95
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_cpp/component_context.cc
@@ -0,0 +1,32 @@
+// 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.
+
+#include <lib/fdio/directory.h>
+#include <lib/sys/cpp/component_context.h>
+#include <lib/sys/cpp/outgoing_directory.h>
+#include <lib/zx/channel.h>
+#include <zircon/process.h>
+#include <zircon/processargs.h>
+
+namespace sys {
+
+ComponentContext::ComponentContext(std::shared_ptr<ServiceDirectory> svc,
+ async_dispatcher_t* dispatcher)
+ : svc_(std::move(svc)), outgoing_(std::make_shared<OutgoingDirectory>()) {}
+
+ComponentContext::ComponentContext(std::shared_ptr<ServiceDirectory> svc,
+ zx::channel directory_request, async_dispatcher_t* dispatcher)
+ : ComponentContext(svc, dispatcher) {
+ outgoing_->Serve(std::move(directory_request), dispatcher);
+}
+
+ComponentContext::~ComponentContext() = default;
+
+std::unique_ptr<ComponentContext> ComponentContext::Create() {
+ zx_handle_t directory_request = zx_take_startup_handle(PA_DIRECTORY_REQUEST);
+ return std::make_unique<ComponentContext>(ServiceDirectory::CreateFromNamespace(),
+ zx::channel(directory_request));
+}
+
+} // namespace sys
diff --git a/third_party/fuchsia-sdk/pkg/sys_cpp/file_descriptor.cc b/third_party/fuchsia-sdk/pkg/sys_cpp/file_descriptor.cc
new file mode 100644
index 0000000..715c88a
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_cpp/file_descriptor.cc
@@ -0,0 +1,23 @@
+// 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.
+
+#include <lib/fdio/fd.h>
+#include <lib/sys/cpp/file_descriptor.h>
+#include <lib/zx/handle.h>
+#include <zircon/processargs.h>
+
+namespace sys {
+
+fuchsia::sys::FileDescriptorPtr CloneFileDescriptor(int fd) {
+ zx::handle handle;
+ zx_status_t status = fdio_fd_clone(fd, handle.reset_and_get_address());
+ if (status != ZX_OK)
+ return nullptr;
+ fuchsia::sys::FileDescriptorPtr result = fuchsia::sys::FileDescriptor::New();
+ result->type0 = PA_HND(PA_FD, fd);
+ result->handle0 = std::move(handle);
+ return result;
+}
+
+} // namespace sys
diff --git a/third_party/fuchsia-sdk/pkg/sys_cpp/include/lib/sys/cpp/component_context.h b/third_party/fuchsia-sdk/pkg/sys_cpp/include/lib/sys/cpp/component_context.h
new file mode 100644
index 0000000..b58d9ea
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_cpp/include/lib/sys/cpp/component_context.h
@@ -0,0 +1,156 @@
+// 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.
+
+#ifndef LIB_SYS_CPP_COMPONENT_CONTEXT_H_
+#define LIB_SYS_CPP_COMPONENT_CONTEXT_H_
+
+#include <lib/sys/cpp/outgoing_directory.h>
+#include <lib/sys/cpp/service_directory.h>
+
+#include <memory>
+
+namespace sys {
+
+// Context information that this component received at startup.
+//
+// Upon creation, components are given a namespace, which is file system local
+// to the component. A components namespace lets the component interact with
+// other components and the system at large. One important part of this
+// namespace is the directory of services, typically located at "/svc" in the
+// components namespace. The |ComponentContext| provides an ergonomic interface
+// to this service bundle through its |svc()| property.
+//
+// In addition to receiving services, components can also publish services and
+// data to other components through their outgoing namespace, which is also a
+// directory. The |ComponentContext| provides an ergonomic interface for
+// exposing services and other file system objects through its |outgoing()|
+// property.
+//
+// This class is thread-hostile.
+//
+// # Simple usage
+//
+// Instances of this class should be owned and managed on the same thread.
+//
+// # Advanced usage
+//
+// You can use a background thread to service this class provided:
+// async_dispatcher_t for the background thread is stopped or suspended
+// prior to destroying the class object.
+//
+// # Example
+//
+// The |ComponentContext| object is typically created early in the startup
+// sequence for components, typically after creating the |async::Loop| for the
+// main thread.
+//
+// ```
+// int main(int argc, const char** argv) {
+// async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
+// auto context = sys::ComponentContext::Create();
+// my::App app(std::move(context))
+// loop.Run();
+// return 0;
+// }
+// ```
+class ComponentContext final {
+ public:
+ // Creates a component context that uses |svc| for incoming services. Callers
+ // can call |OutgoingDirectory::Serve()| if they wish to publish outgoing
+ // directory.
+ //
+ // This constructor is rarely used directly. Instead, most clients create a
+ // component context using the |Create()| static method.
+ explicit ComponentContext(std::shared_ptr<ServiceDirectory> svc,
+ async_dispatcher_t* dispatcher = nullptr);
+
+ // Creates a component context that uses |svc| for incoming services and
+ // serves outgoing requests over |directory_request|. Callers should be
+ // careful to publish outgoing service in |outgoing()| before |dispatcher|
+ // starts processing incoming requests for the outgoing services.
+ ComponentContext(std::shared_ptr<ServiceDirectory> svc, zx::channel directory_request,
+ async_dispatcher_t* dispatcher = nullptr);
+
+ ~ComponentContext();
+
+ // ComponentContext objects cannot be copied.
+ ComponentContext(const ComponentContext&) = delete;
+ ComponentContext& operator=(const ComponentContext&) = delete;
+
+ // Creates a component context from the process startup info.
+ //
+ // Call this function once during process initialization to retrieve the
+ // handles supplied to the component by the component manager. This function
+ // consumes some of those handles, which means subsequent calls to this
+ // function will not return a functional component context.
+ //
+ // Prefer creating the |ComponentContext| in the |main| function for a
+ // component and passing the context to a class named "App" which encapsulates
+ // the main logic of the program. This pattern makes testing easier because
+ // tests can pass a fake |ComponentContext| from |ComponentContextProvider| to
+ // the |App| class to inject dependencies.
+ //
+ // The returned unique_ptr is never null.
+ //
+ // # Example
+ //
+ // ```
+ // int main(int argc, const char** argv) {
+ // async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
+ // auto context = sys::ComponentContext::Create();
+ // my::App app(std::move(context))
+ // loop.Run();
+ // return 0;
+ // }
+ // ```
+ static std::unique_ptr<ComponentContext> Create();
+
+ // The component's incoming directory of services from its namespace.
+ //
+ // Use this object to connect to services offered by other components.
+ //
+ // The returned object is thread-safe.
+ //
+ // # Example
+ //
+ // ```
+ // auto controller = context.svc()->Connect<fuchsia::foo::Controller>();
+ // ```
+ const std::shared_ptr<ServiceDirectory>& svc() const { return svc_; }
+
+ // The component's outgoing directory.
+ //
+ // Use this object to publish services and data to the component manager and
+ // other components.
+ //
+ // The returned object is thread-safe.
+ //
+ // # Example
+ //
+ // ```
+ // class App : public fuchsia::foo::Controller {
+ // public:
+ // App(std::unique_ptr<ComponentContext> context)
+ // : context_(std::move(context) {
+ // context_.outgoing()->AddPublicService(bindings_.GetHandler(this));
+ // }
+ //
+ // // fuchsia::foo::Controller implementation:
+ // [...]
+ //
+ // private:
+ // fidl::BindingSet<fuchsia::foo::Controller> bindings_;
+ // }
+ // ```
+ const std::shared_ptr<OutgoingDirectory>& outgoing() const { return outgoing_; }
+ std::shared_ptr<OutgoingDirectory>& outgoing() { return outgoing_; }
+
+ private:
+ std::shared_ptr<ServiceDirectory> svc_;
+ std::shared_ptr<OutgoingDirectory> outgoing_;
+};
+
+} // namespace sys
+
+#endif // LIB_SYS_CPP_COMPONENT_CONTEXT_H_
diff --git a/third_party/fuchsia-sdk/pkg/sys_cpp/include/lib/sys/cpp/file_descriptor.h b/third_party/fuchsia-sdk/pkg/sys_cpp/include/lib/sys/cpp/file_descriptor.h
new file mode 100644
index 0000000..546c5d8
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_cpp/include/lib/sys/cpp/file_descriptor.h
@@ -0,0 +1,23 @@
+// 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.
+
+#ifndef LIB_SYS_CPP_FILE_DESCRIPTOR_H_
+#define LIB_SYS_CPP_FILE_DESCRIPTOR_H_
+
+#include <fuchsia/sys/cpp/fidl.h>
+
+namespace sys {
+
+// Clone the given file descriptor as a |fuchsia::sys::FileDescriptorPtr|.
+//
+// For example, the returned |fuchsia::sys::FileDescriptorPtr| is suitable for
+// use as the stdout or stderr when creating a component. To obtain only a
+// |zx_handle_t|, consider calling |fdio_fd_clone| directory instead.
+//
+// Returns |nullptr| if |fd| is invalid or cannot be cloned.
+fuchsia::sys::FileDescriptorPtr CloneFileDescriptor(int fd);
+
+} // namespace sys
+
+#endif // LIB_SYS_CPP_FILE_DESCRIPTOR_H_
diff --git a/third_party/fuchsia-sdk/pkg/sys_cpp/include/lib/sys/cpp/outgoing_directory.h b/third_party/fuchsia-sdk/pkg/sys_cpp/include/lib/sys/cpp/outgoing_directory.h
new file mode 100644
index 0000000..80f67f7
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_cpp/include/lib/sys/cpp/outgoing_directory.h
@@ -0,0 +1,236 @@
+// 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.
+
+#ifndef LIB_SYS_CPP_OUTGOING_DIRECTORY_H_
+#define LIB_SYS_CPP_OUTGOING_DIRECTORY_H_
+
+#include <lib/async/dispatcher.h>
+#include <lib/fit/function.h>
+#include <lib/sys/service/cpp/service.h>
+#include <lib/sys/service/cpp/service_handler.h>
+#include <lib/vfs/cpp/pseudo_dir.h>
+#include <lib/vfs/cpp/service.h>
+
+#include <memory>
+#include <utility>
+
+namespace sys {
+
+// The directory provided by this component to the component manager.
+//
+// A component's outgoing directory contains services, data, and other objects
+// that can be consumed by either the component manager itself or by other
+// components in the system.
+//
+// The outgoing directory contains several subdirectories with well-known
+// names:
+//
+// * svc. This directory contains the services offered by this component to
+// other components.
+// * debug. This directory contains arbitrary debugging output offered by this
+// component.
+//
+// The outgoing directory may optionally contain other directories constructed
+// using |GetOrCreateDirectory|. Common optional directories include:
+//
+// * objects. This directory contains Inspect API files and interfaces for use
+// in component inspection.
+//
+// This class is thread-hostile.
+//
+// # Simple usage
+//
+// Instances of this class should be owned and managed on the same thread
+// that services their connections.
+//
+// # Advanced usage
+//
+// You can use a background thread to service connections provided:
+// async_dispatcher_t for the background thread is stopped or suspended
+// prior to destroying the class object.
+class OutgoingDirectory final {
+ public:
+ OutgoingDirectory();
+ ~OutgoingDirectory();
+
+ // Outgoing objects cannot be copied.
+ OutgoingDirectory(const OutgoingDirectory&) = delete;
+ OutgoingDirectory& operator=(const OutgoingDirectory&) = delete;
+
+ // Starts serving the outgoing directory on the given channel.
+ //
+ // This object will implement the |fuchsia.io.Directory| interface using this
+ // channel.
+ //
+ // If |dispatcher| is NULL, this object will serve the outgoing directory
+ // using the |async_dispatcher_t| from |async_get_default_dispatcher()|.
+ //
+ // # Errors
+ //
+ // ZX_ERR_BAD_HANDLE: |directory_request| is not a valid handle.
+ //
+ // ZX_ERR_ACCESS_DENIED: |directory_request| has insufficient rights.
+ //
+ // TODO: Document more errors.
+ zx_status_t Serve(zx::channel directory_request, async_dispatcher_t* dispatcher = nullptr);
+
+ // Starts serving the outgoing directory on the channel provided to this
+ // process at startup as |PA_DIRECTORY_REQUEST|.
+ //
+ // This object will implement the |fuchsia.io.Directory| interface using this
+ // channel.
+ //
+ // If |dispatcher| is NULL, this object will serve the outgoing directory
+ // using the |async_dispatcher_t| from |async_get_default_dispatcher()|.
+ //
+ // # Errors
+ //
+ // ZX_ERR_BAD_HANDLE: the process did not receive a |PA_DIRECTORY_REQUEST|
+ // startup handle or it was already taken.
+ //
+ // ZX_ERR_ACCESS_DENIED: |directory_request| has insufficient rights.
+ //
+ // TODO: Document more errors.
+ zx_status_t ServeFromStartupInfo(async_dispatcher_t* dispatcher = nullptr);
+
+ // Adds the specified interface to the set of public interfaces.
+ //
+ // Adds a supported service with the given |service_name|, using the given
+ // |interface_request_handler|. |interface_request_handler| should
+ // remain valid for the lifetime of this object.
+ //
+ // # Errors
+ //
+ // ZX_ERR_ALREADY_EXISTS: The public directory already contains an entry for
+ // this service.
+ //
+ // # Example
+ //
+ // ```
+ // fidl::BindingSet<fuchsia::foo::Controller> bindings;
+ // outgoing.AddPublicService(bindings.GetHandler(this));
+ // ```
+ template <typename Interface>
+ zx_status_t AddPublicService(fidl::InterfaceRequestHandler<Interface> handler,
+ std::string service_name = Interface::Name_) const {
+ return AddPublicService(std::make_unique<vfs::Service>(std::move(handler)),
+ std::move(service_name));
+ }
+
+ // Adds the specified service to the set of public services.
+ //
+ // Adds a supported service with the given |service_name|, using the given
+ // |service|.
+ //
+ // # Errors
+ //
+ // ZX_ERR_ALREADY_EXISTS: The public directory already contains an entry for
+ // this service.
+ zx_status_t AddPublicService(std::unique_ptr<vfs::Service> service,
+ std::string service_name) const;
+
+ // Removes the specified interface from the set of public interfaces.
+ //
+ // # Errors
+ //
+ // ZX_ERR_NOT_FOUND: The public directory does not contain an entry for this
+ // service.
+ //
+ // # Example
+ //
+ // ```
+ // outgoing.RemovePublicService<fuchsia::foo::Controller>();
+ // ```
+ template <typename Interface>
+ zx_status_t RemovePublicService(const std::string& name = Interface::Name_) const {
+ return svc_->RemoveEntry(name);
+ }
+
+ // Adds an instance of a service.
+ //
+ // A |handler| is added to provide an |instance| of a service.
+ //
+ // # Errors
+ //
+ // ZX_ERR_ALREADY_EXISTS: The instance already exists.
+ //
+ // # Example
+ //
+ // ```
+ // ServiceHandler handler;
+ // handler.AddMember("my-member", ...);
+ // outgoing.AddService<MyService>(std::move(handler), "my-instance");
+ // ```
+ template <typename Service>
+ zx_status_t AddService(ServiceHandler handler, std::string instance = kDefaultInstance) const {
+ return AddNamedService(std::move(handler), Service::Name, std::move(instance));
+ }
+
+ // Adds an instance of a service.
+ //
+ // A |handler| is added to provide an |instance| of a |service|.
+ //
+ // # Errors
+ //
+ // ZX_ERR_ALREADY_EXISTS: The instance already exists.
+ zx_status_t AddNamedService(ServiceHandler handler, std::string service,
+ std::string instance = kDefaultInstance) const;
+
+ // Removes an instance of a service.
+ //
+ // # Errors
+ //
+ // ZX_ERR_NOT_FOUND: The instance was not found.
+ //
+ // # Example
+ //
+ // ```
+ // outgoing.RemoveService<MyService>("my-instance");
+ // ```
+ template <typename Service>
+ zx_status_t RemoveService(const std::string& instance) const {
+ return RemoveNamedService(Service::Name, instance);
+ }
+
+ // Removes an instance of a service.
+ //
+ // # Errors
+ //
+ // ZX_ERR_NOT_FOUND: The instance was not found.
+ zx_status_t RemoveNamedService(const std::string& service, const std::string& instance) const;
+
+ // Gets the root directory.
+ //
+ // The returned directory is owned by this class.
+ vfs::PseudoDir* root_dir() const { return root_.get(); }
+
+ // Gets the directory to publish debug data.
+ //
+ // The returned directory is owned by this class.
+ vfs::PseudoDir* debug_dir() const { return debug_; }
+
+ // Gets a subdirectory with the given |name|, creates it if it does not
+ // already exist.
+ //
+ // The returned directory is owned by this class.
+ vfs::PseudoDir* GetOrCreateDirectory(const std::string& name);
+
+ private:
+ // The root of the outgoing directory itself.
+ std::unique_ptr<vfs::PseudoDir> root_;
+
+ // The service subdirectory of the root directory.
+ //
+ // The underlying |vfs::PseudoDir| object is owned by |root_|.
+ vfs::PseudoDir* svc_;
+
+ // The debug subdirectory of the root directory.
+ //
+ // The underlying |vfs::PseudoDir| object is owned by |root_|.
+ vfs::PseudoDir* debug_;
+};
+
+} // namespace sys
+
+#endif // LIB_SYS_CPP_OUTGOING_DIRECTORY_H_
diff --git a/third_party/fuchsia-sdk/pkg/sys_cpp/include/lib/sys/cpp/service_directory.h b/third_party/fuchsia-sdk/pkg/sys_cpp/include/lib/sys/cpp/service_directory.h
new file mode 100644
index 0000000..3a0e448
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_cpp/include/lib/sys/cpp/service_directory.h
@@ -0,0 +1,179 @@
+// 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.
+
+#ifndef LIB_SYS_CPP_SERVICE_DIRECTORY_H_
+#define LIB_SYS_CPP_SERVICE_DIRECTORY_H_
+
+#include <fuchsia/io/cpp/fidl.h>
+#include <lib/fidl/cpp/interface_ptr.h>
+#include <lib/fidl/cpp/interface_request.h>
+#include <lib/zx/channel.h>
+
+#include <memory>
+#include <string>
+#include <utility>
+
+namespace sys {
+
+// A directory of services provided by another component.
+//
+// These services are typically received by the component through its namespace,
+// specifically through the "/svc" entry.
+//
+// Instances of this class are thread-safe.
+class ServiceDirectory final {
+ public:
+ // Create an directory of services backed by given |directory|.
+ //
+ // Requests for services are routed to entries in this directory.
+ //
+ // The directory is expected to implement the |fuchsia.io.Directory| protocol.
+ explicit ServiceDirectory(zx::channel directory);
+ explicit ServiceDirectory(fidl::InterfaceHandle<fuchsia::io::Directory> directory);
+
+ ~ServiceDirectory();
+
+ // ServiceDirectory objects cannot be copied.
+ ServiceDirectory(const ServiceDirectory&) = delete;
+ ServiceDirectory& operator=(const ServiceDirectory&) = delete;
+
+ // ServiceDirectory objects can be moved.
+ ServiceDirectory(ServiceDirectory&& other) : directory_(std::move(other.directory_)) {}
+ ServiceDirectory& operator=(ServiceDirectory&& other) {
+ directory_ = std::move(other.directory_);
+ return *this;
+ }
+
+ // Create an directory of services from this component's namespace.
+ //
+ // Uses the "/svc" entry in the namespace as the backing directory for the
+ // returned directory of services.
+ //
+ // Rather than creating a new |ServiceDirectory| consider passing |svc()| from
+ // your |ComponentContext| around as that makes your code unit testable and
+ // consumes one less kernel handle.
+ static std::shared_ptr<ServiceDirectory> CreateFromNamespace();
+
+ // Create a directory of services and return a request for an implementation
+ // of the underlying directory in |out_request|.
+ //
+ // Useful when creating components.
+ static std::shared_ptr<ServiceDirectory> CreateWithRequest(zx::channel* out_request);
+ static std::shared_ptr<ServiceDirectory> CreateWithRequest(
+ fidl::InterfaceRequest<fuchsia::io::Directory>* out_request);
+
+ // Connect to an interface in the directory.
+ //
+ // The discovery name of the interface is inferred from the C++ type of the
+ // interface. Callers can supply an interface name explicitly to override
+ // the default name.
+ //
+ // This overload for |Connect| discards the status of the underlying
+ // connection operation. Callers that wish to recieve that status should use
+ // one of the other overloads that returns a |zx_status_t|.
+ //
+ // # Example
+ //
+ // ```
+ // auto controller = directory.Connect<fuchsia::foo::Controller>();
+ // ```
+ template <typename Interface>
+ fidl::InterfacePtr<Interface> Connect(
+ const std::string& interface_name = Interface::Name_) const {
+ fidl::InterfacePtr<Interface> result;
+ Connect(result.NewRequest(), interface_name);
+ return std::move(result);
+ }
+
+ // Connect to an interface in the directory.
+ //
+ // The discovery name of the interface is inferred from the C++ type of the
+ // interface request. Callers can supply an interface name explicitly to
+ // override the default name.
+ //
+ // Returns whether the request was successfully sent to the remote directory
+ // backing this service bundle.
+ //
+ // # Errors
+ //
+ // ZX_ERR_UNAVAILABLE: The directory backing this service bundle is invalid.
+ //
+ // ZX_ERR_ACCESS_DENIED: This service bundle has insufficient rights to
+ // connect to services.
+ //
+ // # Example
+ //
+ // ```
+ // fuchsia::foo::ControllerPtr controller;
+ // directory.Connect(controller.NewRequest());
+ // ```
+ template <typename Interface>
+ zx_status_t Connect(fidl::InterfaceRequest<Interface> request,
+ const std::string& interface_name = Interface::Name_) const {
+ return Connect(interface_name, request.TakeChannel());
+ }
+
+ // Connect to an interface in the directory.
+ //
+ // The interface name and the channel must be supplied explicitly.
+ //
+ // Returns whether the request was successfully sent to the remote directory
+ // backing this service bundle.
+ //
+ // # Errors
+ //
+ // ZX_ERR_UNAVAILABLE: The directory backing this service bundle is invalid.
+ //
+ // ZX_ERR_ACCESS_DENIED: This service bundle has insufficient rights to
+ // connect to services.
+ //
+ // # Example
+ //
+ // ```
+ // zx::channel controller, request;
+ // zx_status_t status = zx::channel::create(0, &controller, &request);
+ // if (status != ZX_OK) {
+ // [...]
+ // }
+ // directory.Connect("fuchsia.foo.Controller", std::move(request));
+ // ```
+ zx_status_t Connect(const std::string& interface_name, zx::channel request) const;
+
+ // Clone underlying directory channel.
+ //
+ // This overload for |CloneHandle| discards the status of the underlying
+ // operation. Callers that wish to recieve that status should use
+ // other overload that returns a |zx_status_t|.
+ fidl::InterfaceHandle<fuchsia::io::Directory> CloneChannel() const;
+
+ // Clone underlying directory channel.
+ //
+ // Returns whether the request was successfully sent to the remote directory
+ // backing this service bundle.
+ //
+ // # Errors
+ //
+ // ZX_ERR_UNAVAILABLE: The directory backing this service bundle is invalid.
+ //
+ // Other transport and application-level errors associated with
+ // |fuchsia.io.Node/Clone|.
+ //
+ // # Example
+ //
+ // ```
+ // fuchsia::io::DirectoryPtr dir;
+ // directory.CloneHandle(dir.NewRequest());
+ // ```
+ zx_status_t CloneChannel(fidl::InterfaceRequest<fuchsia::io::Directory>) const;
+
+ private:
+ // The directory to which connection requests are routed.
+ //
+ // Implements |fuchsia.io.Directory| protocol.
+ zx::channel directory_;
+};
+
+} // namespace sys
+
+#endif // LIB_SYS_CPP_SERVICE_DIRECTORY_H_
diff --git a/third_party/fuchsia-sdk/pkg/sys_cpp/include/lib/sys/cpp/termination_reason.h b/third_party/fuchsia-sdk/pkg/sys_cpp/include/lib/sys/cpp/termination_reason.h
new file mode 100644
index 0000000..3d7d7a7
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_cpp/include/lib/sys/cpp/termination_reason.h
@@ -0,0 +1,22 @@
+// Copyright 2016 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.
+
+// TODO(FIDL-549): Delete this class.
+
+#ifndef LIB_SYS_CPP_TERMINATION_REASON_H_
+#define LIB_SYS_CPP_TERMINATION_REASON_H_
+
+#include <fuchsia/sys/cpp/fidl.h>
+
+#include <string>
+
+namespace sys {
+
+std::string TerminationReasonToString(fuchsia::sys::TerminationReason termination_reason);
+
+std::string HumanReadableTerminationReason(fuchsia::sys::TerminationReason termination_reason);
+
+} // namespace sys
+
+#endif // LIB_SYS_CPP_TERMINATION_REASON_H_
diff --git a/third_party/fuchsia-sdk/pkg/sys_cpp/meta.json b/third_party/fuchsia-sdk/pkg/sys_cpp/meta.json
new file mode 100644
index 0000000..7a6ffac
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_cpp/meta.json
@@ -0,0 +1,31 @@
+{
+ "banjo_deps": [],
+ "deps": [
+ "sys_service_cpp",
+ "vfs_cpp",
+ "fit",
+ "zx"
+ ],
+ "fidl_deps": [
+ "fuchsia.sys",
+ "fuchsia.io"
+ ],
+ "headers": [
+ "pkg/sys_cpp/include/lib/sys/cpp/component_context.h",
+ "pkg/sys_cpp/include/lib/sys/cpp/file_descriptor.h",
+ "pkg/sys_cpp/include/lib/sys/cpp/outgoing_directory.h",
+ "pkg/sys_cpp/include/lib/sys/cpp/service_directory.h",
+ "pkg/sys_cpp/include/lib/sys/cpp/termination_reason.h"
+ ],
+ "include_dir": "pkg/sys_cpp/include",
+ "name": "sys_cpp",
+ "root": "pkg/sys_cpp",
+ "sources": [
+ "pkg/sys_cpp/component_context.cc",
+ "pkg/sys_cpp/file_descriptor.cc",
+ "pkg/sys_cpp/outgoing_directory.cc",
+ "pkg/sys_cpp/service_directory.cc",
+ "pkg/sys_cpp/termination_reason.cc"
+ ],
+ "type": "cc_source_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/sys_cpp/outgoing_directory.cc b/third_party/fuchsia-sdk/pkg/sys_cpp/outgoing_directory.cc
new file mode 100644
index 0000000..7391028
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_cpp/outgoing_directory.cc
@@ -0,0 +1,77 @@
+// 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.
+
+#include <lib/sys/cpp/outgoing_directory.h>
+#include <zircon/process.h>
+#include <zircon/processargs.h>
+
+#include <utility>
+
+namespace {
+
+// Adds a new empty directory |name| to |dir| and returns pointer to new
+// directory. Will fail silently if directory with that name already exists.
+vfs::PseudoDir* AddNewEmptyDirectory(vfs::PseudoDir* dir, std::string name) {
+ auto subdir = std::make_unique<vfs::PseudoDir>();
+ auto ptr = subdir.get();
+ dir->AddEntry(std::move(name), std::move(subdir));
+ return ptr;
+}
+
+vfs::PseudoDir* GetOrCreateDirectory(vfs::PseudoDir* dir, std::string name) {
+ vfs::internal::Node* node;
+ zx_status_t status = dir->Lookup(name, &node);
+ if (status != ZX_OK) {
+ return AddNewEmptyDirectory(dir, std::move(name));
+ }
+ return static_cast<vfs::PseudoDir*>(node);
+}
+
+} // namespace
+
+namespace sys {
+
+OutgoingDirectory::OutgoingDirectory()
+ : root_(std::make_unique<vfs::PseudoDir>()),
+ svc_(GetOrCreateDirectory("svc")),
+ debug_(GetOrCreateDirectory("debug")) {}
+
+OutgoingDirectory::~OutgoingDirectory() = default;
+
+zx_status_t OutgoingDirectory::Serve(zx::channel directory_request,
+ async_dispatcher_t* dispatcher) {
+ return root_->Serve(fuchsia::io::OPEN_RIGHT_READABLE | fuchsia::io::OPEN_RIGHT_WRITABLE,
+ std::move(directory_request), dispatcher);
+}
+
+zx_status_t OutgoingDirectory::ServeFromStartupInfo(async_dispatcher_t* dispatcher) {
+ return Serve(zx::channel(zx_take_startup_handle(PA_DIRECTORY_REQUEST)), dispatcher);
+}
+
+vfs::PseudoDir* OutgoingDirectory::GetOrCreateDirectory(const std::string& name) {
+ return ::GetOrCreateDirectory(root_.get(), name);
+}
+
+zx_status_t OutgoingDirectory::AddPublicService(std::unique_ptr<vfs::Service> service,
+ std::string service_name) const {
+ return svc_->AddEntry(std::move(service_name), std::move(service));
+}
+
+zx_status_t OutgoingDirectory::AddNamedService(ServiceHandler handler, std::string service,
+ std::string instance) const {
+ auto dir = ::GetOrCreateDirectory(svc_, std::move(service));
+ return dir->AddEntry(std::move(instance), handler.TakeDirectory());
+}
+
+zx_status_t OutgoingDirectory::RemoveNamedService(const std::string& service,
+ const std::string& instance) const {
+ vfs::internal::Node* node;
+ zx_status_t status = svc_->Lookup(instance, &node);
+ if (status != ZX_OK) {
+ return ZX_OK;
+ }
+ return static_cast<vfs::PseudoDir*>(node)->RemoveEntry(service);
+}
+
+} // namespace sys
diff --git a/third_party/fuchsia-sdk/pkg/sys_cpp/service_directory.cc b/third_party/fuchsia-sdk/pkg/sys_cpp/service_directory.cc
new file mode 100644
index 0000000..a3c769f
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_cpp/service_directory.cc
@@ -0,0 +1,67 @@
+// 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.
+
+#include <lib/fdio/directory.h>
+#include <lib/sys/cpp/service_directory.h>
+#include <lib/zx/channel.h>
+
+namespace sys {
+namespace {
+
+zx::channel OpenServiceRoot() {
+ zx::channel request, service_root;
+ if (zx::channel::create(0, &request, &service_root) != ZX_OK)
+ return zx::channel();
+ if (fdio_service_connect("/svc/.", request.release()) != ZX_OK)
+ return zx::channel();
+ return service_root;
+}
+
+} // namespace
+
+ServiceDirectory::ServiceDirectory(zx::channel directory) : directory_(std::move(directory)) {}
+
+ServiceDirectory::ServiceDirectory(fidl::InterfaceHandle<fuchsia::io::Directory> directory)
+ : ServiceDirectory(directory.TakeChannel()) {}
+
+ServiceDirectory::~ServiceDirectory() = default;
+
+std::shared_ptr<ServiceDirectory> ServiceDirectory::CreateFromNamespace() {
+ return std::make_shared<ServiceDirectory>(OpenServiceRoot());
+}
+
+std::shared_ptr<ServiceDirectory> ServiceDirectory::CreateWithRequest(zx::channel* out_request) {
+ zx::channel directory;
+ // no need to check status, even if this fails, service directory would be
+ // backed by invalid channel and Connect will return correct error.
+ zx::channel::create(0, &directory, out_request);
+
+ return std::make_shared<ServiceDirectory>(ServiceDirectory(std::move(directory)));
+}
+
+std::shared_ptr<ServiceDirectory> ServiceDirectory::CreateWithRequest(
+ fidl::InterfaceRequest<fuchsia::io::Directory>* out_request) {
+ zx::channel request;
+ auto directory = CreateWithRequest(&request);
+ out_request->set_channel(std::move(request));
+ return directory;
+}
+
+zx_status_t ServiceDirectory::Connect(const std::string& interface_name,
+ zx::channel channel) const {
+ return fdio_service_connect_at(directory_.get(), interface_name.c_str(), channel.release());
+}
+
+fidl::InterfaceHandle<fuchsia::io::Directory> ServiceDirectory::CloneChannel() const {
+ fidl::InterfaceHandle<fuchsia::io::Directory> dir;
+ CloneChannel(dir.NewRequest());
+ return dir;
+}
+
+zx_status_t ServiceDirectory::CloneChannel(
+ fidl::InterfaceRequest<fuchsia::io::Directory> dir) const {
+ return fdio_service_clone_to(directory_.get(), dir.TakeChannel().release());
+}
+
+} // namespace sys
diff --git a/third_party/fuchsia-sdk/pkg/sys_cpp/termination_reason.cc b/third_party/fuchsia-sdk/pkg/sys_cpp/termination_reason.cc
new file mode 100644
index 0000000..8069722
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_cpp/termination_reason.cc
@@ -0,0 +1,56 @@
+// 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.
+
+#include "lib/sys/cpp/termination_reason.h"
+
+#include <sstream>
+#include <string>
+
+namespace sys {
+
+std::string TerminationReasonToString(fuchsia::sys::TerminationReason termination_reason) {
+ switch (termination_reason) {
+ case fuchsia::sys::TerminationReason::UNKNOWN:
+ return "UNKNOWN";
+ case fuchsia::sys::TerminationReason::EXITED:
+ return "EXITED";
+ case fuchsia::sys::TerminationReason::URL_INVALID:
+ return "URL_INVALID";
+ case fuchsia::sys::TerminationReason::PACKAGE_NOT_FOUND:
+ return "PACKAGE_NOT_FOUND";
+ case fuchsia::sys::TerminationReason::INTERNAL_ERROR:
+ return "INTERNAL_ERROR";
+ case fuchsia::sys::TerminationReason::PROCESS_CREATION_ERROR:
+ return "PROCESS_CREATION_ERROR";
+ case fuchsia::sys::TerminationReason::RUNNER_FAILED:
+ return "RUNNER_FAILED";
+ case fuchsia::sys::TerminationReason::RUNNER_TERMINATED:
+ return "RUNNER_TERMINATED";
+ default:
+ return std::to_string(static_cast<int>(termination_reason));
+ }
+}
+
+std::string HumanReadableTerminationReason(fuchsia::sys::TerminationReason termination_reason) {
+ switch (termination_reason) {
+ case fuchsia::sys::TerminationReason::EXITED:
+ return "exited";
+ case fuchsia::sys::TerminationReason::URL_INVALID:
+ return "url invalid";
+ case fuchsia::sys::TerminationReason::PACKAGE_NOT_FOUND:
+ return "not found";
+ case fuchsia::sys::TerminationReason::PROCESS_CREATION_ERROR:
+ return "failed to spawn process";
+ case fuchsia::sys::TerminationReason::RUNNER_FAILED:
+ return "failed to start runner for process";
+ case fuchsia::sys::TerminationReason::RUNNER_TERMINATED:
+ return "runner failed to execute";
+ default:
+ std::ostringstream out;
+ out << "failed to create component (" << TerminationReasonToString(termination_reason) << ")";
+ return out.str();
+ }
+}
+
+} // namespace sys
diff --git a/third_party/fuchsia-sdk/pkg/sys_cpp_testing/BUILD.gn b/third_party/fuchsia-sdk/pkg/sys_cpp_testing/BUILD.gn
new file mode 100644
index 0000000..f71dc12
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_cpp_testing/BUILD.gn
@@ -0,0 +1,36 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("sys_cpp_testing") {
+ sources = [
+ "component_context_provider.cc",
+ "fake_component.cc",
+ "fake_launcher.cc",
+ "service_directory_provider.cc",
+ "include/lib/sys/cpp/testing/component_context_provider.h",
+ "include/lib/sys/cpp/testing/fake_component.h",
+ "include/lib/sys/cpp/testing/fake_launcher.h",
+ "include/lib/sys/cpp/testing/service_directory_provider.h",
+ ]
+ include_dirs = [ "include" ]
+ public_deps = [
+ "../../fidl/fuchsia.io",
+ "../fit",
+ "../sys_cpp",
+ "../vfs_cpp",
+ "../zx",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":sys_cpp_testing",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/sys_cpp_testing/component_context_provider.cc b/third_party/fuchsia-sdk/pkg/sys_cpp_testing/component_context_provider.cc
new file mode 100644
index 0000000..8c6518c
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_cpp_testing/component_context_provider.cc
@@ -0,0 +1,32 @@
+// 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.
+
+#include <lib/fdio/directory.h>
+#include <lib/sys/cpp/testing/component_context_provider.h>
+#include <lib/sys/cpp/testing/service_directory_provider.h>
+#include <zircon/processargs.h>
+
+#include <memory>
+
+namespace sys {
+namespace testing {
+
+ComponentContextProvider::ComponentContextProvider(async_dispatcher_t* dispatcher)
+ : svc_provider_(std::make_shared<ServiceDirectoryProvider>(dispatcher)) {
+ // remove this handle from namespace so that no one is using it.
+ zx_take_startup_handle(PA_DIRECTORY_REQUEST);
+
+ component_context_ = std::make_unique<sys::ComponentContext>(
+ svc_provider_->service_directory(),
+ outgoing_directory_ptr_.NewRequest(dispatcher).TakeChannel(), dispatcher);
+
+ zx::channel request;
+ public_service_directory_ = sys::ServiceDirectory::CreateWithRequest(&request);
+ fdio_service_connect_at(outgoing_directory_ptr_.channel().get(), "svc", request.release());
+}
+
+ComponentContextProvider::~ComponentContextProvider() = default;
+
+} // namespace testing
+} // namespace sys
diff --git a/third_party/fuchsia-sdk/pkg/sys_cpp_testing/fake_component.cc b/third_party/fuchsia-sdk/pkg/sys_cpp_testing/fake_component.cc
new file mode 100644
index 0000000..5474908
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_cpp_testing/fake_component.cc
@@ -0,0 +1,29 @@
+// Copyright 2018 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.
+
+#include <fuchsia/io/cpp/fidl.h>
+#include <lib/sys/cpp/testing/fake_component.h>
+
+namespace sys {
+namespace testing {
+
+FakeComponent::FakeComponent() {}
+
+FakeComponent::~FakeComponent() = default;
+
+void FakeComponent::Register(std::string url, FakeLauncher& fake_launcher,
+ async_dispatcher_t* dispatcher) {
+ fake_launcher.RegisterComponent(
+ url, [this, dispatcher](fuchsia::sys::LaunchInfo launch_info,
+ fidl::InterfaceRequest<fuchsia::sys::ComponentController> ctrl) {
+ ctrls_.push_back(std::move(ctrl));
+ zx_status_t status =
+ directory_.Serve(fuchsia::io::OPEN_RIGHT_READABLE | fuchsia::io::OPEN_RIGHT_WRITABLE,
+ std::move(launch_info.directory_request), dispatcher);
+ ZX_ASSERT(status == ZX_OK);
+ });
+}
+
+} // namespace testing
+} // namespace sys
diff --git a/third_party/fuchsia-sdk/pkg/sys_cpp_testing/fake_launcher.cc b/third_party/fuchsia-sdk/pkg/sys_cpp_testing/fake_launcher.cc
new file mode 100644
index 0000000..eb3f97d
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_cpp_testing/fake_launcher.cc
@@ -0,0 +1,36 @@
+// Copyright 2018 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.
+
+#include <lib/sys/cpp/testing/fake_launcher.h>
+
+namespace sys {
+namespace testing {
+
+using fuchsia::sys::Launcher;
+
+FakeLauncher::FakeLauncher() {}
+
+FakeLauncher::~FakeLauncher() = default;
+
+void FakeLauncher::CreateComponent(
+ fuchsia::sys::LaunchInfo launch_info,
+ fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller) {
+ auto it = connectors_.find(launch_info.url);
+ if (it != connectors_.end()) {
+ it->second(std::move(launch_info), std::move(controller));
+ }
+}
+
+void FakeLauncher::RegisterComponent(std::string url, ComponentConnector connector) {
+ connectors_[url] = std::move(connector);
+}
+
+fidl::InterfaceRequestHandler<Launcher> FakeLauncher::GetHandler(async_dispatcher_t* dispatcher) {
+ return [this, dispatcher](fidl::InterfaceRequest<Launcher> request) {
+ binding_set_.AddBinding(this, std::move(request), dispatcher);
+ };
+}
+
+} // namespace testing
+} // namespace sys
diff --git a/third_party/fuchsia-sdk/pkg/sys_cpp_testing/include/lib/sys/cpp/testing/component_context_provider.h b/third_party/fuchsia-sdk/pkg/sys_cpp_testing/include/lib/sys/cpp/testing/component_context_provider.h
new file mode 100644
index 0000000..bb07214
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_cpp_testing/include/lib/sys/cpp/testing/component_context_provider.h
@@ -0,0 +1,109 @@
+// 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.
+
+#ifndef LIB_SYS_CPP_TESTING_COMPONENT_CONTEXT_PROVIDER_H_
+#define LIB_SYS_CPP_TESTING_COMPONENT_CONTEXT_PROVIDER_H_
+
+#include <lib/fdio/directory.h>
+#include <lib/sys/cpp/component_context.h>
+#include <lib/sys/cpp/testing/service_directory_provider.h>
+
+namespace sys {
+namespace testing {
+
+// Provides fake |ComponentContext| for unit testing.
+// Provides access to services that have been added to this object.
+// The object of this class should be kept alive for fake |ComponentContext| to
+// work.
+//
+// This class is thread-hostile.
+//
+// # Simple usage
+//
+// Instances of this class should be owned and managed on the same thread.
+//
+// # Advanced usage
+//
+// You can use a background thread to service this class provided:
+// async_dispatcher_t for the background thread is stopped or suspended
+// prior to destroying the class object.
+class ComponentContextProvider {
+ public:
+ explicit ComponentContextProvider(async_dispatcher_t* dispatcher = nullptr);
+
+ ~ComponentContextProvider();
+
+ // Points to outgoing root directory of outgoing directory, test can get it
+ // and try to connect to internal directories/objects/files/services to test
+ // code which published them.
+ fuchsia::io::DirectoryPtr& outgoing_directory_ptr() { return outgoing_directory_ptr_; }
+
+ // Connects to public service which was published in "svc" directory by
+ // code under test.
+ template <typename Interface>
+ fidl::InterfacePtr<Interface> ConnectToPublicService(
+ const std::string& name = Interface::Name_, async_dispatcher_t* dispatcher = nullptr) const {
+ fidl::InterfacePtr<Interface> ptr;
+ ConnectToPublicService(ptr.NewRequest(dispatcher), name);
+ return ptr;
+ }
+
+ // Connects to public service which was published in "svc" directory by code
+ // under test.
+ template <typename Interface>
+ void ConnectToPublicService(fidl::InterfaceRequest<Interface> request,
+ const std::string& name = Interface::Name_) const {
+ public_service_directory_->Connect(std::move(request), name);
+ }
+
+ // Returns a service directory which can be useful to test services published to out/svc.
+ // For example,
+ // context_provider.context()->AddPublicService("my service", ...);
+ // ...
+ // auto mock = MyMock(context_provider.public_service_directory());
+ // ...
+ // ...
+ // Code inside mock
+ // MyMock::MyMock(std::shared_ptr<sys::ServiceDirectory> svc) {
+ // svc->Connect("my service", channel);
+ // }
+ std::shared_ptr<sys::ServiceDirectory> public_service_directory() {
+ return public_service_directory_;
+ }
+
+ // Gets a fake service directory that can be used to inject services
+ // which can be accessed by code under test.
+ //
+ // # Example
+ //
+ // ```
+ // fidl::BindingSet<fuchsia::foo::Controller> bindings;
+ // context_provider->service_directory_provider()->AddService(bindings.GetHandler(this));
+ // auto context = context_provider->context();
+ // ...
+ // ...
+ // ...
+ // context->svc()->Connect(...);
+ // ```
+ const std::shared_ptr<ServiceDirectoryProvider>& service_directory_provider() const {
+ return svc_provider_;
+ }
+
+ // Relinquishes the ownership of fake context. This object should be alive
+ // for lifetime of returned context.
+ std::unique_ptr<sys::ComponentContext> TakeContext() { return std::move(component_context_); }
+
+ sys::ComponentContext* context() { return component_context_.get(); }
+
+ private:
+ fuchsia::io::DirectoryPtr outgoing_directory_ptr_;
+ std::shared_ptr<sys::ServiceDirectory> public_service_directory_;
+ std::shared_ptr<ServiceDirectoryProvider> svc_provider_;
+ std::unique_ptr<sys::ComponentContext> component_context_;
+};
+
+} // namespace testing
+} // namespace sys
+
+#endif // LIB_SYS_CPP_TESTING_COMPONENT_CONTEXT_PROVIDER_H_
diff --git a/third_party/fuchsia-sdk/pkg/sys_cpp_testing/include/lib/sys/cpp/testing/fake_component.h b/third_party/fuchsia-sdk/pkg/sys_cpp_testing/include/lib/sys/cpp/testing/fake_component.h
new file mode 100644
index 0000000..b5cb944
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_cpp_testing/include/lib/sys/cpp/testing/fake_component.h
@@ -0,0 +1,54 @@
+// Copyright 2018 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.
+
+#ifndef LIB_SYS_CPP_TESTING_FAKE_COMPONENT_H_
+#define LIB_SYS_CPP_TESTING_FAKE_COMPONENT_H_
+
+#include <lib/async/dispatcher.h>
+#include <lib/sys/cpp/testing/fake_launcher.h>
+#include <lib/vfs/cpp/pseudo_dir.h>
+#include <lib/vfs/cpp/service.h>
+
+#include <memory>
+#include <utility>
+
+namespace sys {
+namespace testing {
+
+// A fake component which can be used to intercept component launch using
+// |FakeLauncher| and publish fake services for unit testing.
+class FakeComponent {
+ public:
+ FakeComponent();
+ ~FakeComponent();
+
+ // Adds specified interface to the set of public interfaces.
+ //
+ // Adds a supported service with the given |service_name|, using the given
+ // |interface_request_handler|, which should remain valid for the lifetime of
+ // this object.
+ //
+ // A typical usage may be:
+ //
+ // AddPublicService(foobar_bindings_.GetHandler(this));
+ template <typename Interface>
+ zx_status_t AddPublicService(fidl::InterfaceRequestHandler<Interface> handler,
+ const std::string& service_name = Interface::Name_) {
+ return directory_.AddEntry(service_name.c_str(),
+ std::make_unique<vfs::Service>(std::move(handler)));
+ }
+
+ // Registers this component with a FakeLauncher.
+ void Register(std::string url, FakeLauncher& fake_launcher,
+ async_dispatcher_t* dispatcher = nullptr);
+
+ private:
+ vfs::PseudoDir directory_;
+ std::vector<fidl::InterfaceRequest<fuchsia::sys::ComponentController>> ctrls_;
+};
+
+} // namespace testing
+} // namespace sys
+
+#endif // LIB_SYS_CPP_TESTING_FAKE_COMPONENT_H_
diff --git a/third_party/fuchsia-sdk/pkg/sys_cpp_testing/include/lib/sys/cpp/testing/fake_launcher.h b/third_party/fuchsia-sdk/pkg/sys_cpp_testing/include/lib/sys/cpp/testing/fake_launcher.h
new file mode 100644
index 0000000..58f13e0
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_cpp_testing/include/lib/sys/cpp/testing/fake_launcher.h
@@ -0,0 +1,56 @@
+// Copyright 2018 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.
+
+#ifndef LIB_SYS_CPP_TESTING_FAKE_LAUNCHER_H_
+#define LIB_SYS_CPP_TESTING_FAKE_LAUNCHER_H_
+
+#include <fuchsia/sys/cpp/fidl.h>
+#include <lib/async/dispatcher.h>
+#include <lib/fidl/cpp/binding_set.h>
+#include <lib/fidl/cpp/interface_request.h>
+#include <lib/fit/function.h>
+
+namespace sys {
+namespace testing {
+
+// A fake |Launcher| for testing.
+// Used to intercept component component launch from code under test.
+class FakeLauncher : public fuchsia::sys::Launcher {
+ public:
+ FakeLauncher();
+ ~FakeLauncher() override;
+
+ FakeLauncher(const FakeLauncher&) = delete;
+ FakeLauncher& operator=(const FakeLauncher&) = delete;
+
+ using ComponentConnector = fit::function<void(
+ fuchsia::sys::LaunchInfo, fidl::InterfaceRequest<fuchsia::sys::ComponentController>)>;
+
+ // Registers a component located at "url" with a connector. When someone
+ // tries to CreateComponent() with this |url|, the supplied |connector| is
+ // called with the the LaunchInfo and associated ComponentController request.
+ // The connector may implement the |LaunchInfo.services| and
+ // |ComponentController| interfaces to communicate with its connector and
+ // listen for component signals.
+ void RegisterComponent(std::string url, ComponentConnector connector);
+
+ // Forwards this |CreateComponent| request to a registered connector, if an
+ // associated one exists. If one is not registered for |launch_info.url|, then
+ // this call is dropped.
+ void CreateComponent(
+ fuchsia::sys::LaunchInfo launch_info,
+ fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller) override;
+
+ fidl::InterfaceRequestHandler<fuchsia::sys::Launcher> GetHandler(
+ async_dispatcher_t* dispatcher = nullptr);
+
+ private:
+ std::map<std::string, ComponentConnector> connectors_;
+ fidl::BindingSet<Launcher> binding_set_;
+};
+
+} // namespace testing
+} // namespace sys
+
+#endif // LIB_SYS_CPP_TESTING_FAKE_LAUNCHER_H_
diff --git a/third_party/fuchsia-sdk/pkg/sys_cpp_testing/include/lib/sys/cpp/testing/service_directory_provider.h b/third_party/fuchsia-sdk/pkg/sys_cpp_testing/include/lib/sys/cpp/testing/service_directory_provider.h
new file mode 100644
index 0000000..004a73a
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_cpp_testing/include/lib/sys/cpp/testing/service_directory_provider.h
@@ -0,0 +1,87 @@
+// 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.
+
+#ifndef LIB_SYS_CPP_TESTING_SERVICE_DIRECTORY_PROVIDER_H_
+#define LIB_SYS_CPP_TESTING_SERVICE_DIRECTORY_PROVIDER_H_
+
+#include <lib/vfs/cpp/pseudo_dir.h>
+#include <lib/vfs/cpp/service.h>
+
+#include <memory>
+
+#include "lib/sys/cpp/service_directory.h"
+
+namespace sys {
+namespace testing {
+
+// This provides a fake |ServiceDirectory| for unit testing.
+// Provides access to services that have been added to this object.
+// The object of this class should be kept alive for fake |ServiceDirectory| to
+// work.
+//
+// This class is thread-hostile.
+//
+// # Simple usage
+//
+// Instances of this class should be owned and managed on the same thread.
+//
+// # Advanced usage
+//
+// You can use a background thread to service this class provided:
+// async_dispatcher_t for the background thread is stopped or suspended
+// prior to destroying the class object.
+class ServiceDirectoryProvider {
+ public:
+ explicit ServiceDirectoryProvider(async_dispatcher_t* dispatcher = nullptr);
+
+ ~ServiceDirectoryProvider();
+
+ // Injects a service which can be accessed by calling Connect on
+ // |sys::ServiceDirectory| by code under test.
+ //
+ // Adds a supported service with the given |service_name|, using the given
+ // |interface_request_handler|. |interface_request_handler| should
+ // remain valid for the lifetime of this object.
+ //
+ // # Errors
+ //
+ // ZX_ERR_ALREADY_EXISTS: This already contains an entry for
+ // this service.
+ //
+ // # Example
+ //
+ // ```
+ // fidl::BindingSet<fuchsia::foo::Controller> bindings;
+ // svc->AddService(bindings.GetHandler(this));
+ // ```
+ template <typename Interface>
+ zx_status_t AddService(fidl::InterfaceRequestHandler<Interface> handler,
+ const std::string& name = Interface::Name_) const {
+ return AddService(std::make_unique<vfs::Service>(std::move(handler)), name);
+ }
+
+ // Injects a service which can be accessed by calling Connect on
+ // |sys::ServiceDirectory| by code under test.
+ //
+ // Adds a supported service with the given |service_name|, using the given
+ // |service|. |service| closure should
+ // remain valid for the lifetime of this object.
+ //
+ // # Errors
+ //
+ // ZX_ERR_ALREADY_EXISTS: This already contains an entry for
+ // this service.
+ zx_status_t AddService(std::unique_ptr<vfs::Service> service, const std::string& name) const;
+
+ std::shared_ptr<ServiceDirectory>& service_directory() { return service_directory_; }
+
+ private:
+ std::shared_ptr<ServiceDirectory> service_directory_;
+ std::unique_ptr<vfs::PseudoDir> svc_dir_;
+};
+
+} // namespace testing
+} // namespace sys
+
+#endif // LIB_SYS_CPP_TESTING_SERVICE_DIRECTORY_PROVIDER_H_
diff --git a/third_party/fuchsia-sdk/pkg/sys_cpp_testing/meta.json b/third_party/fuchsia-sdk/pkg/sys_cpp_testing/meta.json
new file mode 100644
index 0000000..5c8afa0
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_cpp_testing/meta.json
@@ -0,0 +1,28 @@
+{
+ "banjo_deps": [],
+ "deps": [
+ "sys_cpp",
+ "vfs_cpp",
+ "fit",
+ "zx"
+ ],
+ "fidl_deps": [
+ "fuchsia.io"
+ ],
+ "headers": [
+ "pkg/sys_cpp_testing/include/lib/sys/cpp/testing/component_context_provider.h",
+ "pkg/sys_cpp_testing/include/lib/sys/cpp/testing/fake_component.h",
+ "pkg/sys_cpp_testing/include/lib/sys/cpp/testing/fake_launcher.h",
+ "pkg/sys_cpp_testing/include/lib/sys/cpp/testing/service_directory_provider.h"
+ ],
+ "include_dir": "pkg/sys_cpp_testing/include",
+ "name": "sys_cpp_testing",
+ "root": "pkg/sys_cpp_testing",
+ "sources": [
+ "pkg/sys_cpp_testing/component_context_provider.cc",
+ "pkg/sys_cpp_testing/fake_component.cc",
+ "pkg/sys_cpp_testing/fake_launcher.cc",
+ "pkg/sys_cpp_testing/service_directory_provider.cc"
+ ],
+ "type": "cc_source_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/sys_cpp_testing/service_directory_provider.cc b/third_party/fuchsia-sdk/pkg/sys_cpp_testing/service_directory_provider.cc
new file mode 100644
index 0000000..25eb783
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_cpp_testing/service_directory_provider.cc
@@ -0,0 +1,26 @@
+// 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.
+
+#include <lib/sys/cpp/testing/service_directory_provider.h>
+
+namespace sys {
+namespace testing {
+
+ServiceDirectoryProvider::ServiceDirectoryProvider(async_dispatcher_t* dispatcher)
+ : svc_dir_(std::make_unique<vfs::PseudoDir>()) {
+ fidl::InterfaceHandle<fuchsia::io::Directory> directory_ptr;
+ svc_dir_->Serve(fuchsia::io::OPEN_RIGHT_READABLE | fuchsia::io::OPEN_RIGHT_WRITABLE,
+ directory_ptr.NewRequest().TakeChannel(), dispatcher);
+ service_directory_ = std::make_shared<sys::ServiceDirectory>(directory_ptr.TakeChannel());
+}
+
+ServiceDirectoryProvider::~ServiceDirectoryProvider() = default;
+
+zx_status_t ServiceDirectoryProvider::AddService(std::unique_ptr<vfs::Service> service,
+ const std::string& name) const {
+ return svc_dir_->AddEntry(name, std::move(service));
+}
+
+} // namespace testing
+} // namespace sys
diff --git a/third_party/fuchsia-sdk/pkg/sys_inspect_cpp/BUILD.gn b/third_party/fuchsia-sdk/pkg/sys_inspect_cpp/BUILD.gn
new file mode 100644
index 0000000..75136ae
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_inspect_cpp/BUILD.gn
@@ -0,0 +1,29 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("sys_inspect_cpp") {
+ sources = [
+ "component.cc",
+ "include/lib/sys/inspect/cpp/component.h",
+ ]
+ include_dirs = [ "include" ]
+ public_deps = [
+ "../../fidl/fuchsia.inspect",
+ "../inspect",
+ "../inspect_service_cpp",
+ "../sys_cpp",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":sys_inspect_cpp",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/sys_inspect_cpp/component.cc b/third_party/fuchsia-sdk/pkg/sys_inspect_cpp/component.cc
new file mode 100644
index 0000000..5568a02
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_inspect_cpp/component.cc
@@ -0,0 +1,35 @@
+// 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.
+
+#include <lib/fidl/cpp/binding_set.h>
+#include <lib/inspect/service/cpp/service.h>
+#include <lib/sys/inspect/cpp/component.h>
+#include <lib/vfs/cpp/service.h>
+#include <lib/vfs/cpp/vmo_file.h>
+
+#include <memory>
+
+using inspect::NodeHealth;
+
+namespace sys {
+
+ComponentInspector::ComponentInspector(sys::ComponentContext* startup_context) : inspector_() {
+ auto connections = std::make_unique<
+ fidl::BindingSet<fuchsia::inspect::Tree, std::unique_ptr<fuchsia::inspect::Tree>>>();
+ auto state = inspect::internal::GetState(&inspector_);
+
+ startup_context->outgoing()
+ ->GetOrCreateDirectory("diagnostics")
+ ->AddEntry(fuchsia::inspect::Tree::Name_,
+ std::make_unique<vfs::Service>(inspect::MakeTreeHandler(&inspector_)));
+}
+
+NodeHealth& ComponentInspector::Health() {
+ if (!component_health_) {
+ component_health_ = std::make_unique<NodeHealth>(&inspector()->GetRoot());
+ }
+ return *component_health_;
+}
+
+} // namespace sys
diff --git a/third_party/fuchsia-sdk/pkg/sys_inspect_cpp/include/lib/sys/inspect/cpp/component.h b/third_party/fuchsia-sdk/pkg/sys_inspect_cpp/include/lib/sys/inspect/cpp/component.h
new file mode 100644
index 0000000..3b915ad
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_inspect_cpp/include/lib/sys/inspect/cpp/component.h
@@ -0,0 +1,49 @@
+// 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.
+
+#ifndef LIB_SYS_INSPECT_CPP_COMPONENT_H_
+#define LIB_SYS_INSPECT_CPP_COMPONENT_H_
+
+#include <lib/inspect/cpp/health.h>
+#include <lib/inspect/cpp/inspect.h>
+#include <lib/sys/cpp/component_context.h>
+
+namespace sys {
+
+// ComponentInspector is a singleton wrapping an Inspector for a Fuchsia Component.
+//
+// Callers must ensure the ComponentInspector returned by Initialize remains alive for the lifetime
+// of the component.
+class ComponentInspector final {
+ public:
+ // Creates a new Inspector for this component, and publishes it in this component's outgoing
+ // directory at the path "diagnostics/root.inspect".
+ explicit ComponentInspector(sys::ComponentContext* startup_context);
+
+ // Get the inspector for this component.
+ ::inspect::Inspector* inspector() { return &inspector_; }
+
+ // Get the root tree for this component.
+ ::inspect::Node& root() { return inspector_.GetRoot(); }
+
+ // Gets the NodeHealth for this component.
+ // This method is NOT thread safe.
+ ::inspect::NodeHealth& Health();
+
+ // Emplace a value in the wrapped Inspector.
+ template <typename T>
+ void emplace(T value) {
+ inspector_.emplace(std::move(value));
+ }
+
+ private:
+ ComponentInspector();
+
+ std::unique_ptr<::inspect::NodeHealth> component_health_;
+ ::inspect::Inspector inspector_;
+};
+
+} // namespace sys
+
+#endif // LIB_SYS_INSPECT_CPP_COMPONENT_H_
diff --git a/third_party/fuchsia-sdk/pkg/sys_inspect_cpp/meta.json b/third_party/fuchsia-sdk/pkg/sys_inspect_cpp/meta.json
new file mode 100644
index 0000000..282fb3f
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_inspect_cpp/meta.json
@@ -0,0 +1,21 @@
+{
+ "banjo_deps": [],
+ "deps": [
+ "inspect_service_cpp",
+ "sys_cpp",
+ "inspect"
+ ],
+ "fidl_deps": [
+ "fuchsia.inspect"
+ ],
+ "headers": [
+ "pkg/sys_inspect_cpp/include/lib/sys/inspect/cpp/component.h"
+ ],
+ "include_dir": "pkg/sys_inspect_cpp/include",
+ "name": "sys_inspect_cpp",
+ "root": "pkg/sys_inspect_cpp",
+ "sources": [
+ "pkg/sys_inspect_cpp/component.cc"
+ ],
+ "type": "cc_source_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/sys_service_cpp/BUILD.gn b/third_party/fuchsia-sdk/pkg/sys_service_cpp/BUILD.gn
new file mode 100644
index 0000000..3a1df5c
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_service_cpp/BUILD.gn
@@ -0,0 +1,36 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("sys_service_cpp") {
+ sources = [
+ "service.cc",
+ "service_aggregate.cc",
+ "service_watcher.cc",
+ "include/lib/sys/service/cpp/service.h",
+ "include/lib/sys/service/cpp/service_aggregate.h",
+ "include/lib/sys/service/cpp/service_handler.h",
+ "include/lib/sys/service/cpp/service_watcher.h",
+ ]
+ include_dirs = [ "include" ]
+ public_deps = [
+ "../../fidl/fuchsia.io",
+ "../async-cpp",
+ "../fdio",
+ "../fidl_cpp",
+ "../vfs_cpp",
+ "../zx",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":sys_service_cpp",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/sys_service_cpp/include/lib/sys/service/cpp/service.h b/third_party/fuchsia-sdk/pkg/sys_service_cpp/include/lib/sys/service/cpp/service.h
new file mode 100644
index 0000000..704c7a5
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_service_cpp/include/lib/sys/service/cpp/service.h
@@ -0,0 +1,107 @@
+// 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.
+
+#ifndef LIB_SYS_SERVICE_CPP_SERVICE_H_
+#define LIB_SYS_SERVICE_CPP_SERVICE_H_
+
+#include <fuchsia/io/cpp/fidl.h>
+#include <lib/fdio/namespace.h>
+#include <lib/fidl/cpp/service_connector.h>
+
+namespace sys {
+
+// Name of the default instance of a service.
+extern const char kDefaultInstance[];
+
+// Opens a named |instance| of a service at |service_path|, within a directory
+// provided by |handle|.
+//
+// The instance is opened under `service_path/instance` within |handle|.
+//
+// If |instance| is not provided, the default instance is opened.
+//
+// Returns a `fuchsia::io::Directory`, representing an instance of the service.
+std::unique_ptr<fidl::ServiceConnector> OpenNamedServiceAt(
+ const fidl::InterfaceHandle<fuchsia::io::Directory>& handle, const std::string& service_path,
+ const std::string& instance = kDefaultInstance);
+
+// Opens a named |instance| of a |Service|, within a directory provided by
+// |handle|.
+//
+// The instance is opened under `Service::Name/instance` within |handle|.
+//
+// If |instance| is not provided, the default instance is opened.
+//
+// Returns a |Service|, which is a FIDL-generated service.
+template <typename Service>
+Service OpenServiceAt(const fidl::InterfaceHandle<fuchsia::io::Directory>& handle,
+ const std::string& instance = kDefaultInstance) {
+ return Service(OpenNamedServiceAt(handle, Service::Name, instance));
+}
+
+// Opens a named |instance| of a service at |service_path|, within a namespace
+// provided by |ns|.
+//
+// If |service_path| is an absolute path, the instance is opened under
+// `service_path/instance` within |ns|. Otherwise, if |service_path| is a
+// relative path, the instance is opened under `/svc/service_path/instance`
+// within |ns|.
+//
+// If |instance| is not provided, the default instance is opened.
+//
+// |ns| must not be null.
+//
+// Returns a `fuchsia::io::Directory`, representing an instance of the service.
+std::unique_ptr<fidl::ServiceConnector> OpenNamedServiceIn(
+ fdio_ns_t* ns, const std::string& service_path, const std::string& instance = kDefaultInstance);
+
+// Opens a named |instance| of a |Service|, within a namespace provided by
+// |ns|.
+//
+// The instance is opened under `/svc/Service::Name/instance` within |ns|.
+//
+// If |instance| is not provided, the default instance is opened.
+//
+// |ns| must not be null.
+//
+// Returns a |Service|, which is a FIDL-generated service.
+template <typename Service>
+Service OpenServiceIn(fdio_ns_t* ns, const std::string& instance = kDefaultInstance) {
+ return Service(OpenNamedServiceIn(ns, Service::Name, instance));
+}
+
+// Opens a named |instance| of a service at |service_path|, within the default
+// namespace.
+//
+// If |service_path| is an absolute path, the instance is opened under
+// `service_path/instance` within the default namespace. Otherwise, if
+// |service_path| is a relative path, the instance is opened under
+// `/svc/service_path/instance` within the default namespace.
+//
+// If |instance| is not provided, the default instance is opened.
+//
+// See `fdio_ns_get_installed()`.
+//
+// Returns a `fuchsia::io::Directory`, representing an instance of the service.
+std::unique_ptr<fidl::ServiceConnector> OpenNamedService(
+ const std::string& service_path, const std::string& instance = kDefaultInstance);
+
+// Opens a named |instance| of a |Service|, within the default namespace.
+//
+// The instance is opened under `/svc/Service::Name/instance` within the default
+// namespace.
+//
+// If |instance| is not provided, the default instance is opened.
+//
+// See `fdio_ns_get_installed()`.
+//
+// Returns a |Service|, which is a FIDL-generated service.
+template <typename Service>
+Service OpenService(const std::string& instance = kDefaultInstance) {
+ return Service(OpenNamedService(Service::Name, instance));
+}
+
+} // namespace sys
+
+#endif // LIB_SYS_SERVICE_CPP_SERVICE_H_
diff --git a/third_party/fuchsia-sdk/pkg/sys_service_cpp/include/lib/sys/service/cpp/service_aggregate.h b/third_party/fuchsia-sdk/pkg/sys_service_cpp/include/lib/sys/service/cpp/service_aggregate.h
new file mode 100644
index 0000000..1242623
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_service_cpp/include/lib/sys/service/cpp/service_aggregate.h
@@ -0,0 +1,110 @@
+// 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.
+
+#ifndef LIB_SYS_SERVICE_CPP_SERVICE_AGGREGATE_H_
+#define LIB_SYS_SERVICE_CPP_SERVICE_AGGREGATE_H_
+
+#include <fuchsia/io/cpp/fidl.h>
+#include <lib/fdio/namespace.h>
+#include <lib/zx/channel.h>
+
+namespace sys {
+
+// A base class for a service aggregate, providing common functionality.
+class ServiceAggregateBase {
+ public:
+ // Returns whether the underlying directory is valid.
+ bool is_valid() const { return dir_.is_valid(); }
+
+ // Returns the channel of the underlying directory.
+ const zx::channel& channel() const { return dir_.channel(); }
+
+ // Lists all available instances of a service.
+ std::vector<std::string> ListInstances() const;
+
+ protected:
+ explicit ServiceAggregateBase(fidl::InterfaceHandle<fuchsia::io::Directory> dir)
+ : dir_(std::move(dir)) {}
+
+ private:
+ const fidl::InterfaceHandle<fuchsia::io::Directory> dir_;
+};
+
+// A service aggregate, containing zero or more instances of a service.
+template <typename Service>
+struct ServiceAggregate final : public ServiceAggregateBase {
+ // Constructs a service aggregate from a `fuchsia::io::Directory`.
+ explicit ServiceAggregate(fidl::InterfaceHandle<fuchsia::io::Directory> dir)
+ : ServiceAggregateBase(std::move(dir)) {}
+};
+
+// Opens a service aggregate at |service_path|, within a directory provided by
+// |handle|.
+//
+// A service aggregate contains zero or more instances of a service.
+//
+// Returns a `fuchsia::io::Directory`, representing a service aggregate.
+fidl::InterfaceHandle<fuchsia::io::Directory> OpenNamedServiceAggregateAt(
+ const fidl::InterfaceHandle<fuchsia::io::Directory>& handle, const std::string& service_path);
+
+// Opens a service aggregate for |Service|, within a directory provided by
+// |handle|.
+//
+// A service aggregate contains zero or more instances of a service.
+//
+// Returns a |ServiceAggregate| for a FIDL-generated service.
+template <typename Service>
+ServiceAggregate<Service> OpenServiceAggregateAt(
+ const fidl::InterfaceHandle<fuchsia::io::Directory>& handle) {
+ return ServiceAggregate<Service>(OpenNamedServiceAggregateAt(handle, Service::Name));
+}
+
+// Opens a service aggregate at |service_path|, within a namespace provided by
+// |ns|.
+//
+// A service aggregate contains zero or more instances of a service.
+//
+// |ns| must not be null.
+//
+// Returns a `fuchsia::io::Directory`, representing a service aggregate.
+fidl::InterfaceHandle<fuchsia::io::Directory> OpenNamedServiceAggregateIn(
+ fdio_ns_t* ns, const std::string& service_path);
+
+// Opens a service aggregate for |Service|, within a namespace provided by |ns|.
+//
+// A service aggregate contains zero or more instances of a service.
+//
+// |ns| must not be null.
+//
+// Returns a |ServiceAggregate| for a FIDL-generated service.
+template <typename Service>
+ServiceAggregate<Service> OpenServiceAggregateIn(fdio_ns_t* ns) {
+ return ServiceAggregate<Service>(OpenNamedServiceAggregateIn(ns, Service::Name));
+}
+
+// Opens a service aggregate at |service_path|, within the default namespace.
+//
+// A service aggregate contains zero or more instances of a service.
+//
+// See `fdio_ns_get_installed()`.
+//
+// Returns a `fuchsia::io::Directory`, representing a service aggregate.
+fidl::InterfaceHandle<fuchsia::io::Directory> OpenNamedServiceAggregate(
+ const std::string& service_path);
+
+// Opens a service aggregate for |Service|, within the default namespace.
+//
+// A service aggregate contains zero or more instances of a service.
+//
+// See `fdio_ns_get_installed()`.
+//
+// Returns a |ServiceAggregate| for a FIDL-generated service.
+template <typename Service>
+ServiceAggregate<Service> OpenServiceAggregate() {
+ return ServiceAggregate<Service>(OpenNamedServiceAggregate(Service::Name));
+}
+
+} // namespace sys
+
+#endif // LIB_SYS_SERVICE_CPP_SERVICE_AGGREGATE_H_
diff --git a/third_party/fuchsia-sdk/pkg/sys_service_cpp/include/lib/sys/service/cpp/service_handler.h b/third_party/fuchsia-sdk/pkg/sys_service_cpp/include/lib/sys/service/cpp/service_handler.h
new file mode 100644
index 0000000..5babb86
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_service_cpp/include/lib/sys/service/cpp/service_handler.h
@@ -0,0 +1,34 @@
+// 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.
+
+#ifndef LIB_SYS_SERVICE_CPP_SERVICE_HANDLER_H_
+#define LIB_SYS_SERVICE_CPP_SERVICE_HANDLER_H_
+
+#include <lib/fidl/cpp/interface_request.h>
+#include <lib/fidl/cpp/service_handler_base.h>
+#include <lib/vfs/cpp/pseudo_dir.h>
+#include <lib/vfs/cpp/service.h>
+
+namespace sys {
+
+// A handler for an instance of a service.
+class ServiceHandler : public fidl::ServiceHandlerBase {
+ public:
+ // Add a |member| to the instance, which will is handled by |handler|.
+ zx_status_t AddMember(std::string member, MemberHandler handler) const override {
+ return dir_->AddEntry(std::move(member), std::make_unique<vfs::Service>(std::move(handler)));
+ }
+
+ // Take the underlying pseudo-directory from the service handler.
+ //
+ // Once taken, the service handler is no longer safe to use.
+ std::unique_ptr<vfs::PseudoDir> TakeDirectory() { return std::move(dir_); }
+
+ private:
+ std::unique_ptr<vfs::PseudoDir> dir_ = std::make_unique<vfs::PseudoDir>();
+};
+
+} // namespace sys
+
+#endif // LIB_SYS_SERVICE_CPP_SERVICE_HANDLER_H_
diff --git a/third_party/fuchsia-sdk/pkg/sys_service_cpp/include/lib/sys/service/cpp/service_watcher.h b/third_party/fuchsia-sdk/pkg/sys_service_cpp/include/lib/sys/service/cpp/service_watcher.h
new file mode 100644
index 0000000..02a419d
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_service_cpp/include/lib/sys/service/cpp/service_watcher.h
@@ -0,0 +1,53 @@
+// 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.
+
+#ifndef LIB_SYS_SERVICE_CPP_SERVICE_WATCHER_H_
+#define LIB_SYS_SERVICE_CPP_SERVICE_WATCHER_H_
+
+#include <lib/async/cpp/wait.h>
+#include <lib/zx/channel.h>
+
+#include <vector>
+
+namespace sys {
+
+class ServiceAggregateBase;
+
+// A watcher for service instances.
+//
+// Watching is automatically stopped on destruction.
+class ServiceWatcher final {
+ public:
+ // A callback to be invoked when service instances are added or removed.
+ //
+ // |event| will be either fuchsia::io::WATCH_MASK_EXISTING, if an instance was
+ // existing at the beginning, fuchsia::io::WATCH_EVENT_ADDED, if an instance
+ // was added, or fuchsia::io::WATCH_EVENT_REMOVED, if an instance was removed.
+ // |instance| will be the name of the instance associated with the event.
+ using Callback = fit::function<void(uint8_t event, std::string instance)>;
+
+ // Constructs a watcher for service instances.
+ //
+ // Each time a service instance is added or removed, |callback| is invoked.
+ explicit ServiceWatcher(Callback callback) : callback_(std::move(callback)) {}
+
+ // Begins watching for service instances in a service directory.
+ zx_status_t Begin(const ServiceAggregateBase& service_aggregate, async_dispatcher_t* dispatcher);
+
+ // Cancels watching for service instances.
+ zx_status_t Cancel();
+
+ private:
+ void OnWatchedEvent(async_dispatcher_t* dispatcher, async::WaitBase* wait, zx_status_t status,
+ const zx_packet_signal_t* signal);
+
+ Callback callback_;
+ std::vector<uint8_t> buf_;
+ zx::channel client_end_;
+ async::WaitMethod<ServiceWatcher, &ServiceWatcher::OnWatchedEvent> wait_{this};
+};
+
+} // namespace sys
+
+#endif // LIB_SYS_SERVICE_CPP_SERVICE_WATCHER_H_
diff --git a/third_party/fuchsia-sdk/pkg/sys_service_cpp/meta.json b/third_party/fuchsia-sdk/pkg/sys_service_cpp/meta.json
new file mode 100644
index 0000000..467889c
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_service_cpp/meta.json
@@ -0,0 +1,28 @@
+{
+ "banjo_deps": [],
+ "deps": [
+ "fidl_cpp",
+ "vfs_cpp",
+ "async-cpp",
+ "fdio",
+ "zx"
+ ],
+ "fidl_deps": [
+ "fuchsia.io"
+ ],
+ "headers": [
+ "pkg/sys_service_cpp/include/lib/sys/service/cpp/service.h",
+ "pkg/sys_service_cpp/include/lib/sys/service/cpp/service_aggregate.h",
+ "pkg/sys_service_cpp/include/lib/sys/service/cpp/service_handler.h",
+ "pkg/sys_service_cpp/include/lib/sys/service/cpp/service_watcher.h"
+ ],
+ "include_dir": "pkg/sys_service_cpp/include",
+ "name": "sys_service_cpp",
+ "root": "pkg/sys_service_cpp",
+ "sources": [
+ "pkg/sys_service_cpp/service.cc",
+ "pkg/sys_service_cpp/service_aggregate.cc",
+ "pkg/sys_service_cpp/service_watcher.cc"
+ ],
+ "type": "cc_source_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/sys_service_cpp/service.cc b/third_party/fuchsia-sdk/pkg/sys_service_cpp/service.cc
new file mode 100644
index 0000000..24c3cf8
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_service_cpp/service.cc
@@ -0,0 +1,76 @@
+// 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.
+
+#include <lib/fdio/directory.h>
+#include <lib/fdio/namespace.h>
+#include <lib/sys/service/cpp/service.h>
+
+namespace sys {
+
+namespace {
+
+// An implementation of a ServiceConnector based on fuchsia.io.Directory.
+class DirectoryServiceConnector final : public fidl::ServiceConnector {
+ public:
+ explicit DirectoryServiceConnector(fidl::InterfaceHandle<fuchsia::io::Directory> dir)
+ : dir_(std::move(dir)) {}
+
+ zx_status_t Connect(const std::string& path, zx::channel channel) const override {
+ return fdio_service_connect_at(dir_.channel().get(), path.data(), channel.release());
+ }
+
+ private:
+ fidl::InterfaceHandle<fuchsia::io::Directory> dir_;
+};
+
+} // namespace
+
+const char kDefaultInstance[] = "default";
+
+std::unique_ptr<fidl::ServiceConnector> OpenNamedServiceAt(
+ const fidl::InterfaceHandle<fuchsia::io::Directory>& handle, const std::string& service_path,
+ const std::string& instance) {
+ if (service_path.compare(0, 1, "/") == 0) {
+ return nullptr;
+ }
+ std::string path = service_path + '/' + instance;
+
+ fidl::InterfaceHandle<fuchsia::io::Directory> dir;
+ zx_status_t status = fdio_service_connect_at(handle.channel().get(), path.data(),
+ dir.NewRequest().TakeChannel().release());
+ if (status != ZX_OK) {
+ return nullptr;
+ }
+ return std::make_unique<DirectoryServiceConnector>(std::move(dir));
+}
+
+std::unique_ptr<fidl::ServiceConnector> OpenNamedServiceIn(fdio_ns_t* ns,
+ const std::string& service_path,
+ const std::string& instance) {
+ std::string path;
+ if (service_path.compare(0, 1, "/") != 0) {
+ path = "/svc/";
+ }
+ path += service_path + '/' + instance;
+
+ fidl::InterfaceHandle<fuchsia::io::Directory> dir;
+ zx_status_t status = fdio_ns_connect(ns, path.data(), fuchsia::io::OPEN_RIGHT_READABLE,
+ dir.NewRequest().TakeChannel().release());
+ if (status != ZX_OK) {
+ return nullptr;
+ }
+ return std::make_unique<DirectoryServiceConnector>(std::move(dir));
+}
+
+std::unique_ptr<fidl::ServiceConnector> OpenNamedService(const std::string& service_path,
+ const std::string& instance) {
+ fdio_ns_t* ns;
+ zx_status_t status = fdio_ns_get_installed(&ns);
+ if (status != ZX_OK) {
+ return nullptr;
+ }
+ return OpenNamedServiceIn(ns, service_path, instance);
+}
+
+} // namespace sys
diff --git a/third_party/fuchsia-sdk/pkg/sys_service_cpp/service_aggregate.cc b/third_party/fuchsia-sdk/pkg/sys_service_cpp/service_aggregate.cc
new file mode 100644
index 0000000..475c20d
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_service_cpp/service_aggregate.cc
@@ -0,0 +1,82 @@
+// 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.
+
+#include <dirent.h>
+#include <fuchsia/io/cpp/fidl.h>
+#include <lib/fdio/directory.h>
+#include <lib/fit/defer.h>
+#include <lib/sys/service/cpp/service_aggregate.h>
+
+#include <vector>
+
+namespace sys {
+
+std::vector<std::string> ServiceAggregateBase::ListInstances() const {
+ std::vector<std::string> instances;
+
+ int fd;
+ zx_status_t status = fdio_fd_create(fdio_service_clone(dir_.channel().get()), &fd);
+ if (status != ZX_OK) {
+ return instances;
+ }
+ auto defer_close = fit::defer([fd] { close(fd); });
+
+ DIR* dir = fdopendir(fd);
+ if (dir == nullptr) {
+ return instances;
+ }
+ auto defer_closedir = fit::defer([dir] { closedir(dir); });
+
+ for (dirent* entry; (entry = readdir(dir)) != nullptr;) {
+ if (strcmp(entry->d_name, ".") != 0) {
+ instances.emplace_back(entry->d_name);
+ }
+ }
+
+ return instances;
+}
+
+fidl::InterfaceHandle<fuchsia::io::Directory> OpenNamedServiceAggregateAt(
+ const fidl::InterfaceHandle<fuchsia::io::Directory>& handle, const std::string& service_path) {
+ if (service_path.compare(0, 1, "/") == 0) {
+ return nullptr;
+ }
+
+ fidl::InterfaceHandle<fuchsia::io::Directory> dir;
+ zx_status_t status = fdio_service_connect_at(handle.channel().get(), service_path.data(),
+ dir.NewRequest().TakeChannel().release());
+ if (status != ZX_OK) {
+ return nullptr;
+ }
+ return dir;
+}
+
+fidl::InterfaceHandle<fuchsia::io::Directory> OpenNamedServiceAggregateIn(
+ fdio_ns_t* ns, const std::string& service_path) {
+ std::string path;
+ if (service_path.compare(0, 1, "/") != 0) {
+ path = "/svc/";
+ }
+ path += service_path;
+
+ fidl::InterfaceHandle<fuchsia::io::Directory> dir;
+ zx_status_t status = fdio_ns_connect(ns, path.data(), fuchsia::io::OPEN_RIGHT_READABLE,
+ dir.NewRequest().TakeChannel().release());
+ if (status != ZX_OK) {
+ return nullptr;
+ }
+ return dir;
+}
+
+fidl::InterfaceHandle<fuchsia::io::Directory> OpenNamedServiceAggregate(
+ const std::string& service_path) {
+ fdio_ns_t* ns;
+ zx_status_t status = fdio_ns_get_installed(&ns);
+ if (status != ZX_OK) {
+ return nullptr;
+ }
+ return OpenNamedServiceAggregateIn(ns, service_path);
+}
+
+} // namespace sys
diff --git a/third_party/fuchsia-sdk/pkg/sys_service_cpp/service_watcher.cc b/third_party/fuchsia-sdk/pkg/sys_service_cpp/service_watcher.cc
new file mode 100644
index 0000000..c2cfbdc
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sys_service_cpp/service_watcher.cc
@@ -0,0 +1,69 @@
+// 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.
+
+#include <fuchsia/io/cpp/fidl.h>
+#include <lib/fdio/directory.h>
+#include <lib/sys/service/cpp/service_aggregate.h>
+#include <lib/sys/service/cpp/service_watcher.h>
+
+namespace sys {
+
+zx_status_t ServiceWatcher::Begin(const ServiceAggregateBase& service_aggregate,
+ async_dispatcher_t* dispatcher) {
+ zx::channel client_end, server_end;
+ zx_status_t status = zx::channel::create(0, &client_end, &server_end);
+ if (status != ZX_OK) {
+ return status;
+ }
+
+ fidl::SynchronousInterfacePtr<fuchsia::io::Directory> dir;
+ dir.Bind(zx::channel(fdio_service_clone(service_aggregate.channel().get())));
+ zx_status_t fidl_status;
+ status = dir->Watch(fuchsia::io::WATCH_MASK_EXISTING | fuchsia::io::WATCH_MASK_ADDED |
+ fuchsia::io::WATCH_MASK_REMOVED,
+ 0, std::move(server_end), &fidl_status);
+ if (status != ZX_OK) {
+ return status;
+ } else if (fidl_status != ZX_OK) {
+ return fidl_status;
+ }
+
+ buf_.resize(fuchsia::io::MAX_BUF);
+ client_end_ = std::move(client_end);
+ wait_.set_object(client_end_.get());
+ wait_.set_trigger(ZX_CHANNEL_READABLE);
+ return wait_.Begin(dispatcher);
+}
+
+zx_status_t ServiceWatcher::Cancel() { return wait_.Cancel(); }
+
+void ServiceWatcher::OnWatchedEvent(async_dispatcher_t* dispatcher, async::WaitBase* wait,
+ zx_status_t status, const zx_packet_signal_t* signal) {
+ if (status != ZX_OK || !(signal->observed & ZX_CHANNEL_READABLE)) {
+ return;
+ }
+ uint32_t size = buf_.size();
+ status = client_end_.read(0, buf_.data(), nullptr, size, 0, &size, nullptr);
+ if (status != ZX_OK) {
+ return;
+ }
+
+ for (auto i = buf_.begin(), end = buf_.begin() + size; std::distance(i, end) > 2;) {
+ // Process message structure, as described by fuchsia::io::WatchedEvent.
+ uint8_t event = *i++;
+ uint8_t len = *i++;
+ // Restrict the length to the remaining size of the buffer.
+ len = std::min<uint8_t>(len, std::max(0l, std::distance(i, end)));
+ // If the entry is valid, invoke the callback.
+ if (len != 1 || *i != '.') {
+ std::string instance(reinterpret_cast<char*>(i.base()), len);
+ callback_(event, std::move(instance));
+ }
+ i += len;
+ }
+
+ wait_.Begin(dispatcher);
+}
+
+} // namespace sys
diff --git a/third_party/fuchsia-sdk/pkg/syslog/BUILD.gn b/third_party/fuchsia-sdk/pkg/syslog/BUILD.gn
new file mode 100644
index 0000000..4b83a7f
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/syslog/BUILD.gn
@@ -0,0 +1,28 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("syslog") {
+ shared_libs = [ "syslog" ]
+
+ deps = [
+ ]
+ sources = [
+ "include/lib/syslog/global.h",
+ "include/lib/syslog/logger.h",
+ "include/lib/syslog/wire_format.h",
+ ]
+ include_dirs = [ "include" ]
+}
+
+group("all"){
+ deps = [
+ ":syslog",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/syslog/include/lib/syslog/global.h b/third_party/fuchsia-sdk/pkg/syslog/include/lib/syslog/global.h
new file mode 100644
index 0000000..2f3513e
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/syslog/include/lib/syslog/global.h
@@ -0,0 +1,133 @@
+// Copyright 2018 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.
+
+//
+// Entry points used by clients.
+
+#ifndef LIB_SYSLOG_GLOBAL_H_
+#define LIB_SYSLOG_GLOBAL_H_
+
+#include <lib/syslog/logger.h>
+
+__BEGIN_CDECLS
+
+// Gets the global logger for the process to which log messages emitted
+// using the FX_LOG macros will be written. This function returns the same
+// logger on all threads and is thread-safe. The returned pointer is never
+// null and it does not get invalidated when the logger is reconfigured.
+fx_logger_t* fx_log_get_logger(void);
+
+// Returns true if writing messages with the given severity is enabled in the
+// global logger.
+static inline bool fx_log_is_enabled(fx_log_severity_t severity) {
+ fx_logger_t* logger = fx_log_get_logger();
+ return severity >= fx_logger_get_min_severity(logger);
+}
+
+// Reconfigures the global logger for this process with the specified
+// configuration.
+// If |console_fd| and |log_service_channel| are invalid in |config|,
+// this function doesn't change the currently used file descriptor or channel.
+// |config| can be safely deallocated after this function returns.
+// This function is NOT thread-safe and must be called early in the program
+// before other threads are spawned.
+// Returns:
+// - ZX_ERR_INVALID_ARGS if config is invalid (i.e. is null or has more than
+// FX_LOG_MAX_TAGS tags),
+// - ZX_OK if the reconfiguration succeeds.
+zx_status_t fx_log_reconfigure(const fx_logger_config_t* config);
+
+// DEPRECATED. Do not use.
+zx_status_t fx_log_init_with_config(const fx_logger_config_t* config);
+
+// Returns true if writing messages with the given severity is enabled in the
+// global logger. |severity| is one of DEBUG, INFO, WARNING, ERROR, or FATAL.
+#define FX_LOG_IS_ENABLED(severity) (fx_log_is_enabled(FX_LOG_##severity))
+
+// Returns true if writing messages with the given verbosity is enabled in the
+// global logger. |verbosity| is positive number.
+#define FX_VLOG_IS_ENABLED(verbosity) (fx_log_is_enabled(-(verbosity)))
+
+#define _FX_LOG_SET_SEVERITY(severity) \
+ do { \
+ fx_logger_t* logger = fx_log_get_logger(); \
+ if (logger) { \
+ fx_logger_set_min_severity(logger, (severity)); \
+ } \
+ } while (0)
+
+// Sets severity for global logger.
+// |severity| is one of DEBUG, INFO, WARNING, ERROR, or FATAL.
+#define FX_LOG_SET_SEVERITY(severity) _FX_LOG_SET_SEVERITY(FX_LOG_##severity)
+
+// Sets verbosity for global logger.
+// |verbosity| is positive number. Logger severity is set to -verbosity
+#define FX_LOG_SET_VERBOSITY(verbosity) _FX_LOG_SET_SEVERITY(-(verbosity))
+
+#define _FX_LOG(severity, tag, message) \
+ do { \
+ fx_logger_t* logger = fx_log_get_logger(); \
+ if (fx_logger_get_min_severity(logger) <= (severity)) { \
+ fx_logger_log(logger, (severity), (tag), (message)); \
+ } \
+ } while (0)
+
+#define _FX_LOGF(severity, tag, message, ...) \
+ do { \
+ fx_logger_t* logger = fx_log_get_logger(); \
+ if (fx_logger_get_min_severity(logger) <= (severity)) { \
+ fx_logger_logf(logger, (severity), (tag), (message), __VA_ARGS__); \
+ } \
+ } while (0)
+
+#define _FX_LOGVF(severity, tag, message, args) \
+ do { \
+ fx_logger_t* logger = fx_log_get_logger(); \
+ if (fx_logger_get_min_severity(logger) <= (severity)) { \
+ fx_logger_logvf(logger, (severity), (tag), (message), (args)); \
+ } \
+ } while (0)
+
+// Writes a message to the global logger.
+// |severity| is one of DEBUG, INFO, WARNING, ERROR, FATAL
+// |tag| is a tag to associated with the message, or NULL if none.
+// |message| is the message to write, or NULL if none.
+#define FX_LOG(severity, tag, message) _FX_LOG((FX_LOG_##severity), tag, message)
+
+// Writes formatted message to the global logger.
+// |severity| is one of DEBUG, INFO, WARNING, ERROR, FATAL
+// |tag| is a tag to associated with the message, or NULL if none.
+// |message| is the message to write, or NULL if none.
+#define FX_LOGF(severity, tag, message, ...) \
+ _FX_LOGF((FX_LOG_##severity), tag, message, __VA_ARGS__)
+
+// Writes formatted message to the global logger using vaargs
+// |severity| is one of DEBUG, INFO, WARNING, ERROR, FATAL
+// |tag| is a tag to associated with the message, or NULL if none.
+// |message| is the message to write, or NULL if none.
+// |args| are the arguments to |message|.
+#define FX_LOGVF(severity, tag, message, args) _FX_LOGVF((FX_LOG_##severity), tag, message, args)
+
+// Writes verbose message to the global logger.
+// |verbosity| is positive integer.
+// |tag| is a tag to associated with the message, or NULL if none.
+// |message| is the message to write, or NULL if none.
+#define FX_VLOG(verbosity, tag, message) _FX_LOG(-(verbosity), tag, message)
+
+// Writes formatted verbose message to the global logger.
+// |verbosity| is positive integer.
+// |tag| is a tag to associated with the message, or NULL if none.
+// |message| is the message to write, or NULL if none.
+#define FX_VLOGF(verbosity, tag, message, ...) _FX_LOGF(-(verbosity), tag, message, __VA_ARGS__)
+
+// Writes formatted verbose message to the global logger using vaargs
+// |verbosity| is positive integer.
+// |tag| is a tag to associated with the message, or NULL if none.
+// |message| is the message to write, or NULL if none.
+// |args| are the arguments to |message|.
+#define FX_VLOGVF(verbosity, tag, message, args) _FX_LOGVF(-(verbosity), tag, message, args)
+
+__END_CDECLS
+
+#endif // LIB_SYSLOG_GLOBAL_H_
diff --git a/third_party/fuchsia-sdk/pkg/syslog/include/lib/syslog/logger.h b/third_party/fuchsia-sdk/pkg/syslog/include/lib/syslog/logger.h
new file mode 100644
index 0000000..383767e
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/syslog/include/lib/syslog/logger.h
@@ -0,0 +1,122 @@
+// Copyright 2018 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.
+
+//
+// This header contains definition for the logger object and protocol.
+
+#ifndef LIB_SYSLOG_LOGGER_H_
+#define LIB_SYSLOG_LOGGER_H_
+
+#include <stdarg.h>
+#include <unistd.h>
+#include <zircon/types.h>
+
+// Max no of tags associated with a logger.
+#define FX_LOG_MAX_TAGS (4)
+
+// Max individual tag length including terminating character.
+#define FX_LOG_MAX_TAG_LEN (64)
+
+// Log entry severity.
+// Used for coarse filtering of log messages
+typedef int fx_log_severity_t;
+#define FX_LOG_INFO (0)
+#define FX_LOG_WARNING (1)
+#define FX_LOG_ERROR (2)
+#define FX_LOG_FATAL (3)
+
+__BEGIN_CDECLS
+
+// Configuration for a logger object.
+// Specifies the destination to which log messages should be written.
+// Multiple destinations may be used concurrently.
+typedef struct fx_logger_config {
+ // The minimum log severity.
+ // Log messages with lower severity will be discarded.
+ fx_log_severity_t min_severity;
+
+ // The file descriptor to which formatted log messages should be written,
+ // or -1 if log messages should not be written to the console.
+ // logger takes ownership of this fd.
+ int console_fd;
+
+ // One end of the socket that goes to the log service. |ZX_HANDLE_INVALID| if
+ // logs should not go to the log service.
+ // logger takes ownership of this handle.
+ zx_handle_t log_service_channel;
+
+ // An array of tag strings to associate with all messages written
+ // by this logger. Tags will be truncated if they are (individually) longer
+ // than |FX_LOG_MAX_TAG_LEN|.
+ const char** tags;
+
+ // Number of tag strings. Must be no more than |FX_LOG_MAX_TAGS|.
+ size_t num_tags;
+} fx_logger_config_t;
+
+// Opaque type representing a logger object.
+typedef struct fx_logger fx_logger_t;
+
+// Creates a logger object from the specified configuration.
+//
+// This will return ZX_ERR_INVALID_ARGS if |num_tags| is more than
+// |FX_LOG_MAX_TAGS|.
+// |config| can be safely deleted after this function returns.
+zx_status_t fx_logger_create(const fx_logger_config_t* config, fx_logger_t** out_logger);
+
+// Destroys a logger object.
+//
+// This closes |console_fd| or |log_service_channel| which were passed in
+// |fx_logger_config_t|.
+void fx_logger_destroy(fx_logger_t* logger);
+
+// Gets the logger's minimum log severity.
+fx_log_severity_t fx_logger_get_min_severity(fx_logger_t* logger);
+
+// Sets logger severity
+void fx_logger_set_min_severity(fx_logger_t* logger, fx_log_severity_t severity);
+
+// Activates fallback mode and logger starts writing to |fallback_fd|.
+// There is no way to revert this action.
+//
+// This function does not take ownership of |fallback_fd| and it should not be
+// closed till this logger object is no longer in use. Logger will log to
+// stderr if -1 is provided.
+//
+// This function is thread unsafe.
+void fx_logger_activate_fallback(fx_logger_t* logger, int fallback_fd);
+
+// Writes formatted message to a logger.
+// The message will be discarded if |severity| is less than the logger's
+// minimum log severity.
+// The |tag| may be NULL, in which case no additional tags are added to the
+// log message.
+// The |tag| will be truncated if it is longer than |FX_LOG_MAX_TAG_LEN|.
+// No message is written if |message| is NULL.
+zx_status_t fx_logger_logf(fx_logger_t* logger, fx_log_severity_t severity, const char* tag,
+ const char* msg, ...);
+
+// Writes formatted message to a logger using varargs.
+// The message will be discarded if |severity| is less than the logger's
+// minimum log severity.
+// The |tag| may be NULL, in which case no additional tags are added to the
+// log message.
+// The |tag| will be truncated if it is longer than |FX_LOG_MAX_TAG_LEN|.
+// No message is written if |message| is NULL.
+zx_status_t fx_logger_logvf(fx_logger_t* logger, fx_log_severity_t severity, const char* tag,
+ const char* msg, va_list args);
+
+// Writes a message to a logger.
+// The message will be discarded if |severity| is less than the logger's
+// minimum log severity.
+// The |tag| may be NULL, in which case no additional tags are added to the
+// log message.
+// The |tag| will be truncated if it is longer than |FX_LOG_MAX_TAG_LEN|.
+// No message is written if |message| is NULL.
+zx_status_t fx_logger_log(fx_logger_t* logger, fx_log_severity_t severity, const char* tag,
+ const char* msg);
+
+__END_CDECLS
+
+#endif // LIB_SYSLOG_LOGGER_H_
diff --git a/third_party/fuchsia-sdk/pkg/syslog/include/lib/syslog/wire_format.h b/third_party/fuchsia-sdk/pkg/syslog/include/lib/syslog/wire_format.h
new file mode 100644
index 0000000..0130fa9
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/syslog/include/lib/syslog/wire_format.h
@@ -0,0 +1,38 @@
+// Copyright 2018 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.
+//
+// This header file defines wire format to transfer logs to listening service.
+
+#ifndef LIB_SYSLOG_WIRE_FORMAT_H_
+#define LIB_SYSLOG_WIRE_FORMAT_H_
+
+#include <lib/syslog/logger.h>
+#include <zircon/types.h>
+
+// Defines max length for storing log_metadata, tags and msgbuffer.
+// TODO(anmittal): Increase it when zircon sockets are able to support a higher
+// buffer.
+#define FX_LOG_MAX_DATAGRAM_LEN (2032)
+
+typedef struct fx_log_metadata {
+ zx_koid_t pid;
+ zx_koid_t tid;
+ zx_time_t time;
+ fx_log_severity_t severity;
+
+ // Increment this field whenever there is a socket write error and client
+ // drops the log and send it with next log msg.
+ uint32_t dropped_logs;
+} fx_log_metadata_t;
+
+// Packet to transfer over socket.
+typedef struct fx_log_packet {
+ fx_log_metadata_t metadata;
+
+ // Contains concatenated tags and message and a null terminating character at
+ // the end.
+ char data[FX_LOG_MAX_DATAGRAM_LEN - sizeof(fx_log_metadata_t)];
+} fx_log_packet_t;
+
+#endif // LIB_SYSLOG_WIRE_FORMAT_H_
diff --git a/third_party/fuchsia-sdk/pkg/syslog/meta.json b/third_party/fuchsia-sdk/pkg/syslog/meta.json
new file mode 100644
index 0000000..db2697d
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/syslog/meta.json
@@ -0,0 +1,27 @@
+{
+ "binaries": {
+ "arm64": {
+ "debug": ".build-id/ea/46fea0942ef671.debug",
+ "dist": "arch/arm64/dist/libsyslog.so",
+ "dist_path": "lib/libsyslog.so",
+ "link": "arch/arm64/lib/libsyslog.so"
+ },
+ "x64": {
+ "debug": ".build-id/0e/754a242d3990b5.debug",
+ "dist": "arch/x64/dist/libsyslog.so",
+ "dist_path": "lib/libsyslog.so",
+ "link": "arch/x64/lib/libsyslog.so"
+ }
+ },
+ "deps": [],
+ "format": "shared",
+ "headers": [
+ "pkg/syslog/include/lib/syslog/global.h",
+ "pkg/syslog/include/lib/syslog/logger.h",
+ "pkg/syslog/include/lib/syslog/wire_format.h"
+ ],
+ "include_dir": "pkg/syslog/include",
+ "name": "syslog",
+ "root": "pkg/syslog",
+ "type": "cc_prebuilt_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/sysroot/meta.json b/third_party/fuchsia-sdk/pkg/sysroot/meta.json
new file mode 100644
index 0000000..7ad71ff
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/sysroot/meta.json
@@ -0,0 +1,618 @@
+{
+ "name": "sysroot",
+ "type": "sysroot",
+ "versions": {
+ "arm64": {
+ "debug_libs": [
+ ".build-id/fa/39648a29eb2f06.debug",
+ ".build-id/ab/9f1945a249d81a.debug"
+ ],
+ "dist_dir": "arch/arm64/sysroot",
+ "dist_libs": [
+ "arch/arm64/sysroot/dist/lib/ld.so.1"
+ ],
+ "headers": [
+ "arch/arm64/sysroot/include/zircon/assert.h",
+ "arch/arm64/sysroot/include/zircon/boot/driver-config.h",
+ "arch/arm64/sysroot/include/zircon/boot/e820.h",
+ "arch/arm64/sysroot/include/zircon/boot/image.h",
+ "arch/arm64/sysroot/include/zircon/boot/multiboot.h",
+ "arch/arm64/sysroot/include/zircon/boot/netboot.h",
+ "arch/arm64/sysroot/include/zircon/boot/sysconfig.h",
+ "arch/arm64/sysroot/include/zircon/compiler.h",
+ "arch/arm64/sysroot/include/zircon/driver/binding.h",
+ "arch/arm64/sysroot/include/zircon/errors.h",
+ "arch/arm64/sysroot/include/zircon/features.h",
+ "arch/arm64/sysroot/include/zircon/fidl.h",
+ "arch/arm64/sysroot/include/zircon/hw/gpt.h",
+ "arch/arm64/sysroot/include/zircon/hw/i2c.h",
+ "arch/arm64/sysroot/include/zircon/hw/pci.h",
+ "arch/arm64/sysroot/include/zircon/hw/usb.h",
+ "arch/arm64/sysroot/include/zircon/hw/usb/audio.h",
+ "arch/arm64/sysroot/include/zircon/hw/usb/cdc.h",
+ "arch/arm64/sysroot/include/zircon/hw/usb/dfu.h",
+ "arch/arm64/sysroot/include/zircon/hw/usb/hid.h",
+ "arch/arm64/sysroot/include/zircon/hw/usb/hub.h",
+ "arch/arm64/sysroot/include/zircon/hw/usb/ums.h",
+ "arch/arm64/sysroot/include/zircon/hw/usb/video.h",
+ "arch/arm64/sysroot/include/zircon/limits.h",
+ "arch/arm64/sysroot/include/zircon/listnode.h",
+ "arch/arm64/sysroot/include/zircon/pixelformat.h",
+ "arch/arm64/sysroot/include/zircon/process.h",
+ "arch/arm64/sysroot/include/zircon/processargs.h",
+ "arch/arm64/sysroot/include/zircon/rights.h",
+ "arch/arm64/sysroot/include/zircon/string_view.h",
+ "arch/arm64/sysroot/include/zircon/syscalls.h",
+ "arch/arm64/sysroot/include/zircon/syscalls/clock.h",
+ "arch/arm64/sysroot/include/zircon/syscalls/debug.h",
+ "arch/arm64/sysroot/include/zircon/syscalls/exception.h",
+ "arch/arm64/sysroot/include/zircon/syscalls/hypervisor.h",
+ "arch/arm64/sysroot/include/zircon/syscalls/iommu.h",
+ "arch/arm64/sysroot/include/zircon/syscalls/log.h",
+ "arch/arm64/sysroot/include/zircon/syscalls/object.h",
+ "arch/arm64/sysroot/include/zircon/syscalls/pci.h",
+ "arch/arm64/sysroot/include/zircon/syscalls/policy.h",
+ "arch/arm64/sysroot/include/zircon/syscalls/port.h",
+ "arch/arm64/sysroot/include/zircon/syscalls/profile.h",
+ "arch/arm64/sysroot/include/zircon/syscalls/resource.h",
+ "arch/arm64/sysroot/include/zircon/syscalls/scheduler.h",
+ "arch/arm64/sysroot/include/zircon/syscalls/smc.h",
+ "arch/arm64/sysroot/include/zircon/syscalls/system.h",
+ "arch/arm64/sysroot/include/zircon/syscalls/types.h",
+ "arch/arm64/sysroot/include/zircon/time.h",
+ "arch/arm64/sysroot/include/zircon/tls.h",
+ "arch/arm64/sysroot/include/zircon/types.h",
+ "arch/arm64/sysroot/include/zircon/device/audio.h",
+ "arch/arm64/sysroot/include/../../vdso/alias_workarounds.fidl",
+ "arch/arm64/sysroot/include/../../vdso/bti.fidl",
+ "arch/arm64/sysroot/include/../../vdso/cache.fidl",
+ "arch/arm64/sysroot/include/../../vdso/channel.fidl",
+ "arch/arm64/sysroot/include/../../vdso/clock.fidl",
+ "arch/arm64/sysroot/include/../../vdso/cprng.fidl",
+ "arch/arm64/sysroot/include/../../vdso/debug.fidl",
+ "arch/arm64/sysroot/include/../../vdso/debuglog.fidl",
+ "arch/arm64/sysroot/include/../../vdso/event.fidl",
+ "arch/arm64/sysroot/include/../../vdso/eventpair.fidl",
+ "arch/arm64/sysroot/include/../../vdso/exception.fidl",
+ "arch/arm64/sysroot/include/../../vdso/fifo.fidl",
+ "arch/arm64/sysroot/include/../../vdso/framebuffer.fidl",
+ "arch/arm64/sysroot/include/../../vdso/futex.fidl",
+ "arch/arm64/sysroot/include/../../vdso/guest.fidl",
+ "arch/arm64/sysroot/include/../../vdso/handle.fidl",
+ "arch/arm64/sysroot/include/../../vdso/interrupt.fidl",
+ "arch/arm64/sysroot/include/../../vdso/iommu.fidl",
+ "arch/arm64/sysroot/include/../../vdso/ioports.fidl",
+ "arch/arm64/sysroot/include/../../vdso/job.fidl",
+ "arch/arm64/sysroot/include/../../vdso/ktrace.fidl",
+ "arch/arm64/sysroot/include/../../vdso/misc.fidl",
+ "arch/arm64/sysroot/include/../../vdso/mtrace.fidl",
+ "arch/arm64/sysroot/include/../../vdso/object.fidl",
+ "arch/arm64/sysroot/include/../../vdso/pager.fidl",
+ "arch/arm64/sysroot/include/../../vdso/pc.fidl",
+ "arch/arm64/sysroot/include/../../vdso/pci.fidl",
+ "arch/arm64/sysroot/include/../../vdso/pmt.fidl",
+ "arch/arm64/sysroot/include/../../vdso/port.fidl",
+ "arch/arm64/sysroot/include/../../vdso/process.fidl",
+ "arch/arm64/sysroot/include/../../vdso/profile.fidl",
+ "arch/arm64/sysroot/include/../../vdso/resource.fidl",
+ "arch/arm64/sysroot/include/../../vdso/rights.fidl",
+ "arch/arm64/sysroot/include/../../vdso/smc.fidl",
+ "arch/arm64/sysroot/include/../../vdso/socket.fidl",
+ "arch/arm64/sysroot/include/../../vdso/stream.fidl",
+ "arch/arm64/sysroot/include/../../vdso/syscall.fidl",
+ "arch/arm64/sysroot/include/../../vdso/system.fidl",
+ "arch/arm64/sysroot/include/../../vdso/task.fidl",
+ "arch/arm64/sysroot/include/../../vdso/thread.fidl",
+ "arch/arm64/sysroot/include/../../vdso/timer.fidl",
+ "arch/arm64/sysroot/include/../../vdso/vcpu.fidl",
+ "arch/arm64/sysroot/include/../../vdso/vmar.fidl",
+ "arch/arm64/sysroot/include/../../vdso/vmo.fidl",
+ "arch/arm64/sysroot/include/../../vdso/zx.fidl",
+ "arch/arm64/sysroot/include/zircon/testonly-syscalls.h",
+ "arch/arm64/sysroot/include/alloca.h",
+ "arch/arm64/sysroot/include/ar.h",
+ "arch/arm64/sysroot/include/arpa/ftp.h",
+ "arch/arm64/sysroot/include/arpa/inet.h",
+ "arch/arm64/sysroot/include/arpa/nameser.h",
+ "arch/arm64/sysroot/include/arpa/nameser_compat.h",
+ "arch/arm64/sysroot/include/arpa/telnet.h",
+ "arch/arm64/sysroot/include/arpa/tftp.h",
+ "arch/arm64/sysroot/include/assert.h",
+ "arch/arm64/sysroot/include/bits/aarch64/endian.h",
+ "arch/arm64/sysroot/include/bits/aarch64/fenv.h",
+ "arch/arm64/sysroot/include/bits/aarch64/io.h",
+ "arch/arm64/sysroot/include/bits/aarch64/ioctl.h",
+ "arch/arm64/sysroot/include/bits/aarch64/ipc.h",
+ "arch/arm64/sysroot/include/bits/aarch64/reg.h",
+ "arch/arm64/sysroot/include/bits/aarch64/setjmp.h",
+ "arch/arm64/sysroot/include/bits/aarch64/signal.h",
+ "arch/arm64/sysroot/include/bits/aarch64/stat.h",
+ "arch/arm64/sysroot/include/bits/alltypes.h",
+ "arch/arm64/sysroot/include/bits/endian.h",
+ "arch/arm64/sysroot/include/bits/errno.h",
+ "arch/arm64/sysroot/include/bits/fcntl.h",
+ "arch/arm64/sysroot/include/bits/fenv.h",
+ "arch/arm64/sysroot/include/bits/io.h",
+ "arch/arm64/sysroot/include/bits/ioctl.h",
+ "arch/arm64/sysroot/include/bits/ipc.h",
+ "arch/arm64/sysroot/include/bits/limits.h",
+ "arch/arm64/sysroot/include/bits/msg.h",
+ "arch/arm64/sysroot/include/bits/null.h",
+ "arch/arm64/sysroot/include/bits/poll.h",
+ "arch/arm64/sysroot/include/bits/posix.h",
+ "arch/arm64/sysroot/include/bits/reg.h",
+ "arch/arm64/sysroot/include/bits/resource.h",
+ "arch/arm64/sysroot/include/bits/sem.h",
+ "arch/arm64/sysroot/include/bits/setjmp.h",
+ "arch/arm64/sysroot/include/bits/shm.h",
+ "arch/arm64/sysroot/include/bits/signal.h",
+ "arch/arm64/sysroot/include/bits/socket.h",
+ "arch/arm64/sysroot/include/bits/stat.h",
+ "arch/arm64/sysroot/include/bits/statfs.h",
+ "arch/arm64/sysroot/include/bits/termios.h",
+ "arch/arm64/sysroot/include/bits/x86_64/endian.h",
+ "arch/arm64/sysroot/include/bits/x86_64/fenv.h",
+ "arch/arm64/sysroot/include/bits/x86_64/io.h",
+ "arch/arm64/sysroot/include/bits/x86_64/ioctl.h",
+ "arch/arm64/sysroot/include/bits/x86_64/ipc.h",
+ "arch/arm64/sysroot/include/bits/x86_64/reg.h",
+ "arch/arm64/sysroot/include/bits/x86_64/setjmp.h",
+ "arch/arm64/sysroot/include/bits/x86_64/signal.h",
+ "arch/arm64/sysroot/include/bits/x86_64/stat.h",
+ "arch/arm64/sysroot/include/byteswap.h",
+ "arch/arm64/sysroot/include/complex.h",
+ "arch/arm64/sysroot/include/cpio.h",
+ "arch/arm64/sysroot/include/ctype.h",
+ "arch/arm64/sysroot/include/dirent.h",
+ "arch/arm64/sysroot/include/dlfcn.h",
+ "arch/arm64/sysroot/include/elf.h",
+ "arch/arm64/sysroot/include/endian.h",
+ "arch/arm64/sysroot/include/err.h",
+ "arch/arm64/sysroot/include/errno.h",
+ "arch/arm64/sysroot/include/fcntl.h",
+ "arch/arm64/sysroot/include/features.h",
+ "arch/arm64/sysroot/include/fenv.h",
+ "arch/arm64/sysroot/include/fmtmsg.h",
+ "arch/arm64/sysroot/include/fnmatch.h",
+ "arch/arm64/sysroot/include/getopt.h",
+ "arch/arm64/sysroot/include/glob.h",
+ "arch/arm64/sysroot/include/grp.h",
+ "arch/arm64/sysroot/include/iconv.h",
+ "arch/arm64/sysroot/include/ifaddrs.h",
+ "arch/arm64/sysroot/include/inttypes.h",
+ "arch/arm64/sysroot/include/iso646.h",
+ "arch/arm64/sysroot/include/langinfo.h",
+ "arch/arm64/sysroot/include/libgen.h",
+ "arch/arm64/sysroot/include/limits.h",
+ "arch/arm64/sysroot/include/link.h",
+ "arch/arm64/sysroot/include/locale.h",
+ "arch/arm64/sysroot/include/malloc.h",
+ "arch/arm64/sysroot/include/math.h",
+ "arch/arm64/sysroot/include/memory.h",
+ "arch/arm64/sysroot/include/monetary.h",
+ "arch/arm64/sysroot/include/net/ethernet.h",
+ "arch/arm64/sysroot/include/net/if.h",
+ "arch/arm64/sysroot/include/net/if_arp.h",
+ "arch/arm64/sysroot/include/net/route.h",
+ "arch/arm64/sysroot/include/netdb.h",
+ "arch/arm64/sysroot/include/netinet/ether.h",
+ "arch/arm64/sysroot/include/netinet/icmp6.h",
+ "arch/arm64/sysroot/include/netinet/if_ether.h",
+ "arch/arm64/sysroot/include/netinet/igmp.h",
+ "arch/arm64/sysroot/include/netinet/in.h",
+ "arch/arm64/sysroot/include/netinet/in_systm.h",
+ "arch/arm64/sysroot/include/netinet/ip.h",
+ "arch/arm64/sysroot/include/netinet/ip6.h",
+ "arch/arm64/sysroot/include/netinet/ip_icmp.h",
+ "arch/arm64/sysroot/include/netinet/tcp.h",
+ "arch/arm64/sysroot/include/netinet/udp.h",
+ "arch/arm64/sysroot/include/netpacket/packet.h",
+ "arch/arm64/sysroot/include/nl_types.h",
+ "arch/arm64/sysroot/include/paths.h",
+ "arch/arm64/sysroot/include/poll.h",
+ "arch/arm64/sysroot/include/pthread.h",
+ "arch/arm64/sysroot/include/pwd.h",
+ "arch/arm64/sysroot/include/regex.h",
+ "arch/arm64/sysroot/include/resolv.h",
+ "arch/arm64/sysroot/include/sched.h",
+ "arch/arm64/sysroot/include/search.h",
+ "arch/arm64/sysroot/include/semaphore.h",
+ "arch/arm64/sysroot/include/setjmp.h",
+ "arch/arm64/sysroot/include/signal.h",
+ "arch/arm64/sysroot/include/spawn.h",
+ "arch/arm64/sysroot/include/stdio.h",
+ "arch/arm64/sysroot/include/stdlib.h",
+ "arch/arm64/sysroot/include/string.h",
+ "arch/arm64/sysroot/include/strings.h",
+ "arch/arm64/sysroot/include/stropts.h",
+ "arch/arm64/sysroot/include/sys/acct.h",
+ "arch/arm64/sysroot/include/sys/auxv.h",
+ "arch/arm64/sysroot/include/sys/dir.h",
+ "arch/arm64/sysroot/include/sys/errno.h",
+ "arch/arm64/sysroot/include/sys/eventfd.h",
+ "arch/arm64/sysroot/include/sys/fcntl.h",
+ "arch/arm64/sysroot/include/sys/file.h",
+ "arch/arm64/sysroot/include/sys/fsuid.h",
+ "arch/arm64/sysroot/include/sys/io.h",
+ "arch/arm64/sysroot/include/sys/ioctl.h",
+ "arch/arm64/sysroot/include/sys/ipc.h",
+ "arch/arm64/sysroot/include/sys/klog.h",
+ "arch/arm64/sysroot/include/sys/mman.h",
+ "arch/arm64/sysroot/include/sys/mount.h",
+ "arch/arm64/sysroot/include/sys/msg.h",
+ "arch/arm64/sysroot/include/sys/mtio.h",
+ "arch/arm64/sysroot/include/sys/param.h",
+ "arch/arm64/sysroot/include/sys/personality.h",
+ "arch/arm64/sysroot/include/sys/poll.h",
+ "arch/arm64/sysroot/include/sys/quota.h",
+ "arch/arm64/sysroot/include/sys/random.h",
+ "arch/arm64/sysroot/include/sys/reboot.h",
+ "arch/arm64/sysroot/include/sys/reg.h",
+ "arch/arm64/sysroot/include/sys/select.h",
+ "arch/arm64/sysroot/include/sys/sem.h",
+ "arch/arm64/sysroot/include/sys/shm.h",
+ "arch/arm64/sysroot/include/sys/signal.h",
+ "arch/arm64/sysroot/include/sys/signalfd.h",
+ "arch/arm64/sysroot/include/sys/socket.h",
+ "arch/arm64/sysroot/include/sys/stat.h",
+ "arch/arm64/sysroot/include/sys/statfs.h",
+ "arch/arm64/sysroot/include/sys/statvfs.h",
+ "arch/arm64/sysroot/include/sys/stropts.h",
+ "arch/arm64/sysroot/include/sys/swap.h",
+ "arch/arm64/sysroot/include/sys/syslog.h",
+ "arch/arm64/sysroot/include/sys/termios.h",
+ "arch/arm64/sysroot/include/sys/time.h",
+ "arch/arm64/sysroot/include/sys/timeb.h",
+ "arch/arm64/sysroot/include/sys/timerfd.h",
+ "arch/arm64/sysroot/include/sys/times.h",
+ "arch/arm64/sysroot/include/sys/timex.h",
+ "arch/arm64/sysroot/include/sys/ttydefaults.h",
+ "arch/arm64/sysroot/include/sys/types.h",
+ "arch/arm64/sysroot/include/sys/ucontext.h",
+ "arch/arm64/sysroot/include/sys/uio.h",
+ "arch/arm64/sysroot/include/sys/un.h",
+ "arch/arm64/sysroot/include/sys/utsname.h",
+ "arch/arm64/sysroot/include/sys/vfs.h",
+ "arch/arm64/sysroot/include/sys/wait.h",
+ "arch/arm64/sysroot/include/sysexits.h",
+ "arch/arm64/sysroot/include/syslog.h",
+ "arch/arm64/sysroot/include/tar.h",
+ "arch/arm64/sysroot/include/termios.h",
+ "arch/arm64/sysroot/include/threads.h",
+ "arch/arm64/sysroot/include/time.h",
+ "arch/arm64/sysroot/include/uchar.h",
+ "arch/arm64/sysroot/include/ucontext.h",
+ "arch/arm64/sysroot/include/unistd.h",
+ "arch/arm64/sysroot/include/utime.h",
+ "arch/arm64/sysroot/include/values.h",
+ "arch/arm64/sysroot/include/wait.h",
+ "arch/arm64/sysroot/include/wchar.h",
+ "arch/arm64/sysroot/include/wctype.h",
+ "arch/arm64/sysroot/include/wordexp.h",
+ "arch/arm64/sysroot/include/zircon/dlfcn.h",
+ "arch/arm64/sysroot/include/zircon/sanitizer.h",
+ "arch/arm64/sysroot/include/zircon/threads.h",
+ "arch/arm64/sysroot/include/zircon/syscalls/internal/cdecls.inc",
+ "arch/arm64/sysroot/include/zircon/status.h",
+ "arch/arm64/sysroot/include/zircon/exception.h"
+ ],
+ "include_dir": "arch/arm64/sysroot/include",
+ "link_libs": [
+ "arch/arm64/sysroot/lib/libc.so",
+ "arch/arm64/sysroot/lib/libdl.so",
+ "arch/arm64/sysroot/lib/libm.so",
+ "arch/arm64/sysroot/lib/libpthread.so",
+ "arch/arm64/sysroot/lib/librt.so",
+ "arch/arm64/sysroot/lib/Scrt1.o",
+ "arch/arm64/sysroot/lib/libzircon.so"
+ ],
+ "root": "arch/arm64/sysroot"
+ },
+ "x64": {
+ "debug_libs": [
+ ".build-id/99/7608d3dc8531e7.debug",
+ ".build-id/b9/5927328f66db02.debug"
+ ],
+ "dist_dir": "arch/x64/sysroot",
+ "dist_libs": [
+ "arch/x64/sysroot/dist/lib/ld.so.1"
+ ],
+ "headers": [
+ "arch/x64/sysroot/include/zircon/assert.h",
+ "arch/x64/sysroot/include/zircon/boot/driver-config.h",
+ "arch/x64/sysroot/include/zircon/boot/e820.h",
+ "arch/x64/sysroot/include/zircon/boot/image.h",
+ "arch/x64/sysroot/include/zircon/boot/multiboot.h",
+ "arch/x64/sysroot/include/zircon/boot/netboot.h",
+ "arch/x64/sysroot/include/zircon/boot/sysconfig.h",
+ "arch/x64/sysroot/include/zircon/compiler.h",
+ "arch/x64/sysroot/include/zircon/driver/binding.h",
+ "arch/x64/sysroot/include/zircon/errors.h",
+ "arch/x64/sysroot/include/zircon/features.h",
+ "arch/x64/sysroot/include/zircon/fidl.h",
+ "arch/x64/sysroot/include/zircon/hw/gpt.h",
+ "arch/x64/sysroot/include/zircon/hw/i2c.h",
+ "arch/x64/sysroot/include/zircon/hw/pci.h",
+ "arch/x64/sysroot/include/zircon/hw/usb.h",
+ "arch/x64/sysroot/include/zircon/hw/usb/audio.h",
+ "arch/x64/sysroot/include/zircon/hw/usb/cdc.h",
+ "arch/x64/sysroot/include/zircon/hw/usb/dfu.h",
+ "arch/x64/sysroot/include/zircon/hw/usb/hid.h",
+ "arch/x64/sysroot/include/zircon/hw/usb/hub.h",
+ "arch/x64/sysroot/include/zircon/hw/usb/ums.h",
+ "arch/x64/sysroot/include/zircon/hw/usb/video.h",
+ "arch/x64/sysroot/include/zircon/limits.h",
+ "arch/x64/sysroot/include/zircon/listnode.h",
+ "arch/x64/sysroot/include/zircon/pixelformat.h",
+ "arch/x64/sysroot/include/zircon/process.h",
+ "arch/x64/sysroot/include/zircon/processargs.h",
+ "arch/x64/sysroot/include/zircon/rights.h",
+ "arch/x64/sysroot/include/zircon/string_view.h",
+ "arch/x64/sysroot/include/zircon/syscalls.h",
+ "arch/x64/sysroot/include/zircon/syscalls/clock.h",
+ "arch/x64/sysroot/include/zircon/syscalls/debug.h",
+ "arch/x64/sysroot/include/zircon/syscalls/exception.h",
+ "arch/x64/sysroot/include/zircon/syscalls/hypervisor.h",
+ "arch/x64/sysroot/include/zircon/syscalls/iommu.h",
+ "arch/x64/sysroot/include/zircon/syscalls/log.h",
+ "arch/x64/sysroot/include/zircon/syscalls/object.h",
+ "arch/x64/sysroot/include/zircon/syscalls/pci.h",
+ "arch/x64/sysroot/include/zircon/syscalls/policy.h",
+ "arch/x64/sysroot/include/zircon/syscalls/port.h",
+ "arch/x64/sysroot/include/zircon/syscalls/profile.h",
+ "arch/x64/sysroot/include/zircon/syscalls/resource.h",
+ "arch/x64/sysroot/include/zircon/syscalls/scheduler.h",
+ "arch/x64/sysroot/include/zircon/syscalls/smc.h",
+ "arch/x64/sysroot/include/zircon/syscalls/system.h",
+ "arch/x64/sysroot/include/zircon/syscalls/types.h",
+ "arch/x64/sysroot/include/zircon/time.h",
+ "arch/x64/sysroot/include/zircon/tls.h",
+ "arch/x64/sysroot/include/zircon/types.h",
+ "arch/x64/sysroot/include/zircon/device/audio.h",
+ "arch/x64/sysroot/include/../../vdso/alias_workarounds.fidl",
+ "arch/x64/sysroot/include/../../vdso/bti.fidl",
+ "arch/x64/sysroot/include/../../vdso/cache.fidl",
+ "arch/x64/sysroot/include/../../vdso/channel.fidl",
+ "arch/x64/sysroot/include/../../vdso/clock.fidl",
+ "arch/x64/sysroot/include/../../vdso/cprng.fidl",
+ "arch/x64/sysroot/include/../../vdso/debug.fidl",
+ "arch/x64/sysroot/include/../../vdso/debuglog.fidl",
+ "arch/x64/sysroot/include/../../vdso/event.fidl",
+ "arch/x64/sysroot/include/../../vdso/eventpair.fidl",
+ "arch/x64/sysroot/include/../../vdso/exception.fidl",
+ "arch/x64/sysroot/include/../../vdso/fifo.fidl",
+ "arch/x64/sysroot/include/../../vdso/framebuffer.fidl",
+ "arch/x64/sysroot/include/../../vdso/futex.fidl",
+ "arch/x64/sysroot/include/../../vdso/guest.fidl",
+ "arch/x64/sysroot/include/../../vdso/handle.fidl",
+ "arch/x64/sysroot/include/../../vdso/interrupt.fidl",
+ "arch/x64/sysroot/include/../../vdso/iommu.fidl",
+ "arch/x64/sysroot/include/../../vdso/ioports.fidl",
+ "arch/x64/sysroot/include/../../vdso/job.fidl",
+ "arch/x64/sysroot/include/../../vdso/ktrace.fidl",
+ "arch/x64/sysroot/include/../../vdso/misc.fidl",
+ "arch/x64/sysroot/include/../../vdso/mtrace.fidl",
+ "arch/x64/sysroot/include/../../vdso/object.fidl",
+ "arch/x64/sysroot/include/../../vdso/pager.fidl",
+ "arch/x64/sysroot/include/../../vdso/pc.fidl",
+ "arch/x64/sysroot/include/../../vdso/pci.fidl",
+ "arch/x64/sysroot/include/../../vdso/pmt.fidl",
+ "arch/x64/sysroot/include/../../vdso/port.fidl",
+ "arch/x64/sysroot/include/../../vdso/process.fidl",
+ "arch/x64/sysroot/include/../../vdso/profile.fidl",
+ "arch/x64/sysroot/include/../../vdso/resource.fidl",
+ "arch/x64/sysroot/include/../../vdso/rights.fidl",
+ "arch/x64/sysroot/include/../../vdso/smc.fidl",
+ "arch/x64/sysroot/include/../../vdso/socket.fidl",
+ "arch/x64/sysroot/include/../../vdso/stream.fidl",
+ "arch/x64/sysroot/include/../../vdso/syscall.fidl",
+ "arch/x64/sysroot/include/../../vdso/system.fidl",
+ "arch/x64/sysroot/include/../../vdso/task.fidl",
+ "arch/x64/sysroot/include/../../vdso/thread.fidl",
+ "arch/x64/sysroot/include/../../vdso/timer.fidl",
+ "arch/x64/sysroot/include/../../vdso/vcpu.fidl",
+ "arch/x64/sysroot/include/../../vdso/vmar.fidl",
+ "arch/x64/sysroot/include/../../vdso/vmo.fidl",
+ "arch/x64/sysroot/include/../../vdso/zx.fidl",
+ "arch/x64/sysroot/include/zircon/testonly-syscalls.h",
+ "arch/x64/sysroot/include/alloca.h",
+ "arch/x64/sysroot/include/ar.h",
+ "arch/x64/sysroot/include/arpa/ftp.h",
+ "arch/x64/sysroot/include/arpa/inet.h",
+ "arch/x64/sysroot/include/arpa/nameser.h",
+ "arch/x64/sysroot/include/arpa/nameser_compat.h",
+ "arch/x64/sysroot/include/arpa/telnet.h",
+ "arch/x64/sysroot/include/arpa/tftp.h",
+ "arch/x64/sysroot/include/assert.h",
+ "arch/x64/sysroot/include/bits/aarch64/endian.h",
+ "arch/x64/sysroot/include/bits/aarch64/fenv.h",
+ "arch/x64/sysroot/include/bits/aarch64/io.h",
+ "arch/x64/sysroot/include/bits/aarch64/ioctl.h",
+ "arch/x64/sysroot/include/bits/aarch64/ipc.h",
+ "arch/x64/sysroot/include/bits/aarch64/reg.h",
+ "arch/x64/sysroot/include/bits/aarch64/setjmp.h",
+ "arch/x64/sysroot/include/bits/aarch64/signal.h",
+ "arch/x64/sysroot/include/bits/aarch64/stat.h",
+ "arch/x64/sysroot/include/bits/alltypes.h",
+ "arch/x64/sysroot/include/bits/endian.h",
+ "arch/x64/sysroot/include/bits/errno.h",
+ "arch/x64/sysroot/include/bits/fcntl.h",
+ "arch/x64/sysroot/include/bits/fenv.h",
+ "arch/x64/sysroot/include/bits/io.h",
+ "arch/x64/sysroot/include/bits/ioctl.h",
+ "arch/x64/sysroot/include/bits/ipc.h",
+ "arch/x64/sysroot/include/bits/limits.h",
+ "arch/x64/sysroot/include/bits/msg.h",
+ "arch/x64/sysroot/include/bits/null.h",
+ "arch/x64/sysroot/include/bits/poll.h",
+ "arch/x64/sysroot/include/bits/posix.h",
+ "arch/x64/sysroot/include/bits/reg.h",
+ "arch/x64/sysroot/include/bits/resource.h",
+ "arch/x64/sysroot/include/bits/sem.h",
+ "arch/x64/sysroot/include/bits/setjmp.h",
+ "arch/x64/sysroot/include/bits/shm.h",
+ "arch/x64/sysroot/include/bits/signal.h",
+ "arch/x64/sysroot/include/bits/socket.h",
+ "arch/x64/sysroot/include/bits/stat.h",
+ "arch/x64/sysroot/include/bits/statfs.h",
+ "arch/x64/sysroot/include/bits/termios.h",
+ "arch/x64/sysroot/include/bits/x86_64/endian.h",
+ "arch/x64/sysroot/include/bits/x86_64/fenv.h",
+ "arch/x64/sysroot/include/bits/x86_64/io.h",
+ "arch/x64/sysroot/include/bits/x86_64/ioctl.h",
+ "arch/x64/sysroot/include/bits/x86_64/ipc.h",
+ "arch/x64/sysroot/include/bits/x86_64/reg.h",
+ "arch/x64/sysroot/include/bits/x86_64/setjmp.h",
+ "arch/x64/sysroot/include/bits/x86_64/signal.h",
+ "arch/x64/sysroot/include/bits/x86_64/stat.h",
+ "arch/x64/sysroot/include/byteswap.h",
+ "arch/x64/sysroot/include/complex.h",
+ "arch/x64/sysroot/include/cpio.h",
+ "arch/x64/sysroot/include/ctype.h",
+ "arch/x64/sysroot/include/dirent.h",
+ "arch/x64/sysroot/include/dlfcn.h",
+ "arch/x64/sysroot/include/elf.h",
+ "arch/x64/sysroot/include/endian.h",
+ "arch/x64/sysroot/include/err.h",
+ "arch/x64/sysroot/include/errno.h",
+ "arch/x64/sysroot/include/fcntl.h",
+ "arch/x64/sysroot/include/features.h",
+ "arch/x64/sysroot/include/fenv.h",
+ "arch/x64/sysroot/include/fmtmsg.h",
+ "arch/x64/sysroot/include/fnmatch.h",
+ "arch/x64/sysroot/include/getopt.h",
+ "arch/x64/sysroot/include/glob.h",
+ "arch/x64/sysroot/include/grp.h",
+ "arch/x64/sysroot/include/iconv.h",
+ "arch/x64/sysroot/include/ifaddrs.h",
+ "arch/x64/sysroot/include/inttypes.h",
+ "arch/x64/sysroot/include/iso646.h",
+ "arch/x64/sysroot/include/langinfo.h",
+ "arch/x64/sysroot/include/libgen.h",
+ "arch/x64/sysroot/include/limits.h",
+ "arch/x64/sysroot/include/link.h",
+ "arch/x64/sysroot/include/locale.h",
+ "arch/x64/sysroot/include/malloc.h",
+ "arch/x64/sysroot/include/math.h",
+ "arch/x64/sysroot/include/memory.h",
+ "arch/x64/sysroot/include/monetary.h",
+ "arch/x64/sysroot/include/net/ethernet.h",
+ "arch/x64/sysroot/include/net/if.h",
+ "arch/x64/sysroot/include/net/if_arp.h",
+ "arch/x64/sysroot/include/net/route.h",
+ "arch/x64/sysroot/include/netdb.h",
+ "arch/x64/sysroot/include/netinet/ether.h",
+ "arch/x64/sysroot/include/netinet/icmp6.h",
+ "arch/x64/sysroot/include/netinet/if_ether.h",
+ "arch/x64/sysroot/include/netinet/igmp.h",
+ "arch/x64/sysroot/include/netinet/in.h",
+ "arch/x64/sysroot/include/netinet/in_systm.h",
+ "arch/x64/sysroot/include/netinet/ip.h",
+ "arch/x64/sysroot/include/netinet/ip6.h",
+ "arch/x64/sysroot/include/netinet/ip_icmp.h",
+ "arch/x64/sysroot/include/netinet/tcp.h",
+ "arch/x64/sysroot/include/netinet/udp.h",
+ "arch/x64/sysroot/include/netpacket/packet.h",
+ "arch/x64/sysroot/include/nl_types.h",
+ "arch/x64/sysroot/include/paths.h",
+ "arch/x64/sysroot/include/poll.h",
+ "arch/x64/sysroot/include/pthread.h",
+ "arch/x64/sysroot/include/pwd.h",
+ "arch/x64/sysroot/include/regex.h",
+ "arch/x64/sysroot/include/resolv.h",
+ "arch/x64/sysroot/include/sched.h",
+ "arch/x64/sysroot/include/search.h",
+ "arch/x64/sysroot/include/semaphore.h",
+ "arch/x64/sysroot/include/setjmp.h",
+ "arch/x64/sysroot/include/signal.h",
+ "arch/x64/sysroot/include/spawn.h",
+ "arch/x64/sysroot/include/stdio.h",
+ "arch/x64/sysroot/include/stdlib.h",
+ "arch/x64/sysroot/include/string.h",
+ "arch/x64/sysroot/include/strings.h",
+ "arch/x64/sysroot/include/stropts.h",
+ "arch/x64/sysroot/include/sys/acct.h",
+ "arch/x64/sysroot/include/sys/auxv.h",
+ "arch/x64/sysroot/include/sys/dir.h",
+ "arch/x64/sysroot/include/sys/errno.h",
+ "arch/x64/sysroot/include/sys/eventfd.h",
+ "arch/x64/sysroot/include/sys/fcntl.h",
+ "arch/x64/sysroot/include/sys/file.h",
+ "arch/x64/sysroot/include/sys/fsuid.h",
+ "arch/x64/sysroot/include/sys/io.h",
+ "arch/x64/sysroot/include/sys/ioctl.h",
+ "arch/x64/sysroot/include/sys/ipc.h",
+ "arch/x64/sysroot/include/sys/klog.h",
+ "arch/x64/sysroot/include/sys/mman.h",
+ "arch/x64/sysroot/include/sys/mount.h",
+ "arch/x64/sysroot/include/sys/msg.h",
+ "arch/x64/sysroot/include/sys/mtio.h",
+ "arch/x64/sysroot/include/sys/param.h",
+ "arch/x64/sysroot/include/sys/personality.h",
+ "arch/x64/sysroot/include/sys/poll.h",
+ "arch/x64/sysroot/include/sys/quota.h",
+ "arch/x64/sysroot/include/sys/random.h",
+ "arch/x64/sysroot/include/sys/reboot.h",
+ "arch/x64/sysroot/include/sys/reg.h",
+ "arch/x64/sysroot/include/sys/select.h",
+ "arch/x64/sysroot/include/sys/sem.h",
+ "arch/x64/sysroot/include/sys/shm.h",
+ "arch/x64/sysroot/include/sys/signal.h",
+ "arch/x64/sysroot/include/sys/signalfd.h",
+ "arch/x64/sysroot/include/sys/socket.h",
+ "arch/x64/sysroot/include/sys/stat.h",
+ "arch/x64/sysroot/include/sys/statfs.h",
+ "arch/x64/sysroot/include/sys/statvfs.h",
+ "arch/x64/sysroot/include/sys/stropts.h",
+ "arch/x64/sysroot/include/sys/swap.h",
+ "arch/x64/sysroot/include/sys/syslog.h",
+ "arch/x64/sysroot/include/sys/termios.h",
+ "arch/x64/sysroot/include/sys/time.h",
+ "arch/x64/sysroot/include/sys/timeb.h",
+ "arch/x64/sysroot/include/sys/timerfd.h",
+ "arch/x64/sysroot/include/sys/times.h",
+ "arch/x64/sysroot/include/sys/timex.h",
+ "arch/x64/sysroot/include/sys/ttydefaults.h",
+ "arch/x64/sysroot/include/sys/types.h",
+ "arch/x64/sysroot/include/sys/ucontext.h",
+ "arch/x64/sysroot/include/sys/uio.h",
+ "arch/x64/sysroot/include/sys/un.h",
+ "arch/x64/sysroot/include/sys/utsname.h",
+ "arch/x64/sysroot/include/sys/vfs.h",
+ "arch/x64/sysroot/include/sys/wait.h",
+ "arch/x64/sysroot/include/sysexits.h",
+ "arch/x64/sysroot/include/syslog.h",
+ "arch/x64/sysroot/include/tar.h",
+ "arch/x64/sysroot/include/termios.h",
+ "arch/x64/sysroot/include/threads.h",
+ "arch/x64/sysroot/include/time.h",
+ "arch/x64/sysroot/include/uchar.h",
+ "arch/x64/sysroot/include/ucontext.h",
+ "arch/x64/sysroot/include/unistd.h",
+ "arch/x64/sysroot/include/utime.h",
+ "arch/x64/sysroot/include/values.h",
+ "arch/x64/sysroot/include/wait.h",
+ "arch/x64/sysroot/include/wchar.h",
+ "arch/x64/sysroot/include/wctype.h",
+ "arch/x64/sysroot/include/wordexp.h",
+ "arch/x64/sysroot/include/zircon/dlfcn.h",
+ "arch/x64/sysroot/include/zircon/sanitizer.h",
+ "arch/x64/sysroot/include/zircon/threads.h",
+ "arch/x64/sysroot/include/zircon/syscalls/internal/cdecls.inc",
+ "arch/x64/sysroot/include/zircon/status.h",
+ "arch/x64/sysroot/include/zircon/exception.h"
+ ],
+ "include_dir": "arch/x64/sysroot/include",
+ "link_libs": [
+ "arch/x64/sysroot/lib/libc.so",
+ "arch/x64/sysroot/lib/libdl.so",
+ "arch/x64/sysroot/lib/libm.so",
+ "arch/x64/sysroot/lib/libpthread.so",
+ "arch/x64/sysroot/lib/librt.so",
+ "arch/x64/sysroot/lib/Scrt1.o",
+ "arch/x64/sysroot/lib/libzircon.so"
+ ],
+ "root": "arch/x64/sysroot"
+ }
+ }
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/trace-engine/BUILD.gn b/third_party/fuchsia-sdk/pkg/trace-engine/BUILD.gn
new file mode 100644
index 0000000..f0317fd
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/trace-engine/BUILD.gn
@@ -0,0 +1,31 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("trace-engine") {
+ shared_libs = [ "trace-engine" ]
+
+ deps = [
+ "../async",
+ ]
+ sources = [
+ "include/lib/trace-engine/context.h",
+ "include/lib/trace-engine/fields.h",
+ "include/lib/trace-engine/handler.h",
+ "include/lib/trace-engine/instrumentation.h",
+ "include/lib/trace-engine/types.h",
+ ]
+ include_dirs = [ "include" ]
+}
+
+group("all"){
+ deps = [
+ ":trace-engine",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/trace-engine/include/lib/trace-engine/context.h b/third_party/fuchsia-sdk/pkg/trace-engine/include/lib/trace-engine/context.h
new file mode 100644
index 0000000..d4483cb
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/trace-engine/include/lib/trace-engine/context.h
@@ -0,0 +1,591 @@
+// Copyright 2017 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.
+
+//
+// The ABI-stable entry points used by trace instrumentation libraries.
+//
+// These functions are used to write trace records into the trace buffer
+// associated with a trace context.
+//
+// Writing trace records is intended to be very fast but the cost varies
+// depending on the size and complexity of the event and any arguments
+// which are associated with it.
+//
+// At this time, there exists only one trace context, the engine's trace context,
+// which can be acquired and released using the functions in
+// <trace-engine/instrumentation.h>. In the future, this API may be extended
+// to support trace contexts with different scopes.
+//
+// Client code shouldn't be using these APIs directly.
+// See <trace/event.h> for instrumentation macros.
+//
+
+#ifndef ZIRCON_SYSTEM_ULIB_LIB_TRACE_ENGINE_CONTEXT_H_
+#define ZIRCON_SYSTEM_ULIB_LIB_TRACE_ENGINE_CONTEXT_H_
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <zircon/assert.h>
+#include <zircon/compiler.h>
+#include <zircon/syscalls/object.h>
+#include <zircon/types.h>
+
+#include <lib/trace-engine/types.h>
+
+__BEGIN_CDECLS
+
+// Opaque type representing a trace context.
+// Most functions in this header require a valid trace context to operate.
+typedef struct trace_context trace_context_t;
+
+// Opaque type representing a trace context that is held for prolonged
+// periods of time.
+typedef struct trace_prolonged_context trace_prolonged_context_t;
+
+// Returns true if tracing of the specified category has been enabled.
+//
+// Use |trace_context_register_category_literal()| if you intend to immediately
+// write a record into the trace buffer after checking the category.
+//
+// |context| must be a valid trace context reference.
+// |category_literal| must be a null-terminated static string constant.
+//
+// This function is thread-safe.
+bool trace_context_is_category_enabled(trace_context_t* context, const char* category_literal);
+
+// Registers a copy of a string into the string table.
+//
+// Writes a string record into the trace buffer if the string was added to the
+// string table. If the string table is full, returns an inline string reference.
+//
+// |context| must be a valid trace context reference.
+// |string| must be the string to register.
+// |length| must be the length of the string.
+// |out_ref| points to where the registered string reference should be returned.
+//
+// This function is thread-safe.
+void trace_context_register_string_copy(trace_context_t* context, const char* string, size_t length,
+ trace_string_ref_t* out_ref);
+
+// Registers a copy of a string and returns its string ref.
+// Helper for |trace_context_register_thread()|.
+static inline trace_string_ref_t trace_context_make_registered_string_copy(trace_context_t* context,
+ const char* string,
+ size_t length) {
+ trace_string_ref_t ref;
+ trace_context_register_string_copy(context, string, length, &ref);
+ return ref;
+}
+
+// Registers a string literal into the string table keyed by its address in memory.
+//
+// The trace context caches the string so that subsequent registrations using
+// the same memory address may return the same indexed string reference if
+// found in the cache.
+//
+// Writes a string record into the trace buffer if the string was added to the
+// string table. If the string table is full, returns an inline string reference.
+//
+// |context| must be a valid trace context reference.
+// |string_literal| must be a null-terminated static string constant.
+// |out_ref| points to where the registered string reference should be returned.
+//
+// This function is thread-safe.
+void trace_context_register_string_literal(trace_context_t* context, const char* string_literal,
+ trace_string_ref_t* out_ref);
+
+// Registers a string literal and returns its string ref.
+// Helper for |trace_context_register_string_literal()|.
+static inline trace_string_ref_t trace_context_make_registered_string_literal(
+ trace_context_t* context, const char* string_literal) {
+ trace_string_ref_t ref;
+ trace_context_register_string_literal(context, string_literal, &ref);
+ return ref;
+}
+
+// Registers a category into the string table, if it is enabled, keyed by its
+// address in memory.
+//
+// The trace context caches the string so that subsequent registrations using
+// the same memory address may return the same indexed string reference if
+// found in the cache.
+//
+// Writes a string record into the trace buffer if the category was added to the
+// string table. If the string table is full, returns an inline string reference.
+//
+// |context| must be a valid trace context reference.
+// |category_literal| must be a null-terminated static string constant.
+// |out_ref| points to where the registered string reference should be returned.
+//
+// Returns true and registers the string if the category is enabled, otherwise
+// returns false and does not modify |*out_ref|.
+//
+// This function is thread-safe.
+bool trace_context_register_category_literal(trace_context_t* context, const char* category_literal,
+ trace_string_ref_t* out_ref);
+
+// Registers the current thread into the thread table.
+//
+// Writes a process and/or thread kernel object record into the trace buffer if
+// the process and/or thread have not previously been described. Writes a
+// thread record into the trace buffer if the thread was added to the thread table.
+//
+// If the thread table is full, returns an inline thread reference.
+//
+// |context| must be a valid trace context reference.
+// |out_ref| points to where the registered thread reference should be returned.
+//
+// This function is thread-safe.
+void trace_context_register_current_thread(trace_context_t* context, trace_thread_ref_t* out_ref);
+
+// Registers the virtual thread into the thread table.
+//
+// Writes a thread record into the trace buffer if the virtual thread was added
+// to the thread table.
+//
+// If the thread table is full, returns an inline thread reference.
+//
+// |context| must be a valid trace context reference.
+// |process_koid| is the koid of the process which contains the thread.
+// If ZX_KOID_INVALID is passed, the koid of the current process is used.
+// |vthread_literal| must be a null-terminated static string constant.
+// |vthread_id| is the id of the virtual thread to register.
+// |out_ref| points to where the registered thread reference should be returned.
+//
+// This function is thread-safe.
+void trace_context_register_vthread(trace_context_t* context, zx_koid_t process_koid,
+ const char* vthread_literal, trace_vthread_id_t vthread_id,
+ trace_thread_ref_t* out_ref);
+
+// Registers the specified thread into the thread table.
+//
+// Writes a thread record into the trace buffer if the thread was added to the
+// thread table.
+//
+// If the thread table is full, returns an inline thread reference.
+//
+// Unlike |trace_context_register_current_thread()|, the caller is responsible for
+// writing a process and/or thread kernel object record into the trace buffer
+// if the process and/or thread have not previously been described.
+//
+// |context| must be a valid trace context reference.
+// |process_koid| is the koid of the process which contains the thread.
+// |thread_koid| is the koid of the thread to register.
+// |out_ref| points to where the registered thread reference should be returned.
+//
+// This function is thread-safe.
+void trace_context_register_thread(trace_context_t* context, zx_koid_t process_koid,
+ zx_koid_t thread_koid, trace_thread_ref_t* out_ref);
+
+// Registers a thread and returns its thread ref.
+// Helper for |trace_context_register_thread()|.
+static inline trace_thread_ref_t trace_context_make_registered_thread(trace_context_t* context,
+ zx_koid_t process_koid,
+ zx_koid_t thread_koid) {
+ trace_thread_ref_t ref;
+ trace_context_register_thread(context, process_koid, thread_koid, &ref);
+ return ref;
+}
+
+// Allocate space for a blob and write its header.
+// Returns a pointer to the "raw" contents of the blob,
+// which must be filled in by the caller.
+// Returns |nullptr| if there is no space in the buffer for |blob_size| bytes,
+// or if |blob_size| is larger than TRACE_MAX_BLOB_SIZE.
+// |context| must be a valid trace context reference.
+// |type| is the blob type.
+// |name_ref| is the name of the blob.
+// |blob_size| is the size of the binary data to write.
+// The caller is required to fill in the blob after we return.
+// There is no need to zero out any padding, that has already been done.
+void* trace_context_begin_write_blob_record(trace_context_t* context, trace_blob_type_t type,
+ const trace_string_ref_t* name_ref, size_t blob_size);
+
+// Write a blob of binary data into the trace buffer.
+// Discards the record if it cannot be written.
+// |context| must be a valid trace context reference.
+// |type| is the blob type.
+// |name_ref| is the name of the blob.
+// |blob| is the binary data to write.
+// |blob_size| is the size of the binary data to write.
+void trace_context_write_blob_record(trace_context_t* context, trace_blob_type_t type,
+ const trace_string_ref_t* name_ref, const void* blob,
+ size_t blob_size);
+
+// Sends an alert.
+// |context| must be a valid trace context reference.
+// |alert_name| is the name of the alert (max 14 characters).
+//
+// This function is thread-safe.
+void trace_context_send_alert(trace_context_t* context, const char* alert_name);
+
+// Writes a kernel object record for the object reference by the specified handle
+// into the trace buffer. Discards the record if it cannot be written.
+//
+// Collects the necessary information by querying the object's type and properties.
+//
+// |context| must be a valid trace context reference.
+// |handle| is the handle of the object being described.
+// |args| contains |num_args| key/value pairs to include in the record, or NULL if none.
+//
+// This function is thread-safe.
+void trace_context_write_kernel_object_record_for_handle(trace_context_t* context,
+ zx_handle_t handle,
+ const trace_arg_t* args, size_t num_args);
+
+// Writes a kernel object record for the specified process into the trace buffer.
+// Discards the record if it cannot be written.
+//
+// |context| must be a valid trace context reference.
+// |process_koid| is the koid of the process being described.
+// |process_name_ref| is the name of the process.
+//
+// This function is thread-safe.
+void trace_context_write_process_info_record(trace_context_t* context, zx_koid_t process_koid,
+ const trace_string_ref_t* process_name_ref);
+
+// Writes a kernel object record for the specified thread into the trace buffer.
+// Discards the record if it cannot be written.
+//
+// |context| must be a valid trace context reference.
+// |process_koid| is the koid of the process which contains the thread.
+// |thread_koid| is the koid of the thread being described.
+// |thread_name_ref| is the name of the thread.
+//
+// This function is thread-safe.
+void trace_context_write_thread_info_record(trace_context_t* context, zx_koid_t process_koid,
+ zx_koid_t thread_koid,
+ const trace_string_ref_t* thread_name_ref);
+
+// Writes a context switch record into the trace buffer.
+// Discards the record if it cannot be written.
+//
+// |context| must be a valid trace context reference.
+// |event_time| is the time of the event, in ticks.
+// |cpu_number| is the CPU upon which the context switch occurred.
+// |outgoing_thread_state| is the state of the thread which was descheduled from the CPU.
+// |outgoing_thread_ref| is the thread which was descheduled from the CPU.
+// |incoming_thread_ref| is the thread which was scheduled on the CPU.
+//
+// This function is thread-safe.
+void trace_context_write_context_switch_record(trace_context_t* context, trace_ticks_t event_time,
+ trace_cpu_number_t cpu_number,
+ trace_thread_state_t outgoing_thread_state,
+ const trace_thread_ref_t* outgoing_thread_ref,
+ const trace_thread_ref_t* incoming_thread_ref,
+ trace_thread_priority_t outgoing_thread_priority,
+ trace_thread_priority_t incoming_thread_priority);
+
+// Writes a log record into the trace buffer.
+// Discards the record if it cannot be written.
+//
+// |context| must be a valid trace context reference.
+// |event_time| is the time of the event, in ticks.
+// |thread_ref| is the thread which wrote the log message.
+// |log_message| is the content of the log message.
+// |log_message_length| is the length of the log message.
+//
+// This function is thread-safe.
+void trace_context_write_log_record(trace_context_t* context, trace_ticks_t event_time,
+ const trace_thread_ref_t* thread_ref, const char* log_message,
+ size_t log_message_length);
+
+// Writes an instant event record with arguments into the trace buffer.
+// Discards the record if it cannot be written.
+//
+// |context| must be a valid trace context reference.
+// |event_time| is the time of the event, in ticks.
+// |thread_ref| is the thread on which the event occurred.
+// |category_ref| is the category of the event.
+// |name_ref| is the name of the event.
+// |scope| is the scope to which the instant event applies (thread, process, global).
+// |args| contains |num_args| key/value pairs to include in the record, or NULL if none.
+//
+// This function is thread-safe.
+void trace_context_write_instant_event_record(trace_context_t* context, trace_ticks_t event_time,
+ const trace_thread_ref_t* thread_ref,
+ const trace_string_ref_t* category_ref,
+ const trace_string_ref_t* name_ref,
+ trace_scope_t scope, const trace_arg_t* args,
+ size_t num_args);
+
+// Writes a counter event record with arguments into the trace buffer.
+// Discards the record if it cannot be written.
+//
+// |context| must be a valid trace context reference.
+// |event_time| is the time of the event, in ticks.
+// |thread_ref| is the thread on which the event occurred.
+// |category_ref| is the category of the event.
+// |name_ref| is the name of the event.
+// |counter_id| is the correlation id of the counter.
+// Must be unique for a given process, category, and name combination.
+// |args| contains |num_args| key/value pairs to include in the record, or NULL if none.
+//
+// This function is thread-safe.
+void trace_context_write_counter_event_record(trace_context_t* context, trace_ticks_t event_time,
+ const trace_thread_ref_t* thread_ref,
+ const trace_string_ref_t* category_ref,
+ const trace_string_ref_t* name_ref,
+ trace_counter_id_t counter_id,
+ const trace_arg_t* args, size_t num_args);
+
+// Writes a duration begin event record and a duration end event record with
+// arguments into the trace buffer.
+// Discards the record if it cannot be written.
+//
+// |context| must be a valid trace context reference.
+// |start_time| is the start time of the event, in ticks.
+// |end_time| is the end time of the event, in ticks.
+// |thread_ref| is the thread on which the event occurred.
+// |category_ref| is the category of the event.
+// |name_ref| is the name of the event.
+// |args| contains |num_args| key/value pairs to include in the record, or NULL if none.
+//
+// This function is thread-safe.
+void trace_context_write_duration_event_record(trace_context_t* context, trace_ticks_t start_time,
+ trace_ticks_t end_time,
+ const trace_thread_ref_t* thread_ref,
+ const trace_string_ref_t* category_ref,
+ const trace_string_ref_t* name_ref,
+ const trace_arg_t* args, size_t num_args);
+
+// Writes a duration begin event record with arguments into the trace buffer.
+// Discards the record if it cannot be written.
+//
+// |context| must be a valid trace context reference.
+// |event_time| is the start time of the event, in ticks.
+// |thread_ref| is the thread on which the event occurred.
+// |category_ref| is the category of the event.
+// |name_ref| is the name of the event.
+// |args| contains |num_args| key/value pairs to include in the record, or NULL if none.
+//
+// This function is thread-safe.
+void trace_context_write_duration_begin_event_record(trace_context_t* context,
+ trace_ticks_t event_time,
+ const trace_thread_ref_t* thread_ref,
+ const trace_string_ref_t* category_ref,
+ const trace_string_ref_t* name_ref,
+ const trace_arg_t* args, size_t num_args);
+
+// Writes a duration end event record with arguments into the trace buffer.
+// Discards the record if it cannot be written.
+//
+// |context| must be a valid trace context reference.
+// |event_time| is the end time of the event, in ticks.
+// |thread_ref| is the thread on which the event occurred.
+// |category_ref| is the category of the event.
+// |name_ref| is the name of the event.
+// |args| contains |num_args| key/value pairs to include in the record, or NULL if none.
+//
+// This function is thread-safe.
+void trace_context_write_duration_end_event_record(trace_context_t* context,
+ trace_ticks_t event_time,
+ const trace_thread_ref_t* thread_ref,
+ const trace_string_ref_t* category_ref,
+ const trace_string_ref_t* name_ref,
+ const trace_arg_t* args, size_t num_args);
+
+// Writes an asynchronous begin event record into the trace buffer.
+// Discards the record if it cannot be written.
+//
+// |context| must be a valid trace context reference.
+// |event_time| is the start time of the event, in ticks.
+// |thread_ref| is the thread on which the event occurred.
+// |category_ref| is the category of the event.
+// |name_ref| is the name of the event.
+// |async_id| is the correlation id of the asynchronous operation.
+// Must be unique for a given process, category, and name combination.
+// |args| contains |num_args| key/value pairs to include in the record, or NULL if none.
+//
+// This function is thread-safe.
+void trace_context_write_async_begin_event_record(
+ trace_context_t* context, trace_ticks_t event_time, const trace_thread_ref_t* thread_ref,
+ const trace_string_ref_t* category_ref, const trace_string_ref_t* name_ref,
+ trace_async_id_t async_id, const trace_arg_t* args, size_t num_args);
+
+// Writes an asynchronous instant event record into the trace buffer.
+// Discards the record if it cannot be written.
+//
+// |context| must be a valid trace context reference.
+// |event_time| is the time of the event, in ticks.
+// |thread_ref| is the thread on which the event occurred.
+// |category_ref| is the category of the event.
+// |name_ref| is the name of the event.
+// |async_id| is the correlation id of the asynchronous operation.
+// Must be unique for a given process, category, and name combination.
+// |args| contains |num_args| key/value pairs to include in the record, or NULL if none.
+//
+// This function is thread-safe.
+void trace_context_write_async_instant_event_record(
+ trace_context_t* context, trace_ticks_t event_time, const trace_thread_ref_t* thread_ref,
+ const trace_string_ref_t* category_ref, const trace_string_ref_t* name_ref,
+ trace_async_id_t async_id, const trace_arg_t* args, size_t num_args);
+
+// Writes an asynchronous end event record into the trace buffer.
+// Discards the record if it cannot be written.
+//
+// |context| must be a valid trace context reference.
+// |event_time| is the end time of the event, in ticks.
+// |thread_ref| is the thread on which the event occurred.
+// |category_ref| is the category of the event.
+// |name_ref| is the name of the event.
+// |async_id| is the correlation id of the asynchronous operation.
+// Must be unique for a given process, category, and name combination.
+// |args| contains |num_args| key/value pairs to include in the record, or NULL if none.
+//
+// This function is thread-safe.
+void trace_context_write_async_end_event_record(trace_context_t* context, trace_ticks_t event_time,
+ const trace_thread_ref_t* thread_ref,
+ const trace_string_ref_t* category_ref,
+ const trace_string_ref_t* name_ref,
+ trace_async_id_t async_id, const trace_arg_t* args,
+ size_t num_args);
+
+// Writes a flow begin event record into the trace buffer.
+// Discards the record if it cannot be written.
+//
+// |context| must be a valid trace context reference.
+// |event_time| is the start time of the event, in ticks.
+// |thread_ref| is the thread on which the event occurred.
+// |category_ref| is the category of the event.
+// |name_ref| is the name of the event.
+// |flow_id| is the correlation id of the flow.
+// Must be unique for a given category and name combination.
+// |args| contains |num_args| key/value pairs to include in the record, or NULL if none.
+//
+// This function is thread-safe.
+void trace_context_write_flow_begin_event_record(trace_context_t* context, trace_ticks_t event_time,
+ const trace_thread_ref_t* thread_ref,
+ const trace_string_ref_t* category_ref,
+ const trace_string_ref_t* name_ref,
+ trace_flow_id_t flow_id, const trace_arg_t* args,
+ size_t num_args);
+
+// Writes a flow step event record into the trace buffer.
+// Discards the record if it cannot be written.
+//
+// |context| must be a valid trace context reference.
+// |event_time| is the time of the event, in ticks.
+// |thread_ref| is the thread on which the event occurred.
+// |category_ref| is the category of the event.
+// |name_ref| is the name of the event.
+// |flow_id| is the correlation id of the flow.
+// Must be unique for a given category and name combination.
+// |args| contains |num_args| key/value pairs to include in the record, or NULL if none.
+//
+// This function is thread-safe.
+void trace_context_write_flow_step_event_record(trace_context_t* context, trace_ticks_t event_time,
+ const trace_thread_ref_t* thread_ref,
+ const trace_string_ref_t* category_ref,
+ const trace_string_ref_t* name_ref,
+ trace_flow_id_t flow_id, const trace_arg_t* args,
+ size_t num_args);
+
+// Writes a flow end event record into the trace buffer.
+// Discards the record if it cannot be written.
+//
+// |context| must be a valid trace context reference.
+// |event_time| is the end time of the event, in ticks.
+// |thread_ref| is the thread on which the event occurred.
+// |category_ref| is the category of the event.
+// |name_ref| is the name of the event.
+// |flow_id| is the correlation id of the flow.
+// Must be unique for a given category and name combination.
+// |args| contains |num_args| key/value pairs to include in the record, or NULL if none.
+//
+// This function is thread-safe.
+void trace_context_write_flow_end_event_record(trace_context_t* context, trace_ticks_t event_time,
+ const trace_thread_ref_t* thread_ref,
+ const trace_string_ref_t* category_ref,
+ const trace_string_ref_t* name_ref,
+ trace_flow_id_t flow_id, const trace_arg_t* args,
+ size_t num_args);
+
+// Writes a large blob record with metadata into the trace buffer.
+// Discards the record if it cannot be written.
+//
+// |context| must be a valid trace context reference.
+// |event_time| is the time of the event, in ticks.
+// |thread_ref| is the thread on which the event occurred.
+// |category_ref| is the category of the event.
+// |name_ref| is the name of the event.
+// |blob| is a pointer to the data, and contains |blob_size| bytes.
+// |args| contains |num_args| key/value pairs to include in the record, or NULL if none.
+//
+// This function is thread-safe.
+void trace_context_write_blob_event_record(trace_context_t* context, trace_ticks_t event_time,
+ const trace_thread_ref_t* thread_ref,
+ const trace_string_ref_t* category_ref,
+ const trace_string_ref_t* name_ref, const void* blob,
+ size_t blob_size, const trace_arg_t* args,
+ size_t num_args);
+
+// Writes a large blob record without metadata into the trace buffer.
+// Discards the record if it cannot be written.
+//
+// |context| must be a valid trace context reference.
+// |category_ref| is the category of the event.
+// |name_ref| is the name of the event.
+// |blob| is a pointer to the data, and contains |blob_size| bytes.
+//
+// This function is thread-safe.
+void trace_context_write_blob_attachment_record(trace_context_t* context,
+ const trace_string_ref_t* category_ref,
+ const trace_string_ref_t* name_ref,
+ const void* blob, size_t blob_size);
+
+// Writes an initialization record into the trace buffer.
+// Discards the record if it cannot be written.
+//
+// |context| must be a valid trace context reference.
+// |ticks_per_second| is the number of |trace_ticks_t| per second used in the trace.
+//
+// This function is thread-safe.
+void trace_context_write_initialization_record(trace_context_t* context,
+ zx_ticks_t ticks_per_second);
+
+// Writes a string record into the trace buffer.
+// Discards the record if it cannot be written.
+//
+// |context| must be a valid trace context reference.
+// |index| is the index of the string, between |TRACE_ENCODED_STRING_REF_MIN_INDEX|
+// and |TRACE_ENCODED_STRING_REF_MAX_INDEX| inclusive.
+// |string| is the content of the string.
+// |length| is the length of the string; the string will be truncated if it is longer
+// than |TRACE_ENCODED_STRING_REF_MAX_LENGTH|.
+//
+// This function is thread-safe.
+void trace_context_write_string_record(trace_context_t* context, trace_string_index_t index,
+ const char* string, size_t length);
+
+// Writes a thread record into the trace buffer.
+// Discards the record if it cannot be written.
+//
+// |context| must be a valid trace context reference.
+// |index| is the index of the thread, between |TRACE_ENCODED_THREAD_REF_MIN_INDEX|
+// and |TRACE_ENCODED_THREAD_REF_MAX_INDEX| inclusive.
+// |process_koid| is the koid of the process which contains the thread.
+// |thread_koid| is the koid of the thread being described.
+//
+// This function is thread-safe.
+void trace_context_write_thread_record(trace_context_t* context, trace_thread_index_t index,
+ zx_koid_t process_koid, zx_koid_t thread_koid);
+
+// Allocates space for a record in the trace buffer.
+//
+// |context| must be a valid trace context reference.
+// |num_bytes| must be a multiple of 8 bytes.
+//
+// Returns a pointer to the allocated space within the trace buffer with
+// 8 byte alignment, or NULL if the trace buffer is full or if |num_bytes|
+// exceeds |TRACE_ENCODED_RECORD_MAX_LENGTH|.
+//
+// This function is thread-safe, fail-fast, and lock-free.
+void* trace_context_alloc_record(trace_context_t* context, size_t num_bytes);
+
+__END_CDECLS
+
+#endif // ZIRCON_SYSTEM_ULIB_LIB_TRACE_ENGINE_CONTEXT_H_
diff --git a/third_party/fuchsia-sdk/pkg/trace-engine/include/lib/trace-engine/fields.h b/third_party/fuchsia-sdk/pkg/trace-engine/include/lib/trace-engine/fields.h
new file mode 100644
index 0000000..70c1037
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/trace-engine/include/lib/trace-engine/fields.h
@@ -0,0 +1,188 @@
+// Copyright 2017 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.
+
+//
+// Field declarations for the trace record format.
+//
+
+#ifndef ZIRCON_SYSTEM_ULIB_LIB_TRACE_ENGINE_FIELDS_H_
+#define ZIRCON_SYSTEM_ULIB_LIB_TRACE_ENGINE_FIELDS_H_
+
+#include <lib/trace-engine/types.h>
+
+#ifdef __cplusplus
+
+#include <type_traits>
+
+namespace trace {
+
+inline constexpr size_t Pad(size_t size) { return size + ((8 - (size & 7)) & 7); }
+
+inline constexpr size_t BytesToWords(size_t num_bytes) { return Pad(num_bytes) / sizeof(uint64_t); }
+
+inline constexpr size_t WordsToBytes(size_t num_words) { return num_words * sizeof(uint64_t); }
+
+// Casts an enum's value to its underlying type.
+template <typename T>
+inline constexpr typename std::underlying_type<T>::type ToUnderlyingType(T value) {
+ return static_cast<typename std::underlying_type<T>::type>(value);
+}
+
+// Describes the layout of a bit-field packed into a 64-bit word.
+template <size_t begin, size_t end>
+struct Field {
+ static_assert(begin < sizeof(uint64_t) * 8, "begin is out of bounds");
+ static_assert(end < sizeof(uint64_t) * 8, "end is out of bounds");
+ static_assert(begin <= end, "begin must not be larger than end");
+ static_assert(end - begin + 1 < 64, "must be a part of a word, not a whole word");
+
+ static constexpr uint64_t kMask = (uint64_t(1) << (end - begin + 1)) - 1;
+
+ static constexpr uint64_t Make(uint64_t value) { return value << begin; }
+
+ template <typename U>
+ static constexpr U Get(uint64_t word) {
+ static_assert(sizeof(U) * 8 >= end - begin + 1, "type must fit all the bits");
+ return static_cast<U>((word >> begin) & kMask);
+ }
+
+ static constexpr void Set(uint64_t& word, uint64_t value) {
+ word = (word & ~(kMask << begin)) | (value << begin);
+ }
+};
+
+struct ArgumentFields {
+ using Type = Field<0, 3>;
+ using ArgumentSize = Field<4, 15>;
+ using NameRef = Field<16, 31>;
+};
+
+struct BoolArgumentFields : ArgumentFields {
+ using Value = Field<32, 32>;
+};
+
+struct Int32ArgumentFields : ArgumentFields {
+ using Value = Field<32, 63>;
+};
+
+struct Uint32ArgumentFields : ArgumentFields {
+ using Value = Field<32, 63>;
+};
+
+struct StringArgumentFields : ArgumentFields {
+ using Index = Field<32, 47>;
+};
+
+struct RecordFields {
+ static constexpr uint64_t kMaxRecordSizeWords = 0xfff;
+ static constexpr uint64_t kMaxRecordSizeBytes = WordsToBytes(kMaxRecordSizeWords);
+
+ using Type = Field<0, 3>;
+ using RecordSize = Field<4, 15>;
+};
+
+struct LargeRecordFields {
+ static constexpr uint64_t kMaxRecordSizeWords = (1ull << 32) - 1;
+ static constexpr uint64_t kMaxRecordSizeBytes = WordsToBytes(kMaxRecordSizeWords);
+
+ using Type = Field<0, 3>;
+ using RecordSize = Field<4, 35>;
+ using LargeType = Field<36, 39>;
+};
+
+struct MetadataRecordFields : RecordFields {
+ using MetadataType = Field<16, 19>;
+};
+
+struct ProviderInfoMetadataRecordFields : MetadataRecordFields {
+ static constexpr size_t kMaxNameLength = 0xff;
+
+ using Id = Field<20, 51>;
+ using NameLength = Field<52, 59>;
+};
+
+struct ProviderSectionMetadataRecordFields : MetadataRecordFields {
+ using Id = Field<20, 51>;
+};
+
+struct ProviderEventMetadataRecordFields : MetadataRecordFields {
+ using Id = Field<20, 51>;
+ using Event = Field<52, 55>;
+};
+
+struct TraceInfoMetadataRecordFields : MetadataRecordFields {
+ using TraceInfoType = Field<20, 23>;
+};
+
+struct MagicNumberRecordFields : TraceInfoMetadataRecordFields {
+ using Magic = Field<24, 55>;
+};
+
+using InitializationRecordFields = RecordFields;
+
+struct StringRecordFields : RecordFields {
+ using StringIndex = Field<16, 30>;
+ using StringLength = Field<32, 46>;
+};
+
+struct ThreadRecordFields : RecordFields {
+ using ThreadIndex = Field<16, 23>;
+};
+
+struct EventRecordFields : RecordFields {
+ using EventType = Field<16, 19>;
+ using ArgumentCount = Field<20, 23>;
+ using ThreadRef = Field<24, 31>;
+ using CategoryStringRef = Field<32, 47>;
+ using NameStringRef = Field<48, 63>;
+};
+
+struct BlobRecordFields : RecordFields {
+ using NameStringRef = Field<16, 31>;
+ using BlobSize = Field<32, 46>;
+ using BlobType = Field<48, 55>;
+};
+
+struct KernelObjectRecordFields : RecordFields {
+ using ObjectType = Field<16, 23>;
+ using NameStringRef = Field<24, 39>;
+ using ArgumentCount = Field<40, 43>;
+};
+
+struct ContextSwitchRecordFields : RecordFields {
+ using CpuNumber = Field<16, 23>;
+ using OutgoingThreadState = Field<24, 27>;
+ using OutgoingThreadRef = Field<28, 35>;
+ using IncomingThreadRef = Field<36, 43>;
+ using OutgoingThreadPriority = Field<44, 51>;
+ using IncomingThreadPriority = Field<52, 59>;
+};
+
+struct LogRecordFields : RecordFields {
+ static constexpr size_t kMaxMessageLength = 0x7fff;
+ using LogMessageLength = Field<16, 30>;
+ using ThreadRef = Field<32, 39>;
+};
+
+struct LargeBlobFields : LargeRecordFields {
+ using BlobFormat = Field<40, 43>;
+};
+
+struct BlobFormatAttachmentFields {
+ using CategoryStringRef = Field<0, 15>;
+ using NameStringRef = Field<16, 31>;
+};
+
+struct BlobFormatEventFields {
+ using CategoryStringRef = Field<0, 15>;
+ using NameStringRef = Field<16, 31>;
+ using ArgumentCount = Field<32, 35>;
+ using ThreadRef = Field<36, 43>;
+};
+
+} // namespace trace
+
+#endif // __cplusplus
+
+#endif // ZIRCON_SYSTEM_ULIB_LIB_TRACE_ENGINE_FIELDS_H_
diff --git a/third_party/fuchsia-sdk/pkg/trace-engine/include/lib/trace-engine/handler.h b/third_party/fuchsia-sdk/pkg/trace-engine/include/lib/trace-engine/handler.h
new file mode 100644
index 0000000..b2bd7d8
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/trace-engine/include/lib/trace-engine/handler.h
@@ -0,0 +1,179 @@
+// Copyright 2017 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.
+
+//
+// The ABI-stable entry points used by trace instrumentation libraries.
+//
+// Trace handlers manage the configuration, lifecycle, and external communication
+// of the trace engine. The trace engine binds to a single trace handler for
+// the duration of a trace. During the trace, the trace engine invokes methods
+// on the trace handler to ask about enabled categories and to report relevant
+// state changes.
+//
+// Client code shouldn't be using these APIs directly.
+// See <trace/event.h> for instrumentation macros.
+//
+
+#ifndef ZIRCON_SYSTEM_ULIB_LIB_TRACE_ENGINE_HANDLER_H_
+#define ZIRCON_SYSTEM_ULIB_LIB_TRACE_ENGINE_HANDLER_H_
+
+#include <stdbool.h>
+
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+#include <lib/async/dispatcher.h>
+#include <lib/trace-engine/instrumentation.h>
+
+__BEGIN_CDECLS
+
+// Trace handler interface.
+//
+// Implementations must supply valid function pointers for each function
+// defined in the |ops| structure.
+typedef struct trace_handler_ops trace_handler_ops_t;
+
+typedef struct trace_handler {
+ const trace_handler_ops_t* ops;
+} trace_handler_t;
+
+struct trace_handler_ops {
+ // Called by the trace engine to ask whether the specified category is enabled.
+ //
+ // This method may be called frequently so it must be efficiently implemented.
+ // Clients may cache the results while a trace is running; dynamic changes
+ // to the enabled categories may go unnoticed until the next trace.
+ //
+ // |handler| is the trace handler object itself.
+ // |category| is the name of the category.
+ //
+ // Called by instrumentation on any thread. Must be thread-safe.
+ bool (*is_category_enabled)(trace_handler_t* handler, const char* category);
+
+ // Called by the trace engine to indicate it has completed startup.
+ void (*trace_started)(trace_handler_t* handler);
+
+ // Called by the trace engine when tracing has stopped.
+ //
+ // The trace collection status is |ZX_OK| if trace collection was successful.
+ // An error indicates that the trace data may be inaccurate or incomplete.
+ //
+ // |handler| is the trace handler object itself.
+ // |disposition| is |ZX_OK| if tracing stopped normally, otherwise indicates
+ // that tracing was aborted due to an error.
+ //
+ // Called on an asynchronous dispatch thread.
+ void (*trace_stopped)(trace_handler_t* handler, zx_status_t disposition);
+
+ // Called by the trace engine to indicate it has terminated.
+ //
+ // Called on an asynchronous dispatch thread.
+ void (*trace_terminated)(trace_handler_t* handler);
+
+ // Called by the trace engine after an attempt to allocate space
+ // for a new record has failed because the buffer is full.
+ //
+ // Called by instrumentation on any thread. Must be thread-safe.
+ void (*notify_buffer_full)(trace_handler_t* handler, uint32_t wrapped_count,
+ uint64_t durable_data_end);
+
+ // Called by the trace engine to send an alert.
+ //
+ // Called by instrumentation on any thread. Must be thread-safe.
+ void (*send_alert)(trace_handler_t* handler, const char* alert_name);
+};
+
+// Whether to clear the trace buffer when starting the engine.
+typedef enum {
+ // The numbering here is chosen to match the |BufferDisposition| enum in
+ // the fuchsia.tracing.provider.Provider FIDL protocol.
+ TRACE_START_CLEAR_ENTIRE_BUFFER = 1,
+ TRACE_START_CLEAR_NONDURABLE_BUFFER = 2,
+ TRACE_START_RETAIN_BUFFER = 3,
+} trace_start_mode_t;
+
+// Initialize the trace engine.
+//
+// |async| is the asynchronous dispatcher which the trace engine will use for dispatch (borrowed).
+// |handler| is the trace handler which will handle lifecycle events (borrowed).
+// |buffer| is the trace buffer into which the trace engine will write trace events (borrowed).
+// |buffer_num_bytes| is the size of the trace buffer in bytes.
+//
+// Returns |ZX_OK| if tracing is ready to go.
+// Returns |ZX_ERR_BAD_STATE| if tracing has already been initialized.
+// Returns |ZX_ERR_NO_MEMORY| if allocation failed.
+//
+// This function is thread-safe.
+//
+// NOTE: Asynchronous dispatcher shutdown behavior:
+//
+// The trace engine will attempt to stop itself automatically when the
+// asynchronous dispatcher specified in |async| begins the process of shutting
+// itself down (usually just prior to the dispatcher's destruction). However,
+// the trace engine may fail to come to a complete stop if there remain outstanding
+// references to the trace context during dispatcher shutdown. When this happens,
+// the trace handler will not be notified of trace completion and subsequent calls
+// to |trace_engine_start()| will return |ZX_ERR_BAD_STATE|.
+//
+// For this reason, it is a good idea to call |trace_engine_terminate()| and wait
+// for the handler to receive the |trace_handler_ops.trace_terminated()| callback
+// prior to shutting down the trace engine's asynchronous dispatcher.
+//
+// Better yet, don't shut down the trace engine's asynchronous dispatcher unless
+// the process is already about to exit.
+zx_status_t trace_engine_initialize(async_dispatcher_t* dispatcher, trace_handler_t* handler,
+ trace_buffering_mode_t buffering_mode, void* buffer,
+ size_t buffer_num_bytes);
+
+// Asynchronously starts the trace engine.
+// The engine must have already be initialized with |trace_engine_initialize()|.
+//
+// |mode| specifies whether to clear the trace buffer first.
+//
+// Returns |ZX_OK| if tracing is ready to go.
+// Returns |ZX_ERR_BAD_STATE| if tracing is already in progress.
+//
+// This function is thread-safe.
+zx_status_t trace_engine_start(trace_start_mode_t mode);
+
+// Asynchronously stops the trace engine.
+//
+// The trace handler's |trace_stopped()| method will be invoked asynchronously
+// when the trace engine transitions to the |TRACE_STOPPED| state.
+// Does nothing if tracing has already stopped.
+//
+// |disposition| is |ZX_OK| if tracing is being stopped normally, otherwise indicates
+// that tracing is being aborted due to an error.
+//
+// This function is thread-safe.
+void trace_engine_stop(zx_status_t disposition);
+
+// Asynchronously terminates the trace engine.
+//
+// This must be called before tracing is initialized again.
+//
+// The trace handler's |trace_terminated()| method will be invoked asynchronously,
+// after the trace engine transitions to the |TRACE_STOPPED| state if not already
+// stopped.
+// This may be called whether tracing is currenting started or not.
+// Does nothing if tracing has already terminated.
+//
+// If tracing is not already stopped the disposition is set to |ZX_OK|.
+// If a different disposition is desired, call |trace_engine_stop()| first.
+//
+// This function is thread-safe.
+void trace_engine_terminate();
+
+// Asynchronously notifies the engine that buffers up to |wrapped_count|
+// have been saved.
+//
+// Returns |ZX_OK| if the current state is |TRACE_STARTED| or |TRACE_STOPPING|.
+// Returns |ZX_ERR_BAD_STATE| if current state is |TRACE_STOPPED|.
+//
+// This function is thread-safe.
+zx_status_t trace_engine_mark_buffer_saved(uint32_t wrapped_count, uint64_t durable_data_end);
+
+__END_CDECLS
+
+#endif // ZIRCON_SYSTEM_ULIB_LIB_TRACE_ENGINE_HANDLER_H_
diff --git a/third_party/fuchsia-sdk/pkg/trace-engine/include/lib/trace-engine/instrumentation.h b/third_party/fuchsia-sdk/pkg/trace-engine/include/lib/trace-engine/instrumentation.h
new file mode 100644
index 0000000..e3524c6
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/trace-engine/include/lib/trace-engine/instrumentation.h
@@ -0,0 +1,364 @@
+// Copyright 2017 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.
+
+//
+// The ABI-stable entry points used by trace instrumentation libraries.
+//
+// Functions used by process-wide trace instrumentation to query the state
+// of the trace engine and acquire the engine's trace context.
+//
+// The engine's trace context is initialized when the trace engine is started
+// and is destroyed when the trace engine completely stops after all references
+// have been released.
+//
+// Acquiring a reference to the engine's trace context is optimized for speed
+// to be fail-fast and lock-free. This helps to ensure that trace
+// instrumentation has negligible performance impact when tracing is disabled
+// (on the order of nanoseconds) and only a small impact when tracing is enabled
+// (on the order of tens to hundreds of nanoseconds depending on the complexity
+// of the trace records being written).
+//
+// Client code shouldn't be using these APIs directly.
+// See <trace/event.h> for instrumentation macros.
+//
+
+#ifndef ZIRCON_SYSTEM_ULIB_LIB_TRACE_ENGINE_INSTRUMENTATION_H_
+#define ZIRCON_SYSTEM_ULIB_LIB_TRACE_ENGINE_INSTRUMENTATION_H_
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <zircon/compiler.h>
+
+#include <lib/trace-engine/context.h>
+
+__BEGIN_CDECLS
+
+// Returns a new unique 64-bit unsigned integer (within this process).
+// Each invocation returns a new unique non-zero value.
+//
+// Useful for generating unique correlation ids for async and flow events.
+//
+// This function is thread-safe and lock-free.
+uint64_t trace_generate_nonce(void);
+
+// Describes the state of the trace engine.
+typedef enum {
+ // Trace instrumentation is inactive.
+ // Any data attempted to be written will be discarded.
+ // This enum doesn't distinguish between "stopped" and "terminated".
+ TRACE_STOPPED = 0,
+ // Trace instrumentation is active.
+ TRACE_STARTED = 1,
+ // Trace instrumentation is active but is in the process of shutting down.
+ // Tracing will stop once all references to the trace buffer have been released.
+ TRACE_STOPPING = 2,
+} trace_state_t;
+
+// Gets the current state of the trace engine.
+//
+// This function is thread-safe.
+trace_state_t trace_state(void);
+
+// Returns true if tracing is enabled (started or stopping but not stopped).
+//
+// This function is thread-safe and lock-free.
+static inline bool trace_is_enabled(void) { return trace_state() != TRACE_STOPPED; }
+
+// Returns true if tracing of the specified category has been enabled (which
+// implies that |trace_is_enabled()| is also true).
+//
+// Use |trace_acquire_context_for_category()| if you intend to immediately
+// write a record into the trace buffer after checking the category.
+//
+// |category_literal| must be a null-terminated static string constant.
+//
+// This function is thread-safe.
+bool trace_is_category_enabled(const char* category_literal);
+
+// Acquires a reference to the trace engine's context.
+// Must be balanced by a call to |trace_release_context()| when the result is non-NULL.
+//
+// This function is optimized to return quickly when tracing is not enabled.
+//
+// Trace engine shutdown is deferred until all references to the trace context
+// have been released, therefore it is important for clients to promptly
+// release their reference to the trace context once they have finished
+// writing records into the trace buffer.
+// It is also important to release the context promptly to maintain proper
+// operation in streaming mode: The buffer can't be saved until all writers
+// have released their context.
+//
+// Returns a valid trace context if tracing is enabled.
+// Returns NULL otherwise.
+//
+// This function is thread-safe, fail-fast, and lock-free.
+trace_context_t* trace_acquire_context(void);
+
+// Acquires a reference to the trace engine's context, only if the specified
+// category is enabled. Must be balanced by a call to |trace_release_context()|
+// when the result is non-NULL.
+//
+// This function is optimized to return quickly when tracing is not enabled.
+//
+// Trace engine shutdown is deferred until all references to the trace context
+// have been released, therefore it is important for clients to promptly
+// release their reference to the trace context once they have finished
+// writing records into the trace buffer.
+// It is also important to release the context promptly to maintain proper
+// operation in streaming mode: The buffer can't be saved until all writers
+// have released their context.
+//
+// This function is equivalent to calling |trace_acquire_context()| to acquire
+// the engine's context, then calling |trace_context_register_category_literal()|
+// to check whether the specified category is enabled and register it in the
+// string table. It releases the context and returns NULL if the category
+// is not enabled.
+//
+// |category_literal| must be a null-terminated static string constant.
+// |out_ref| points to where the registered string reference should be returned.
+//
+// Returns a valid trace context if tracing is enabled for the specified category.
+// Returns NULL otherwise.
+//
+// This function is thread-safe and lock-free.
+trace_context_t* trace_acquire_context_for_category(const char* category_literal,
+ trace_string_ref_t* out_ref);
+
+// Opaque type that is used to cache category enabled/disabled state.
+// ["opaque" in the sense that client code must not touch it]
+// The term "site" is used because it's relatively unique and because this type
+// is generally used to record category state at TRACE_<event>() call sites.
+typedef uintptr_t trace_site_state_t;
+typedef struct {
+ // "state" is intentionally non-descript
+ trace_site_state_t state;
+} trace_site_t;
+
+// Same as |trace_acquire_context_for_category()| except includes an extra
+// parameter to allow for caching of the category lookup.
+//
+// |category_literal| must be a null-terminated static string constant.
+// |site_ptr| must point to a variable of static storage duration initialized
+// to zero. A static local variable at the call site of recording a trace
+// event is the normal solution. The caller must not touch the memory pointed
+// to by this value, it is for the sole use of the trace engine.
+// |out_ref| points to where the registered string reference should be returned.
+//
+// Returns a valid trace context if tracing is enabled for the specified category.
+// Returns NULL otherwise.
+//
+// This function is thread-safe and lock-free.
+trace_context_t* trace_acquire_context_for_category_cached(const char* category_literal,
+ trace_site_t* site_ptr,
+ trace_string_ref_t* out_ref);
+
+// Flush the cache built up by calls to
+// |trace_acquire_context_for_category_cached()|.
+//
+// The trace engine maintains this cache, but there is one case where it
+// needs help: When a DSO containing cache state is unloaded; that is the
+// |site_ptr| argument to a call to
+// |trace_acquire_context_for_category_cached()| points into the soon to be
+// unloaded DSO.
+// This is normally not a problem as |dlclose()| is basically a nop.
+// However, should a DSO get physically unloaded then this function must be
+// called before the DSO is unloaded. The actual unloading procedure must be:
+// 1) Stop execution in the DSO.
+// 2) Stop tracing.
+// 3) Call |trace_engine_flush_category_cache()|.
+// 4) Unload DSO.
+// (1,2) can be done in either order.
+//
+// Returns ZX_OK on success.
+// Returns ZX_ERR_BAD_STATE if the engine is not stopped.
+//
+// This function is thread-safe.
+zx_status_t trace_engine_flush_category_cache(void);
+
+// Releases a reference to the trace engine's context.
+// Must balance a prior successful call to |trace_acquire_context()|
+// or |trace_acquire_context_for_category()|.
+//
+// |context| must be a valid trace context reference.
+//
+// This function is thread-safe, never-fail, and lock-free.
+void trace_release_context(trace_context_t* context);
+
+// Acquires a reference to the trace engine's context, for prolonged use.
+// This cannot be used to acquire the context for the purposes of writing to
+// the trace buffer. Instead, this is intended for uses like the ktrace
+// provider where it wishes to hold a copy of the context for the duration of
+// the trace.
+// Must be balanced by a call to |trace_release_prolonged_context()| when the
+// result is non-NULL.
+//
+// This function is optimized to return quickly when tracing is not enabled.
+//
+// Trace engine shutdown is deferred until all references to the trace context
+// have been released, therefore it is important for clients to promptly
+// release their reference to the trace context once they have finished with
+// it.
+//
+// Returns a valid trace context if tracing is enabled.
+// Returns NULL otherwise.
+//
+// This function is thread-safe, fail-fast, and lock-free.
+trace_prolonged_context_t* trace_acquire_prolonged_context(void);
+
+// Releases a reference to the trace engine's prolonged context.
+// Must balance a prior successful call to |trace_acquire_prolonged_context()|.
+//
+// |context| must be a valid trace context reference.
+//
+// This function is thread-safe, never-fail, and lock-free.
+void trace_release_prolonged_context(trace_prolonged_context_t* context);
+
+// Registers an event handle which the trace engine will signal when the
+// trace state or set of enabled categories changes.
+//
+// Trace observers can use this mechanism to activate custom instrumentation
+// mechanisms and write collected information into the trace buffer in response
+// to state changes.
+//
+// The protocol works like this:
+//
+// 1. The trace observer creates an event object (using |zx_event_create()| or
+// equivalent) then calls |trace_register_observer()| to register itself.
+// 2. The trace observer queries the current trace state and set of enabled categories.
+// 3. If tracing is enabled, the trace observer configures itself to collect data
+// and write trace records relevant to the set of enabled categories.
+// 4. When the trace state and/or set of enabled categories changes, the trace engine
+// sets the |ZX_EVENT_SIGNALED| signal bit of each |event| associated with
+// currently registered observers.
+// 5. In response to observing the |ZX_EVENT_SIGNALED| signal, the trace observer
+// first clears the |ZX_EVENT_SIGNALED| bit (using |zx_object_signal()| or equivalent)
+// then adjusts its behavior as in step 2 and 3 above, and then calls
+// trace_notify_observer_updated().
+// 6. When no longer interested in receiving events, the trace observer calls
+// |trace_unregister_observer()| to unregister itself then closes the event handle.
+//
+// Returns |ZX_OK| if successful.
+// Returns |ZX_ERR_INVALID_ARGS| if the event was already registered.
+zx_status_t trace_register_observer(zx_handle_t event);
+
+// Unregisters the observer event handle previously registered with
+// |trace_register_observer|.
+//
+// Returns |ZX_OK| if successful.
+// Returns |ZX_ERR_NOT_FOUND| if the event was not previously registered.
+zx_status_t trace_unregister_observer(zx_handle_t event);
+
+// Callback to notify the engine that the observer has finished processing
+// all state changes.
+void trace_notify_observer_updated(zx_handle_t event);
+
+__END_CDECLS
+
+#ifdef __cplusplus
+
+namespace trace {
+
+// Holds and retains ownership of a trace context.
+// Releases the context automatically when destroyed.
+class TraceContext final {
+ public:
+ TraceContext() : context_(nullptr) {}
+
+ TraceContext(trace_context_t* context) : context_(context) {}
+
+ TraceContext(TraceContext&& other) : context_(other.context_) { other.context_ = nullptr; }
+
+ ~TraceContext() { Release(); }
+
+ // Gets the trace context, or null if there is none.
+ trace_context_t* get() const { return context_; }
+
+ // Returns true if the holder contains a valid context.
+ explicit operator bool() const { return context_ != nullptr; }
+
+ // Acquires a reference to the trace engine's context.
+ static TraceContext Acquire() { return TraceContext(trace_acquire_context()); }
+
+ // Acquires a reference to the trace engine's context, only if the specified
+ // category is enabled.
+ static TraceContext AcquireForCategory(const char* category_literal,
+ trace_string_ref_t* out_ref) {
+ return TraceContext(trace_acquire_context_for_category(category_literal, out_ref));
+ }
+
+ // Releases the trace context.
+ void Release() {
+ if (context_) {
+ trace_release_context(context_);
+ context_ = nullptr;
+ }
+ }
+
+ TraceContext& operator=(TraceContext&& other) {
+ Release();
+ context_ = other.context_;
+ other.context_ = nullptr;
+ return *this;
+ }
+
+ private:
+ trace_context_t* context_;
+
+ TraceContext(const TraceContext&) = delete;
+ TraceContext& operator=(const TraceContext&) = delete;
+};
+
+// Holds and retains ownership of a prolonged trace context.
+// Releases the context automatically when destroyed.
+class TraceProlongedContext final {
+ public:
+ TraceProlongedContext() : context_(nullptr) {}
+
+ TraceProlongedContext(trace_prolonged_context_t* context) : context_(context) {}
+
+ TraceProlongedContext(TraceProlongedContext&& other) : context_(other.context_) {
+ other.context_ = nullptr;
+ }
+
+ ~TraceProlongedContext() { Release(); }
+
+ // Gets the trace context, or null if there is none.
+ trace_prolonged_context_t* get() const { return context_; }
+
+ // Returns true if the holder contains a valid context.
+ explicit operator bool() const { return context_ != nullptr; }
+
+ // Acquires a reference to the trace engine's context.
+ static TraceProlongedContext Acquire() {
+ return TraceProlongedContext(trace_acquire_prolonged_context());
+ }
+
+ // Releases the trace context.
+ void Release() {
+ if (context_) {
+ trace_release_prolonged_context(context_);
+ context_ = nullptr;
+ }
+ }
+
+ TraceProlongedContext& operator=(TraceProlongedContext&& other) {
+ Release();
+ context_ = other.context_;
+ other.context_ = nullptr;
+ return *this;
+ }
+
+ private:
+ trace_prolonged_context_t* context_;
+
+ TraceProlongedContext(const TraceProlongedContext&) = delete;
+ TraceProlongedContext& operator=(const TraceProlongedContext&) = delete;
+};
+
+} // namespace trace
+
+#endif // __cplusplus
+
+#endif // ZIRCON_SYSTEM_ULIB_LIB_TRACE_ENGINE_INSTRUMENTATION_H_
diff --git a/third_party/fuchsia-sdk/pkg/trace-engine/include/lib/trace-engine/types.h b/third_party/fuchsia-sdk/pkg/trace-engine/include/lib/trace-engine/types.h
new file mode 100644
index 0000000..6c2e721
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/trace-engine/include/lib/trace-engine/types.h
@@ -0,0 +1,444 @@
+// Copyright 2017 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.
+
+//
+// Types, constants, and inline functions used to encode and decode trace records.
+// This header is used by C and C++ code. For simple support of all choices of
+// C/C++ and -O0/-On the inline functions are "static inline".
+//
+
+#ifndef ZIRCON_SYSTEM_ULIB_LIB_TRACE_ENGINE_TYPES_H_
+#define ZIRCON_SYSTEM_ULIB_LIB_TRACE_ENGINE_TYPES_H_
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <zircon/assert.h>
+#include <zircon/compiler.h>
+#include <zircon/syscalls/object.h>
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+// Timebase recorded into trace files, as returned by zx_ticks_get().
+typedef uint64_t trace_ticks_t;
+
+// The ids used to correlate related counters, asynchronous operations, flows, and virtual threads.
+typedef uint64_t trace_counter_id_t;
+typedef uint64_t trace_async_id_t;
+typedef uint64_t trace_flow_id_t;
+typedef uint64_t trace_vthread_id_t;
+
+// Specifies the scope of instant events.
+typedef enum {
+ // The event is only relevant to the thread it occurred on.
+ TRACE_SCOPE_THREAD = 0,
+ // The event is only relevant to the process in which it occurred.
+ TRACE_SCOPE_PROCESS = 1,
+ // The event is globally relevant.
+ TRACE_SCOPE_GLOBAL = 2,
+} trace_scope_t;
+
+// Thread states used to describe context switches.
+// Use the |ZX_THREAD_STATE_XXX| values defined in <zircon/syscalls/object.h>.
+typedef uint32_t trace_thread_state_t;
+
+// Identifies a particular CPU in a context switch trace record.
+typedef uint32_t trace_cpu_number_t;
+
+// Contains a thread's priority in a context switch trace record.
+typedef uint32_t trace_thread_priority_t;
+
+// Represents an index into the string table.
+typedef uint32_t trace_string_index_t;
+
+// Represents the encoded form of string references.
+typedef uint32_t trace_encoded_string_ref_t;
+#define TRACE_ENCODED_STRING_REF_EMPTY ((trace_encoded_string_ref_t)0u)
+#define TRACE_ENCODED_STRING_REF_INLINE_FLAG ((trace_encoded_string_ref_t)0x8000u)
+#define TRACE_ENCODED_STRING_REF_LENGTH_MASK ((trace_encoded_string_ref_t)0x7fffu)
+#define TRACE_ENCODED_STRING_REF_MAX_LENGTH ((trace_encoded_string_ref_t)32000)
+#define TRACE_ENCODED_STRING_REF_MIN_INDEX ((trace_encoded_string_ref_t)0x1u)
+#define TRACE_ENCODED_STRING_REF_MAX_INDEX ((trace_encoded_string_ref_t)0x7fffu)
+
+// Represents an index into the thread table.
+typedef uint32_t trace_thread_index_t;
+
+// Represents the encoded form of thread references.
+typedef uint32_t trace_encoded_thread_ref_t;
+#define TRACE_ENCODED_THREAD_REF_INLINE ((trace_encoded_thread_ref_t)0u)
+#define TRACE_ENCODED_THREAD_REF_MIN_INDEX ((trace_encoded_thread_ref_t)0x01)
+#define TRACE_ENCODED_THREAD_REF_MAX_INDEX ((trace_encoded_thread_ref_t)0xff)
+
+// A string reference which is either encoded inline or indirectly by string table index.
+typedef struct trace_string_ref {
+ trace_encoded_string_ref_t encoded_value;
+ const char* inline_string; // only non-null for inline strings
+} trace_string_ref_t;
+
+// Makes true if the string ref's content is empty.
+static inline bool trace_is_empty_string_ref(const trace_string_ref_t* string_ref) {
+ return string_ref->encoded_value == TRACE_ENCODED_STRING_REF_EMPTY;
+}
+
+// Returns true if the string ref's content is stored inline (rather than empty or indexed).
+static inline bool trace_is_inline_string_ref(const trace_string_ref_t* string_ref) {
+ return string_ref->encoded_value & TRACE_ENCODED_STRING_REF_INLINE_FLAG;
+}
+
+// Returns true if the string ref's content is stored as an index into the string table.
+static inline bool trace_is_indexed_string_ref(const trace_string_ref_t* string_ref) {
+ return string_ref->encoded_value >= TRACE_ENCODED_STRING_REF_MIN_INDEX &&
+ string_ref->encoded_value <= TRACE_ENCODED_STRING_REF_MAX_INDEX;
+}
+
+// Returns the length of an inline string.
+// Only valid for inline strings.
+static inline size_t trace_inline_string_ref_length(const trace_string_ref_t* string_ref) {
+ return string_ref->encoded_value & TRACE_ENCODED_STRING_REF_LENGTH_MASK;
+}
+
+// Makes an empty string ref.
+static inline trace_string_ref_t trace_make_empty_string_ref(void) {
+ trace_string_ref_t ref = {.encoded_value = TRACE_ENCODED_STRING_REF_EMPTY, .inline_string = NULL};
+ return ref;
+}
+
+// Makes an inline or empty string ref from a string with given size.
+// The |string| does not need to be null-terminated because its length is provided.
+// The |string| must not be null if length is non-zero.
+// The |string| is truncated if longer than |TRACE_ENCODED_STRING_REF_MAX_LENGTH|.
+static inline trace_string_ref_t trace_make_inline_string_ref(const char* string, size_t length) {
+ if (!length)
+ return trace_make_empty_string_ref();
+
+ ZX_DEBUG_ASSERT(string != NULL);
+ if (length > TRACE_ENCODED_STRING_REF_MAX_LENGTH)
+ length = TRACE_ENCODED_STRING_REF_MAX_LENGTH;
+ trace_string_ref_t ref = {
+ .encoded_value = TRACE_ENCODED_STRING_REF_INLINE_FLAG | (trace_encoded_string_ref_t)length,
+ .inline_string = string};
+ return ref;
+}
+
+// Makes an inline or empty string ref from a null-terminated string.
+// The |string| is truncated if longer than |TRACE_ENCODED_STRING_REF_MAX_LENGTH|.
+static inline trace_string_ref_t trace_make_inline_c_string_ref(const char* string) {
+ return trace_make_inline_string_ref(string, string ? strlen(string) : 0u);
+}
+
+// Makes an indexed string ref.
+// The |index| must be >= |TRACE_ENCODED_STRING_REF_MIN_INDEX|
+// and <= |TRACE_ENCODED_STRING_REF_MAX_INDEX|.
+static inline trace_string_ref_t trace_make_indexed_string_ref(trace_string_index_t index) {
+ ZX_DEBUG_ASSERT(index >= TRACE_ENCODED_STRING_REF_MIN_INDEX &&
+ index <= TRACE_ENCODED_STRING_REF_MAX_INDEX);
+ trace_string_ref_t ref = {.encoded_value = index, .inline_string = NULL};
+ return ref;
+}
+
+// A thread reference which is either encoded inline or indirectly by thread table index.
+typedef struct trace_thread_ref {
+ trace_encoded_thread_ref_t encoded_value;
+ zx_koid_t inline_process_koid;
+ zx_koid_t inline_thread_koid;
+} trace_thread_ref_t;
+
+// Returns true if the thread ref's value is unknown.
+static inline bool trace_is_unknown_thread_ref(const trace_thread_ref_t* thread_ref) {
+ return thread_ref->encoded_value == TRACE_ENCODED_THREAD_REF_INLINE &&
+ thread_ref->inline_process_koid == ZX_KOID_INVALID &&
+ thread_ref->inline_thread_koid == ZX_KOID_INVALID;
+}
+
+// Returns true if the thread ref's content is stored as an index into the thread table.
+static inline bool trace_is_indexed_thread_ref(const trace_thread_ref_t* thread_ref) {
+ return thread_ref->encoded_value >= TRACE_ENCODED_THREAD_REF_MIN_INDEX &&
+ thread_ref->encoded_value <= TRACE_ENCODED_THREAD_REF_MAX_INDEX;
+}
+
+// Returns true if the thread ref's value is stored inline (rather than unknown or indexed).
+static inline bool trace_is_inline_thread_ref(const trace_thread_ref_t* thread_ref) {
+ return thread_ref->encoded_value == TRACE_ENCODED_THREAD_REF_INLINE &&
+ (thread_ref->inline_process_koid != ZX_KOID_INVALID ||
+ thread_ref->inline_thread_koid != ZX_KOID_INVALID);
+}
+
+// Makes a thread ref representing an unknown thread.
+// TODO(ZX-1030): Reserve thread ref index 0 for unknown threads,
+// use thread ref index 255 for inline threads.
+static inline trace_thread_ref_t trace_make_unknown_thread_ref(void) {
+ trace_thread_ref_t ref = {.encoded_value = TRACE_ENCODED_THREAD_REF_INLINE,
+ .inline_process_koid = ZX_KOID_INVALID,
+ .inline_thread_koid = ZX_KOID_INVALID};
+ return ref;
+}
+
+// Makes a thread ref with an inline value.
+// The process and thread koids must not both be invalid.
+static inline trace_thread_ref_t trace_make_inline_thread_ref(zx_koid_t process_koid,
+ zx_koid_t thread_koid) {
+ ZX_DEBUG_ASSERT(process_koid != ZX_KOID_INVALID || thread_koid != ZX_KOID_INVALID);
+ trace_thread_ref_t ref = {.encoded_value = TRACE_ENCODED_THREAD_REF_INLINE,
+ .inline_process_koid = process_koid,
+ .inline_thread_koid = thread_koid};
+ return ref;
+}
+
+// Makes an indexed thread ref.
+// The index must be >= |TRACE_ENCODED_THREAD_REF_MIN_INDEX|
+// and <= |TRACE_ENCODED_THREAD_REF_MAX_INDEX|.
+static inline trace_thread_ref_t trace_make_indexed_thread_ref(trace_thread_index_t index) {
+ ZX_DEBUG_ASSERT(index >= TRACE_ENCODED_THREAD_REF_MIN_INDEX &&
+ index <= TRACE_ENCODED_THREAD_REF_MAX_INDEX);
+ trace_thread_ref_t ref = {.encoded_value = (trace_encoded_thread_ref_t)index,
+ .inline_process_koid = ZX_KOID_INVALID,
+ .inline_thread_koid = ZX_KOID_INVALID};
+ return ref;
+}
+
+// The maximum length of a trace record that is allowed inline in the
+// trace buffer. The limit is currently set to 256KB.
+#define TRACE_ENCODED_INLINE_LARGE_RECORD_MAX_SIZE ((size_t)(1ull << 18))
+
+typedef enum {
+ TRACE_BLOB_FORMAT_EVENT = 0,
+ TRACE_BLOB_FORMAT_ATTACHMENT = 1,
+} trace_blob_format_t;
+
+// Enumerates all known argument types.
+typedef enum {
+ TRACE_ARG_NULL = 0,
+ TRACE_ARG_INT32 = 1,
+ TRACE_ARG_UINT32 = 2,
+ TRACE_ARG_INT64 = 3,
+ TRACE_ARG_UINT64 = 4,
+ TRACE_ARG_DOUBLE = 5,
+ TRACE_ARG_STRING = 6,
+ TRACE_ARG_POINTER = 7,
+ TRACE_ARG_KOID = 8,
+ TRACE_ARG_BOOL = 9,
+} trace_arg_type_t;
+
+// A typed argument value.
+typedef struct {
+ trace_arg_type_t type;
+ union {
+ int32_t int32_value;
+ uint32_t uint32_value;
+ int64_t int64_value;
+ uint64_t uint64_value;
+ double double_value;
+ trace_string_ref_t string_value_ref;
+ uintptr_t pointer_value;
+ zx_koid_t koid_value;
+ bool bool_value;
+ uintptr_t reserved_for_future_expansion[2];
+ };
+} trace_arg_value_t;
+
+// Makes a null argument value.
+static inline trace_arg_value_t trace_make_null_arg_value(void) {
+ trace_arg_value_t arg_value = {TRACE_ARG_NULL, {}};
+ return arg_value;
+}
+
+// Makes a signed 32-bit integer argument value.
+static inline trace_arg_value_t trace_make_int32_arg_value(int32_t value) {
+ trace_arg_value_t arg_value = {TRACE_ARG_INT32, {.int32_value = value}};
+ return arg_value;
+}
+
+// Makes an unsigned 32-bit integer argument value.
+static inline trace_arg_value_t trace_make_uint32_arg_value(uint32_t value) {
+ trace_arg_value_t arg_value = {TRACE_ARG_UINT32, {.uint32_value = value}};
+ return arg_value;
+}
+
+// Makes a signed 64-bit integer argument value.
+static inline trace_arg_value_t trace_make_int64_arg_value(int64_t value) {
+ trace_arg_value_t arg_value = {TRACE_ARG_INT64, {.int64_value = value}};
+ return arg_value;
+}
+
+// Makes an unsigned 64-bit integer argument value.
+static inline trace_arg_value_t trace_make_uint64_arg_value(uint64_t value) {
+ trace_arg_value_t arg_value = {TRACE_ARG_UINT64, {.uint64_value = value}};
+ return arg_value;
+}
+
+// Makes a double-precision floating point argument value.
+static inline trace_arg_value_t trace_make_double_arg_value(double value) {
+ trace_arg_value_t arg_value = {TRACE_ARG_DOUBLE, {.double_value = value}};
+ return arg_value;
+}
+
+// Makes a string argument value.
+static inline trace_arg_value_t trace_make_string_arg_value(trace_string_ref_t value_ref) {
+ trace_arg_value_t arg_value = {TRACE_ARG_STRING, {.string_value_ref = value_ref}};
+ return arg_value;
+}
+
+// Makes a pointer argument value.
+static inline trace_arg_value_t trace_make_pointer_arg_value(uintptr_t value) {
+ trace_arg_value_t arg_value = {TRACE_ARG_POINTER, {.pointer_value = value}};
+ return arg_value;
+}
+
+// Makes a koid argument value.
+static inline trace_arg_value_t trace_make_koid_arg_value(zx_koid_t value) {
+ trace_arg_value_t arg_value = {TRACE_ARG_KOID, {.koid_value = value}};
+ return arg_value;
+}
+
+// Makes a boolean argument value.
+static inline trace_arg_value_t trace_make_bool_arg_value(bool value) {
+ trace_arg_value_t arg_value = {TRACE_ARG_BOOL, {.bool_value = value}};
+ return arg_value;
+}
+
+// A named argument and value.
+// Often packed into an array to form an argument list when writing records.
+typedef struct {
+ trace_string_ref_t name_ref;
+ trace_arg_value_t value;
+} trace_arg_t;
+
+// Makes an argument with name and value.
+static inline trace_arg_t trace_make_arg(trace_string_ref_t name_ref, trace_arg_value_t value) {
+ trace_arg_t arg = {.name_ref = name_ref, .value = value};
+ return arg;
+}
+
+// The trace format specified maximum number of args for a record.
+#define TRACE_MAX_ARGS ((size_t)15u)
+
+// BlobType enumerates all known trace blob types.
+typedef enum {
+ TRACE_BLOB_TYPE_DATA = 1,
+ TRACE_BLOB_TYPE_LAST_BRANCH = 2,
+} trace_blob_type_t;
+
+// The maximum size of a blob.
+// This is slightly less than the actual maximum ((= 0xfff * 8) - header size)
+// to allow room for reasonably sized blob names should they get inlined.
+#define TRACE_MAX_BLOB_SIZE ((size_t)32000u)
+
+// The buffering mode.
+typedef enum {
+ // Keep filling the trace buffer until it is full and then stop tracing.
+ TRACE_BUFFERING_MODE_ONESHOT = 0,
+ // When the buffer fills start overwriting records from the beginning.
+ TRACE_BUFFERING_MODE_CIRCULAR = 1,
+ // When the buffer reaches a critical point notify the trace manager to
+ // save the trace thus far. Essentially this is an implementation of
+ // double buffering, though the underlying details are unspecified.
+ TRACE_BUFFERING_MODE_STREAMING = 2,
+} trace_buffering_mode_t;
+
+__END_CDECLS
+
+#ifdef __cplusplus
+
+namespace trace {
+
+// Enumerates all known record types.
+enum class RecordType {
+ kMetadata = 0,
+ kInitialization = 1,
+ kString = 2,
+ kThread = 3,
+ kEvent = 4,
+ kBlob = 5,
+ kKernelObject = 7,
+ kContextSwitch = 8,
+ kLog = 9,
+
+ // The kLargeRecord uses a 32-bit size field.
+ kLargeRecord = 15,
+};
+
+enum class LargeRecordType {
+ kBlob = 0,
+};
+
+// MetadataType enumerates all known trace metadata types.
+enum class MetadataType {
+ kProviderInfo = 1,
+ kProviderSection = 2,
+ kProviderEvent = 3,
+ kTraceInfo = 4,
+};
+
+// Enumerates all provider events.
+enum class ProviderEventType {
+ kBufferOverflow = 0,
+};
+
+// Enumerates all known trace info types.
+enum class TraceInfoType {
+ kMagicNumber = 0,
+};
+
+// The four byte value present in a magic number record.
+constexpr uint32_t kMagicValue = 0x16547846;
+
+// Enumerates all known argument types.
+enum class ArgumentType {
+ kNull = TRACE_ARG_NULL,
+ kInt32 = TRACE_ARG_INT32,
+ kUint32 = TRACE_ARG_UINT32,
+ kInt64 = TRACE_ARG_INT64,
+ kUint64 = TRACE_ARG_UINT64,
+ kDouble = TRACE_ARG_DOUBLE,
+ kString = TRACE_ARG_STRING,
+ kPointer = TRACE_ARG_POINTER,
+ kKoid = TRACE_ARG_KOID,
+ kBool = TRACE_ARG_BOOL,
+};
+
+// EventType enumerates all known trace event types.
+enum class EventType {
+ kInstant = 0,
+ kCounter = 1,
+ kDurationBegin = 2,
+ kDurationEnd = 3,
+ kDurationComplete = 4,
+ kAsyncBegin = 5,
+ kAsyncInstant = 6,
+ kAsyncEnd = 7,
+ kFlowBegin = 8,
+ kFlowStep = 9,
+ kFlowEnd = 10,
+};
+
+// Specifies the scope of instant events.
+enum class EventScope {
+ kThread = TRACE_SCOPE_THREAD,
+ kProcess = TRACE_SCOPE_PROCESS,
+ kGlobal = TRACE_SCOPE_GLOBAL,
+};
+
+// Trace provider id in a trace session.
+using ProviderId = uint32_t;
+
+// Thread states used to describe context switches.
+enum class ThreadState {
+ kNew = ZX_THREAD_STATE_NEW,
+ kRunning = ZX_THREAD_STATE_RUNNING,
+ kSuspended = ZX_THREAD_STATE_SUSPENDED,
+ kBlocked = ZX_THREAD_STATE_BLOCKED,
+ kDying = ZX_THREAD_STATE_DYING,
+ kDead = ZX_THREAD_STATE_DEAD,
+};
+
+using ArgumentHeader = uint64_t;
+using RecordHeader = uint64_t;
+
+} // namespace trace
+
+#endif // __cplusplus
+
+#endif // ZIRCON_SYSTEM_ULIB_LIB_TRACE_ENGINE_TYPES_H_
diff --git a/third_party/fuchsia-sdk/pkg/trace-engine/meta.json b/third_party/fuchsia-sdk/pkg/trace-engine/meta.json
new file mode 100644
index 0000000..573cb4b
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/trace-engine/meta.json
@@ -0,0 +1,31 @@
+{
+ "binaries": {
+ "arm64": {
+ "debug": ".build-id/47/c225b4c387e374.debug",
+ "dist": "arch/arm64/dist/libtrace-engine.so",
+ "dist_path": "lib/libtrace-engine.so",
+ "link": "arch/arm64/lib/libtrace-engine.so"
+ },
+ "x64": {
+ "debug": ".build-id/88/90c23f2347327f.debug",
+ "dist": "arch/x64/dist/libtrace-engine.so",
+ "dist_path": "lib/libtrace-engine.so",
+ "link": "arch/x64/lib/libtrace-engine.so"
+ }
+ },
+ "deps": [
+ "async"
+ ],
+ "format": "shared",
+ "headers": [
+ "pkg/trace-engine/include/lib/trace-engine/context.h",
+ "pkg/trace-engine/include/lib/trace-engine/fields.h",
+ "pkg/trace-engine/include/lib/trace-engine/handler.h",
+ "pkg/trace-engine/include/lib/trace-engine/instrumentation.h",
+ "pkg/trace-engine/include/lib/trace-engine/types.h"
+ ],
+ "include_dir": "pkg/trace-engine/include",
+ "name": "trace-engine",
+ "root": "pkg/trace-engine",
+ "type": "cc_prebuilt_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/trace-provider-so/BUILD.gn b/third_party/fuchsia-sdk/pkg/trace-provider-so/BUILD.gn
new file mode 100644
index 0000000..937bd97
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/trace-provider-so/BUILD.gn
@@ -0,0 +1,31 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("trace-provider-so") {
+ shared_libs = [ "trace-provider-so" ]
+
+ deps = [
+ "../async",
+ "../trace-engine",
+ "../zx",
+ ]
+ sources = [
+ "include/lib/trace-provider/fdio_connect.h",
+ "include/lib/trace-provider/handler.h",
+ "include/lib/trace-provider/provider.h",
+ ]
+ include_dirs = [ "include" ]
+}
+
+group("all"){
+ deps = [
+ ":trace-provider-so",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/trace-provider-so/include/lib/trace-provider/fdio_connect.h b/third_party/fuchsia-sdk/pkg/trace-provider-so/include/lib/trace-provider/fdio_connect.h
new file mode 100644
index 0000000..0d218cb
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/trace-provider-so/include/lib/trace-provider/fdio_connect.h
@@ -0,0 +1,18 @@
+// Copyright 2018 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.
+
+// A helper library for connecting to the trace manager via fdio.
+
+#ifndef ZIRCON_SYSTEM_ULIB_LIB_TRACE_PROVIDER_FDIO_CONNECT_H_
+#define ZIRCON_SYSTEM_ULIB_LIB_TRACE_PROVIDER_FDIO_CONNECT_H_
+
+#include <zircon/types.h>
+
+__BEGIN_CDECLS
+
+zx_status_t trace_provider_connect_with_fdio(zx_handle_t* out_client);
+
+__END_CDECLS
+
+#endif // ZIRCON_SYSTEM_ULIB_LIB_TRACE_PROVIDER_FDIO_CONNECT_H_
diff --git a/third_party/fuchsia-sdk/pkg/trace-provider-so/include/lib/trace-provider/handler.h b/third_party/fuchsia-sdk/pkg/trace-provider-so/include/lib/trace-provider/handler.h
new file mode 100644
index 0000000..52c96c6
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/trace-provider-so/include/lib/trace-provider/handler.h
@@ -0,0 +1,85 @@
+// Copyright 2017 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.
+
+//
+// Trace handlers manage the configuration, lifecycle, and external communication
+// of the trace engine.
+//
+// See <trace-engine/handler.h> for the C API and more detailed documentation.
+//
+
+#ifndef ZIRCON_SYSTEM_ULIB_LIB_TRACE_PROVIDER_HANDLER_H_
+#define ZIRCON_SYSTEM_ULIB_LIB_TRACE_PROVIDER_HANDLER_H_
+
+#include <lib/trace-engine/handler.h>
+
+#ifdef __cplusplus
+
+namespace trace {
+
+// Implements |trace_handler_t|.
+// Make sure the trace has fully stopped before destroying the handler object.
+class TraceHandler : public trace_handler_t {
+ public:
+ TraceHandler();
+ virtual ~TraceHandler();
+
+ // Called by the trace engine to ask whether the specified category is enabled.
+ //
+ // This method may be called frequently so it must be efficiently implemented.
+ // Clients may cache the results while a trace is running; dynamic changes
+ // to the enabled categories may go unnoticed until the next trace.
+ //
+ // |category| is the name of the category.
+ //
+ // Called by instrumentation on any thread. Must be thread-safe.
+ virtual bool IsCategoryEnabled(const char* category) { return true; }
+
+ // Called by the trace engine to indicate it has completed startup.
+ virtual void TraceStarted() {}
+
+ // Called by the trace engine when tracing has stopped.
+ //
+ // The trace collection status is |ZX_OK| if trace collection was successful.
+ // An error indicates that the trace data may be inaccurate or incomplete.
+ //
+ // |disposition| is |ZX_OK| if tracing stopped normally, otherwise indicates
+ // that tracing was aborted due to an error. If records were dropped (due
+ // to the trace buffer being full) then |disposition| is |ZX_ERR_NO_MEMORY|.
+ //
+ // Called on an asynchronous dispatch thread.
+ virtual void TraceStopped(zx_status_t disposition) {}
+
+ // Called by the trace engine when tracing has terminated.
+ virtual void TraceTerminated() {}
+
+ // Called by the trace engine in streaming mode to indicate a buffer is full.
+ // This is only used in streaming mode where double-buffering is used.
+ // |wrapped_count| is the number of times writing to the buffer has
+ // switched from one buffer to the other.
+ // |durable_buffer_offset| is the offset into the durable buffer when the
+ // buffer filled. It is provided so that TraceManager can save the data
+ // thus far written to the durable buffer.
+ virtual void NotifyBufferFull(uint32_t wrapped_count, uint64_t durable_buffer_offset) {}
+
+ // Called by the trace engine to send an alert.
+ virtual void SendAlert(const char* alert_name) {}
+
+ private:
+ static bool CallIsCategoryEnabled(trace_handler_t* handler, const char* category);
+ static void CallTraceStarted(trace_handler_t* handler);
+ static void CallTraceStopped(trace_handler_t* handler, zx_status_t disposition);
+ static void CallTraceTerminated(trace_handler_t* handler);
+ static void CallNotifyBufferFull(trace_handler_t* handler, uint32_t wrapped_count,
+ uint64_t durable_buffer_offset);
+ static void CallSendAlert(trace_handler_t* handler, const char* alert_name);
+
+ static const trace_handler_ops_t kOps;
+};
+
+} // namespace trace
+
+#endif // __cplusplus
+
+#endif // ZIRCON_SYSTEM_ULIB_LIB_TRACE_PROVIDER_HANDLER_H_
diff --git a/third_party/fuchsia-sdk/pkg/trace-provider-so/include/lib/trace-provider/provider.h b/third_party/fuchsia-sdk/pkg/trace-provider-so/include/lib/trace-provider/provider.h
new file mode 100644
index 0000000..1d28981
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/trace-provider-so/include/lib/trace-provider/provider.h
@@ -0,0 +1,219 @@
+// Copyright 2017 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.
+
+//
+// The API for initializing the trace provider for a process.
+//
+
+#ifndef ZIRCON_SYSTEM_ULIB_LIB_TRACE_PROVIDER_PROVIDER_H_
+#define ZIRCON_SYSTEM_ULIB_LIB_TRACE_PROVIDER_PROVIDER_H_
+
+#include <assert.h>
+#include <zircon/compiler.h>
+#include <zircon/types.h>
+
+#include <lib/async/dispatcher.h>
+
+__BEGIN_CDECLS
+
+// Contents of the provider/manager FIFO.
+// One important function the FIFO serves is to support TraceHandler and
+// TraceProvider having potentially disjoint lifetimes: The trace engine can
+// be running (for however brief a time) after the trace provider goes away,
+// and therefore the FIDL channel can go away while the engine is still
+// running.
+
+// The format of fifo packets for messages passed between the trace manager
+// and trace providers.
+typedef struct trace_provider_packet {
+ // One of TRACE_PROVIDER_*.
+ uint16_t request;
+
+ // Optional data for the request.
+ // The contents depend on the request.
+ // If unused they must be passed as zero.
+ uint16_t data16;
+ uint32_t data32;
+ uint64_t data64;
+} trace_provider_packet_t;
+
+// The protocol version we are using.
+// This is non-zero to catch initialization bugs.
+#define TRACE_PROVIDER_FIFO_PROTOCOL_VERSION 1
+
+// Provider->Manager
+// Zero is reserved to catch initialization bugs.
+
+// Indicate the provider successfully started.
+// |data32| is TRACE_PROVIDER_FIFO_PROTOCOL_VERSION
+// |data16,data64| are unused (must be zero).
+#define TRACE_PROVIDER_STARTED (0x1)
+
+// A buffer is full and needs to be saved (streaming mode only).
+// |data16| is unused (must be zero).
+// |data32| is the "wrapped count", which is a count of the number of times
+// a buffer has filled.
+// |data64| is current offset in the durable buffer
+#define TRACE_PROVIDER_SAVE_BUFFER (0x2)
+
+// Indicate the provider has completely stopped tracing.
+// |data16,data32,data64| are unused (must be zero).
+#define TRACE_PROVIDER_STOPPED (0x3)
+
+// Sends an alert.
+// |data16, data32, data64| contains the alert name, padded with zeros if the name
+// is less than 14 characters.
+#define TRACE_PROVIDER_ALERT (0x4)
+
+// Next Provider->Manager packet = 0x5
+
+// Manager->Provider
+// A buffer has been saved (streaminng mode only).
+// |data32| is the "wrapped count", which is a count of the number of times
+// a buffer has filled.
+// |data16,data64| are unused (must be zero).
+#define TRACE_PROVIDER_BUFFER_SAVED (0x100)
+
+// Next Manager->Provider packet = 0x101
+
+// End fifo packet descriptions.
+
+// Represents a trace provider.
+typedef struct trace_provider trace_provider_t;
+
+// Creates a trace provider associated with the specified async dispatcher
+// and registers it with the tracing system.
+//
+// The trace provider will start and stop the trace engine in response to requests
+// from the tracing system.
+//
+// |to_service| is the channel to use to connect to the trace manager.
+// It is consumed regardless of success/failure.
+//
+// |dispatcher| is the asynchronous dispatcher which the trace provider and trace
+// engine will use for dispatch. This must outlive the trace provider instance,
+// and must be single-threaded.
+//
+// |name| is the name of the trace provider and is used for diagnostic
+// purposes. The maximum supported length is 100 characters.
+//
+// Returns the trace provider, or null if creation failed.
+//
+// TODO(ZX-1036): Currently this connects to the trace manager service.
+// Switch to passively exporting the trace provider via the "hub" through
+// the process's exported directory once that stuff is implemented. We'll
+// probably need to pass some extra parameters to the trace provider then.
+trace_provider_t* trace_provider_create_with_name(zx_handle_t to_service,
+ async_dispatcher_t* dispatcher, const char* name);
+
+// Wrapper around trace_provider_create_with_name for backward compatibility.
+// TODO(DX-422): Update all providers to use create_with_name, then change this
+// to also take a name, then update all providers to call this one, and then
+// delete trace_provider_create_with_name.
+trace_provider_t* trace_provider_create(zx_handle_t to_service, async_dispatcher_t* dispatcher);
+
+// Same as trace_provider_create_with_name except does not return until the
+// provider is registered with the trace manager.
+// On return, if !NULL, |*out_already_started| is true if the trace manager has
+// already started tracing, which is a hint to the provider to wait for the
+// Start() message before continuing if it wishes to not drop trace records
+// before Start() is received.
+trace_provider_t* trace_provider_create_synchronously(zx_handle_t to_service,
+ async_dispatcher_t* dispatcher,
+ const char* name, bool* out_already_started);
+
+// Wrappers on the above functions that use fdio.
+trace_provider_t* trace_provider_create_with_name_fdio(async_dispatcher_t* dispatcher,
+ const char* name);
+trace_provider_t* trace_provider_create_with_fdio(async_dispatcher_t* dispatcher);
+trace_provider_t* trace_provider_create_synchronously_with_fdio(async_dispatcher_t* dispatcher,
+ const char* name,
+ bool* out_already_started);
+
+// Destroys the trace provider.
+void trace_provider_destroy(trace_provider_t* provider);
+
+__END_CDECLS
+
+#ifdef __cplusplus
+
+#include <lib/zx/channel.h>
+
+#include <memory>
+
+namespace trace {
+
+// Convenience RAII wrapper for creating and destroying a trace provider.
+class TraceProvider {
+ public:
+ // Create a trace provider synchronously, and return an indicator of
+ // whether tracing has started already in |*out_already_started|.
+ // Returns a boolean indicating success.
+ // This is done with a factory function because it's more complex than
+ // the basic constructor.
+ static bool CreateSynchronously(zx::channel to_service, async_dispatcher_t* dispatcher,
+ const char* name, std::unique_ptr<TraceProvider>* out_provider,
+ bool* out_already_started) {
+ auto provider = trace_provider_create_synchronously(to_service.release(), dispatcher, name,
+ out_already_started);
+ if (!provider)
+ return false;
+ *out_provider = std::unique_ptr<TraceProvider>(new TraceProvider(provider));
+ return true;
+ }
+
+ // Creates a trace provider.
+ TraceProvider(zx::channel to_service, async_dispatcher_t* dispatcher)
+ : provider_(trace_provider_create(to_service.release(), dispatcher)) {}
+
+ // Creates a trace provider.
+ TraceProvider(zx::channel to_service, async_dispatcher_t* dispatcher, const char* name)
+ : provider_(trace_provider_create_with_name(to_service.release(), dispatcher, name)) {}
+
+ // Destroys a trace provider.
+ ~TraceProvider() {
+ if (provider_)
+ trace_provider_destroy(provider_);
+ }
+
+ // Returns true if the trace provider was created successfully.
+ bool is_valid() const { return provider_ != nullptr; }
+
+ protected:
+ explicit TraceProvider(trace_provider_t* provider) : provider_(provider) {}
+
+ private:
+ trace_provider_t* const provider_;
+};
+
+class TraceProviderWithFdio : public TraceProvider {
+ public:
+ static bool CreateSynchronously(async_dispatcher_t* dispatcher, const char* name,
+ std::unique_ptr<TraceProviderWithFdio>* out_provider,
+ bool* out_already_started) {
+ auto provider =
+ trace_provider_create_synchronously_with_fdio(dispatcher, name, out_already_started);
+ if (!provider)
+ return false;
+ *out_provider = std::unique_ptr<TraceProviderWithFdio>(new TraceProviderWithFdio(provider));
+ return true;
+ }
+
+ // Creates a trace provider.
+ explicit TraceProviderWithFdio(async_dispatcher_t* dispatcher)
+ : TraceProviderWithFdio(trace_provider_create_with_fdio(dispatcher)) {}
+
+ // Creates a trace provider.
+ explicit TraceProviderWithFdio(async_dispatcher_t* dispatcher, const char* name)
+ : TraceProviderWithFdio(trace_provider_create_with_name_fdio(dispatcher, name)) {}
+
+ private:
+ explicit TraceProviderWithFdio(trace_provider_t* provider) : TraceProvider(provider) {}
+};
+
+} // namespace trace
+
+#endif // __cplusplus
+
+#endif // ZIRCON_SYSTEM_ULIB_LIB_TRACE_PROVIDER_PROVIDER_H_
diff --git a/third_party/fuchsia-sdk/pkg/trace-provider-so/meta.json b/third_party/fuchsia-sdk/pkg/trace-provider-so/meta.json
new file mode 100644
index 0000000..69b71b3
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/trace-provider-so/meta.json
@@ -0,0 +1,31 @@
+{
+ "binaries": {
+ "arm64": {
+ "debug": ".build-id/19/dfb7dfc513c781.debug",
+ "dist": "arch/arm64/dist/libtrace-provider-so.so",
+ "dist_path": "lib/libtrace-provider-so.so",
+ "link": "arch/arm64/lib/libtrace-provider-so.so"
+ },
+ "x64": {
+ "debug": ".build-id/55/2eec3497a99775.debug",
+ "dist": "arch/x64/dist/libtrace-provider-so.so",
+ "dist_path": "lib/libtrace-provider-so.so",
+ "link": "arch/x64/lib/libtrace-provider-so.so"
+ }
+ },
+ "deps": [
+ "trace-engine",
+ "async",
+ "zx"
+ ],
+ "format": "shared",
+ "headers": [
+ "pkg/trace-provider-so/include/lib/trace-provider/fdio_connect.h",
+ "pkg/trace-provider-so/include/lib/trace-provider/handler.h",
+ "pkg/trace-provider-so/include/lib/trace-provider/provider.h"
+ ],
+ "include_dir": "pkg/trace-provider-so/include",
+ "name": "trace-provider-so",
+ "root": "pkg/trace-provider-so",
+ "type": "cc_prebuilt_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/trace/BUILD.gn b/third_party/fuchsia-sdk/pkg/trace/BUILD.gn
new file mode 100644
index 0000000..fa7afa0
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/trace/BUILD.gn
@@ -0,0 +1,38 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("trace") {
+ sources = [
+ "event.cc",
+ "observer.cc",
+ "include/lib/trace/event.h",
+ "include/lib/trace/event_args.h",
+ "include/lib/trace/internal/event_args.h",
+ "include/lib/trace/internal/event_common.h",
+ "include/lib/trace/internal/event_internal.h",
+ "include/lib/trace/internal/pairs_internal.h",
+ "include/lib/trace/internal/string_traits.h",
+ "include/lib/trace/observer.h",
+ ]
+ include_dirs = [ "include" ]
+ public_deps = [
+ "../async",
+ "../async-cpp",
+ "../fit",
+ "../trace-engine",
+ "../zx",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":trace",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/trace/event.cc b/third_party/fuchsia-sdk/pkg/trace/event.cc
new file mode 100644
index 0000000..7eb8732
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/trace/event.cc
@@ -0,0 +1,191 @@
+// Copyright 2017 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.
+
+#include <lib/trace/event.h>
+#include <zircon/syscalls.h>
+
+namespace {
+
+struct EventHelper {
+ EventHelper(trace_context_t* context, const char* name_literal) : ticks(zx_ticks_get()) {
+ trace_context_register_current_thread(context, &thread_ref);
+ trace_context_register_string_literal(context, name_literal, &name_ref);
+ }
+
+ trace_ticks_t const ticks;
+ trace_thread_ref_t thread_ref;
+ trace_string_ref_t name_ref;
+};
+
+} // namespace
+
+// Argument names are temporarily stored in |name_ref.inline_string|.
+// Convert them to string references.
+void trace_internal_complete_args(trace_context_t* context, trace_arg_t* args, size_t num_args) {
+ for (size_t i = 0; i < num_args; ++i) {
+ trace_context_register_string_literal(context, args[i].name_ref.inline_string,
+ &args[i].name_ref);
+ }
+}
+
+void trace_internal_write_instant_event_record_and_release_context(
+ trace_context_t* context, const trace_string_ref_t* category_ref, const char* name_literal,
+ trace_scope_t scope, trace_arg_t* args, size_t num_args) {
+ EventHelper helper(context, name_literal);
+ trace_internal_complete_args(context, args, num_args);
+ trace_context_write_instant_event_record(context, helper.ticks, &helper.thread_ref, category_ref,
+ &helper.name_ref, scope, args, num_args);
+ trace_release_context(context);
+}
+
+void trace_internal_write_counter_event_record_and_release_context(
+ trace_context_t* context, const trace_string_ref_t* category_ref, const char* name_literal,
+ trace_counter_id_t counter_id, trace_arg_t* args, size_t num_args) {
+ EventHelper helper(context, name_literal);
+ trace_internal_complete_args(context, args, num_args);
+ trace_context_write_counter_event_record(context, helper.ticks, &helper.thread_ref, category_ref,
+ &helper.name_ref, counter_id, args, num_args);
+ trace_release_context(context);
+}
+
+void trace_internal_write_duration_begin_event_record_and_release_context(
+ trace_context_t* context, const trace_string_ref_t* category_ref, const char* name_literal,
+ trace_arg_t* args, size_t num_args) {
+ EventHelper helper(context, name_literal);
+ trace_internal_complete_args(context, args, num_args);
+ trace_context_write_duration_begin_event_record(context, helper.ticks, &helper.thread_ref,
+ category_ref, &helper.name_ref, args, num_args);
+ trace_release_context(context);
+}
+
+void trace_internal_write_duration_end_event_record_and_release_context(
+ trace_context_t* context, const trace_string_ref_t* category_ref, const char* name_literal,
+ trace_arg_t* args, size_t num_args) {
+ EventHelper helper(context, name_literal);
+ trace_internal_complete_args(context, args, num_args);
+ trace_context_write_duration_end_event_record(context, helper.ticks, &helper.thread_ref,
+ category_ref, &helper.name_ref, args, num_args);
+ trace_release_context(context);
+}
+
+void trace_internal_write_duration_event_record(const trace_internal_duration_scope_t* scope) {
+ trace_string_ref_t category_ref;
+ trace_context_t* context =
+ trace_acquire_context_for_category(scope->category_literal, &category_ref);
+ if (likely(context)) {
+ EventHelper helper(context, scope->name_literal);
+ trace_internal_complete_args(context, scope->args, scope->num_args);
+ trace_context_write_duration_event_record(context, scope->start_time, helper.ticks,
+ &helper.thread_ref, &category_ref, &helper.name_ref,
+ scope->args, scope->num_args);
+ trace_release_context(context);
+ }
+}
+
+void trace_internal_write_async_begin_event_record_and_release_context(
+ trace_context_t* context, const trace_string_ref_t* category_ref, const char* name_literal,
+ trace_async_id_t async_id, trace_arg_t* args, size_t num_args) {
+ EventHelper helper(context, name_literal);
+ trace_internal_complete_args(context, args, num_args);
+ trace_context_write_async_begin_event_record(context, helper.ticks, &helper.thread_ref,
+ category_ref, &helper.name_ref, async_id, args,
+ num_args);
+ trace_release_context(context);
+}
+
+void trace_internal_write_async_instant_event_record_and_release_context(
+ trace_context_t* context, const trace_string_ref_t* category_ref, const char* name_literal,
+ trace_async_id_t async_id, trace_arg_t* args, size_t num_args) {
+ EventHelper helper(context, name_literal);
+ trace_internal_complete_args(context, args, num_args);
+ trace_context_write_async_instant_event_record(context, helper.ticks, &helper.thread_ref,
+ category_ref, &helper.name_ref, async_id, args,
+ num_args);
+ trace_release_context(context);
+}
+
+void trace_internal_write_async_end_event_record_and_release_context(
+ trace_context_t* context, const trace_string_ref_t* category_ref, const char* name_literal,
+ trace_async_id_t async_id, trace_arg_t* args, size_t num_args) {
+ EventHelper helper(context, name_literal);
+ trace_internal_complete_args(context, args, num_args);
+ trace_context_write_async_end_event_record(context, helper.ticks, &helper.thread_ref,
+ category_ref, &helper.name_ref, async_id, args,
+ num_args);
+ trace_release_context(context);
+}
+
+void trace_internal_write_flow_begin_event_record_and_release_context(
+ trace_context_t* context, const trace_string_ref_t* category_ref, const char* name_literal,
+ trace_flow_id_t flow_id, trace_arg_t* args, size_t num_args) {
+ EventHelper helper(context, name_literal);
+ trace_internal_complete_args(context, args, num_args);
+ trace_context_write_flow_begin_event_record(context, helper.ticks, &helper.thread_ref,
+ category_ref, &helper.name_ref, flow_id, args,
+ num_args);
+ trace_release_context(context);
+}
+
+void trace_internal_write_flow_step_event_record_and_release_context(
+ trace_context_t* context, const trace_string_ref_t* category_ref, const char* name_literal,
+ trace_flow_id_t flow_id, trace_arg_t* args, size_t num_args) {
+ EventHelper helper(context, name_literal);
+ trace_internal_complete_args(context, args, num_args);
+ trace_context_write_flow_step_event_record(context, helper.ticks, &helper.thread_ref,
+ category_ref, &helper.name_ref, flow_id, args,
+ num_args);
+ trace_release_context(context);
+}
+
+void trace_internal_write_flow_end_event_record_and_release_context(
+ trace_context_t* context, const trace_string_ref_t* category_ref, const char* name_literal,
+ trace_flow_id_t flow_id, trace_arg_t* args, size_t num_args) {
+ EventHelper helper(context, name_literal);
+ trace_internal_complete_args(context, args, num_args);
+ trace_context_write_flow_end_event_record(context, helper.ticks, &helper.thread_ref, category_ref,
+ &helper.name_ref, flow_id, args, num_args);
+ trace_release_context(context);
+}
+
+void trace_internal_write_blob_event_record_and_release_context(
+ trace_context_t* context, const trace_string_ref_t* category_ref, const char* name_literal,
+ const void* blob, size_t blob_size, trace_arg_t* args, size_t num_args) {
+ EventHelper helper(context, name_literal);
+ trace_internal_complete_args(context, args, num_args);
+ trace_context_write_blob_event_record(context, helper.ticks, &helper.thread_ref, category_ref,
+ &helper.name_ref, blob, blob_size, args, num_args);
+ trace_release_context(context);
+}
+
+void trace_internal_write_blob_attachment_record_and_release_context(
+ trace_context_t* context, const trace_string_ref_t* category_ref, const char* name_literal,
+ const void* blob, size_t blob_size) {
+ trace_string_ref_t name_ref;
+ trace_context_register_string_literal(context, name_literal, &name_ref);
+ trace_context_write_blob_attachment_record(context, category_ref, &name_ref, blob, blob_size);
+ trace_release_context(context);
+}
+
+void trace_internal_write_kernel_object_record_for_handle_and_release_context(
+ trace_context_t* context, zx_handle_t handle, trace_arg_t* args, size_t num_args) {
+ trace_internal_complete_args(context, args, num_args);
+ trace_context_write_kernel_object_record_for_handle(context, handle, args, num_args);
+ trace_release_context(context);
+}
+
+void trace_internal_write_blob_record_and_release_context(trace_context_t* context,
+ trace_blob_type_t type,
+ const char* name_literal,
+ const void* blob, size_t blob_size) {
+ trace_string_ref_t name_ref;
+ trace_context_register_string_literal(context, name_literal, &name_ref);
+ trace_context_write_blob_record(context, type, &name_ref, blob, blob_size);
+ trace_release_context(context);
+}
+
+void trace_internal_send_alert_and_release_context(trace_context_t* context,
+ const char* alert_name) {
+ trace_context_send_alert(context, alert_name);
+ trace_release_context(context);
+}
diff --git a/third_party/fuchsia-sdk/pkg/trace/include/lib/trace/event.h b/third_party/fuchsia-sdk/pkg/trace/include/lib/trace/event.h
new file mode 100644
index 0000000..080c314
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/trace/include/lib/trace/event.h
@@ -0,0 +1,29 @@
+// Copyright 2017 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.
+
+//
+// The API for instrumenting C and C++ programs with trace events.
+//
+// This header defines macros which are used to record trace information during
+// program execution when tracing is enabled. Each trace event macro records
+// an event of a given type together with the current time, a category, name,
+// and named arguments containing additional information about the event.
+//
+// Where indicated, the category and name literal strings must point to
+// null-terminated static string constants whose memory address can be
+// cached by the string table for the lifetime of the trace session.
+//
+// Defining the NTRACE macro completely disables recording of trace events
+// in the compilation unit.
+//
+// For more control over how trace events are written, see <trace-engine/context.h>.
+//
+
+#ifndef ZIRCON_SYSTEM_ULIB_LIB_TRACE_EVENT_H_
+#define ZIRCON_SYSTEM_ULIB_LIB_TRACE_EVENT_H_
+
+// For now userspace and DDK tracing share the same API and implementation.
+#include <lib/trace/internal/event_common.h>
+
+#endif // ZIRCON_SYSTEM_ULIB_LIB_TRACE_EVENT_H_
diff --git a/third_party/fuchsia-sdk/pkg/trace/include/lib/trace/event_args.h b/third_party/fuchsia-sdk/pkg/trace/include/lib/trace/event_args.h
new file mode 100644
index 0000000..72cde9a
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/trace/include/lib/trace/event_args.h
@@ -0,0 +1,164 @@
+// Copyright 2018 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.
+
+// This file contains support for emitting additional arguments to trace
+// events. Most trace events support adding up to 15 additional name/value
+// pairs to provide additional data about the event.
+
+#ifndef ZIRCON_SYSTEM_ULIB_LIB_TRACE_EVENT_ARGS_H_
+#define ZIRCON_SYSTEM_ULIB_LIB_TRACE_EVENT_ARGS_H_
+
+#include <lib/trace/internal/event_args.h>
+
+// Argument type macros used when writing trace events in C.
+//
+// When writing trace events in C, each trace argument value must be
+// individually wrapped with one of these macros to provide type information
+// for the argument.
+//
+// When writing trace events in C++, it is not necessary to wrap each trace
+// argument value with these macros since the compiler can infer the necessary
+// type information, with the exception of |TA_CHAR_ARRAY| and |TA_KOID|.
+//
+// Use |TA_NULL| for null values.
+// Use |TA_BOOL| for boolean values.
+// Use |TA_INT32| for signed 32-bit integer values.
+// Use |TA_UINT32| for unsigned 32-bit integer values.
+// Use |TA_INT64| for signed 64-bit integer values.
+// Use |TA_UINT64| for unsigned 64-bit integer values.
+// Use |TA_DOUBLE| for double-precision floating point values.
+// Use |TA_CHAR_ARRAY| for character arrays with a length (copied rather than cached), required in
+// C++. Use |TA_STRING| for null-terminated dynamic strings (copied rather than cached). Use
+// |TA_POINTER| for pointer values (records the memory address, not the target). Use |TA_KOID| for
+// kernel object ids, required in C++.
+//
+// TODO(PT-66): Re-add |TA_STRING_LITERAL|.
+//
+// C or C++ Usage: (argument type macros required in C)
+//
+// char* chars = ...;
+// size_t length = ...;
+// const char* c_string = ...;
+// void* ptr = ...;
+// zx_koid_t koid = ...;
+//
+// TRACE_DURATION("category", "name", "arg", TA_NULL());
+// TRACE_DURATION("category", "name", "arg", TA_BOOL(true));
+// TRACE_DURATION("category", "name", "arg", TA_INT32(-10));
+// TRACE_DURATION("category", "name", "arg", TA_UINT32(10));
+// TRACE_DURATION("category", "name", "arg", TA_INT64(-10));
+// TRACE_DURATION("category", "name", "arg", TA_UINT64(10));
+// TRACE_DURATION("category", "name", "arg", TA_DOUBLE(3.14));
+// TRACE_DURATION("category", "name", "arg", TA_CHAR_ARRAY(chars, length));
+// TRACE_DURATION("category", "name", "arg", TA_STRING(c_string));
+// TRACE_DURATION("category", "name", "arg", TA_STRING("Hi!"));
+// TRACE_DURATION("category", "name", "arg", TA_POINTER(ptr));
+// TRACE_DURATION("category", "name", "arg", TA_KOID(koid));
+//
+// C++ Usage: (argument type macros only needed for certain types)
+//
+// char* chars = ...;
+// size_t length = ...;
+// const char* c_string = ...;
+// std::string std_string = ...;
+// void* ptr = ...;
+// zx_koid_t koid = ...;
+//
+// TRACE_DURATION("category", "name", "arg", nullptr);
+// TRACE_DURATION("category", "name", "arg", -10);
+// TRACE_DURATION("category", "name", "arg", 10u);
+// TRACE_DURATION("category", "name", "arg", -10l);
+// TRACE_DURATION("category", "name", "arg", 10ul);
+// TRACE_DURATION("category", "name", "arg", 3.14);
+// TRACE_DURATION("category", "name", "arg", TA_CHAR_ARRAY(chars, length));
+// TRACE_DURATION("category", "name", "arg", c_string);
+// TRACE_DURATION("category", "name", "arg", fbl_string);
+// TRACE_DURATION("category", "name", "arg", std_string);
+// TRACE_DURATION("category", "name", "arg", "Hi!");
+// TRACE_DURATION("category", "name", "arg", ptr);
+// TRACE_DURATION("category", "name", "arg", TA_KOID(koid));
+//
+#define TA_NULL() (trace_make_null_arg_value())
+#define TA_BOOL(bool_value) (trace_make_bool_arg_value(bool_value))
+#define TA_INT32(int32_value) (trace_make_int32_arg_value(int32_value))
+#define TA_UINT32(uint32_value) (trace_make_uint32_arg_value(uint32_value))
+#define TA_INT64(int64_value) (trace_make_int64_arg_value(int64_value))
+#define TA_UINT64(uint64_value) (trace_make_uint64_arg_value(uint64_value))
+#define TA_DOUBLE(double_value) (trace_make_double_arg_value(double_value))
+#define TA_CHAR_ARRAY(string_value, length) \
+ (trace_make_string_arg_value(trace_make_inline_string_ref((string_value), (length))))
+#define TA_STRING(string_value) \
+ (trace_make_string_arg_value(trace_make_inline_c_string_ref(string_value)))
+#define TA_POINTER(pointer_value) (trace_make_pointer_arg_value((uintptr_t)pointer_value))
+#define TA_KOID(koid_value) (trace_make_koid_arg_value(koid_value))
+
+// This is a helper macro for use in writing one's own TRACE_<event> wrapper
+// macros.
+//
+// |context| is an object of type |trace_context_t*|.
+// |variable_name| is a C symbol denoting the variable that will contain the
+// arguments.
+// |args| is a potentially empty set of arguments of the form:
+// arg1_name_literal, arg1_value, arg2_name_literal, arg2_value, ...
+// Argument names must be C string literals, i.e., "foo".
+// For C, argument values must use the TA_*() macros to construct the value.
+// E.g., |TA_NULL()|, |TA_BOOL()|, |TA_INT32()|, |TA_UINT32()|, etc.
+// For C++, one can either use the TA_*() macros or for several types the
+// compiler can infer the type: nullptr, bool, int32_t, uint32_t, int64_t,
+// uint64_t, enum, double, const char[] array, const char*.
+//
+// Example:
+// Suppose you want to specify the time of a counter event.
+// The basic TRACE_<event> macros always use the current time for simplicity.
+// You can either write to the underlying trace-engine API directly,
+// or you can write your own helper macro like this:
+//
+// #define MY_TRACE_COUNTER_WITH_TS(category_literal, name_literal,
+// counter_id, timestamp, args...)
+// do {
+// trace_string_ref_t category_ref;
+// trace_context_t* context =
+// trace_acquire_context_for_category((category_literal),
+// &category_ref);
+// if (unlikely(context)) {
+// TRACE_DECLARE_ARGS(context, arguments, args);
+// size_t num_args = TRACE_NUM_ARGS(arguments);
+// trace_thread_ref_t thread_ref;
+// trace_string_ref_t name_ref;
+// trace_context_register_current_thread(context, &thread_ref);
+// trace_context_register_string_literal(context, (name_literal),
+// &name_ref);
+// TRACE_COMPLETE_ARGS(context, arguments, num_args);
+// trace_context_write_counter_event_record(
+// context, (timestamp), &thread_ref, category_ref,
+// &name_ref, (counter_id), arguments, num_args);
+// trace_release_context(context);
+// }
+// } while (0)
+//
+// N.B. Trailing backslashes have been intentionally elided, it avoids errors
+// if this code is compiled with -Werror=comment. You will need to add them
+// back of course.
+//
+// The above macro is written for illustration's sake. In production use one
+// might improve things by using safer names for the local variables (e.g.,
+// lest someone defines a macro with their name), and move some of the code
+// into a helper routine to reduce code bloat.
+// The tracing system recognizes "#define NTRACE" as a way of completely
+// disabling tracing by not emitting any code; you may wish to have your macro
+// emit zero code if NTRACE is defined.
+#define TRACE_DECLARE_ARGS(context, variable_name, args...) \
+ TRACE_INTERNAL_DECLARE_ARGS((context), variable_name, args)
+
+// Before the argument list created by |TRACE_DECLARE_ARGS()| can be passed to
+// the trace-engine API it must be passed through this. This is done in a
+// separate pass as it can reduce the amount of generated code by calling this
+// in a helper routine instead of at the TRACE_<event>() call site.
+#define TRACE_COMPLETE_ARGS(context, arg_array, num_args) \
+ TRACE_INTERNAL_COMPLETE_ARGS((context), (arg_array), (num_args))
+
+// Return the number of arguments in |variable_name|.
+#define TRACE_NUM_ARGS(variable_name) TRACE_INTERNAL_NUM_ARGS(variable_name)
+
+#endif // ZIRCON_SYSTEM_ULIB_LIB_TRACE_EVENT_ARGS_H_
diff --git a/third_party/fuchsia-sdk/pkg/trace/include/lib/trace/internal/event_args.h b/third_party/fuchsia-sdk/pkg/trace/include/lib/trace/internal/event_args.h
new file mode 100644
index 0000000..5e37cd1
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/trace/include/lib/trace/internal/event_args.h
@@ -0,0 +1,202 @@
+// Copyright 2018 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.
+
+// Internal implementation of <trace/event_args.h>.
+// This is not part of the public API: use <trace/event_args.h> instead.
+
+#ifndef ZIRCON_SYSTEM_ULIB_LIB_TRACE_INTERNAL_EVENT_ARGS_H_
+#define ZIRCON_SYSTEM_ULIB_LIB_TRACE_INTERNAL_EVENT_ARGS_H_
+
+#include <assert.h>
+
+#include <zircon/compiler.h>
+
+#include <lib/trace-engine/context.h>
+#include <lib/trace-engine/types.h>
+#include <lib/trace/internal/pairs_internal.h>
+
+#define TRACE_INTERNAL_NUM_ARGS(variable_name) (sizeof(variable_name) / sizeof((variable_name)[0]))
+
+// Note: Argument names are processed in two steps. The first step is here
+// where we store the string in |name_ref.inline_string|. The second step is
+// done by |trace_internal_complete_args()| which is normally called by the
+// helper routines that finish recording the event.
+#define TRACE_INTERNAL_COUNT_ARGS(...) TRACE_INTERNAL_COUNT_PAIRS(__VA_ARGS__)
+#define TRACE_INTERNAL_ALLOCATE_ARGS(var_name, args...) \
+ trace_arg_t var_name[TRACE_INTERNAL_COUNT_ARGS(args)]; \
+ static_assert(TRACE_INTERNAL_NUM_ARGS(var_name) <= TRACE_MAX_ARGS, "too many args")
+
+#ifdef __cplusplus
+
+#define TRACE_INTERNAL_SCOPE_ARG_LABEL(var_name, idx) __trace_arg_##var_name##idx
+
+#define TRACE_INTERNAL_HOLD_ARG(var_name, idx, name_literal, arg_value) \
+ const auto& TRACE_INTERNAL_SCOPE_ARG_LABEL(var_name, idx) = (arg_value);
+#define TRACE_INTERNAL_MAKE_ARG(var_name, idx, name_literal, arg_value) \
+ { \
+ .name_ref = {.encoded_value = 0, .inline_string = (name_literal)}, \
+ .value = ::trace::internal::MakeArgumentValue(TRACE_INTERNAL_SCOPE_ARG_LABEL(var_name, idx)) \
+ }
+
+#define TRACE_INTERNAL_DECLARE_ARGS(context, var_name, args...) \
+ TRACE_INTERNAL_APPLY_PAIRWISE(TRACE_INTERNAL_HOLD_ARG, var_name, args) \
+ trace_arg_t var_name[] = { \
+ TRACE_INTERNAL_APPLY_PAIRWISE_CSV(TRACE_INTERNAL_MAKE_ARG, var_name, args)}; \
+ static_assert(TRACE_INTERNAL_NUM_ARGS(var_name) <= TRACE_MAX_ARGS, "too many args")
+
+#define TRACE_INTERNAL_ASSIGN_ARG(var_name, idx, name_literal, arg_value) \
+ var_name[idx - 1].name_ref.encoded_value = 0; \
+ var_name[idx - 1].name_ref.inline_string = (name_literal); \
+ var_name[idx - 1].value = \
+ ::trace::internal::MakeArgumentValue(TRACE_INTERNAL_SCOPE_ARG_LABEL(var_name, idx));
+#define TRACE_INTERNAL_INIT_ARGS(var_name, args...) \
+ TRACE_INTERNAL_APPLY_PAIRWISE(TRACE_INTERNAL_HOLD_ARG, var_name, args) \
+ TRACE_INTERNAL_APPLY_PAIRWISE(TRACE_INTERNAL_ASSIGN_ARG, var_name, args)
+
+#else
+
+#define TRACE_INTERNAL_MAKE_ARG(var_name, idx, name_literal, arg_value) \
+ { .name_ref = {.encoded_value = 0, .inline_string = (name_literal)}, .value = (arg_value) }
+
+#define TRACE_INTERNAL_DECLARE_ARGS(context, var_name, args...) \
+ trace_arg_t var_name[] = { \
+ TRACE_INTERNAL_APPLY_PAIRWISE_CSV(TRACE_INTERNAL_MAKE_ARG, var_name, args)}; \
+ static_assert(TRACE_INTERNAL_NUM_ARGS(var_name) <= TRACE_MAX_ARGS, "too many args")
+
+#define TRACE_INTERNAL_ASSIGN_ARG(var_name, idx, name_literal, arg_value) \
+ var_name[idx - 1].name_ref.encoded_value = 0; \
+ var_name[idx - 1].name_ref.inline_string = (name_literal); \
+ var_name[idx - 1].value = (arg_value);
+#define TRACE_INTERNAL_INIT_ARGS(var_name, args...) \
+ TRACE_INTERNAL_APPLY_PAIRWISE(TRACE_INTERNAL_ASSIGN_ARG, var_name, args)
+#endif // __cplusplus
+
+__BEGIN_CDECLS
+void trace_internal_complete_args(trace_context_t* context, trace_arg_t* args, size_t num_args);
+__END_CDECLS
+
+#define TRACE_INTERNAL_COMPLETE_ARGS(context, args, num_args) \
+ do { \
+ trace_internal_complete_args((context), (args), (num_args)); \
+ } while (0)
+
+#ifdef __cplusplus
+
+#include <lib/trace/internal/string_traits.h>
+#include <type_traits>
+
+namespace trace {
+namespace internal {
+
+template <typename T>
+struct is_bool : public std::is_same<std::remove_cv_t<T>, bool> {};
+
+// Helps construct trace argument values using SFINAE to coerce types.
+template <typename T, typename Enable = void>
+struct ArgumentValueMaker;
+
+template <>
+struct ArgumentValueMaker<trace_arg_value_t> {
+ static trace_arg_value_t Make(trace_arg_value_t value) { return value; }
+};
+
+template <>
+struct ArgumentValueMaker<decltype(nullptr)> {
+ static trace_arg_value_t Make(decltype(nullptr) value) { return trace_make_null_arg_value(); }
+};
+
+template <typename T>
+struct ArgumentValueMaker<T, typename std::enable_if<is_bool<T>::value>::type> {
+ static trace_arg_value_t Make(bool value) { return trace_make_bool_arg_value(value); }
+};
+
+template <typename T>
+struct ArgumentValueMaker<
+ T, typename std::enable_if<std::is_signed<T>::value && std::is_integral<T>::value &&
+ (sizeof(T) <= sizeof(int32_t))>::type> {
+ static trace_arg_value_t Make(int32_t value) { return trace_make_int32_arg_value(value); }
+};
+
+template <typename T>
+struct ArgumentValueMaker<
+ T, typename std::enable_if<!is_bool<T>::value && std::is_unsigned<T>::value &&
+ !std::is_enum<T>::value &&
+ (sizeof(T) <= sizeof(uint32_t))>::type> {
+ static trace_arg_value_t Make(uint32_t value) { return trace_make_uint32_arg_value(value); }
+};
+
+template <typename T>
+struct ArgumentValueMaker<
+ T, typename std::enable_if<std::is_signed<T>::value && std::is_integral<T>::value &&
+ (sizeof(T) > sizeof(int32_t)) &&
+ (sizeof(T) <= sizeof(int64_t))>::type> {
+ static trace_arg_value_t Make(int64_t value) { return trace_make_int64_arg_value(value); }
+};
+
+template <typename T>
+struct ArgumentValueMaker<
+ T, typename std::enable_if<std::is_unsigned<T>::value &&
+ !std::is_enum<T>::value &&
+ (sizeof(T) > sizeof(uint32_t)) &&
+ (sizeof(T) <= sizeof(uint64_t))>::type> {
+ static trace_arg_value_t Make(uint64_t value) { return trace_make_uint64_arg_value(value); }
+};
+
+template <typename T>
+struct ArgumentValueMaker<T, typename std::enable_if<std::is_enum<T>::value>::type> {
+ using UnderlyingType = typename std::underlying_type<T>::type;
+ static trace_arg_value_t Make(UnderlyingType value) {
+ return ArgumentValueMaker<UnderlyingType>::Make(value);
+ }
+};
+
+template <typename T>
+struct ArgumentValueMaker<T, typename std::enable_if<std::is_floating_point<T>::value>::type> {
+ static trace_arg_value_t Make(double value) { return trace_make_double_arg_value(value); }
+};
+
+template <size_t n>
+struct ArgumentValueMaker<char[n]> {
+ static trace_arg_value_t Make(const char* value) {
+ return trace_make_string_arg_value(
+ trace_make_inline_string_ref(value, value[n - 1] ? n : n - 1));
+ }
+};
+
+template <>
+struct ArgumentValueMaker<const char*> {
+ static trace_arg_value_t Make(const char* value) {
+ return trace_make_string_arg_value(trace_make_inline_c_string_ref(value));
+ }
+};
+
+// Works with various string types including fbl::String, fbl::StringView,
+// std::string, and std::string_view.
+template <typename T>
+struct ArgumentValueMaker<
+ T, typename std::enable_if<::trace::internal::is_string_like<T>::value>::type> {
+ static trace_arg_value_t Make(const T& value) {
+ return trace_make_string_arg_value(trace_make_inline_string_ref(
+ ::trace::internal::GetStringData(value), ::trace::internal::GetStringLength(value)));
+ }
+};
+
+template <typename T>
+struct ArgumentValueMaker<T*> {
+ static trace_arg_value_t Make(const T* pointer) {
+ return trace_make_pointer_arg_value(reinterpret_cast<uintptr_t>(pointer));
+ }
+};
+
+template <typename T>
+trace_arg_value_t MakeArgumentValue(const T& value) {
+ return ArgumentValueMaker<T>::Make(value);
+}
+
+} // namespace internal
+} // namespace trace
+
+#endif // __cplusplus
+
+#endif // ZIRCON_SYSTEM_ULIB_LIB_TRACE_INTERNAL_EVENT_ARGS_H_
diff --git a/third_party/fuchsia-sdk/pkg/trace/include/lib/trace/internal/event_common.h b/third_party/fuchsia-sdk/pkg/trace/include/lib/trace/internal/event_common.h
new file mode 100644
index 0000000..647e5a2
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/trace/include/lib/trace/internal/event_common.h
@@ -0,0 +1,409 @@
+// Copyright 2017 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.
+
+// This file contains definitions common to userspace and DDK tracing.
+
+#ifndef LIB_TRACE_INTERNAL_EVENT_COMMON_H_
+#define LIB_TRACE_INTERNAL_EVENT_COMMON_H_
+
+#include <lib/trace/event_args.h>
+#include <lib/trace/internal/event_internal.h>
+
+// Returns true if tracing is enabled.
+//
+// Usage:
+//
+// if (TRACE_ENABLED()) {
+// // do something possibly expensive only when tracing is enabled
+// }
+//
+#ifndef NTRACE
+#define TRACE_ENABLED() (trace_is_enabled())
+#else
+#define TRACE_ENABLED() (false)
+#endif // NTRACE
+
+// Returns true if tracing of the specified category has been enabled (which
+// implies that |TRACE_ENABLED()| is also true).
+//
+// |category_literal| must be a null-terminated static string constant.
+//
+// Usage:
+//
+// if (TRACE_CATEGORY_ENABLED("category")) {
+// // do something possibly expensive only when tracing this category
+// }
+//
+#define TRACE_CATEGORY_ENABLED(category_literal) TRACE_INTERNAL_CATEGORY_ENABLED(category_literal)
+
+// Returns a new unique 64-bit unsigned integer (within this process).
+// Each invocation returns a different non-zero value.
+// Useful for generating identifiers for async and flow events.
+//
+// Usage:
+//
+// trace_async_id_t async_id = TRACE_NONCE();
+// TRACE_ASYNC_BEGIN("category", "name", async_id);
+// // a little while later...
+// TRACE_ASYNC_END("category", "name", async_id);
+//
+#define TRACE_NONCE() (trace_generate_nonce())
+
+// Writes an instant event representing a single moment in time (a probe).
+//
+// 0 to 15 arguments can be associated with the event, each of which is used
+// to annotate the moment with additional information.
+//
+// |category_literal| and |name_literal| must be null-terminated static string constants.
+// |scope| is |TRACE_SCOPE_THREAD|, |TRACE_SCOPE_PROCESS|, or |TRACE_SCOPE_GLOBAL|.
+// |args| is the list of argument key/value pairs.
+//
+// Usage:
+//
+// TRACE_INSTANT("category", "name", TRACE_SCOPE_PROCESS, "x", TA_INT32(42));
+//
+#define TRACE_INSTANT(category_literal, name_literal, scope, args...) \
+ TRACE_INTERNAL_INSTANT((category_literal), (name_literal), (scope), args)
+
+// Writes a counter event with the specified id.
+//
+// The arguments to this event are numeric samples are typically represented by
+// the visualizer as a stacked area chart. The id serves to distinguish multiple
+// instances of counters which share the same category and name within the
+// same process.
+//
+// 1 to 15 numeric arguments can be associated with the event, each of which is
+// interpreted as a distinct time series.
+//
+// |category_literal| and |name_literal| must be null-terminated static string constants.
+// |counter_id| is the correlation id of the counter.
+// Must be unique for a given process, category, and name combination.
+// |args| is the list of argument key/value pairs.
+//
+// Usage:
+//
+// trace_counter_id_t counter_id = 555;
+// TRACE_COUNTER("category", "name", counter_id, "x", TA_INT32(42), "y", TA_DOUBLE(2.0))
+//
+#define TRACE_COUNTER(category_literal, name_literal, counter_id, arg1, args...) \
+ TRACE_INTERNAL_COUNTER((category_literal), (name_literal), (counter_id), arg1, ##args)
+
+// Writes a duration event which ends when the current scope exits.
+//
+// Durations describe work which is happening synchronously on one thread.
+// They can be nested to represent a control flow stack.
+//
+// 0 to 15 arguments can be associated with the event, each of which is used
+// to annotate the duration with additional information.
+//
+// |category_literal| and |name_literal| must be null-terminated static string constants.
+// |args| is the list of argument key/value pairs.
+//
+// Usage:
+//
+// void function(int arg) {
+// TRACE_DURATION("category", "name", "arg", TA_INT32(arg));
+// // do something useful here
+// }
+//
+#define TRACE_DURATION(category_literal, name_literal, args...) \
+ TRACE_INTERNAL_DURATION((category_literal), (name_literal), args)
+
+// Writes a duration begin event only.
+// This event must be matched by a duration end event with the same category and name.
+//
+// Durations describe work which is happening synchronously on one thread.
+// They can be nested to represent a control flow stack.
+//
+// 0 to 15 arguments can be associated with the event, each of which is used
+// to annotate the duration with additional information. The arguments provided
+// to matching duration begin and duration end events are combined together in
+// the trace; it is not necessary to repeat them.
+//
+// |category_literal| and |name_literal| must be null-terminated static string constants.
+// |args| is the list of argument key/value pairs.
+//
+// Usage:
+//
+// TRACE_DURATION_BEGIN("category", "name", "x", TA_INT32(42));
+//
+#define TRACE_DURATION_BEGIN(category_literal, name_literal, args...) \
+ TRACE_INTERNAL_DURATION_BEGIN((category_literal), (name_literal), args)
+
+// Writes a duration end event only.
+//
+// Durations describe work which is happening synchronously on one thread.
+// They can be nested to represent a control flow stack.
+//
+// 0 to 15 arguments can be associated with the event, each of which is used
+// to annotate the duration with additional information. The arguments provided
+// to matching duration begin and duration end events are combined together in
+// the trace; it is not necessary to repeat them.
+//
+// |category_literal| and |name_literal| must be null-terminated static string constants.
+// |args| is the list of argument key/value pairs.
+//
+// Usage:
+//
+// TRACE_DURATION_END("category", "name", "x", TA_INT32(42));
+//
+#define TRACE_DURATION_END(category_literal, name_literal, args...) \
+ TRACE_INTERNAL_DURATION_END((category_literal), (name_literal), args)
+
+// Writes an asynchronous begin event with the specified id.
+// This event may be followed by async instant events and must be matched by
+// an async end event with the same category, name, and id.
+//
+// Asynchronous events describe work which is happening asynchronously and which
+// may span multiple threads. Asynchronous events do not nest. The id serves
+// to correlate the progress of distinct asynchronous operations which share
+// the same category and name within the same process.
+//
+// 0 to 15 arguments can be associated with the event, each of which is used
+// to annotate the asynchronous operation with additional information. The
+// arguments provided to matching async begin, async instant, and async end
+// events are combined together in the trace; it is not necessary to repeat them.
+//
+// |category_literal| and |name_literal| must be null-terminated static string constants.
+// |async_id| is the correlation id of the asynchronous operation.
+// Must be unique for a given process, category, and name combination.
+// |args| is the list of argument key/value pairs.
+//
+// Usage:
+//
+// trace_async_id_t async_id = 555;
+// TRACE_ASYNC_BEGIN("category", "name", async_id, "x", TA_INT32(42));
+//
+#define TRACE_ASYNC_BEGIN(category_literal, name_literal, async_id, args...) \
+ TRACE_INTERNAL_ASYNC_BEGIN((category_literal), (name_literal), (async_id), args)
+
+// Writes an asynchronous instant event with the specified id.
+//
+// Asynchronous events describe work which is happening asynchronously and which
+// may span multiple threads. Asynchronous events do not nest. The id serves
+// to correlate the progress of distinct asynchronous operations which share
+// the same category and name within the same process.
+//
+// 0 to 15 arguments can be associated with the event, each of which is used
+// to annotate the asynchronous operation with additional information. The
+// arguments provided to matching async begin, async instant, and async end
+// events are combined together in the trace; it is not necessary to repeat them.
+//
+// |category_literal| and |name_literal| must be null-terminated static string constants.
+// |async_id| is the correlation id of the asynchronous operation.
+// Must be unique for a given process, category, and name combination.
+// |args| is the list of argument key/value pairs.
+//
+// Usage:
+//
+// trace_async_id_t async_id = 555;
+// TRACE_ASYNC_INSTANT("category", "name", async_id, "x", TA_INT32(42));
+//
+#define TRACE_ASYNC_INSTANT(category_literal, name_literal, async_id, args...) \
+ TRACE_INTERNAL_ASYNC_INSTANT((category_literal), (name_literal), (async_id), args)
+
+// Writes an asynchronous end event with the specified id.
+//
+// Asynchronous events describe work which is happening asynchronously and which
+// may span multiple threads. Asynchronous events do not nest. The id serves
+// to correlate the progress of distinct asynchronous operations which share
+// the same category and name within the same process.
+//
+// 0 to 15 arguments can be associated with the event, each of which is used
+// to annotate the asynchronous operation with additional information. The
+// arguments provided to matching async begin, async instant, and async end
+// events are combined together in the trace; it is not necessary to repeat them.
+//
+// |category_literal| and |name_literal| must be null-terminated static string constants.
+// |async_id| is the correlation id of the asynchronous operation.
+// Must be unique for a given process, category, and name combination.
+// |args| is the list of argument key/value pairs.
+//
+// Usage:
+//
+// trace_async_id_t async_id = 555;
+// TRACE_ASYNC_END("category", "name", async_id, "x", TA_INT32(42));
+//
+#define TRACE_ASYNC_END(category_literal, name_literal, async_id, args...) \
+ TRACE_INTERNAL_ASYNC_END((category_literal), (name_literal), (async_id), args)
+
+// Writes a flow begin event with the specified id.
+// This event may be followed by flow steps events and must be matched by
+// a flow end event with the same category, name, and id.
+//
+// Flow events describe control flow handoffs between threads or across processes.
+// They are typically represented as arrows in a visualizer. Flow arrows are
+// from the end of the duration event which encloses the beginning of the flow
+// to the beginning of the duration event which encloses the next step or the
+// end of the flow. The id serves to correlate flows which share the same
+// category and name across processes.
+//
+// This event must be enclosed in a duration event which represents where
+// the flow handoff occurs.
+//
+// 0 to 15 arguments can be associated with the event, each of which is used
+// to annotate the flow with additional information. The arguments provided
+// to matching flow begin, flow step, and flow end events are combined together
+// in the trace; it is not necessary to repeat them.
+//
+// |category_literal| and |name_literal| must be null-terminated static string constants.
+// |flow_id| is the correlation id of the flow.
+// Must be unique for a given category and name combination.
+// |args| is the list of argument key/value pairs.
+//
+// Usage:
+//
+// trace_flow_id_t flow_id = 555;
+// TRACE_FLOW_BEGIN("category", "name", flow_id, "x", TA_INT32(42));
+//
+#define TRACE_FLOW_BEGIN(category_literal, name_literal, flow_id, args...) \
+ TRACE_INTERNAL_FLOW_BEGIN((category_literal), (name_literal), (flow_id), args)
+
+// Writes a flow step event with the specified id.
+//
+// Flow events describe control flow handoffs between threads or across processes.
+// They are typically represented as arrows in a visualizer. Flow arrows are
+// from the end of the duration event which encloses the beginning of the flow
+// to the beginning of the duration event which encloses the next step or the
+// end of the flow. The id serves to correlate flows which share the same
+// category and name across processes.
+//
+// This event must be enclosed in a duration event which represents where
+// the flow handoff occurs.
+//
+// 0 to 15 arguments can be associated with the event, each of which is used
+// to annotate the flow with additional information. The arguments provided
+// to matching flow begin, flow step, and flow end events are combined together
+// in the trace; it is not necessary to repeat them.
+//
+// |category_literal| and |name_literal| must be null-terminated static string constants.
+// |flow_id| is the correlation id of the flow.
+// Must be unique for a given category and name combination.
+// |args| is the list of argument key/value pairs.
+//
+// Usage:
+//
+// trace_flow_id_t flow_id = 555;
+// TRACE_FLOW_STEP("category", "name", flow_id, "x", TA_INT32(42));
+//
+#define TRACE_FLOW_STEP(category_literal, name_literal, flow_id, args...) \
+ TRACE_INTERNAL_FLOW_STEP((category_literal), (name_literal), (flow_id), args)
+
+// Writes a flow end event with the specified id.
+//
+// Flow events describe control flow handoffs between threads or across processes.
+// They are typically represented as arrows in a visualizer. Flow arrows are
+// from the end of the duration event which encloses the beginning of the flow
+// to the beginning of the duration event which encloses the next step or the
+// end of the flow. The id serves to correlate flows which share the same
+// category and name across processes.
+//
+// This event must be enclosed in a duration event which represents where
+// the flow handoff occurs.
+//
+// 0 to 15 arguments can be associated with the event, each of which is used
+// to annotate the flow with additional information. The arguments provided
+// to matching flow begin, flow step, and flow end events are combined together
+// in the trace; it is not necessary to repeat them.
+//
+// |category_literal| and |name_literal| must be null-terminated static string constants.
+// |flow_id| is the correlation id of the flow.
+// Must be unique for a given category and name combination.
+// |args| is the list of argument key/value pairs.
+//
+// Usage:
+//
+// trace_flow_id_t id = 555;
+// TRACE_FLOW_END("category", "name", flow_id, "x", TA_INT32(42));
+//
+#define TRACE_FLOW_END(category_literal, name_literal, flow_id, args...) \
+ TRACE_INTERNAL_FLOW_END((category_literal), (name_literal), (flow_id), args)
+
+// Writes a large blob record with the given blob data and metadata.
+// Here metadata includes timestamp, thread and process information, and arguments,
+// which is what most event records contain.
+//
+// Blobs which exceed |TRACE_ENCODED_RECORD_MAX_TOTAL_LENGTH| will be silently
+// ignored, as will blobs which cannot fit within the remaining space in the
+// trace buffer.
+//
+// |category_literal| and |name_literal| must be null-terminated static string constants.
+// |blob| is a pointer to the data.
+// |blob_size| is the size, in bytes, of the data.
+// |args| is the list of argument key/value pairs.
+#define TRACE_BLOB_EVENT(category_literal, name_literal, blob, blob_size, args...) \
+ TRACE_INTERNAL_BLOB_EVENT(category_literal, name_literal, blob, blob_size, args)
+
+// Writes a large blob record with the given blob data, with only a
+// category and name associated with the blob. This will not contain much
+// additional metadata. This means timestamp, thread and process information,
+// and arguments are not included with the record.
+//
+// Blobs which exceed |TRACE_ENCODED_RECORD_MAX_TOTAL_LENGTH| will be silently
+// ignored, as will blobs which cannot fit within the remaining space in the
+// trace buffer.
+//
+// |category_literal| and |name_literal| must be null-terminated static string constants.
+// |blob| is a pointer to the data.
+// |blob_size| is the size, in bytes, of the data.
+#define TRACE_BLOB_ATTACHMENT(category_literal, name_literal, blob, blob_size) \
+ TRACE_INTERNAL_BLOB_ATTACHMENT(category_literal, name_literal, blob, blob_size)
+
+// Writes a description of a kernel object indicated by |handle|,
+// including its koid, name, and the supplied arguments.
+//
+// 0 to 15 arguments can be associated with the record, each of which is used
+// to annotate the handle with additional information.
+//
+// |handle| is the handle of the object being described.
+// |args| is the list of argument key/value pairs.
+//
+// Usage:
+//
+// zx_handle_t handle = ...;
+// TRACE_KERNEL_OBJECT(handle, "description", TA_STRING("some object"));
+//
+#define TRACE_KERNEL_OBJECT(handle, args...) TRACE_INTERNAL_KERNEL_OBJECT((handle), args)
+
+// WARNING! |TRACE_BLOB| is deprecated in favor of the |TRACE_BLOB_*| macros.
+//
+// Writes a blob of binary data to the trace buffer.
+//
+// |type| is the type of the blob, and must be one of the enums in type
+// |trace_blob_type_t|.
+// |name_ref| is the name of the blob, and must be a string literal.
+// |blob| is a pointer to the data.
+// |blob_size| is the size, in bytes, of the data.
+//
+// A size of zero is ok. The maximum size of a blob is defined by
+// TRACE_MAX_BLOB_SIZE which is slighly less than 32K.
+// Exercise caution when emitting blob records: space is shared with all
+// trace records and large blobs can eat up space fast.
+// The blob must fit in the remaining space in the buffer. If the blob does
+// not fit the call silently fails, as do all calls that write trace records
+// when the buffer is full.
+//
+// Usage:
+// size_t blob_size = ...;
+// const void* blob = ...;
+// TRACE_BLOB(TRACE_BLOB_TYPE_DATA, "my-blob", blob, blob_size);
+//
+#define TRACE_BLOB(type, name, blob, blob_size) \
+ TRACE_INTERNAL_BLOB((type), (name), (blob), (blob_size))
+
+// Sends an alert. Alerts are forwarded directly to trace controller clients
+// and are typically used to trigger actions, such as stopping the current
+// trace.
+//
+// |alert_name| is the name of the alert to send.
+//
+// Alert names are limited to at most 14 characters.
+//
+// Usage:
+// TRACE_ALERT("my-category", "my-alert");
+//
+#define TRACE_ALERT(category_literal, alert_name) \
+ TRACE_INTERNAL_ALERT((category_literal), (alert_name))
+
+#endif // LIB_TRACE_INTERNAL_EVENT_COMMON_H_
diff --git a/third_party/fuchsia-sdk/pkg/trace/include/lib/trace/internal/event_internal.h b/third_party/fuchsia-sdk/pkg/trace/include/lib/trace/internal/event_internal.h
new file mode 100644
index 0000000..681c434
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/trace/include/lib/trace/internal/event_internal.h
@@ -0,0 +1,394 @@
+// Copyright 2017 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.
+
+//
+// Internal declarations used by the C tracing macros.
+// This is not part of the public API: use <trace/event.h> instead.
+//
+
+#ifndef LIB_TRACE_INTERNAL_EVENT_INTERNAL_H_
+#define LIB_TRACE_INTERNAL_EVENT_INTERNAL_H_
+
+#include <lib/trace-engine/instrumentation.h>
+#include <lib/trace/internal/event_args.h>
+#include <zircon/compiler.h>
+#include <zircon/syscalls.h>
+
+__BEGIN_CDECLS
+
+// Variable used to refer to the current trace context.
+#define TRACE_INTERNAL_CONTEXT __trace_context
+
+// Variable used to hold call-site cache state.
+#define TRACE_INTERNAL_SITE_STATE __trace_site_state
+
+// Variable used to maintain the category enabled state.
+#define TRACE_INTERNAL_CATEGORY_ENABLED_STATE __trace_is_category_group_enabled
+
+// Variable used to refer to the current trace category's string ref.
+#define TRACE_INTERNAL_CATEGORY_REF __trace_category_ref
+
+// Variable used to contain the array of arguments.
+#define TRACE_INTERNAL_ARGS __trace_args
+
+// Number of arguments recorded in |TRACE_INTERNAL_ARGS|.
+#define TRACE_INTERNAL_NUM_INTERNAL_ARGS TRACE_INTERNAL_NUM_ARGS(TRACE_INTERNAL_ARGS)
+
+// Obtains a unique identifier name within the containing scope.
+#define TRACE_INTERNAL_SCOPE_LABEL() TRACE_INTERNAL_SCOPE_LABEL_(__COUNTER__)
+#define TRACE_INTERNAL_SCOPE_LABEL_(token) TRACE_INTERNAL_SCOPE_LABEL__(token)
+#define TRACE_INTERNAL_SCOPE_LABEL__(token) __trace_scope_##token
+
+#define TRACE_INTERNAL_SCOPE_ARGS_LABEL(scope) TRACE_INTERNAL_SCOPE_ARGS_LABEL_(scope)
+#define TRACE_INTERNAL_SCOPE_ARGS_LABEL_(scope) scope##_args
+
+// Scaffolding for category enabled check.
+#ifndef NTRACE
+#define TRACE_INTERNAL_CATEGORY_ENABLED(category_literal) \
+ ({ \
+ static trace_site_t TRACE_INTERNAL_SITE_STATE; \
+ trace_string_ref_t TRACE_INTERNAL_CATEGORY_REF; \
+ bool TRACE_INTERNAL_CATEGORY_ENABLED_STATE = false; \
+ trace_context_t* TRACE_INTERNAL_CONTEXT = trace_acquire_context_for_category_cached( \
+ (category_literal), &TRACE_INTERNAL_SITE_STATE, &TRACE_INTERNAL_CATEGORY_REF); \
+ if (unlikely(TRACE_INTERNAL_CONTEXT)) { \
+ TRACE_INTERNAL_CATEGORY_ENABLED_STATE = true; \
+ trace_release_context(TRACE_INTERNAL_CONTEXT); \
+ } \
+ TRACE_INTERNAL_CATEGORY_ENABLED_STATE; \
+ })
+#else
+#define TRACE_INTERNAL_CATEGORY_ENABLED(category_literal) ((void)(category_literal), false)
+#endif // NTRACE
+
+// Scaffolding for a trace macro that does not have a category.
+#ifndef NTRACE
+#define TRACE_INTERNAL_SIMPLE_RECORD(stmt, args...) \
+ do { \
+ trace_context_t* TRACE_INTERNAL_CONTEXT = trace_acquire_context(); \
+ if (unlikely(TRACE_INTERNAL_CONTEXT)) { \
+ TRACE_INTERNAL_DECLARE_ARGS(TRACE_INTERNAL_CONTEXT, TRACE_INTERNAL_ARGS, args); \
+ stmt; \
+ } \
+ } while (0)
+#else
+#define TRACE_INTERNAL_SIMPLE_RECORD(stmt, args...) \
+ do { \
+ if (0) { \
+ trace_context_t* TRACE_INTERNAL_CONTEXT = 0; \
+ TRACE_INTERNAL_DECLARE_ARGS(TRACE_INTERNAL_CONTEXT, TRACE_INTERNAL_ARGS, args); \
+ stmt; \
+ } \
+ } while (0)
+#endif // NTRACE
+
+// Scaffolding for a trace macro that has a category (such as a trace event).
+#ifndef NTRACE
+#define TRACE_INTERNAL_EVENT_RECORD(category_literal, stmt, args...) \
+ do { \
+ static trace_site_t TRACE_INTERNAL_SITE_STATE; \
+ trace_string_ref_t TRACE_INTERNAL_CATEGORY_REF; \
+ trace_context_t* TRACE_INTERNAL_CONTEXT = trace_acquire_context_for_category_cached( \
+ (category_literal), &TRACE_INTERNAL_SITE_STATE, &TRACE_INTERNAL_CATEGORY_REF); \
+ if (unlikely(TRACE_INTERNAL_CONTEXT)) { \
+ TRACE_INTERNAL_DECLARE_ARGS(TRACE_INTERNAL_CONTEXT, TRACE_INTERNAL_ARGS, args); \
+ stmt; \
+ } \
+ } while (0)
+#else
+#define TRACE_INTERNAL_EVENT_RECORD(category_literal, stmt, args...) \
+ do { \
+ if (0) { \
+ trace_string_ref_t TRACE_INTERNAL_CATEGORY_REF; \
+ trace_context_t* TRACE_INTERNAL_CONTEXT = 0; \
+ TRACE_INTERNAL_DECLARE_ARGS(TRACE_INTERNAL_CONTEXT, TRACE_INTERNAL_ARGS, args); \
+ stmt; \
+ } \
+ } while (0)
+#endif // NTRACE
+
+#define TRACE_INTERNAL_INSTANT(category_literal, name_literal, scope, args...) \
+ do { \
+ TRACE_INTERNAL_EVENT_RECORD( \
+ (category_literal), \
+ trace_internal_write_instant_event_record_and_release_context( \
+ TRACE_INTERNAL_CONTEXT, &TRACE_INTERNAL_CATEGORY_REF, (name_literal), (scope), \
+ TRACE_INTERNAL_ARGS, TRACE_INTERNAL_NUM_INTERNAL_ARGS), \
+ args); \
+ } while (0)
+
+#define TRACE_INTERNAL_COUNTER(category_literal, name_literal, counter_id, args...) \
+ do { \
+ TRACE_INTERNAL_EVENT_RECORD( \
+ (category_literal), \
+ trace_internal_write_counter_event_record_and_release_context( \
+ TRACE_INTERNAL_CONTEXT, &TRACE_INTERNAL_CATEGORY_REF, (name_literal), (counter_id), \
+ TRACE_INTERNAL_ARGS, TRACE_INTERNAL_NUM_INTERNAL_ARGS), \
+ args); \
+ } while (0)
+
+#define TRACE_INTERNAL_DURATION_BEGIN(category_literal, name_literal, args...) \
+ do { \
+ TRACE_INTERNAL_EVENT_RECORD( \
+ (category_literal), \
+ trace_internal_write_duration_begin_event_record_and_release_context( \
+ TRACE_INTERNAL_CONTEXT, &TRACE_INTERNAL_CATEGORY_REF, (name_literal), \
+ TRACE_INTERNAL_ARGS, TRACE_INTERNAL_NUM_INTERNAL_ARGS), \
+ args); \
+ } while (0)
+
+#define TRACE_INTERNAL_DURATION_END(category_literal, name_literal, args...) \
+ do { \
+ TRACE_INTERNAL_EVENT_RECORD( \
+ (category_literal), \
+ trace_internal_write_duration_end_event_record_and_release_context( \
+ TRACE_INTERNAL_CONTEXT, &TRACE_INTERNAL_CATEGORY_REF, (name_literal), \
+ TRACE_INTERNAL_ARGS, TRACE_INTERNAL_NUM_INTERNAL_ARGS), \
+ args); \
+ } while (0)
+
+#ifndef NTRACE
+// TODO(fmeawad): The generated code for this macro is too big (PT-87)
+#define TRACE_INTERNAL_DECLARE_DURATION_SCOPE(variable, args_variable, category_literal, \
+ name_literal, args...) \
+ TRACE_INTERNAL_ALLOCATE_ARGS(args_variable, args); \
+ __attribute__((cleanup(trace_internal_cleanup_duration_scope))) \
+ trace_internal_duration_scope_t variable; \
+ do { \
+ static trace_site_t TRACE_INTERNAL_SITE_STATE; \
+ trace_string_ref_t TRACE_INTERNAL_CATEGORY_REF; \
+ trace_context_t* TRACE_INTERNAL_CONTEXT = trace_acquire_context_for_category_cached( \
+ (category_literal), &TRACE_INTERNAL_SITE_STATE, &TRACE_INTERNAL_CATEGORY_REF); \
+ if (unlikely(TRACE_INTERNAL_CONTEXT)) { \
+ TRACE_INTERNAL_INIT_ARGS(args_variable, args); \
+ trace_release_context(TRACE_INTERNAL_CONTEXT); \
+ trace_internal_make_duration_scope(&variable, (category_literal), (name_literal), \
+ args_variable, TRACE_INTERNAL_NUM_ARGS(args_variable)); \
+ } else { \
+ variable.start_time = 0; \
+ } \
+ } while (0)
+
+#define TRACE_INTERNAL_DURATION_(scope_label, scope_category_literal, scope_name_literal, args...) \
+ TRACE_INTERNAL_DECLARE_DURATION_SCOPE(scope_label, TRACE_INTERNAL_SCOPE_ARGS_LABEL(scope_label), \
+ scope_category_literal, scope_name_literal, args)
+#define TRACE_INTERNAL_DURATION(category_literal, name_literal, args...) \
+ TRACE_INTERNAL_DURATION_(TRACE_INTERNAL_SCOPE_LABEL(), (category_literal), (name_literal), args)
+#else
+#define TRACE_INTERNAL_DURATION(category_literal, name_literal, args...) \
+ TRACE_INTERNAL_DURATION_BEGIN((category_literal), (name_literal), args)
+#endif // NTRACE
+
+#define TRACE_INTERNAL_ASYNC_BEGIN(category_literal, name_literal, async_id, args...) \
+ do { \
+ TRACE_INTERNAL_EVENT_RECORD( \
+ (category_literal), \
+ trace_internal_write_async_begin_event_record_and_release_context( \
+ TRACE_INTERNAL_CONTEXT, &TRACE_INTERNAL_CATEGORY_REF, (name_literal), (async_id), \
+ TRACE_INTERNAL_ARGS, TRACE_INTERNAL_NUM_INTERNAL_ARGS), \
+ args); \
+ } while (0)
+
+#define TRACE_INTERNAL_ASYNC_INSTANT(category_literal, name_literal, async_id, args...) \
+ do { \
+ TRACE_INTERNAL_EVENT_RECORD( \
+ (category_literal), \
+ trace_internal_write_async_instant_event_record_and_release_context( \
+ TRACE_INTERNAL_CONTEXT, &TRACE_INTERNAL_CATEGORY_REF, (name_literal), (async_id), \
+ TRACE_INTERNAL_ARGS, TRACE_INTERNAL_NUM_INTERNAL_ARGS), \
+ args); \
+ } while (0)
+
+#define TRACE_INTERNAL_ASYNC_END(category_literal, name_literal, async_id, args...) \
+ do { \
+ TRACE_INTERNAL_EVENT_RECORD( \
+ (category_literal), \
+ trace_internal_write_async_end_event_record_and_release_context( \
+ TRACE_INTERNAL_CONTEXT, &TRACE_INTERNAL_CATEGORY_REF, (name_literal), (async_id), \
+ TRACE_INTERNAL_ARGS, TRACE_INTERNAL_NUM_INTERNAL_ARGS), \
+ args); \
+ } while (0)
+
+#define TRACE_INTERNAL_FLOW_BEGIN(category_literal, name_literal, flow_id, args...) \
+ do { \
+ TRACE_INTERNAL_EVENT_RECORD( \
+ (category_literal), \
+ trace_internal_write_flow_begin_event_record_and_release_context( \
+ TRACE_INTERNAL_CONTEXT, &TRACE_INTERNAL_CATEGORY_REF, (name_literal), (flow_id), \
+ TRACE_INTERNAL_ARGS, TRACE_INTERNAL_NUM_INTERNAL_ARGS), \
+ args); \
+ } while (0)
+
+#define TRACE_INTERNAL_FLOW_STEP(category_literal, name_literal, flow_id, args...) \
+ do { \
+ TRACE_INTERNAL_EVENT_RECORD( \
+ (category_literal), \
+ trace_internal_write_flow_step_event_record_and_release_context( \
+ TRACE_INTERNAL_CONTEXT, &TRACE_INTERNAL_CATEGORY_REF, (name_literal), (flow_id), \
+ TRACE_INTERNAL_ARGS, TRACE_INTERNAL_NUM_INTERNAL_ARGS), \
+ args); \
+ } while (0)
+
+#define TRACE_INTERNAL_FLOW_END(category_literal, name_literal, flow_id, args...) \
+ do { \
+ TRACE_INTERNAL_EVENT_RECORD( \
+ (category_literal), \
+ trace_internal_write_flow_end_event_record_and_release_context( \
+ TRACE_INTERNAL_CONTEXT, &TRACE_INTERNAL_CATEGORY_REF, (name_literal), (flow_id), \
+ TRACE_INTERNAL_ARGS, TRACE_INTERNAL_NUM_INTERNAL_ARGS), \
+ args); \
+ } while (0)
+
+#define TRACE_INTERNAL_BLOB_EVENT(category_literal, name_literal, blob, blob_size, args...) \
+ do { \
+ TRACE_INTERNAL_EVENT_RECORD( \
+ (category_literal), \
+ trace_internal_write_blob_event_record_and_release_context( \
+ TRACE_INTERNAL_CONTEXT, &TRACE_INTERNAL_CATEGORY_REF, (name_literal), (blob), \
+ (blob_size), TRACE_INTERNAL_ARGS, TRACE_INTERNAL_NUM_INTERNAL_ARGS), \
+ args); \
+ } while (0)
+
+#define TRACE_INTERNAL_BLOB_ATTACHMENT(category_literal, name_literal, blob, blob_size) \
+ do { \
+ static trace_site_t TRACE_INTERNAL_SITE_STATE; \
+ trace_string_ref_t TRACE_INTERNAL_CATEGORY_REF; \
+ trace_context_t* TRACE_INTERNAL_CONTEXT = trace_acquire_context_for_category_cached( \
+ (category_literal), &TRACE_INTERNAL_SITE_STATE, &TRACE_INTERNAL_CATEGORY_REF); \
+ if (unlikely(TRACE_INTERNAL_CONTEXT)) { \
+ trace_internal_write_blob_attachment_record_and_release_context( \
+ TRACE_INTERNAL_CONTEXT, &TRACE_INTERNAL_CATEGORY_REF, (name_literal), blob, blob_size); \
+ } \
+ } while (0)
+
+#define TRACE_INTERNAL_KERNEL_OBJECT(handle, args...) \
+ do { \
+ TRACE_INTERNAL_SIMPLE_RECORD( \
+ trace_internal_write_kernel_object_record_for_handle_and_release_context( \
+ TRACE_INTERNAL_CONTEXT, (handle), TRACE_INTERNAL_ARGS, \
+ TRACE_INTERNAL_NUM_INTERNAL_ARGS), \
+ args); \
+ } while (0)
+
+#define TRACE_INTERNAL_BLOB(type, name, blob, blob_size) \
+ do { \
+ trace_context_t* TRACE_INTERNAL_CONTEXT = trace_acquire_context(); \
+ if (unlikely(TRACE_INTERNAL_CONTEXT)) { \
+ trace_internal_write_blob_record_and_release_context(TRACE_INTERNAL_CONTEXT, (type), (name), \
+ (blob), (blob_size)); \
+ } \
+ } while (0)
+
+#ifndef NTRACE
+#define TRACE_INTERNAL_ALERT(category_literal, alert_name) \
+ do { \
+ trace_string_ref_t TRACE_INTERNAL_CATEGORY_REF; \
+ trace_context_t* TRACE_INTERNAL_CONTEXT = \
+ trace_acquire_context_for_category((category_literal), &TRACE_INTERNAL_CATEGORY_REF); \
+ if (unlikely(TRACE_INTERNAL_CONTEXT)) { \
+ trace_internal_send_alert_and_release_context(TRACE_INTERNAL_CONTEXT, (alert_name)); \
+ } \
+ } while (0)
+#else
+#define TRACE_INTERNAL_ALERT(category_literal, alert_name) \
+ ((void)(alert_name), (void)(category_literal), false)
+#endif // NTRACE
+
+///////////////////////////////////////////////////////////////////////////////
+
+// When "destroyed" (by the cleanup attribute), writes a duration event.
+typedef struct trace_internal_duration_scope {
+ const char* category_literal;
+ const char* name_literal;
+ trace_ticks_t start_time;
+ trace_arg_t* args;
+ size_t num_args;
+} trace_internal_duration_scope_t;
+
+void trace_internal_write_instant_event_record_and_release_context(
+ trace_context_t* context, const trace_string_ref_t* category_ref, const char* name_literal,
+ trace_scope_t scope, trace_arg_t* args, size_t num_args);
+
+void trace_internal_write_counter_event_record_and_release_context(
+ trace_context_t* context, const trace_string_ref_t* category_ref, const char* name_literal,
+ uint64_t counter_id, trace_arg_t* args, size_t num_args);
+
+void trace_internal_write_duration_begin_event_record_and_release_context(
+ trace_context_t* context, const trace_string_ref_t* category_ref, const char* name_literal,
+ trace_arg_t* args, size_t num_args);
+
+void trace_internal_write_duration_end_event_record_and_release_context(
+ trace_context_t* context, const trace_string_ref_t* category_ref, const char* name_literal,
+ trace_arg_t* args, size_t num_args);
+
+void trace_internal_write_duration_event_record(const trace_internal_duration_scope_t* scope);
+
+void trace_internal_write_async_begin_event_record_and_release_context(
+ trace_context_t* context, const trace_string_ref_t* category_ref, const char* name_literal,
+ trace_async_id_t async_id, trace_arg_t* args, size_t num_args);
+
+void trace_internal_write_async_instant_event_record_and_release_context(
+ trace_context_t* context, const trace_string_ref_t* category_ref, const char* name_literal,
+ trace_async_id_t async_id, trace_arg_t* args, size_t num_args);
+
+void trace_internal_write_async_end_event_record_and_release_context(
+ trace_context_t* context, const trace_string_ref_t* category_ref, const char* name_literal,
+ trace_async_id_t async_id, trace_arg_t* args, size_t num_args);
+
+void trace_internal_write_flow_begin_event_record_and_release_context(
+ trace_context_t* context, const trace_string_ref_t* category_ref, const char* name_literal,
+ trace_flow_id_t flow_id, trace_arg_t* args, size_t num_args);
+
+void trace_internal_write_flow_step_event_record_and_release_context(
+ trace_context_t* context, const trace_string_ref_t* category_ref, const char* name_literal,
+ trace_flow_id_t flow_id, trace_arg_t* args, size_t num_args);
+
+void trace_internal_write_flow_end_event_record_and_release_context(
+ trace_context_t* context, const trace_string_ref_t* category_ref, const char* name_literal,
+ trace_flow_id_t flow_id, trace_arg_t* args, size_t num_args);
+
+void trace_internal_write_blob_event_record_and_release_context(
+ trace_context_t* context, const trace_string_ref_t* category_ref, const char* name_literal,
+ const void* blob, size_t blob_size, trace_arg_t* args, size_t num_args);
+
+void trace_internal_write_blob_attachment_record_and_release_context(
+ trace_context_t* context, const trace_string_ref_t* category_ref, const char* name_literal,
+ const void* blob, size_t blob_size);
+
+void trace_internal_write_kernel_object_record_for_handle_and_release_context(
+ trace_context_t* context, zx_handle_t handle, trace_arg_t* args, size_t num_args);
+
+void trace_internal_write_blob_record_and_release_context(trace_context_t* context,
+ trace_blob_type_t type,
+ const char* name_literal,
+ const void* blob, size_t blob_size);
+
+void trace_internal_send_alert_and_release_context(trace_context_t* context,
+ const char* alert_name);
+
+#ifndef NTRACE
+
+static inline void trace_internal_make_duration_scope(trace_internal_duration_scope_t* scope,
+ const char* category_literal,
+ const char* name_literal, trace_arg_t* args,
+ size_t num_args) {
+ scope->category_literal = category_literal;
+ scope->name_literal = name_literal;
+ scope->start_time = zx_ticks_get();
+ scope->args = args;
+ scope->num_args = num_args;
+}
+
+static inline void trace_internal_cleanup_duration_scope(trace_internal_duration_scope_t* scope) {
+ // Check if the scope has been initialized. It can be un-initialized if
+ // tracing started after the scope was created or tracing is off.
+ if (likely(scope->start_time == 0))
+ return;
+ trace_internal_write_duration_event_record(scope);
+}
+#endif // NTRACE
+
+__END_CDECLS
+
+#endif // LIB_TRACE_INTERNAL_EVENT_INTERNAL_H_
diff --git a/third_party/fuchsia-sdk/pkg/trace/include/lib/trace/internal/pairs_internal.h b/third_party/fuchsia-sdk/pkg/trace/include/lib/trace/internal/pairs_internal.h
new file mode 100644
index 0000000..536c5c5
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/trace/include/lib/trace/internal/pairs_internal.h
@@ -0,0 +1,211 @@
+// Copyright 2017 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.
+
+//
+// Internal declarations used by the C tracing macros.
+// This is not part of the public API: use <trace/event.h> instead.
+//
+
+#ifndef ZIRCON_SYSTEM_ULIB_LIB_TRACE_INTERNAL_PAIRS_INTERNAL_H_
+#define ZIRCON_SYSTEM_ULIB_LIB_TRACE_INTERNAL_PAIRS_INTERNAL_H_
+
+// Count the number of pairs of arguments passed to it without evaluating them.
+// When the number of arguments is uneven, rounds down.
+// Works with 0 to 15 pairs.
+#define TRACE_INTERNAL_COUNT_PAIRS(...) \
+ TRACE_INTERNAL_COUNT_PAIRS_(__VA_ARGS__, 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8, \
+ 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0)
+#define TRACE_INTERNAL_COUNT_PAIRS_(_15, _15X, _14, _14X, _13, _13X, _12, _12X, _11, _11X, _10, \
+ _10X, _9, _9X, _8, _8X, _7, _7X, _6, _6X, _5, _5X, _4, _4X, \
+ _3, _3X, _2, _2X, _1, _1X, N, ...) \
+ N
+
+// Applies a function or macro to each pair of arguments.
+// Works with 0 to 15 pairs.
+//
+// |fn| is the function or macro name to apply
+// |vn| is the name of a local variable that the caller may be using. It is
+// passed on to |fn| in case it needs it, e.g., to uniquify any further local
+// variable names that |fn| as a macro may want to create.
+//
+// |fn| must accept four arguments:
+// - |vn|, described above
+// - |idx|, which is 0,1,2,...,15 and designates the index of the name/value
+// pair in the provided list
+// - |key|, which is the key part of the key/value pair
+// - |value|, which is the value part of the key/value pair
+//
+// Example:
+// #define MY_FN(vn, idx, a, b)
+// TRACE_INTERNAL_APPLY_PAIRWISE(MY_FN, my_var, "x", 1, "y", 2)
+
+#define TRACE_INTERNAL_APPLY_PAIRWISE(fn, vn, ...) \
+ TRACE_INTERNAL_APPLY_PAIRWISE_(TRACE_INTERNAL_COUNT_PAIRS(__VA_ARGS__)) \
+ (fn, vn, __VA_ARGS__)
+#define TRACE_INTERNAL_APPLY_PAIRWISE_(n) TRACE_INTERNAL_APPLY_PAIRWISE__(n)
+#define TRACE_INTERNAL_APPLY_PAIRWISE__(n) TRACE_INTERNAL_APPLY_PAIRWISE##n
+// clang-format off
+#define TRACE_INTERNAL_APPLY_PAIRWISE0(fn, vn, ...)
+#define TRACE_INTERNAL_APPLY_PAIRWISE1(fn, vn, k1, v1) \
+ fn(vn, 1, k1, v1)
+#define TRACE_INTERNAL_APPLY_PAIRWISE2(fn, vn, k1, v1, k2, v2) \
+ fn(vn, 1, k1, v1) fn(vn, 2, k2, v2)
+#define TRACE_INTERNAL_APPLY_PAIRWISE3(fn, vn, k1, v1, k2, v2, k3, v3) \
+ fn(vn, 1, k1, v1) fn(vn, 2, k2, v2) fn(vn, 3, k3, v3)
+#define TRACE_INTERNAL_APPLY_PAIRWISE4(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4) \
+ fn(vn, 1, k1, v1) fn(vn, 2, k2, v2) fn(vn, 3, k3, v3) fn(vn, 4, k4, v4)
+#define TRACE_INTERNAL_APPLY_PAIRWISE5(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \
+ k5, v5) \
+ fn(vn, 1, k1, v1) fn(vn, 2, k2, v2) fn(vn, 3, k3, v3) fn(vn, 4, k4, v4) \
+ fn(vn, 5, k5, v5)
+#define TRACE_INTERNAL_APPLY_PAIRWISE6(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \
+ k5, v5, k6, v6) \
+ fn(vn, 1, k1, v1) fn(vn, 2, k2, v2) fn(vn, 3, k3, v3) fn(vn, 4, k4, v4) \
+ fn(vn, 5, k5, v5) fn(vn, 6, k6, v6)
+#define TRACE_INTERNAL_APPLY_PAIRWISE7(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \
+ k5, v5, k6, v6, k7, v7) \
+ fn(vn, 1, k1, v1) fn(vn, 2, k2, v2) fn(vn, 3, k3, v3) fn(vn, 4, k4, v4) \
+ fn(vn, 5, k5, v5) fn(vn, 6, k6, v6) fn(vn, 7, k7, v7)
+#define TRACE_INTERNAL_APPLY_PAIRWISE8(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \
+ k5, v5, k6, v6, k7, v7, k8, v8) \
+ fn(vn, 1, k1, v1) fn(vn, 2, k2, v2) fn(vn, 3, k3, v3) fn(vn, 4, k4, v4) \
+ fn(vn, 5, k5, v5) fn(vn, 6, k6, v6) fn(vn, 7, k7, v7) fn(vn, 8, k8, v8)
+#define TRACE_INTERNAL_APPLY_PAIRWISE9(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \
+ k5, v5, k6, v6, k7, v7, k8, v8, \
+ k9, v9) \
+ fn(vn, 1, k1, v1) fn(vn, 2, k2, v2) fn(vn, 3, k3, v3) fn(vn, 4, k4, v4) \
+ fn(vn, 5, k5, v5) fn(vn, 6, k6, v6) fn(vn, 7, k7, v7) fn(vn, 8, k8, v8) \
+ fn(vn, 9, k9, v9)
+#define TRACE_INTERNAL_APPLY_PAIRWISE10(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \
+ k5, v5, k6, v6, k7, v7, k8, v8, \
+ k9, v9, k10, v10) \
+ fn(vn, 1, k1, v1) fn(vn, 2, k2, v2) fn(vn, 3, k3, v3) fn(vn, 4, k4, v4) \
+ fn(vn, 5, k5, v5) fn(vn, 6, k6, v6) fn(vn, 7, k7, v7) fn(vn, 8, k8, v8) \
+ fn(vn, 9, k9, v9) fn(vn, 10, k10, v10)
+#define TRACE_INTERNAL_APPLY_PAIRWISE11(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \
+ k5, v5, k6, v6, k7, v7, k8, v8, \
+ k9, v9, k10, v10, k11, v11) \
+ fn(vn, 1, k1, v1) fn(vn, 2, k2, v2) fn(vn, 3, k3, v3) fn(vn, 4, k4, v4) \
+ fn(vn, 5, k5, v5) fn(vn, 6, k6, v6) fn(vn, 7, k7, v7) fn(vn, 8, k8, v8) \
+ fn(vn, 9, k9, v9) fn(vn, 10, k10, v10) fn(vn, 11, k11, v11)
+#define TRACE_INTERNAL_APPLY_PAIRWISE12(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \
+ k5, v5, k6, v6, k7, v7, k8, v8, \
+ k9, v9, k10, v10, k11, v11, k12, v12) \
+ fn(vn, 1, k1, v1) fn(vn, 2, k2, v2) fn(vn, 3, k3, v3) fn(vn, 4, k4, v4) \
+ fn(vn, 5, k5, v5) fn(vn, 6, k6, v6) fn(vn, 7, k7, v7) fn(vn, 8, k8, v8) \
+ fn(vn, 9, k9, v9) fn(vn, 10, k10, v10) fn(vn, 11, k11, v11) fn(vn, 12, k12, v12)
+#define TRACE_INTERNAL_APPLY_PAIRWISE13(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \
+ k5, v5, k6, v6, k7, v7, k8, v8, \
+ k9, v9, k10, v10, k11, v11, k12, v12, \
+ k13, v13) \
+ fn(vn, 1, k1, v1) fn(vn, 2, k2, v2) fn(vn, 3, k3, v3) fn(vn, 4, k4, v4) \
+ fn(vn, 5, k5, v5) fn(vn, 6, k6, v6) fn(vn, 7, k7, v7) fn(vn, 8, k8, v8) \
+ fn(vn, 9, k9, v9) fn(vn, 10, k10, v10) fn(vn, 11, k11, v11) fn(vn, 12, k12, v12) \
+ fn(vn, 13, k13, v13)
+#define TRACE_INTERNAL_APPLY_PAIRWISE14(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \
+ k5, v5, k6, v6, k7, v7, k8, v8, \
+ k9, v9, k10, v10, k11, v11, k12, v12, \
+ k13, v13, k14, v14) \
+ fn(vn, 1, k1, v1) fn(vn, 2, k2, v2) fn(vn, 3, k3, v3) fn(vn, 4, k4, v4) \
+ fn(vn, 5, k5, v5) fn(vn, 6, k6, v6) fn(vn, 7, k7, v7) fn(vn, 8, k8, v8) \
+ fn(vn, 9, k9, v9) fn(vn, 10, k10, v10) fn(vn, 11, k11, v11) fn(vn, 12, k12, v12) \
+ fn(vn, 13, k13, v13) fn(vn, 14, k14, v14)
+#define TRACE_INTERNAL_APPLY_PAIRWISE15(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \
+ k5, v5, k6, v6, k7, v7, k8, v8, \
+ k9, v9, k10, v10, k11, v11, k12, v12, \
+ k13, v13, k14, v14, k15, v15) \
+ fn(vn, 1, k1, v1) fn(vn, 2, k2, v2) fn(vn, 3, k3, v3) fn(vn, 4, k4, v4) \
+ fn(vn, 5, k5, v5) fn(vn, 6, k6, v6) fn(vn, 7, k7, v7) fn(vn, 8, k8, v8) \
+ fn(vn, 9, k9, v9) fn(vn, 10, k10, v10) fn(vn, 11, k11, v11) fn(vn, 12, k12, v12) \
+ fn(vn, 13, k13, v13) fn(vn, 14, k14, v14) fn(vn, 15, k15, v15)
+// clang-format on
+
+// Applies a function or macro to each pair of arguments to produce a
+// comma-separated result. Works with 0 to 15 pairs.
+//
+// Example:
+// #define MY_FN(vn, idx, a, b)
+// TRACE_INTERNAL_APPLY_PAIRWISE_CSV(MY_FN, my_var, "x", 1, "y", 2)
+#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV(fn, vn, ...) \
+ TRACE_INTERNAL_APPLY_PAIRWISE_CSV_(TRACE_INTERNAL_COUNT_PAIRS(__VA_ARGS__)) \
+ (fn, vn, __VA_ARGS__)
+#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV_(n) TRACE_INTERNAL_APPLY_PAIRWISE_CSV__(n)
+#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV__(n) TRACE_INTERNAL_APPLY_PAIRWISE_CSV##n
+// clang-format off
+#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV0(fn, vn, ...)
+#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV1(fn, vn, k1, v1) \
+ fn(vn, 1, k1, v1)
+#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV2(fn, vn, k1, v1, k2, v2) \
+ fn(vn, 1, k1, v1), fn(vn, 2, k2, v2)
+#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV3(fn, vn, k1, v1, k2, v2, k3, v3) \
+ fn(vn, 1, k1, v1), fn(vn, 2, k2, v2), fn(vn, 3, k3, v3)
+#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV4(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4) \
+ fn(vn, 1, k1, v1), fn(vn, 2, k2, v2), fn(vn, 3, k3, v3), fn(vn, 4, k4, v4)
+#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV5(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \
+ k5, v5) \
+ fn(vn, 1, k1, v1), fn(vn, 2, k2, v2), fn(vn, 3, k3, v3), fn(vn, 4, k4, v4), \
+ fn(vn, 5, k5, v5)
+#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV6(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \
+ k5, v5, k6, v6) \
+ fn(vn, 1, k1, v1), fn(vn, 2, k2, v2), fn(vn, 3, k3, v3), fn(vn, 4, k4, v4), \
+ fn(vn, 5, k5, v5), fn(vn, 6, k6, v6)
+#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV7(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \
+ k5, v5, k6, v6, k7, v7) \
+ fn(vn, 1, k1, v1), fn(vn, 2, k2, v2), fn(vn, 3, k3, v3), fn(vn, 4, k4, v4), \
+ fn(vn, 5, k5, v5), fn(vn, 6, k6, v6), fn(vn, 7, k7, v7)
+#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV8(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \
+ k5, v5, k6, v6, k7, v7, k8, v8) \
+ fn(vn, 1, k1, v1), fn(vn, 2, k2, v2), fn(vn, 3, k3, v3), fn(vn, 4, k4, v4), \
+ fn(vn, 5, k5, v5), fn(vn, 6, k6, v6), fn(vn, 7, k7, v7), fn(vn, 8, k8, v8)
+#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV9(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \
+ k5, v5, k6, v6, k7, v7, k8, v8, \
+ k9, v9) \
+ fn(vn, 1, k1, v1), fn(vn, 2, k2, v2), fn(vn, 3, k3, v3), fn(vn, 4, k4, v4), \
+ fn(vn, 5, k5, v5), fn(vn, 6, k6, v6), fn(vn, 7, k7, v7), fn(vn, 8, k8, v8), \
+ fn(vn, 9, k9, v9)
+#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV10(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \
+ k5, v5, k6, v6, k7, v7, k8, v8, \
+ k9, v9, k10, v10) \
+ fn(vn, 1, k1, v1), fn(vn, 2, k2, v2), fn(vn, 3, k3, v3), fn(vn, 4, k4, v4), \
+ fn(vn, 5, k5, v5), fn(vn, 6, k6, v6), fn(vn, 7, k7, v7), fn(vn, 8, k8, v8), \
+ fn(vn, 9, k9, v9), fn(vn, 10, k10, v10)
+#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV11(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \
+ k5, v5, k6, v6, k7, v7, k8, v8, \
+ k9, v9, k10, v10, k11, v11) \
+ fn(vn, 1, k1, v1), fn(vn, 2, k2, v2), fn(vn, 3, k3, v3), fn(vn, 4, k4, v4), \
+ fn(vn, 5, k5, v5), fn(vn, 6, k6, v6), fn(vn, 7, k7, v7), fn(vn, 8, k8, v8), \
+ fn(vn, 9, k9, v9), fn(vn, 10, k10, v10), fn(vn, 11, k11, v11)
+#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV12(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \
+ k5, v5, k6, v6, k7, v7, k8, v8, \
+ k9, v9, k10, v10, k11, v11, k12, v12) \
+ fn(vn, 1, k1, v1), fn(vn, 2, k2, v2), fn(vn, 3, k3, v3), fn(vn, 4, k4, v4), \
+ fn(vn, 5, k5, v5), fn(vn, 6, k6, v6), fn(vn, 7, k7, v7), fn(vn, 8, k8, v8), \
+ fn(vn, 9, k9, v9), fn(vn, 10, k10, v10), fn(vn, 11, k11, v11), fn(vn, 12, k12, v12)
+#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV13(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \
+ k5, v5, k6, v6, k7, v7, k8, v8, \
+ k9, v9, k10, v10, k11, v11, k12, v12, \
+ k13, v13) \
+ fn(vn, 1, k1, v1), fn(vn, 2, k2, v2), fn(vn, 3, k3, v3), fn(vn, 4, k4, v4), \
+ fn(vn, 5, k5, v5), fn(vn, 6, k6, v6), fn(vn, 7, k7, v7), fn(vn, 8, k8, v8), \
+ fn(vn, 9, k9, v9), fn(vn, 10, k10, v10), fn(vn, 11, k11, v11), fn(vn, 12, k12, v12), \
+ fn(vn, 13, k13, v13)
+#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV14(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \
+ k5, v5, k6, v6, k7, v7, k8, v8, \
+ k9, v9, k10, v10, k11, v11, k12, v12, \
+ k13, v13, k14, v14) \
+ fn(vn, 1, k1, v1), fn(vn, 2, k2, v2), fn(vn, 3, k3, v3), fn(vn, 4, k4, v4), \
+ fn(vn, 5, k5, v5), fn(vn, 6, k6, v6), fn(vn, 7, k7, v7), fn(vn, 8, k8, v8), \
+ fn(vn, 9, k9, v9), fn(vn, 10, k10, v10), fn(vn, 11, k11, v11), fn(vn, 12, k12, v12), \
+ fn(vn, 13, k13, v13), fn(vn, 14, k14, v14)
+#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV15(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \
+ k5, v5, k6, v6, k7, v7, k8, v8, \
+ k9, v9, k10, v10, k11, v11, k12, v12, \
+ k13, v13, k14, v14, k15, v15) \
+ fn(vn, 1, k1, v1), fn(vn, 2, k2, v2), fn(vn, 3, k3, v3), fn(vn, 4, k4, v4), \
+ fn(vn, 5, k5, v5), fn(vn, 6, k6, v6), fn(vn, 7, k7, v7), fn(vn, 8, k8, v8), \
+ fn(vn, 9, k9, v9), fn(vn, 10, k10, v10), fn(vn, 11, k11, v11), fn(vn, 12, k12, v12), \
+ fn(vn, 13, k13, v13), fn(vn, 14, k14, v14), fn(vn, 15, k15, v15)
+// clang-format on
+
+#endif // ZIRCON_SYSTEM_ULIB_LIB_TRACE_INTERNAL_PAIRS_INTERNAL_H_
diff --git a/third_party/fuchsia-sdk/pkg/trace/include/lib/trace/internal/string_traits.h b/third_party/fuchsia-sdk/pkg/trace/include/lib/trace/internal/string_traits.h
new file mode 100644
index 0000000..c918863
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/trace/include/lib/trace/internal/string_traits.h
@@ -0,0 +1,68 @@
+// Copyright 2017 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.
+
+// This header provides functions which make it easier to work generically
+// with string-like objects such as fbl::StringPiece, fbl::String, std::string,
+// and std::string_view.
+
+#ifndef LIB_TRACE_INTERNAL_STRING_TRAITS_H_
+#define LIB_TRACE_INTERNAL_STRING_TRAITS_H_
+
+#include <stddef.h>
+
+#include <type_traits>
+
+namespace trace {
+namespace internal {
+
+// Macro for defining a trait that checks if a type T has a method with the
+// given name. See fbl/macros.h.
+//
+// Example:
+//
+// TRACE_INTERNAL_DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(
+// has_c_str, c_str, const char* (C::*)() const);
+#define TRACE_INTERNAL_DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(trait_name, fn_name, sig) \
+ template <typename T> \
+ struct trait_name { \
+ private: \
+ template <typename C> \
+ static std::true_type test(decltype(static_cast<sig>(&C::fn_name))); \
+ template <typename C> \
+ static std::false_type test(...); \
+ \
+ public: \
+ static constexpr bool value = decltype(test<T>(nullptr))::value; \
+ }; \
+ template <typename T> \
+ static /*inline*/ constexpr bool trait_name##_v = trait_name<T>::value
+
+TRACE_INTERNAL_DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_data, data, const char* (C::*)() const);
+TRACE_INTERNAL_DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_length, length, size_t (C::*)() const);
+
+#undef TRACE_INTERNAL_DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE
+
+// Gets the character data from a string-like object.
+template <typename T>
+constexpr const char* GetStringData(const T& value) {
+ return value.data();
+}
+
+// Gets the length (in characters) of a string-like object.
+template <typename T>
+constexpr size_t GetStringLength(const T& value) {
+ return value.length();
+}
+
+// is_string_like_v<T>
+//
+// Evaluates to true if GetStringData() and GetStringLength() are supported
+// instances of type T.
+template <typename T>
+using is_string_like = std::integral_constant<bool, has_data_v<T> && has_length_v<T>>;
+
+} // namespace internal
+} // namespace trace
+
+#endif // LIB_TRACE_INTERNAL_STRING_TRAITS_H_
diff --git a/third_party/fuchsia-sdk/pkg/trace/include/lib/trace/observer.h b/third_party/fuchsia-sdk/pkg/trace/include/lib/trace/observer.h
new file mode 100644
index 0000000..0fd6604
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/trace/include/lib/trace/observer.h
@@ -0,0 +1,58 @@
+// Copyright 2017 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.
+
+//
+// Trace observers allow components to observe when tracing is starting or
+// stopping so they can prepare themselves to capture data accordingly.
+//
+// See <trace-engine/instrumentation.h> for the C API and more detailed
+// documentation.
+//
+
+#ifndef ZIRCON_SYSTEM_ULIB_LIB_TRACE_OBSERVER_H_
+#define ZIRCON_SYSTEM_ULIB_LIB_TRACE_OBSERVER_H_
+
+#include <lib/trace-engine/instrumentation.h>
+
+#ifdef __cplusplus
+
+#include <lib/async/cpp/wait.h>
+#include <lib/fit/function.h>
+#include <lib/zx/event.h>
+
+namespace trace {
+
+// Receives notifications when the trace state or set of enabled categories changes.
+class TraceObserver {
+ public:
+ // Initializes the trace observer.
+ TraceObserver();
+
+ // Stops watching for state changes and destroys the observer.
+ ~TraceObserver();
+
+ // Starts watching for state changes.
+ //
+ // |async| the asynchronous dispatcher, must not be null.
+ // |callback| the callback which is invoked whenever a state change is observed.
+ void Start(async_dispatcher_t* dispatcher, fit::closure callback);
+
+ // Stops watching for state changes.
+ void Stop();
+
+ private:
+ void Handle(async_dispatcher_t* dispatcher, async::WaitBase* wait, zx_status_t status,
+ const zx_packet_signal_t* signal);
+ void BeginWait(async_dispatcher_t* dispatcher);
+
+ fit::closure callback_;
+ zx::event event_;
+ async::WaitMethod<TraceObserver, &TraceObserver::Handle> wait_{this};
+};
+
+} // namespace trace
+
+#endif // __cplusplus
+
+#endif // ZIRCON_SYSTEM_ULIB_LIB_TRACE_OBSERVER_H_
diff --git a/third_party/fuchsia-sdk/pkg/trace/meta.json b/third_party/fuchsia-sdk/pkg/trace/meta.json
new file mode 100644
index 0000000..950dcbe
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/trace/meta.json
@@ -0,0 +1,29 @@
+{
+ "banjo_deps": [],
+ "deps": [
+ "async",
+ "trace-engine",
+ "async-cpp",
+ "fit",
+ "zx"
+ ],
+ "fidl_deps": [],
+ "headers": [
+ "pkg/trace/include/lib/trace/internal/event_args.h",
+ "pkg/trace/include/lib/trace/internal/event_common.h",
+ "pkg/trace/include/lib/trace/internal/event_internal.h",
+ "pkg/trace/include/lib/trace/internal/pairs_internal.h",
+ "pkg/trace/include/lib/trace/internal/string_traits.h",
+ "pkg/trace/include/lib/trace/event.h",
+ "pkg/trace/include/lib/trace/event_args.h",
+ "pkg/trace/include/lib/trace/observer.h"
+ ],
+ "include_dir": "pkg/trace/include",
+ "name": "trace",
+ "root": "pkg/trace",
+ "sources": [
+ "pkg/trace/event.cc",
+ "pkg/trace/observer.cc"
+ ],
+ "type": "cc_source_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/trace/observer.cc b/third_party/fuchsia-sdk/pkg/trace/observer.cc
new file mode 100644
index 0000000..a4f5021
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/trace/observer.cc
@@ -0,0 +1,75 @@
+// Copyright 2017 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.
+
+#include <lib/trace/observer.h>
+
+#include <zircon/assert.h>
+
+#include <utility>
+
+namespace trace {
+
+TraceObserver::TraceObserver() {}
+
+TraceObserver::~TraceObserver() { Stop(); }
+
+void TraceObserver::Start(async_dispatcher_t* dispatcher, fit::closure callback) {
+ ZX_DEBUG_ASSERT(dispatcher);
+ ZX_DEBUG_ASSERT(callback);
+
+ Stop();
+ callback_ = std::move(callback);
+
+ zx_status_t status = zx::event::create(0u, &event_);
+ ZX_ASSERT(status == ZX_OK);
+ trace_register_observer(event_.get());
+
+ wait_.set_object(event_.get());
+ wait_.set_trigger(ZX_EVENT_SIGNALED);
+ BeginWait(dispatcher);
+}
+
+void TraceObserver::Stop() {
+ wait_.Cancel();
+ callback_ = nullptr;
+
+ if (event_) {
+ trace_unregister_observer(event_.get());
+ event_.reset();
+ }
+}
+
+void TraceObserver::Handle(async_dispatcher_t* dispatcher, async::WaitBase* wait,
+ zx_status_t status, const zx_packet_signal_t* signal) {
+ if (status != ZX_OK) {
+ Stop();
+ return;
+ }
+
+ ZX_DEBUG_ASSERT(status == ZX_OK);
+ ZX_DEBUG_ASSERT(signal->observed & ZX_EVENT_SIGNALED);
+
+ // Clear the signal otherwise we'll keep getting called.
+ // Clear the signal *before* invoking the callback because there's no
+ // synchronization between the engine and the observers, thus it's possible
+ // that an observer could get back to back notifications.
+ event_.signal(ZX_EVENT_SIGNALED, 0u);
+
+ // Invoke the callback.
+ callback_();
+
+ // Tell engine we're done.
+ trace_notify_observer_updated(event_.get());
+
+ // Wait again!
+ BeginWait(dispatcher);
+}
+
+void TraceObserver::BeginWait(async_dispatcher_t* dispatcher) {
+ zx_status_t status = wait_.Begin(dispatcher);
+ if (status != ZX_OK)
+ Stop();
+}
+
+} // namespace trace
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/BUILD.gn b/third_party/fuchsia-sdk/pkg/vfs_cpp/BUILD.gn
new file mode 100644
index 0000000..022926e
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/BUILD.gn
@@ -0,0 +1,60 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("vfs_cpp") {
+ sources = [
+ "composed_service_dir.cc",
+ "internal/connection.cc",
+ "internal/directory.cc",
+ "internal/directory_connection.cc",
+ "internal/dirent_filler.cc",
+ "internal/file.cc",
+ "internal/file_connection.cc",
+ "internal/node.cc",
+ "internal/node_connection.cc",
+ "lazy_dir.cc",
+ "pseudo_dir.cc",
+ "pseudo_file.cc",
+ "remote_dir.cc",
+ "service.cc",
+ "vmo_file.cc",
+ "include/lib/vfs/cpp/composed_service_dir.h",
+ "include/lib/vfs/cpp/flags.h",
+ "include/lib/vfs/cpp/internal/connection.h",
+ "include/lib/vfs/cpp/internal/directory.h",
+ "include/lib/vfs/cpp/internal/directory_connection.h",
+ "include/lib/vfs/cpp/internal/dirent_filler.h",
+ "include/lib/vfs/cpp/internal/file.h",
+ "include/lib/vfs/cpp/internal/file_connection.h",
+ "include/lib/vfs/cpp/internal/node.h",
+ "include/lib/vfs/cpp/internal/node_connection.h",
+ "include/lib/vfs/cpp/lazy_dir.h",
+ "include/lib/vfs/cpp/node_kind.h",
+ "include/lib/vfs/cpp/pseudo_dir.h",
+ "include/lib/vfs/cpp/pseudo_file.h",
+ "include/lib/vfs/cpp/remote_dir.h",
+ "include/lib/vfs/cpp/service.h",
+ "include/lib/vfs/cpp/vmo_file.h",
+ ]
+ include_dirs = [ "include" ]
+ public_deps = [
+ "../../fidl/fuchsia.io",
+ "../async",
+ "../fdio",
+ "../fidl_cpp",
+ "../zx",
+ ]
+}
+
+group("all"){
+ deps = [
+ ":vfs_cpp",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/composed_service_dir.cc b/third_party/fuchsia-sdk/pkg/vfs_cpp/composed_service_dir.cc
new file mode 100644
index 0000000..815d549
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/composed_service_dir.cc
@@ -0,0 +1,58 @@
+// Copyright 2018 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.
+
+#include <lib/async/default.h>
+#include <lib/fdio/directory.h>
+#include <lib/vfs/cpp/composed_service_dir.h>
+#include <zircon/status.h>
+
+namespace vfs {
+
+ComposedServiceDir::ComposedServiceDir() : root_(std::make_unique<vfs::PseudoDir>()) {}
+
+ComposedServiceDir::~ComposedServiceDir() {}
+
+void ComposedServiceDir::set_fallback(fidl::InterfaceHandle<fuchsia::io::Directory> fallback_dir) {
+ fallback_dir_ = fallback_dir.TakeChannel();
+}
+
+void ComposedServiceDir::AddService(const std::string& service_name,
+ std::unique_ptr<vfs::Service> service) {
+ root_->AddEntry(service_name, std::move(service));
+}
+
+zx_status_t ComposedServiceDir::GetAttr(fuchsia::io::NodeAttributes* out_attributes) const {
+ return root_->GetAttr(out_attributes);
+}
+
+zx_status_t ComposedServiceDir::Readdir(uint64_t offset, void* data, uint64_t len,
+ uint64_t* out_offset, uint64_t* out_actual) {
+ return root_->Readdir(offset, data, len, out_offset, out_actual);
+}
+
+zx_status_t ComposedServiceDir::Lookup(const std::string& name, vfs::internal::Node** out) const {
+ zx_status_t status = root_->Lookup(name, out);
+ if (status == ZX_OK) {
+ return status;
+ }
+ if (fallback_dir_) {
+ auto entry = fallback_services_.find(name);
+ if (entry != fallback_services_.end()) {
+ *out = entry->second.get();
+ } else {
+ auto service = std::make_unique<vfs::Service>(
+ [name = std::string(name.data(), name.length()), dir = &fallback_dir_](
+ zx::channel request, async_dispatcher_t* dispatcher) {
+ fdio_service_connect_at(dir->get(), name.c_str(), request.release());
+ });
+ *out = service.get();
+ fallback_services_[name] = std::move(service);
+ }
+ } else {
+ return ZX_ERR_NOT_FOUND;
+ }
+ return ZX_OK;
+}
+
+} // namespace vfs
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/composed_service_dir.h b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/composed_service_dir.h
new file mode 100644
index 0000000..1b11436
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/composed_service_dir.h
@@ -0,0 +1,57 @@
+// Copyright 2018 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.
+
+#ifndef LIB_VFS_CPP_COMPOSED_SERVICE_DIR_H_
+#define LIB_VFS_CPP_COMPOSED_SERVICE_DIR_H_
+
+#include <fuchsia/io/cpp/fidl.h>
+#include <lib/vfs/cpp/pseudo_dir.h>
+#include <lib/vfs/cpp/service.h>
+
+#include <map>
+#include <string>
+
+namespace vfs {
+
+// A directory-like object which created a composed PseudoDir on top of
+// |fallback_dir|.It can be used to connect to services in |fallback_dir| but it
+// will not enumerate them.
+class ComposedServiceDir : public vfs::internal::Directory {
+ public:
+ ComposedServiceDir();
+ ~ComposedServiceDir() override;
+
+ void set_fallback(fidl::InterfaceHandle<fuchsia::io::Directory> fallback_dir);
+
+ void AddService(const std::string& service_name, std::unique_ptr<vfs::Service> service);
+
+ //
+ // |vfs::internal::Node| Implementations:
+ //
+ zx_status_t Lookup(const std::string& name, vfs::internal::Node** out_node) const final;
+
+ zx_status_t GetAttr(fuchsia::io::NodeAttributes* out_attributes) const final;
+
+ zx_status_t Readdir(uint64_t offset, void* data, uint64_t len, uint64_t* out_offset,
+ uint64_t* out_actual) final;
+
+ private:
+ std::unique_ptr<vfs::PseudoDir> root_;
+ zx::channel fallback_dir_;
+ // The collection of services that have been looked up on the fallback
+ // directory. These services are just passthrough in the sense that they
+ // forward connection requests to the fallback directory. Since there is no
+ // good way in the present context to know whether these service entries
+ // actually match an existing service, and since the present object must own
+ // these entries, we keep them around until the present object gets deleted.
+ mutable std::map<std::string, std::unique_ptr<vfs::Service>> fallback_services_;
+
+ // Disallow copy and assignment.
+ ComposedServiceDir(const ComposedServiceDir&) = delete;
+ ComposedServiceDir& operator=(const ComposedServiceDir&) = delete;
+};
+
+} // namespace vfs
+
+#endif // LIB_VFS_CPP_COMPOSED_SERVICE_DIR_H_
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/flags.h b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/flags.h
new file mode 100644
index 0000000..8cfd6b0
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/flags.h
@@ -0,0 +1,91 @@
+// 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.
+
+#ifndef LIB_VFS_CPP_FLAGS_H_
+#define LIB_VFS_CPP_FLAGS_H_
+
+#include <fuchsia/io/cpp/fidl.h>
+
+namespace vfs {
+
+class Flags {
+ public:
+ Flags() = delete;
+
+ static bool IsReadable(uint32_t flags) { return (flags & fuchsia::io::OPEN_RIGHT_READABLE) != 0; }
+
+ static bool IsWritable(uint32_t flags) { return (flags & fuchsia::io::OPEN_RIGHT_WRITABLE) != 0; }
+
+ static bool IsAdminable(uint32_t flags) { return (flags & fuchsia::io::OPEN_RIGHT_ADMIN) != 0; }
+
+ static bool IsDirectory(uint32_t flags) {
+ return (flags & fuchsia::io::OPEN_FLAG_DIRECTORY) != 0;
+ }
+
+ static bool IsNotDirectory(uint32_t flags) {
+ return (flags & fuchsia::io::OPEN_FLAG_NOT_DIRECTORY) != 0;
+ }
+
+ static bool ShouldDescribe(uint32_t flags) {
+ return (flags & fuchsia::io::OPEN_FLAG_DESCRIBE) != 0;
+ }
+
+ static bool IsNodeReference(uint32_t flags) {
+ return (flags & fuchsia::io::OPEN_FLAG_NODE_REFERENCE) != 0;
+ }
+
+ static bool ShouldCloneWithSameRights(uint32_t flags) {
+ return (flags & fuchsia::io::CLONE_FLAG_SAME_RIGHTS) != 0;
+ }
+
+ static bool IsPosix(uint32_t flags) { return (flags & fuchsia::io::OPEN_FLAG_POSIX) != 0; }
+
+ // All known rights.
+ static constexpr uint32_t kFsRights = fuchsia::io::OPEN_RIGHT_READABLE |
+ fuchsia::io::OPEN_RIGHT_WRITABLE |
+ fuchsia::io::OPEN_RIGHT_ADMIN;
+
+ // All lower 16 bits are reserved for future rights extensions.
+ static constexpr uint32_t kFsRightsSpace = 0x0000FFFF;
+
+ // Flags which can be modified by FIDL File::SetFlags.
+ static constexpr uint32_t kSettableStatusFlags = fuchsia::io::OPEN_FLAG_APPEND;
+
+ // All flags which indicate state of the connection (excluding rights).
+ static constexpr uint32_t kStatusFlags =
+ kSettableStatusFlags | fuchsia::io::OPEN_FLAG_NODE_REFERENCE;
+
+ // Returns true if the rights flags in |flags_a| does not exceed
+ // those in |flags_b|.
+ static bool StricterOrSameRights(uint32_t flags_a, uint32_t flags_b) {
+ uint32_t rights_a = flags_a & kFsRights;
+ uint32_t rights_b = flags_b & kFsRights;
+ return (rights_a & ~rights_b) == 0;
+ }
+
+ // Perform basic flags validation relevant to Directory::Open and Node::Clone.
+ // Returns false if the flags combination is invalid.
+ static bool InputPrecondition(uint32_t flags) {
+ // If the caller specified an unknown right, reject the request.
+ if ((flags & Flags::kFsRightsSpace) & ~Flags::kFsRights) {
+ return false;
+ }
+
+ // Explicitly reject NODE_REFERENCE together with any invalid flags.
+ if (Flags::IsNodeReference(flags)) {
+ constexpr uint32_t kValidFlagsForNodeRef =
+ fuchsia::io::OPEN_FLAG_NODE_REFERENCE | fuchsia::io::OPEN_FLAG_DIRECTORY |
+ fuchsia::io::OPEN_FLAG_NOT_DIRECTORY | fuchsia::io::OPEN_FLAG_DESCRIBE;
+ if (flags & ~kValidFlagsForNodeRef) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+};
+
+} // namespace vfs
+
+#endif // LIB_VFS_CPP_FLAGS_H_
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/internal/connection.h b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/internal/connection.h
new file mode 100644
index 0000000..6af58c8
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/internal/connection.h
@@ -0,0 +1,118 @@
+// 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.
+
+#ifndef LIB_VFS_CPP_INTERNAL_CONNECTION_H_
+#define LIB_VFS_CPP_INTERNAL_CONNECTION_H_
+
+#include <fuchsia/io/cpp/fidl.h>
+#include <lib/async/dispatcher.h>
+#include <lib/zx/channel.h>
+#include <stddef.h>
+#include <stdint.h>
+
+namespace vfs {
+namespace internal {
+
+class Node;
+
+// A connection to a file system object.
+//
+// A connection manages a single zx::channel, typically to another process.
+class Connection {
+ public:
+ // Create a connection with the given |flags|.
+ //
+ // |flags| define permissions and rights that this connection have over
+ // |Node|. They are defined in |fuchsia.io| fidl for example
+ // |OPEN_FLAG_DESCRIBE|. These are stored in this object for future use and no
+ // validations are performed.
+ explicit Connection(uint32_t flags);
+ virtual ~Connection();
+
+ Connection(const Connection&) = delete;
+ Connection& operator=(const Connection&) = delete;
+
+ // The flags associated with this connection.
+ //
+ // These flags are typically received from |fuchsia.io.Node/Clone| or
+ // |fuchsia.io.Directory/Open|.
+ //
+ // For example, |ZX_FS_RIGHT_READABLE|.
+ uint32_t flags() const { return flags_; }
+
+ // The current file offset.
+ //
+ // Typically used to position |read| and |write| operations. Can be adjusted
+ // using |lseek|.
+ uint64_t offset() const { return offset_; }
+ void set_offset(uint64_t offset) { offset_ = offset; }
+
+ // Associate |request| with this connection.
+ //
+ // Waits for messages asynchronously on the |request| channel using
+ // |dispatcher|. If |dispatcher| is |nullptr|, the implementation will call
+ // |async_get_default_dispatcher| to obtain the default dispatcher for the
+ // current thread.
+ //
+ // After calling internal functions from implementing classes this function
+ // will also send OnOpen event if |OPEN_FLAG_DESCRIBE| is present in |flags_|
+ // and binding is successful.
+ //
+ // Returns |ZX_ERR_BAD_STATE| if channel is already bound.
+ //
+ // Typically called during connection setup.
+ zx_status_t Bind(zx::channel request, async_dispatcher_t* dispatcher);
+
+ protected:
+ // Send OnOpen event for |fuchsia::io::Node|.
+ //
+ // This function will not check for |OPEN_FLAG_DESCRIBE|. Caller should do
+ // that. Every subclass must implement this.
+ //
+ // This should only be called from |Bind()|.
+ virtual void SendOnOpenEvent(zx_status_t status) = 0;
+
+ // Associate |request| with this connection.
+ //
+ // This function is called by |Connection::Bind()|.
+ //
+ // Waits for messages asynchronously on the |request| channel using
+ // |dispatcher|. If |dispatcher| is |nullptr|, the implementation will call
+ // |async_get_default_dispatcher| to obtain the default dispatcher for the
+ // current thread.
+ //
+ // Should returns |ZX_ERR_BAD_STATE| if channel is already bound.
+ virtual zx_status_t BindInternal(zx::channel request, async_dispatcher_t* dispatcher) = 0;
+
+ // Implementations for common |fuchsia.io.Node| operations. Used by
+ // subclasses to avoid code duplication.
+
+ void Clone(Node* vn, uint32_t flags, zx::channel request, async_dispatcher_t* dispatcher);
+ void Close(Node* vn, fuchsia::io::Node::CloseCallback callback);
+ void Describe(Node* vn, fuchsia::io::Node::DescribeCallback callback);
+ void Sync(Node* vn, fuchsia::io::Node::SyncCallback callback);
+ void GetAttr(Node* vn, fuchsia::io::Node::GetAttrCallback callback);
+ void SetAttr(Node* vn, uint32_t flags, fuchsia::io::NodeAttributes attributes,
+ fuchsia::io::Node::SetAttrCallback callback);
+
+ // returns |fuchsia.io.NodeInfo| if status is |ZX_OK|, else returns null
+ // inside unique_ptr.
+ std::unique_ptr<fuchsia::io::NodeInfo> NodeInfoIfStatusOk(Node* vn, zx_status_t status);
+
+ private:
+ // The flags associated with this connection.
+ //
+ // See |flags()| for more information.
+ uint32_t flags_ = 0u;
+
+ // The current file offset.
+ //
+ // See |offset()| for more information.
+ uint64_t offset_ = 0u;
+};
+
+} // namespace internal
+} // namespace vfs
+
+#endif // LIB_VFS_CPP_INTERNAL_CONNECTION_H_
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/internal/directory.h b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/internal/directory.h
new file mode 100644
index 0000000..2da5701
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/internal/directory.h
@@ -0,0 +1,112 @@
+
+// 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.
+
+#ifndef LIB_VFS_CPP_INTERNAL_DIRECTORY_H_
+#define LIB_VFS_CPP_INTERNAL_DIRECTORY_H_
+
+#include <fuchsia/io/cpp/fidl.h>
+#include <lib/vfs/cpp/internal/node.h>
+#include <stdint.h>
+
+#include <string>
+
+namespace vfs {
+
+namespace internal {
+
+// A directory object in a file system.
+//
+// Implements the |fuchsia.io.Directory| interface. Incoming connections are
+// owned by this object and will be destroyed when this object is destroyed.
+//
+// Subclass to implement specific directory semantics.
+//
+// See also:
+//
+// * File, which represents file objects.
+class Directory : public Node {
+ public:
+ Directory();
+ ~Directory() override;
+
+ // |Node| implementation
+ zx_status_t Lookup(const std::string& name, Node** out_node) const override;
+
+ // Override that describes this object as a directory.
+ void Describe(fuchsia::io::NodeInfo* out_info) override;
+
+ // Enumerates Directory
+ //
+ // |offset| will start with 0 and then implementation can set offset as it
+ // pleases.
+ //
+ // Returns |ZX_OK| if able to read at least one dentry else returns
+ // |ZX_ERR_INVALID_ARGS| with |out_actual| as 0 and |out_offset| as |offset|.
+ virtual zx_status_t Readdir(uint64_t offset, void* data, uint64_t len, uint64_t* out_offset,
+ uint64_t* out_actual) = 0;
+
+ // Parses path and opens correct node.
+ //
+ // Called from |fuchsia.io.Directory#Open|.
+ void Open(uint32_t open_flags, uint32_t parent_flags, uint32_t mode, const char* path,
+ size_t path_len, zx::channel request, async_dispatcher_t* dispatcher);
+
+ // Validates passed path
+ //
+ // Returns |ZX_ERR_INVALID_ARGS| if path_len is more than |NAME_MAX| or if
+ // |path| starts with ".." or "/".
+ // Returns |ZX_OK| on valid path.
+ static zx_status_t ValidatePath(const char* path, size_t path_len);
+
+ // Walks provided path to find the first node name in |path| and then
+ // sets |out_path| and |out_len| to correct position in |path| beyond current
+ // node name and sets |out_key| to node name.
+ //
+ // Calls |ValidatePath| and returns |status| on error.
+ // Sets |out_is_self| to true if path is empty or '.' or './'
+ //
+ // Supports paths like 'a/./b//.'
+ // Supports repetitive '/'
+ // Doesn't support 'a/../a/b'
+ //
+ // eg:
+ // path ="a/b/c/d", out_path would be "b/c/d"
+ // path =".", out_path would be ""
+ // path ="./", out_path would be ""
+ // path ="a/b/", out_path would be "b/"
+ static zx_status_t WalkPath(const char* path, size_t path_len, const char** out_path,
+ size_t* out_len, std::string* out_key, bool* out_is_self);
+
+ // |Node| implementation
+ zx_status_t GetAttr(fuchsia::io::NodeAttributes* out_attributes) const override;
+
+ protected:
+ // |Node| implementations
+ zx_status_t CreateConnection(uint32_t flags, std::unique_ptr<Connection>* connection) override;
+
+ // Markes directory with |NODE_KIND_DIRECTORY| and also marks it readable and
+ // writable.
+ NodeKind::Type GetKind() const override;
+
+ // Walks |path| until the node corresponding to |path| is found, or a remote
+ // filesystem was encountered during traversal. In the latter case,
+ // this function will return an intermediate node, on which |IsRemote| returns
+ // true, and will set |out_path| and |out_len| to be the remaining path.
+ //
+ // For example: if path is /a/b/c/d/f/g and c is a remote node, it will return
+ // c in |out_node|, "d/f/g" in |out_path| and |out_len|.
+ //
+ // Sets |out_is_dir| to true if path has '/' or '/.' at the end.
+ //
+ // Calls |WalkPath| in loop and returns status on error. Returns
+ // |ZX_ERR_NOT_DIR| if an intermediate component of |path| is not a directory.
+ zx_status_t LookupPath(const char* path, size_t path_len, bool* out_is_dir, Node** out_node,
+ const char** out_path, size_t* out_len);
+};
+
+} // namespace internal
+} // namespace vfs
+
+#endif // LIB_VFS_CPP_INTERNAL_DIRECTORY_H_
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/internal/directory_connection.h b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/internal/directory_connection.h
new file mode 100644
index 0000000..3a7e629
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/internal/directory_connection.h
@@ -0,0 +1,62 @@
+// 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.
+
+#ifndef LIB_VFS_CPP_INTERNAL_DIRECTORY_CONNECTION_H_
+#define LIB_VFS_CPP_INTERNAL_DIRECTORY_CONNECTION_H_
+
+#include <fuchsia/io/cpp/fidl.h>
+#include <lib/fidl/cpp/binding.h>
+#include <lib/vfs/cpp/internal/connection.h>
+
+#include <memory>
+
+namespace vfs {
+
+namespace internal {
+class Directory;
+
+// Binds an implementation of |fuchsia.io.Directory| to a
+// |vfs::internal::Directory|.
+class DirectoryConnection final : public Connection, public fuchsia::io::Directory {
+ public:
+ // Create a connection to |vn| with the given |flags|.
+ DirectoryConnection(uint32_t flags, vfs::internal::Directory* vn);
+ ~DirectoryConnection() override;
+
+ // Start listening for |fuchsia.io.Directory| messages on |request|.
+ zx_status_t BindInternal(zx::channel request, async_dispatcher_t* dispatcher) override;
+
+ // |fuchsia::io::Directory| Implementation:
+ void Clone(uint32_t flags, fidl::InterfaceRequest<fuchsia::io::Node> object) override;
+ void Close(CloseCallback callback) override;
+ void Describe(DescribeCallback callback) override;
+ void Sync(SyncCallback callback) override;
+ void GetAttr(GetAttrCallback callback) override;
+ void SetAttr(uint32_t flags, fuchsia::io::NodeAttributes attributes,
+ SetAttrCallback callback) override;
+ void Open(uint32_t flags, uint32_t mode, std::string path,
+ fidl::InterfaceRequest<fuchsia::io::Node> object) override;
+ void Unlink(std::string path, UnlinkCallback callback) override;
+ void ReadDirents(uint64_t max_bytes, ReadDirentsCallback callback) override;
+ void Rewind(RewindCallback callback) override;
+ void GetToken(GetTokenCallback callback) override;
+ void Rename(std::string src, zx::handle dst_parent_token, std::string dst,
+ RenameCallback callback) override;
+ void Link(std::string src, zx::handle dst_parent_token, std::string dst,
+ LinkCallback callback) override;
+ void Watch(uint32_t mask, uint32_t options, zx::channel watcher, WatchCallback callback) override;
+
+ protected:
+ // |Connection| Implementation:
+ void SendOnOpenEvent(zx_status_t status) override;
+
+ private:
+ vfs::internal::Directory* vn_;
+ fidl::Binding<fuchsia::io::Directory> binding_;
+};
+
+} // namespace internal
+} // namespace vfs
+
+#endif // LIB_VFS_CPP_INTERNAL_DIRECTORY_CONNECTION_H_
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/internal/dirent_filler.h b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/internal/dirent_filler.h
new file mode 100644
index 0000000..b3c3375
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/internal/dirent_filler.h
@@ -0,0 +1,45 @@
+// 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.
+
+#ifndef LIB_VFS_CPP_INTERNAL_DIRENT_FILLER_H_
+#define LIB_VFS_CPP_INTERNAL_DIRENT_FILLER_H_
+
+#include <stdint.h>
+#include <zircon/types.h>
+
+#include <string>
+
+namespace vfs {
+namespace internal {
+
+// Helper class used to fill direntries during calls to Readdir.
+class DirentFiller {
+ public:
+ DirentFiller(const DirentFiller&) = delete;
+ DirentFiller& operator=(const DirentFiller&) = delete;
+
+ DirentFiller(void* ptr, uint64_t len);
+
+ // Attempts to add the name to the end of the dirent buffer
+ // which is returned by readdir.
+ // Will not write anything incase of error.
+ zx_status_t Next(const std::string& name, uint8_t type, uint64_t ino);
+
+ // Attempts to add the name to the end of the dirent buffer
+ // which is returned by readdir.
+ // Will not write anything incase of error.
+ zx_status_t Next(const char* name, size_t name_len, uint8_t type, uint64_t ino);
+
+ uint64_t GetBytesFilled() const { return pos_; }
+
+ private:
+ char* ptr_;
+ uint64_t pos_;
+ const uint64_t len_;
+};
+
+} // namespace internal
+} // namespace vfs
+
+#endif // LIB_VFS_CPP_INTERNAL_DIRENT_FILLER_H_
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/internal/file.h b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/internal/file.h
new file mode 100644
index 0000000..97016ce
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/internal/file.h
@@ -0,0 +1,72 @@
+// 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.
+
+#ifndef LIB_VFS_CPP_INTERNAL_FILE_H_
+#define LIB_VFS_CPP_INTERNAL_FILE_H_
+
+#include <fuchsia/io/cpp/fidl.h>
+#include <lib/vfs/cpp/internal/node.h>
+#include <stdint.h>
+
+#include <vector>
+
+namespace vfs {
+namespace internal {
+
+// A file object in a file system.
+//
+// Implements the |fuchsia.io.File| interface. Incoming connections are
+// owned by this object and will be destroyed when this object is destroyed.
+//
+// Subclass to implement specific file semantics.
+//
+// See also:
+//
+// * Directory, which represents directory objects.
+class File : public Node {
+ public:
+ File();
+ ~File() override;
+
+ // Create |count| bytes of data from the file at the given |offset|.
+ //
+ // The data read should be copied to |out_data|, which should be empty when
+ // passed as an argument. When |ReadAt| returns, |out_data| should contain no
+ // more than |count| bytes.
+ virtual zx_status_t ReadAt(uint64_t count, uint64_t offset, std::vector<uint8_t>* out_data);
+
+ // Write the given |data| to the file at the given |offset|.
+ //
+ // Data should be copied into the file starting at the beginning of |data|.
+ // If |WriteAt| returns |ZX_OK|, |out_actual| should contain the number of
+ // bytes actually written to the file.
+ virtual zx_status_t WriteAt(std::vector<uint8_t> data, uint64_t offset, uint64_t* out_actual);
+
+ // Resize the file to the given |length|.
+ virtual zx_status_t Truncate(uint64_t length);
+
+ // Override that describes this object as a file.
+ void Describe(fuchsia::io::NodeInfo* out_info) override;
+
+ // Returns current file length.
+ //
+ // All implementations should implement this.
+ virtual uint64_t GetLength() = 0;
+
+ // Returns file capacity.
+ //
+ // Seek() uses this to return ZX_ERR_OUT_OF_RANGE if new seek is more than
+ // this value.
+ virtual size_t GetCapacity();
+
+ protected:
+ NodeKind::Type GetKind() const override;
+
+ zx_status_t CreateConnection(uint32_t flags, std::unique_ptr<Connection>* connection) override;
+};
+
+} // namespace internal
+} // namespace vfs
+
+#endif // LIB_VFS_CPP_INTERNAL_FILE_H_
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/internal/file_connection.h b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/internal/file_connection.h
new file mode 100644
index 0000000..eeb806d
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/internal/file_connection.h
@@ -0,0 +1,58 @@
+// 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.
+
+#ifndef LIB_VFS_CPP_INTERNAL_FILE_CONNECTION_H_
+#define LIB_VFS_CPP_INTERNAL_FILE_CONNECTION_H_
+
+#include <fuchsia/io/cpp/fidl.h>
+#include <lib/fidl/cpp/binding.h>
+#include <lib/vfs/cpp/internal/connection.h>
+
+#include <memory>
+
+namespace vfs {
+namespace internal {
+class File;
+
+// Binds an implementation of |fuchsia.io.File| to a |vfs::internal::File|.
+class FileConnection final : public Connection, public fuchsia::io::File {
+ public:
+ // Create a connection to |vn| with the given |flags|.
+ FileConnection(uint32_t flags, vfs::internal::File* vn);
+ ~FileConnection() override;
+
+ // Start listening for |fuchsia.io.File| messages on |request|.
+ zx_status_t BindInternal(zx::channel request, async_dispatcher_t* dispatcher) override;
+
+ // |fuchsia::io::File| Implementation:
+ void Clone(uint32_t flags, fidl::InterfaceRequest<fuchsia::io::Node> object) override;
+ void Close(CloseCallback callback) override;
+ void Describe(DescribeCallback callback) override;
+ void Sync(SyncCallback callback) override;
+ void GetAttr(GetAttrCallback callback) override;
+ void SetAttr(uint32_t flags, fuchsia::io::NodeAttributes attributes,
+ SetAttrCallback callback) override;
+ void Read(uint64_t count, ReadCallback callback) override;
+ void ReadAt(uint64_t count, uint64_t offset, ReadAtCallback callback) override;
+ void Write(std::vector<uint8_t> data, WriteCallback callback) override;
+ void WriteAt(std::vector<uint8_t> data, uint64_t offset, WriteAtCallback callback) override;
+ void Seek(int64_t offset, fuchsia::io::SeekOrigin start, SeekCallback callback) override;
+ void Truncate(uint64_t length, TruncateCallback callback) override;
+ void GetFlags(GetFlagsCallback callback) override;
+ void SetFlags(uint32_t flags, SetFlagsCallback callback) override;
+ void GetBuffer(uint32_t flags, GetBufferCallback callback) override;
+
+ protected:
+ // |Connection| Implementation:
+ void SendOnOpenEvent(zx_status_t status) override;
+
+ private:
+ vfs::internal::File* vn_;
+ fidl::Binding<fuchsia::io::File> binding_;
+};
+
+} // namespace internal
+} // namespace vfs
+
+#endif // LIB_VFS_CPP_INTERNAL_FILE_CONNECTION_H_
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/internal/node.h b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/internal/node.h
new file mode 100644
index 0000000..a4ea6e0
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/internal/node.h
@@ -0,0 +1,203 @@
+// 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.
+
+#ifndef LIB_VFS_CPP_INTERNAL_NODE_H_
+#define LIB_VFS_CPP_INTERNAL_NODE_H_
+
+#include <fuchsia/io/cpp/fidl.h>
+#include <lib/async/dispatcher.h>
+#include <lib/fidl/cpp/binding.h>
+#include <lib/vfs/cpp/node_kind.h>
+#include <limits.h>
+
+namespace vfs {
+namespace internal {
+
+bool IsValidName(const std::string& name);
+
+class Connection;
+
+// An object in a file system.
+//
+// Implements the |fuchsia.io.Node| interface. Incoming connections are owned by
+// this object and will be destroyed when this object is destroyed.
+//
+// Subclass to implement a particular kind of file system object.
+//
+// See also:
+//
+// * File, which is a subclass for file objects.
+// * Directory, which is a subclass for directory objects.
+class Node {
+ public:
+ Node();
+ virtual ~Node();
+
+ Node(const Node&) = delete;
+ Node& operator=(const Node&) = delete;
+
+ // Notifies |Node| that it should remove and return
+ // |connection| from its list as it is getting closed.
+ virtual std::unique_ptr<Connection> Close(Connection* connection);
+
+ // This function is called before |Close| is called and status is passed to
+ // fuchsia::io::Node#Close| call.
+ // Please note |Node| is closed even if this function returns error, so Node
+ // should be ready a |Close| call.
+ // Default implementation returns |ZX_OK|.
+ virtual zx_status_t PreClose(Connection* connection);
+
+ // Implementation of |fuchsia.io.Node/Describe|.
+ //
+ // Subclass must override this method to describe themselves accurately.
+ virtual void Describe(fuchsia::io::NodeInfo* out_info) = 0;
+
+ // Implementation of |fuchsia.io.Node/Sync|.
+ virtual zx_status_t Sync();
+
+ // Implementation of |fuchsia.io.Node/GetAttr|.
+ virtual zx_status_t GetAttr(fuchsia::io::NodeAttributes* out_attributes) const;
+
+ // Implementation of |fuchsia.io.Node/SetAttr|.
+ virtual zx_status_t SetAttr(uint32_t flags, const fuchsia::io::NodeAttributes& attributes);
+
+ // Implementation of |fuchsia.io.Node/Clone|.
+ virtual void Clone(uint32_t flags, uint32_t parent_flags, zx::channel request,
+ async_dispatcher_t* dispatcher);
+
+ // Establishes a connection for |request| using the given |flags|.
+ //
+ // Waits for messages asynchronously on the |request| channel using
+ // |dispatcher|. If |dispatcher| is |nullptr|, the implementation will call
+ // |async_get_default_dispatcher| to obtain the default dispatcher for the
+ // current thread.
+ //
+ // Calls |Connect| after validating flags and modes.
+ zx_status_t Serve(uint32_t flags, zx::channel request, async_dispatcher_t* dispatcher = nullptr);
+
+ // Validates |mode| and passes request to serve
+ //
+ // Would be called by |Open|.
+ zx_status_t ServeWithMode(uint32_t flags, uint32_t mode, zx::channel request,
+ async_dispatcher_t* dispatcher = nullptr);
+
+ // Find an entry in this directory with the given |name|.
+ //
+ // The entry is returned via |out_node|. The returned entry is owned by this
+ // directory.
+ //
+ // Returns |ZX_ERR_NOT_FOUND| if no entry exists.
+ // Default implementation in this class return |ZX_ERR_NOT_DIR| if
+ // |IsDirectory| is false, else throws error with |ZX_ASSERT|.
+ //
+ // All directory types which are not remote should implement this method.
+ virtual zx_status_t Lookup(const std::string& name, Node** out_node) const;
+
+ // Return true if |Node| is a remote node.
+ // This function is used in |Directory::Open| to correctly open those kind of
+ // nodes.
+ bool IsRemote() const { return NodeKind::IsRemote(GetKind()); }
+
+ // Return true if |Node| is a directory.
+ // This function is used in |ValidateFlags| and |Lookup| to return correct
+ // error.
+ bool IsDirectory() const { return NodeKind::IsDirectory(GetKind()); }
+
+ // Return true if |Node| is a file.
+ bool IsFile() const { return NodeKind::IsFile(GetKind()); }
+
+ // Return true if |Node| is a service.
+ bool IsService() const { return NodeKind::IsService(GetKind()); }
+
+ // Return true if |Node| is a VMO.
+ bool IsVMO() const { return NodeKind::IsVMO(GetKind()); }
+
+ protected:
+ // Return |Kind| of implementing |Node|.
+ virtual NodeKind::Type GetKind() const = 0;
+
+ // Returns total number of active connections
+ uint64_t GetConnectionCount() const;
+
+ // Called by |Serve| after validating flags and modes.
+ // This should be implemented by sub classes which doesn't create a
+ // connection class.
+ //
+ // Default implementation:
+ // Uses |CreateConnection| to create a connection appropriate for the
+ // concrete type of this object.
+ virtual zx_status_t Connect(uint32_t flags, zx::channel request, async_dispatcher_t* dispatcher);
+
+ // Sends OnOpen event on error status if |OPEN_FLAG_DESCRIBE| is set.
+ static void SendOnOpenEventOnError(uint32_t flags, zx::channel request, zx_status_t status);
+
+ // Store given connection.
+ void AddConnection(std::unique_ptr<Connection> connection);
+
+ // Creates a |Connection| appropriate for the concrete type of this object.
+ //
+ // Subclasses must override this method to create an appropriate connection.
+ // The returned connection should be in an "unbound" state.
+ //
+ // Typically called by |Serve|.
+ virtual zx_status_t CreateConnection(uint32_t flags, std::unique_ptr<Connection>* connection) = 0;
+
+ private:
+ // Validate flags on |Serve|.
+ //
+ // If the caller specified an invalid combination of flags as per io.fidl,
+ // returns |ZX_ERR_INVALID_ARGS|.
+ //
+ // Returns |ZX_ERR_NOT_DIR| if |OPEN_FLAG_DIRECTORY| is set and
+ // |IsDirectory| returns false.
+ //
+ // Calls |GetProhibitiveFlags| flags and if one of the flag is in
+ // prohibitive list, returns |ZX_ERR_INVALID_ARGS|.
+ //
+ // Calls |GetAllowedFlags|, appends |OPEN_FLAG_DESCRIBE|,
+ // |OPEN_FLAG_NODE_REFERENCE|, |OPEN_FLAG_DIRECTORY| (only if
+ // |IsDirectory| returns true) to those flags and returns
+ // |ZX_ERR_NOT_SUPPORTED| if flags are not found in allowed list.
+ //
+ // Returns ZX_OK if none of the above cases are true.
+ zx_status_t ValidateFlags(uint32_t flags) const;
+
+ // Validate flags on |ServeWithMode|.
+ //
+ // Calls |GetAttr| and checks that mode should not be anything other than
+ // |MODE_PROTECTION_MASK| and one in attr. Returns |ZX_ERR_INVALID_ARGS| if it
+ // is, else returns |ZX_OK|.
+ zx_status_t ValidateMode(uint32_t mode) const;
+
+ // Filters out flags that are invalid when combined with
+ // |OPEN_FLAG_NODE_REFERENCE|.
+ // Allowed flags are |OPEN_FLAG_DIRECTORY| and |OPEN_FLAG_DESCRIBE|.
+ uint32_t FilterRefFlags(uint32_t flags);
+
+ // Allowed flags for use in |ValidateFlags|.
+ //
+ // Uses a internal map to map |Kind| to flags and retuns flags based on kind
+ // returned by |GetKind()|.
+ //
+ // See documentation of |ValidateFlags| for exact details.
+ uint32_t GetAllowedFlags() const;
+
+ // Prohibitive flags use in |ValidateFlags|.
+ //
+ // Checks if |Node| is a directory and returns flags which cannot be
+ // applied to a directory.
+ //
+ // See documentation of |ValidateFlags| for exact details.
+ uint32_t GetProhibitiveFlags() const;
+
+ // guards connection_
+ mutable std::mutex mutex_;
+ // The active connections associated with this object.
+ std::vector<std::unique_ptr<Connection>> connections_ __TA_GUARDED(mutex_);
+};
+
+} // namespace internal
+} // namespace vfs
+
+#endif // LIB_VFS_CPP_INTERNAL_NODE_H_
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/internal/node_connection.h b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/internal/node_connection.h
new file mode 100644
index 0000000..fade681
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/internal/node_connection.h
@@ -0,0 +1,50 @@
+// 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.
+
+#ifndef LIB_VFS_CPP_INTERNAL_NODE_CONNECTION_H_
+#define LIB_VFS_CPP_INTERNAL_NODE_CONNECTION_H_
+
+#include <fuchsia/io/cpp/fidl.h>
+#include <lib/fidl/cpp/binding.h>
+#include <lib/vfs/cpp/internal/connection.h>
+
+#include <memory>
+
+namespace vfs {
+
+namespace internal {
+class Node;
+
+// Binds an implementation of |fuchsia.io.Node| to a |vfs::internal::Node|.
+class NodeConnection final : public Connection, public fuchsia::io::Node {
+ public:
+ // Create a connection to |vn| with the given |flags|.
+ NodeConnection(uint32_t flags, vfs::internal::Node* vn);
+ ~NodeConnection() override;
+
+ // Start listening for |fuchsia.io.Node| messages on |request|.
+ zx_status_t BindInternal(zx::channel request, async_dispatcher_t* dispatcher) override;
+
+ // |fuchsia::io::Node| Implementation:
+ void Clone(uint32_t flags, fidl::InterfaceRequest<fuchsia::io::Node> object) override;
+ void Close(CloseCallback callback) override;
+ void Describe(DescribeCallback callback) override;
+ void Sync(SyncCallback callback) override;
+ void GetAttr(GetAttrCallback callback) override;
+ void SetAttr(uint32_t flags, fuchsia::io::NodeAttributes attributes,
+ SetAttrCallback callback) override;
+
+ protected:
+ // |Connection| Implementation:
+ void SendOnOpenEvent(zx_status_t status) override;
+
+ private:
+ vfs::internal::Node* vn_;
+ fidl::Binding<fuchsia::io::Node> binding_;
+};
+
+} // namespace internal
+} // namespace vfs
+
+#endif // LIB_VFS_CPP_INTERNAL_NODE_CONNECTION_H_
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/lazy_dir.h b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/lazy_dir.h
new file mode 100644
index 0000000..fd131d2
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/lazy_dir.h
@@ -0,0 +1,75 @@
+// 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.
+
+#ifndef LIB_VFS_CPP_LAZY_DIR_H_
+#define LIB_VFS_CPP_LAZY_DIR_H_
+
+#include <lib/vfs/cpp/internal/directory.h>
+
+namespace vfs {
+
+// A |LazyDir| a base class for directories that dynamically update their
+// contents on each operation. Clients should derive from this class
+// and implement GetContents and GetFile for their use case.
+//
+// This class is thread-hostile, as are the |Nodes| it manages.
+//
+// # Simple usage
+//
+// Instances of this class should be owned and managed on the same thread
+// that services their connections.
+//
+// # Advanced usage
+//
+// You can use a background thread to service connections provided: (a) the
+// contents of the directory are configured prior to starting to service
+// connections, (b) all modifications to the directory occur while the
+// async_dispatcher_t for the background thread is stopped or suspended, and
+// (c) async_dispatcher_t for the background thread is stopped or suspended
+// prior to destroying the directory.
+class LazyDir : public vfs::internal::Directory {
+ public:
+ // Structure storing a single entry in the directory.
+ struct LazyEntry {
+ // Should be more than or equal to |GetStartingId()|, must remain stable
+ // across calls.
+ uint64_t id;
+ std::string name;
+ uint32_t type;
+
+ bool operator<(const LazyEntry& rhs) const;
+ };
+ using LazyEntryVector = std::vector<LazyEntry>;
+
+ LazyDir();
+ ~LazyDir() override;
+
+ // |Directory| implementation:
+ zx_status_t Readdir(uint64_t offset, void* data, uint64_t len, uint64_t* out_offset,
+ uint64_t* out_actual) override;
+
+ // |Node| implementations:
+ zx_status_t GetAttr(fuchsia::io::NodeAttributes* out_attributes) const override;
+
+ zx_status_t Lookup(const std::string& name, Node** out_node) const final;
+
+ protected:
+ // Get the contents of the directory in an output vector.
+ virtual void GetContents(LazyEntryVector* out_vector) const = 0;
+
+ // Get the reference to a single file. The id and name of the entry as
+ // returned from GetContents are passed in to assist locating the file.
+ virtual zx_status_t GetFile(Node** out_node, uint64_t id, std::string name) const = 0;
+
+ // Ids returned by |GetContent| should be more than or equal to id returned by
+ // this function.
+ uint64_t GetStartingId() const;
+
+ private:
+ static constexpr uint64_t kDotId = 1u;
+};
+
+} // namespace vfs
+
+#endif // LIB_VFS_CPP_LAZY_DIR_H_
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/node_kind.h b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/node_kind.h
new file mode 100644
index 0000000..056759f
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/node_kind.h
@@ -0,0 +1,62 @@
+// 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.
+
+#ifndef LIB_VFS_CPP_NODE_KIND_H_
+#define LIB_VFS_CPP_NODE_KIND_H_
+
+#include <cstdint>
+
+namespace vfs {
+
+class NodeKind {
+ public:
+ using Type = uint64_t;
+
+ NodeKind() = delete;
+
+ // Node is a Directory
+ static constexpr Type kDirectory = 0x01;
+
+ // Remote node acts as a proxy between client and a remote directory channel.
+ static constexpr Type kRemote = 0x02;
+
+ // Node is a File.
+ static constexpr Type kFile = 0x04;
+
+ // Node is a service.
+ static constexpr Type kService = 0x08;
+
+ // Node is a VMO.
+ static constexpr Type kVmo = 0x10;
+
+ // Node is Writable.
+ static constexpr Type kWritable = 0x0100;
+
+ // Node is Readable.
+ static constexpr Type kReadable = 0x0200;
+
+ // Node can be mounted,
+ static constexpr Type kMountable = 0x0400;
+
+ // Node can be truncated on open.
+ static constexpr Type kCanTruncate = 0x0800;
+
+ // Node can be created on open.
+ static constexpr Type kCreatable = 0x1000;
+ static constexpr Type kAppendable = 0x2000;
+
+ static bool IsDirectory(Type kind) { return (kind & kDirectory) == kDirectory; }
+
+ static bool IsFile(Type kind) { return (kind & kFile) == kFile; }
+
+ static bool IsService(Type kind) { return (kind & kService) == kService; }
+
+ static bool IsVMO(Type kind) { return (kind & kVmo) == kVmo; }
+
+ static bool IsRemote(Type kind) { return (kind & kRemote) == kRemote; }
+};
+
+} // namespace vfs
+
+#endif // LIB_VFS_CPP_NODE_KIND_H_
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/pseudo_dir.h b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/pseudo_dir.h
new file mode 100644
index 0000000..6c75620
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/pseudo_dir.h
@@ -0,0 +1,138 @@
+// 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.
+
+#ifndef LIB_VFS_CPP_PSEUDO_DIR_H_
+#define LIB_VFS_CPP_PSEUDO_DIR_H_
+
+#include <lib/vfs/cpp/internal/directory.h>
+
+#include <map>
+#include <mutex>
+
+namespace vfs {
+
+// A pseudo-directory is a directory-like object whose entries are constructed
+// by a program at runtime. The client can lookup, enumerate, and watch(not yet
+// implemented) these directory entries but it cannot create, remove, or rename
+// them.
+//
+// This class is thread-hostile, as are the |Nodes| it manages.
+//
+// # Simple usage
+//
+// Instances of this class should be owned and managed on the same thread
+// that services their connections.
+//
+// # Advanced usage
+//
+// You can use a background thread to service connections provided: (a) the
+// contents of the directory are configured prior to starting to service
+// connections, (b) all modifications to the directory occur while the
+// async_dispatcher_t for the background thread is stopped or suspended, and
+// (c) async_dispatcher_t for the background thread is stopped or suspended
+// prior to destroying the directory.
+class PseudoDir : public vfs::internal::Directory {
+ public:
+ // Creates a directory which is initially empty.
+ PseudoDir();
+
+ // Destroys the directory and releases the nodes it contains.
+ ~PseudoDir() override;
+
+ // Adds a directory entry associating the given |name| with |vn|.
+ // It is ok to add the same Node multiple times with different names.
+ //
+ // Returns |ZX_OK| on success.
+ // Returns |ZX_ERR_ALREADY_EXISTS| if there is already a node with the given
+ // name.
+ zx_status_t AddSharedEntry(std::string name, std::shared_ptr<Node> vn);
+
+ // Adds a directory entry associating the given |name| with |vn|.
+ //
+ // Returns |ZX_OK| on success.
+ // Returns |ZX_ERR_ALREADY_EXISTS| if there is already a node with the given
+ // name.
+ zx_status_t AddEntry(std::string name, std::unique_ptr<Node> vn);
+
+ // Removes a directory entry with the given |name|.
+ //
+ // Returns |ZX_OK| on success.
+ // Returns |ZX_ERR_NOT_FOUND| if there is no node with the given name.
+ zx_status_t RemoveEntry(const std::string& name);
+
+ // Removes a directory entry with the given |name| and |node|.
+ //
+ // Returns |ZX_OK| on success.
+ // Returns |ZX_ERR_NOT_FOUND| if there is no node with the given |name| and
+ // matching |node| pointer.
+ zx_status_t RemoveEntry(const std::string& name, Node* node);
+
+ // Removes all directory entries.
+ void RemoveAllEntries();
+
+ // Checks if directory is empty.
+ // Be careful while using this function if using this Dir in multiple
+ // threads.
+ bool IsEmpty() const;
+
+ // |Directory| implementation:
+ zx_status_t Lookup(const std::string& name, vfs::internal::Node** out_node) const final;
+
+ zx_status_t Readdir(uint64_t offset, void* data, uint64_t len, uint64_t* out_offset,
+ uint64_t* out_actual) override;
+
+ private:
+ class Entry {
+ public:
+ Entry(uint64_t id, std::string name);
+ virtual ~Entry();
+
+ uint64_t id() const { return id_; }
+ const std::string& name() const { return name_; }
+ virtual Node* node() const = 0;
+
+ private:
+ uint64_t const id_;
+ std::string name_;
+ };
+
+ class SharedEntry : public Entry {
+ public:
+ SharedEntry(uint64_t id, std::string name, std::shared_ptr<Node> node);
+ ~SharedEntry() override;
+
+ Node* node() const override;
+
+ private:
+ std::shared_ptr<Node> node_;
+ };
+
+ class UniqueEntry : public Entry {
+ public:
+ UniqueEntry(uint64_t id, std::string name, std::unique_ptr<Node> node);
+ ~UniqueEntry() override;
+
+ Node* node() const override;
+
+ private:
+ std::unique_ptr<Node> node_;
+ };
+
+ zx_status_t AddEntry(std::unique_ptr<Entry> entry);
+
+ static constexpr uint64_t kDotId = 1u;
+
+ mutable std::mutex mutex_;
+
+ std::atomic_uint64_t next_node_id_;
+
+ // for enumeration
+ std::map<uint64_t, std::unique_ptr<Entry>> entries_by_id_ __TA_GUARDED(mutex_);
+
+ // for lookup
+ std::map<std::string, Entry*> entries_by_name_ __TA_GUARDED(mutex_);
+};
+
+} // namespace vfs
+#endif // LIB_VFS_CPP_PSEUDO_DIR_H_
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/pseudo_file.h b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/pseudo_file.h
new file mode 100644
index 0000000..835e733
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/pseudo_file.h
@@ -0,0 +1,126 @@
+// 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.
+
+#ifndef LIB_VFS_CPP_PSEUDO_FILE_H_
+#define LIB_VFS_CPP_PSEUDO_FILE_H_
+
+#include <lib/vfs/cpp/internal/connection.h>
+#include <lib/vfs/cpp/internal/file.h>
+
+namespace vfs {
+
+// Buffered pseudo-file.
+//
+// This variant is optimized for incrementally reading and writing properties
+// which are larger than can typically be read or written by the client in
+// a single I/O transaction.
+//
+// In read mode, the pseudo-file invokes its read handler when the file is
+// opened and retains the content in a buffer which the client incrementally
+// reads from and can seek within.
+//
+// In write mode, the client incrementally writes into and seeks within the
+// buffer which the pseudo-file delivers as a whole to the write handler when
+// the file is closed(if there were any writes). Truncation is also supported.
+//
+// This class is thread-hostile.
+//
+// # Simple usage
+//
+// Instances of this class should be owned and managed on the same thread
+// that services their connections.
+//
+// # Advanced usage
+//
+// You can use a background thread to service connections provided:
+// async_dispatcher_t for the background thread is stopped or suspended
+// prior to destroying the file.
+class PseudoFile final : public vfs::internal::File {
+ public:
+ // Handler called to read from the pseudo-file.
+ using ReadHandler = fit::function<zx_status_t(std::vector<uint8_t>* output, size_t max_bytes)>;
+
+ // Handler called to write into the pseudo-file.
+ using WriteHandler = fit::function<zx_status_t(std::vector<uint8_t> input)>;
+
+ // Creates a buffered pseudo-file.
+ //
+ // |read_handler| cannot be null. If the |write_handler| is null, then the
+ // pseudo-file is considered not writable. The |max_file_size|
+ // determines the maximum number of bytes which can be written to andread from
+ // the pseudo-file's input buffer when it it opened for writing/reading.
+ PseudoFile(size_t max_file_size, ReadHandler read_handler = ReadHandler(),
+ WriteHandler write_handler = WriteHandler());
+
+ ~PseudoFile() override;
+
+ // |Node| implementations:
+ zx_status_t GetAttr(fuchsia::io::NodeAttributes* out_attributes) const override;
+
+ protected:
+ zx_status_t CreateConnection(uint32_t flags,
+ std::unique_ptr<vfs::internal::Connection>* connection) override;
+
+ NodeKind::Type GetKind() const override;
+
+ private:
+ class Content final : public vfs::internal::Connection, public File {
+ public:
+ Content(PseudoFile* file, uint32_t flags, std::vector<uint8_t> content);
+ ~Content() override;
+
+ // |File| implementations:
+ zx_status_t ReadAt(uint64_t count, uint64_t offset, std::vector<uint8_t>* out_data) override;
+ zx_status_t WriteAt(std::vector<uint8_t> data, uint64_t offset, uint64_t* out_actual) override;
+ zx_status_t Truncate(uint64_t length) override;
+
+ uint64_t GetLength() override;
+
+ size_t GetCapacity() override;
+
+ // Connection implementation:
+ zx_status_t BindInternal(zx::channel request, async_dispatcher_t* dispatcher) override;
+
+ // |Node| implementations:
+ std::unique_ptr<Connection> Close(Connection* connection) override;
+
+ zx_status_t PreClose(Connection* connection) override;
+
+ void Clone(uint32_t flags, uint32_t parent_flags, zx::channel request,
+ async_dispatcher_t* dispatcher) override;
+
+ zx_status_t GetAttr(fuchsia::io::NodeAttributes* out_attributes) const override;
+
+ protected:
+ void SendOnOpenEvent(zx_status_t status) override;
+
+ NodeKind::Type GetKind() const override;
+
+ private:
+ zx_status_t TryFlushIfRequired();
+
+ void SetInputLength(size_t length);
+
+ PseudoFile* const file_;
+
+ std::vector<uint8_t> buffer_;
+ uint32_t flags_;
+
+ // true if the file was written into
+ bool dirty_ = false;
+ };
+
+ // |File| implementations:
+ uint64_t GetLength() override;
+
+ size_t GetCapacity() override;
+
+ ReadHandler const read_handler_;
+ WriteHandler const write_handler_;
+ const size_t max_file_size_;
+};
+
+} // namespace vfs
+
+#endif // LIB_VFS_CPP_PSEUDO_FILE_H_
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/remote_dir.h b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/remote_dir.h
new file mode 100644
index 0000000..4d24eda
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/remote_dir.h
@@ -0,0 +1,54 @@
+// 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.
+
+#ifndef LIB_VFS_CPP_REMOTE_DIR_H_
+#define LIB_VFS_CPP_REMOTE_DIR_H_
+
+#include <lib/vfs/cpp/internal/directory.h>
+
+namespace vfs {
+
+// A remote directory holds a channel to a remotely hosted directory to
+// which requests are delegated when opened.
+//
+// This class is designed to allow programs to publish remote filesystems
+// as directories without requiring a separate "mount" step. In effect,
+// a remote directory is "mounted" at creation time.
+//
+// It is not possible for the client to detach the remote directory or
+// to mount a new one in its place.
+class RemoteDir final : public vfs::internal::Directory {
+ public:
+ // Binds to a remotely hosted directory using the specified
+ // |fuchsia.io.Directory| client channel endpoint.The channel must be valid.
+ explicit RemoteDir(zx::channel remote_dir, async_dispatcher_t* dispatcher = nullptr);
+
+ // Binds to a remotely hosted directory using the specified
+ // InterfaceHandle. Handle must be valid.
+ explicit RemoteDir(fidl::InterfaceHandle<fuchsia::io::Directory> dir,
+ async_dispatcher_t* dispatcher = nullptr);
+
+ // Binds to a remotely hosted directory using the specified
+ // |fuchsia::io::DirectoryPtr| endpoint. |dir_ptr| must be valid.
+ explicit RemoteDir(fuchsia::io::DirectoryPtr dir_ptr);
+
+ ~RemoteDir() override;
+
+ protected:
+ // |Node| implementation
+ zx_status_t Connect(uint32_t flags, zx::channel request, async_dispatcher_t* dispatcher) final;
+
+ // |Directory| implementation
+ zx_status_t Readdir(uint64_t offset, void* data, uint64_t len, uint64_t* out_offset,
+ uint64_t* out_actual) final;
+
+ NodeKind::Type GetKind() const final;
+
+ private:
+ fuchsia::io::DirectoryPtr dir_ptr_;
+};
+
+} // namespace vfs
+
+#endif // LIB_VFS_CPP_REMOTE_DIR_H_
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/service.h b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/service.h
new file mode 100644
index 0000000..ce0e4cc
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/service.h
@@ -0,0 +1,69 @@
+// 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.
+
+#ifndef LIB_VFS_CPP_SERVICE_H_
+#define LIB_VFS_CPP_SERVICE_H_
+
+#include <fuchsia/io/cpp/fidl.h>
+#include <lib/vfs/cpp/internal/node.h>
+
+namespace vfs {
+
+// A |Node| which binds a channel to a service implementation when opened.
+class Service : public vfs::internal::Node {
+ public:
+ // Handler called to bind the provided channel to an implementation
+ // of the service.
+ using Connector = fit::function<void(zx::channel channel, async_dispatcher_t* dispatcher)>;
+
+ // Adds the specified interface to the set of public interfaces.
+ //
+ // Creates |Service| with a |connector| with the given |service_name|, using
+ // the given |interface_request_handler|. |interface_request_handler| should
+ // remain valid for the lifetime of this object.
+ //
+ // A typical usage may be:
+ //
+ // vfs::Service foo_service(foobar_bindings_.GetHandler(this, dispatcher));
+ //
+ // For now this implementation ignores |dispatcher| that we get from |Serve|
+ // call, if you want to use dispatcher call |Service(Connector)|.
+ template <typename Interface>
+ explicit Service(fidl::InterfaceRequestHandler<Interface> handler)
+ : Service(
+ [handler = std::move(handler)](zx::channel channel, async_dispatcher_t* dispatcher) {
+ handler(fidl::InterfaceRequest<Interface>(std::move(channel)));
+ }) {}
+
+ // Creates a service with the specified connector.
+ //
+ // If the |connector| is null, then incoming connection requests will be
+ // dropped.
+ explicit Service(Connector connector);
+
+ // Destroys the services and releases its connector.
+ ~Service() override;
+
+ // |Node| implementation:
+ zx_status_t GetAttr(fuchsia::io::NodeAttributes* out_attributes) const final;
+
+ void Describe(fuchsia::io::NodeInfo* out_info) override final;
+
+ const Connector& connector() const { return connector_; }
+
+ protected:
+ NodeKind::Type GetKind() const override;
+ // |Node| implementations:
+ zx_status_t CreateConnection(uint32_t flags,
+ std::unique_ptr<vfs::internal::Connection>* connection) final;
+
+ zx_status_t Connect(uint32_t flags, zx::channel request, async_dispatcher_t* dispatcher) override;
+
+ private:
+ Connector connector_;
+};
+
+} // namespace vfs
+
+#endif // LIB_VFS_CPP_SERVICE_H_
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/vmo_file.h b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/vmo_file.h
new file mode 100644
index 0000000..2b79309
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/include/lib/vfs/cpp/vmo_file.h
@@ -0,0 +1,126 @@
+// 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.
+
+#ifndef LIB_VFS_CPP_VMO_FILE_H_
+#define LIB_VFS_CPP_VMO_FILE_H_
+
+#include <fuchsia/io/cpp/fidl.h>
+#include <lib/vfs/cpp/internal/file.h>
+#include <lib/zx/vmo.h>
+#include <stdint.h>
+
+#include <vector>
+
+namespace vfs {
+
+// A file object in a file system backed by a VMO.
+//
+// Implements the |fuchsia.io.File| interface. Incoming connections are
+// owned by this object and will be destroyed when this object is destroyed.
+//
+// See also:
+//
+// * File, which represents file objects.
+class VmoFile final : public vfs::internal::File {
+ public:
+ // Specifies the desired behavior of writes.
+ enum class WriteOption {
+ // The VMO handle and file are read only.
+ READ_ONLY,
+ // The VMO handle and file will be writable.
+ WRITABLE,
+ };
+
+ // Specifies the desired behavior when a client asks for the file's
+ // underlying VMO.
+ enum class Sharing {
+ // The VMO is not shared with the client.
+ NONE,
+
+ // The VMO handle is duplicated for each client.
+ //
+ // This is appropriate when it is okay for clients to access the entire
+ // contents of the VMO, possibly extending beyond the pages spanned by the
+ // file.
+ //
+ // This mode is significantly more efficient than |CLONE| and |CLONE_COW|
+ // and should be preferred when file spans the whole VMO or when the VMO's
+ // entire content is safe for clients to read.
+ DUPLICATE,
+
+ // The VMO range spanned by the file is cloned on demand, using
+ // copy-on-write
+ // semantics to isolate modifications of clients which open the file in
+ // a writable mode.
+ //
+ // This is appropriate when clients need to be restricted from accessing
+ // portions of the VMO outside of the range of the file and when file
+ // modifications by clients should not be visible to each other.
+ CLONE_COW,
+ };
+
+ // Creates a file node backed an VMO owned by the creator.
+ // The creator retains ownership of |unowned_vmo| which must outlive this
+ // object.
+ VmoFile(zx::unowned_vmo unowned_vmo, size_t offset, size_t length,
+ WriteOption write_options = WriteOption::READ_ONLY,
+ Sharing vmo_sharing = Sharing::DUPLICATE);
+
+ // Creates a file node backed by a VMO. The VmoFile takes ownership of the
+ // vmo.
+ VmoFile(zx::vmo vmo, size_t offset, size_t length,
+ WriteOption write_options = WriteOption::READ_ONLY,
+ Sharing vmo_sharing = Sharing::DUPLICATE);
+
+ ~VmoFile();
+
+ // Create |count| bytes of data from the file at the given |offset|.
+ //
+ // The data read should be copied to |out_data|, which should be empty when
+ // passed as an argument. When |ReadAt| returns, |out_data| should contain no
+ // more than |count| bytes.
+ zx_status_t ReadAt(uint64_t count, uint64_t offset, std::vector<uint8_t>* out_data) override;
+
+ // Write the given |data| to the file at the given |offset|.
+ //
+ // Data should be copied into the file starting at the beginning of |data|.
+ // If |WriteAt| returns |ZX_OK|, |out_actual| should contain the number of
+ // bytes actually written to the file.
+ zx_status_t WriteAt(std::vector<uint8_t> data, uint64_t offset, uint64_t* out_actual) override;
+
+ // Resize the file to the given |length|.
+ zx_status_t Truncate(uint64_t length) override;
+
+ // Override that describes this object as a vmofile.
+ void Describe(fuchsia::io::NodeInfo* out_info) override;
+
+ // Returns current file length.
+ //
+ // All implementations should implement this.
+ uint64_t GetLength() override;
+
+ // Returns file capacity.
+ //
+ // Seek() uses this to return ZX_ERR_OUT_OF_RANGE if new seek is more than
+ // this value.
+ size_t GetCapacity() override;
+
+ // Returns the node attributes for this VmoFile.
+ zx_status_t GetAttr(fuchsia::io::NodeAttributes* out_attributes) const override;
+
+ protected:
+ NodeKind::Type GetKind() const override;
+
+ private:
+ const size_t offset_;
+ const size_t length_;
+ const WriteOption write_option_;
+ const Sharing vmo_sharing_;
+
+ zx::vmo vmo_;
+};
+
+} // namespace vfs
+
+#endif // LIB_VFS_CPP_VMO_FILE_H_
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/internal/connection.cc b/third_party/fuchsia-sdk/pkg/vfs_cpp/internal/connection.cc
new file mode 100644
index 0000000..53cdf20
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/internal/connection.cc
@@ -0,0 +1,75 @@
+// 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.
+
+#include <lib/fdio/vfs.h>
+#include <lib/vfs/cpp/flags.h>
+#include <lib/vfs/cpp/internal/connection.h>
+#include <lib/vfs/cpp/internal/node.h>
+
+namespace vfs {
+namespace internal {
+
+Connection::Connection(uint32_t flags) : flags_(flags) {}
+
+Connection::~Connection() = default;
+
+void Connection::Clone(Node* vn, uint32_t flags, zx::channel request,
+ async_dispatcher_t* dispatcher) {
+ vn->Clone(flags, flags_, std::move(request), dispatcher);
+}
+
+void Connection::Close(Node* vn, fuchsia::io::Node::CloseCallback callback) {
+ callback(vn->PreClose(this));
+ vn->Close(this);
+ // |this| is destroyed at this point.
+}
+
+void Connection::Describe(Node* vn, fuchsia::io::Node::DescribeCallback callback) {
+ fuchsia::io::NodeInfo info{};
+ vn->Describe(&info);
+ if (info.has_invalid_tag()) {
+ vn->Close(this);
+ } else {
+ callback(std::move(info));
+ }
+}
+
+zx_status_t Connection::Bind(zx::channel request, async_dispatcher_t* dispatcher) {
+ auto status = BindInternal(std::move(request), dispatcher);
+ if (status == ZX_OK && Flags::ShouldDescribe(flags_)) {
+ SendOnOpenEvent(status);
+ } // can't send status as binding failed and request object is gone.
+ return status;
+}
+
+void Connection::Sync(Node* vn, fuchsia::io::Node::SyncCallback callback) {
+ // TODO: Check flags.
+ callback(vn->Sync());
+}
+
+void Connection::GetAttr(Node* vn, fuchsia::io::Node::GetAttrCallback callback) {
+ // TODO: Check flags.
+ fuchsia::io::NodeAttributes attributes{};
+ zx_status_t status = vn->GetAttr(&attributes);
+ callback(status, attributes);
+}
+
+void Connection::SetAttr(Node* vn, uint32_t flags, fuchsia::io::NodeAttributes attributes,
+ fuchsia::io::Node::SetAttrCallback callback) {
+ // TODO: Check flags.
+ callback(vn->SetAttr(flags, attributes));
+}
+
+std::unique_ptr<fuchsia::io::NodeInfo> Connection::NodeInfoIfStatusOk(Node* vn,
+ zx_status_t status) {
+ std::unique_ptr<fuchsia::io::NodeInfo> node_info;
+ if (status == ZX_OK) {
+ node_info = std::make_unique<fuchsia::io::NodeInfo>();
+ vn->Describe(node_info.get());
+ }
+ return node_info;
+}
+
+} // namespace internal
+} // namespace vfs
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/internal/directory.cc b/third_party/fuchsia-sdk/pkg/vfs_cpp/internal/directory.cc
new file mode 100644
index 0000000..0747b59
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/internal/directory.cc
@@ -0,0 +1,220 @@
+
+// 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.
+
+#include <fuchsia/io/cpp/fidl.h>
+#include <lib/fdio/vfs.h>
+#include <lib/vfs/cpp/flags.h>
+#include <lib/vfs/cpp/internal/directory.h>
+#include <lib/vfs/cpp/internal/directory_connection.h>
+#include <zircon/errors.h>
+
+namespace vfs {
+namespace internal {
+
+Directory::Directory() = default;
+
+Directory::~Directory() = default;
+
+void Directory::Describe(fuchsia::io::NodeInfo* out_info) {
+ out_info->set_directory(fuchsia::io::DirectoryObject());
+}
+
+zx_status_t Directory::Lookup(const std::string& name, Node** out_node) const {
+ return ZX_ERR_NOT_SUPPORTED;
+}
+
+zx_status_t Directory::CreateConnection(uint32_t flags, std::unique_ptr<Connection>* connection) {
+ *connection = std::make_unique<internal::DirectoryConnection>(flags, this);
+ return ZX_OK;
+}
+
+zx_status_t Directory::ValidatePath(const char* path, size_t path_len) {
+ bool starts_with_dot_dot = (path_len > 1 && path[0] == '.' && path[1] == '.');
+ if (path_len > NAME_MAX || (path_len == 2 && starts_with_dot_dot) ||
+ (path_len > 2 && starts_with_dot_dot && path[2] == '/') || (path_len > 0 && path[0] == '/')) {
+ return ZX_ERR_INVALID_ARGS;
+ }
+ return ZX_OK;
+}
+
+NodeKind::Type Directory::GetKind() const {
+ return NodeKind::kDirectory | NodeKind::kReadable | NodeKind::kWritable;
+}
+
+zx_status_t Directory::GetAttr(fuchsia::io::NodeAttributes* out_attributes) const {
+ out_attributes->mode = fuchsia::io::MODE_TYPE_DIRECTORY | V_IRUSR;
+ out_attributes->id = fuchsia::io::INO_UNKNOWN;
+ out_attributes->content_size = 0;
+ out_attributes->storage_size = 0;
+ out_attributes->link_count = 1;
+ out_attributes->creation_time = 0;
+ out_attributes->modification_time = 0;
+ return ZX_OK;
+}
+
+zx_status_t Directory::WalkPath(const char* path, size_t path_len, const char** out_path,
+ size_t* out_len, std::string* out_key, bool* out_is_self) {
+ *out_path = path;
+ *out_len = path_len;
+ *out_is_self = false;
+ zx_status_t status = ValidatePath(path, path_len);
+ if (status != ZX_OK) {
+ return status;
+ }
+
+ // remove any "./", ".//", etc
+ while (path_len > 1 && path[0] == '.' && path[1] == '/') {
+ path += 2;
+ path_len -= 2;
+ size_t index = 0u;
+ while (index < path_len && path[index] == '/') {
+ index++;
+ }
+ path += index;
+ path_len -= index;
+ }
+
+ *out_path = path;
+ *out_len = path_len;
+
+ if (path_len == 0 || (path_len == 1 && path[0] == '.')) {
+ *out_is_self = true;
+ return ZX_OK;
+ }
+
+ // Lookup node
+ const char* path_end = path + path_len;
+ const char* match = std::find(path, path_end, '/');
+
+ if (path_end == match) {
+ // "/" not found
+ *out_key = std::string(path, path_len);
+ *out_len = 0;
+ *out_path = path_end;
+ } else {
+ size_t index = std::distance(path, match);
+ *out_key = std::string(path, index);
+
+ // remove all '/'
+ while (index < path_len && path[index] == '/') {
+ index++;
+ }
+ *out_len -= index;
+ *out_path += index;
+ }
+ return ZX_OK;
+}
+
+zx_status_t Directory::LookupPath(const char* path, size_t path_len, bool* out_is_dir,
+ Node** out_node, const char** out_path, size_t* out_len) {
+ Node* current_node = this;
+ size_t new_path_len = path_len;
+ const char* new_path = path;
+ *out_is_dir = path_len == 0 || path[path_len - 1] == '/';
+ do {
+ std::string key;
+ bool is_self = false;
+ zx_status_t status = WalkPath(new_path, new_path_len, &new_path, &new_path_len, &key, &is_self);
+ if (status != ZX_OK) {
+ return status;
+ }
+ if (is_self) {
+ *out_is_dir = true;
+ *out_node = current_node;
+ return ZX_OK;
+ }
+ Node* n = nullptr;
+ status = current_node->Lookup(key, &n);
+ if (status != ZX_OK) {
+ return status;
+ }
+ current_node = n;
+ if (current_node->IsRemote()) {
+ break;
+ }
+ } while (new_path_len > 0);
+
+ *out_node = current_node;
+ *out_len = new_path_len;
+ *out_path = new_path;
+ return ZX_OK;
+}
+
+void Directory::Open(uint32_t open_flags, uint32_t parent_flags, uint32_t mode, const char* path,
+ size_t path_len, zx::channel request, async_dispatcher_t* dispatcher) {
+ if (!Flags::InputPrecondition(open_flags)) {
+ Node::SendOnOpenEventOnError(open_flags, std::move(request), ZX_ERR_INVALID_ARGS);
+ return;
+ }
+ if (Flags::ShouldCloneWithSameRights(open_flags)) {
+ Node::SendOnOpenEventOnError(open_flags, std::move(request), ZX_ERR_INVALID_ARGS);
+ return;
+ }
+ if (!Flags::IsNodeReference(open_flags) && !(open_flags & Flags::kFsRights)) {
+ Node::SendOnOpenEventOnError(open_flags, std::move(request), ZX_ERR_INVALID_ARGS);
+ return;
+ }
+ if (!Flags::StricterOrSameRights(open_flags, parent_flags)) {
+ Node::SendOnOpenEventOnError(open_flags, std::move(request), ZX_ERR_ACCESS_DENIED);
+ return;
+ }
+ if ((path_len < 1) || (path_len > PATH_MAX)) {
+ Node::SendOnOpenEventOnError(open_flags, std::move(request), ZX_ERR_BAD_PATH);
+ return;
+ }
+
+ Node* n = nullptr;
+ bool path_is_dir = false;
+ size_t new_path_len = path_len;
+ const char* new_path = path;
+ zx_status_t status = LookupPath(path, path_len, &path_is_dir, &n, &new_path, &new_path_len);
+ if (status != ZX_OK) {
+ return SendOnOpenEventOnError(open_flags, std::move(request), status);
+ }
+ bool node_is_dir = n->IsDirectory();
+
+ if (Flags::IsPosix(open_flags) && !Flags::IsWritable(open_flags) &&
+ !Flags::IsWritable(parent_flags)) {
+ // Posix compatibility flag allows the child dir connection to inherit
+ // every right from its immediate parent. Here we know there exists
+ // a read-only directory somewhere along the Open() chain, so remove
+ // this flag to rid the child connection the ability to inherit read-write
+ // right from e.g. crossing a read-write mount point down the line.
+ open_flags &= ~fuchsia::io::OPEN_FLAG_POSIX;
+ }
+
+ if (n->IsRemote() && new_path_len > 0) {
+ fuchsia::io::DirectoryPtr temp_dir;
+ status = n->Serve(open_flags | fuchsia::io::OPEN_FLAG_DIRECTORY,
+ temp_dir.NewRequest().TakeChannel());
+ if (status != ZX_OK) {
+ return SendOnOpenEventOnError(open_flags, std::move(request), status);
+ }
+ temp_dir->Open(open_flags, mode, std::string(new_path, new_path_len),
+ fidl::InterfaceRequest<fuchsia::io::Node>(std::move(request)));
+ return;
+ }
+
+ if (node_is_dir) {
+ // grant POSIX clients additional rights
+ if (Flags::IsPosix(open_flags)) {
+ uint32_t parent_rights = parent_flags & Flags::kFsRights;
+ bool admin = Flags::IsAdminable(open_flags);
+ open_flags |= parent_rights;
+ open_flags &= ~fuchsia::io::OPEN_RIGHT_ADMIN;
+ if (admin) {
+ open_flags |= fuchsia::io::OPEN_RIGHT_ADMIN;
+ }
+ open_flags &= ~fuchsia::io::OPEN_FLAG_POSIX;
+ }
+ }
+ if (path_is_dir) {
+ open_flags |= fuchsia::io::OPEN_FLAG_DIRECTORY;
+ }
+ n->ServeWithMode(open_flags, mode, std::move(request), dispatcher);
+}
+
+} // namespace internal
+} // namespace vfs
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/internal/directory_connection.cc b/third_party/fuchsia-sdk/pkg/vfs_cpp/internal/directory_connection.cc
new file mode 100644
index 0000000..034c4f0
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/internal/directory_connection.cc
@@ -0,0 +1,108 @@
+// 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.
+
+#include <lib/vfs/cpp/flags.h>
+#include <lib/vfs/cpp/internal/directory.h>
+#include <lib/vfs/cpp/internal/directory_connection.h>
+
+#include <utility>
+
+namespace vfs {
+namespace internal {
+
+DirectoryConnection::DirectoryConnection(uint32_t flags, vfs::internal::Directory* vn)
+ : Connection(flags), vn_(vn), binding_(this) {}
+
+DirectoryConnection::~DirectoryConnection() = default;
+
+zx_status_t DirectoryConnection::BindInternal(zx::channel request, async_dispatcher_t* dispatcher) {
+ if (binding_.is_bound()) {
+ return ZX_ERR_BAD_STATE;
+ }
+ zx_status_t status = binding_.Bind(std::move(request), dispatcher);
+ if (status != ZX_OK) {
+ return status;
+ }
+ binding_.set_error_handler([this](zx_status_t status) { vn_->Close(this); });
+ return ZX_OK;
+}
+
+void DirectoryConnection::Clone(uint32_t flags, fidl::InterfaceRequest<fuchsia::io::Node> object) {
+ Connection::Clone(vn_, flags, object.TakeChannel(), binding_.dispatcher());
+}
+
+void DirectoryConnection::Close(CloseCallback callback) {
+ Connection::Close(vn_, std::move(callback));
+}
+
+void DirectoryConnection::Describe(DescribeCallback callback) {
+ Connection::Describe(vn_, std::move(callback));
+}
+
+void DirectoryConnection::Sync(SyncCallback callback) {
+ Connection::Sync(vn_, std::move(callback));
+}
+
+void DirectoryConnection::GetAttr(GetAttrCallback callback) {
+ Connection::GetAttr(vn_, std::move(callback));
+}
+
+void DirectoryConnection::SetAttr(uint32_t flags, fuchsia::io::NodeAttributes attributes,
+ SetAttrCallback callback) {
+ Connection::SetAttr(vn_, flags, attributes, std::move(callback));
+}
+
+void DirectoryConnection::Open(uint32_t flags, uint32_t mode, std::string path,
+ fidl::InterfaceRequest<fuchsia::io::Node> object) {
+ vn_->Open(flags, this->flags(), mode, path.data(), path.length(), object.TakeChannel(),
+ binding_.dispatcher());
+}
+
+void DirectoryConnection::Unlink(::std::string path, UnlinkCallback callback) {
+ callback(ZX_ERR_NOT_SUPPORTED);
+}
+
+void DirectoryConnection::ReadDirents(uint64_t max_bytes, ReadDirentsCallback callback) {
+ uint64_t new_offset = 0, out_bytes = 0;
+ std::vector<uint8_t> vec(max_bytes);
+ zx_status_t status = vn_->Readdir(offset(), vec.data(), max_bytes, &new_offset, &out_bytes);
+ ZX_DEBUG_ASSERT(out_bytes <= max_bytes);
+ vec.resize(out_bytes);
+ if (status == ZX_OK) {
+ set_offset(new_offset);
+ }
+ callback(status, std::move(vec));
+}
+
+void DirectoryConnection::Rewind(RewindCallback callback) {
+ set_offset(0);
+ callback(ZX_OK);
+}
+
+void DirectoryConnection::GetToken(GetTokenCallback callback) {
+ callback(ZX_ERR_NOT_SUPPORTED, zx::handle());
+}
+
+void DirectoryConnection::Rename(::std::string src, zx::handle dst_parent_token, std::string dst,
+ RenameCallback callback) {
+ callback(ZX_ERR_NOT_SUPPORTED);
+}
+
+void DirectoryConnection::Link(::std::string src, zx::handle dst_parent_token, std::string dst,
+ LinkCallback callback) {
+ callback(ZX_ERR_NOT_SUPPORTED);
+}
+
+void DirectoryConnection::Watch(uint32_t mask, uint32_t options, zx::channel watcher,
+ WatchCallback callback) {
+ // TODO: Implement watch.
+ callback(ZX_ERR_NOT_SUPPORTED);
+}
+
+void DirectoryConnection::SendOnOpenEvent(zx_status_t status) {
+ binding_.events().OnOpen(status, NodeInfoIfStatusOk(vn_, status));
+}
+
+} // namespace internal
+} // namespace vfs
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/internal/dirent_filler.cc b/third_party/fuchsia-sdk/pkg/vfs_cpp/internal/dirent_filler.cc
new file mode 100644
index 0000000..5783ad8
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/internal/dirent_filler.cc
@@ -0,0 +1,35 @@
+// 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.
+
+#include <lib/fdio/vfs.h>
+#include <lib/vfs/cpp/internal/dirent_filler.h>
+#include <limits.h>
+
+namespace vfs {
+namespace internal {
+
+DirentFiller::DirentFiller(void* ptr, uint64_t len)
+ : ptr_(static_cast<char*>(ptr)), pos_(0), len_(len) {}
+
+zx_status_t DirentFiller::Next(const std::string& name, uint8_t type, uint64_t ino) {
+ return Next(name.data(), name.length(), type, ino);
+}
+
+zx_status_t DirentFiller::Next(const char* name, size_t name_len, uint8_t type, uint64_t ino) {
+ vdirent_t* de = reinterpret_cast<vdirent_t*>(ptr_ + pos_);
+ size_t sz = sizeof(vdirent_t) + name_len;
+
+ if (sz > len_ - pos_ || name_len > NAME_MAX) {
+ return ZX_ERR_INVALID_ARGS;
+ }
+ de->ino = ino;
+ de->size = static_cast<uint8_t>(name_len);
+ de->type = type;
+ memcpy(de->name, name, name_len);
+ pos_ += sz;
+ return ZX_OK;
+}
+
+} // namespace internal
+} // namespace vfs
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/internal/file.cc b/third_party/fuchsia-sdk/pkg/vfs_cpp/internal/file.cc
new file mode 100644
index 0000000..d0a8a25
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/internal/file.cc
@@ -0,0 +1,38 @@
+// 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.
+
+#include <lib/vfs/cpp/internal/file.h>
+#include <lib/vfs/cpp/internal/file_connection.h>
+
+namespace vfs {
+namespace internal {
+
+File::File() = default;
+File::~File() = default;
+
+void File::Describe(fuchsia::io::NodeInfo* out_info) {
+ out_info->set_file(fuchsia::io::FileObject());
+}
+
+zx_status_t File::ReadAt(uint64_t count, uint64_t offset, std::vector<uint8_t>* out_data) {
+ return ZX_ERR_NOT_SUPPORTED;
+}
+
+zx_status_t File::WriteAt(std::vector<uint8_t> data, uint64_t offset, uint64_t* out_actual) {
+ return ZX_ERR_NOT_SUPPORTED;
+}
+
+zx_status_t File::Truncate(uint64_t length) { return ZX_ERR_NOT_SUPPORTED; }
+
+zx_status_t File::CreateConnection(uint32_t flags, std::unique_ptr<Connection>* connection) {
+ *connection = std::make_unique<internal::FileConnection>(flags, this);
+ return ZX_OK;
+}
+
+size_t File::GetCapacity() { return std::numeric_limits<size_t>::max(); }
+
+NodeKind::Type File::GetKind() const { return NodeKind::kFile; }
+
+} // namespace internal
+} // namespace vfs
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/internal/file_connection.cc b/third_party/fuchsia-sdk/pkg/vfs_cpp/internal/file_connection.cc
new file mode 100644
index 0000000..b9305f7
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/internal/file_connection.cc
@@ -0,0 +1,150 @@
+// 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.
+
+#include <lib/vfs/cpp/flags.h>
+#include <lib/vfs/cpp/internal/file.h>
+#include <lib/vfs/cpp/internal/file_connection.h>
+
+#include <utility>
+
+namespace vfs {
+namespace internal {
+
+FileConnection::FileConnection(uint32_t flags, vfs::internal::File* vn)
+ : Connection(flags), vn_(vn), binding_(this) {}
+
+FileConnection::~FileConnection() = default;
+
+zx_status_t FileConnection::BindInternal(zx::channel request, async_dispatcher_t* dispatcher) {
+ if (binding_.is_bound()) {
+ return ZX_ERR_BAD_STATE;
+ }
+ zx_status_t status = binding_.Bind(std::move(request), dispatcher);
+ if (status != ZX_OK) {
+ return status;
+ }
+ binding_.set_error_handler([this](zx_status_t status) { vn_->Close(this); });
+ return ZX_OK;
+}
+
+void FileConnection::Clone(uint32_t flags, fidl::InterfaceRequest<fuchsia::io::Node> object) {
+ Connection::Clone(vn_, flags, object.TakeChannel(), binding_.dispatcher());
+}
+
+void FileConnection::Close(CloseCallback callback) { Connection::Close(vn_, std::move(callback)); }
+
+void FileConnection::Describe(DescribeCallback callback) {
+ Connection::Describe(vn_, std::move(callback));
+}
+
+void FileConnection::Sync(SyncCallback callback) { Connection::Sync(vn_, std::move(callback)); }
+
+void FileConnection::GetAttr(GetAttrCallback callback) {
+ Connection::GetAttr(vn_, std::move(callback));
+}
+
+void FileConnection::SetAttr(uint32_t flags, fuchsia::io::NodeAttributes attributes,
+ SetAttrCallback callback) {
+ Connection::SetAttr(vn_, flags, attributes, std::move(callback));
+}
+
+void FileConnection::Read(uint64_t count, ReadCallback callback) {
+ std::vector<uint8_t> data;
+ if (!Flags::IsReadable(flags())) {
+ callback(ZX_ERR_ACCESS_DENIED, std::move(data));
+ return;
+ }
+ zx_status_t status = vn_->ReadAt(count, offset(), &data);
+ if (status == ZX_OK) {
+ set_offset(offset() + data.size());
+ }
+ callback(status, std::move(data));
+}
+
+void FileConnection::ReadAt(uint64_t count, uint64_t offset, ReadAtCallback callback) {
+ std::vector<uint8_t> data;
+ if (!Flags::IsReadable(flags())) {
+ callback(ZX_ERR_ACCESS_DENIED, std::move(data));
+ return;
+ }
+ zx_status_t status = vn_->ReadAt(count, offset, &data);
+ callback(status, std::move(data));
+}
+
+void FileConnection::Write(std::vector<uint8_t> data, WriteCallback callback) {
+ if (!Flags::IsWritable(flags())) {
+ callback(ZX_ERR_ACCESS_DENIED, 0);
+ return;
+ }
+ uint64_t actual = 0u;
+ zx_status_t status = vn_->WriteAt(std::move(data), offset(), &actual);
+ if (status == ZX_OK) {
+ set_offset(offset() + actual);
+ }
+ callback(status, actual);
+}
+
+void FileConnection::WriteAt(std::vector<uint8_t> data, uint64_t offset, WriteAtCallback callback) {
+ if (!Flags::IsWritable(flags())) {
+ callback(ZX_ERR_ACCESS_DENIED, 0);
+ return;
+ }
+ uint64_t actual = 0u;
+ zx_status_t status = vn_->WriteAt(std::move(data), offset, &actual);
+ callback(status, actual);
+}
+
+void FileConnection::Seek(int64_t new_offset, fuchsia::io::SeekOrigin seek, SeekCallback callback) {
+ int64_t cur_len = vn_->GetLength();
+ size_t capacity = vn_->GetCapacity();
+ uint64_t calculated_offset = 0u;
+ // TODO: This code does not appear to handle overflow.
+ switch (seek) {
+ case fuchsia::io::SeekOrigin::START:
+ calculated_offset = new_offset;
+ break;
+ case fuchsia::io::SeekOrigin::CURRENT:
+ calculated_offset = offset() + new_offset;
+ break;
+ case fuchsia::io::SeekOrigin::END:
+ calculated_offset = cur_len + new_offset;
+ break;
+ default:
+ callback(ZX_ERR_INVALID_ARGS, 0u);
+ return;
+ }
+
+ if (static_cast<size_t>(calculated_offset) > capacity) {
+ callback(ZX_ERR_OUT_OF_RANGE, offset());
+ return;
+ }
+ set_offset(calculated_offset);
+ callback(ZX_OK, offset());
+}
+
+void FileConnection::Truncate(uint64_t length, TruncateCallback callback) {
+ if (!Flags::IsWritable(flags())) {
+ callback(ZX_ERR_ACCESS_DENIED);
+ return;
+ }
+ callback(vn_->Truncate(length));
+}
+
+void FileConnection::GetFlags(GetFlagsCallback callback) { callback(ZX_OK, flags()); }
+
+void FileConnection::SetFlags(uint32_t flags, SetFlagsCallback callback) {
+ // TODO: Implement set flags.
+ callback(ZX_ERR_NOT_SUPPORTED);
+}
+
+void FileConnection::GetBuffer(uint32_t flags, GetBufferCallback callback) {
+ callback(ZX_ERR_NOT_SUPPORTED, nullptr);
+}
+
+void FileConnection::SendOnOpenEvent(zx_status_t status) {
+ binding_.events().OnOpen(status, NodeInfoIfStatusOk(vn_, status));
+}
+
+} // namespace internal
+} // namespace vfs
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/internal/node.cc b/third_party/fuchsia-sdk/pkg/vfs_cpp/internal/node.cc
new file mode 100644
index 0000000..1786b89
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/internal/node.cc
@@ -0,0 +1,234 @@
+// 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.
+
+#include <lib/fidl/cpp/event_sender.h>
+#include <lib/vfs/cpp/flags.h>
+#include <lib/vfs/cpp/internal/connection.h>
+#include <lib/vfs/cpp/internal/node.h>
+#include <lib/vfs/cpp/internal/node_connection.h>
+#include <zircon/assert.h>
+
+#include <algorithm>
+#include <mutex>
+
+namespace vfs {
+namespace {
+
+constexpr uint32_t kCommonAllowedFlags =
+ fuchsia::io::OPEN_FLAG_DESCRIBE | fuchsia::io::OPEN_FLAG_NODE_REFERENCE |
+ fuchsia::io::OPEN_FLAG_POSIX | fuchsia::io::CLONE_FLAG_SAME_RIGHTS;
+
+constexpr std::tuple<NodeKind::Type, uint32_t> kKindFlagMap[] = {
+ {NodeKind::kReadable, fuchsia::io::OPEN_RIGHT_READABLE},
+ {NodeKind::kMountable, fuchsia::io::OPEN_RIGHT_ADMIN},
+ {NodeKind::kWritable, fuchsia::io::OPEN_RIGHT_WRITABLE},
+ {NodeKind::kAppendable, fuchsia::io::OPEN_FLAG_APPEND},
+ {NodeKind::kCanTruncate, fuchsia::io::OPEN_FLAG_TRUNCATE},
+ {NodeKind::kCreatable,
+ fuchsia::io::OPEN_FLAG_CREATE | fuchsia::io::OPEN_FLAG_CREATE_IF_ABSENT}};
+
+} // namespace
+
+namespace internal {
+
+bool IsValidName(const std::string& name) {
+ return name.length() <= NAME_MAX && memchr(name.data(), '/', name.length()) == nullptr &&
+ name != "." && name != "..";
+}
+
+Node::Node() = default;
+Node::~Node() = default;
+
+std::unique_ptr<Connection> Node::Close(Connection* connection) {
+ std::lock_guard<std::mutex> guard(mutex_);
+
+ auto connection_iterator =
+ std::find_if(connections_.begin(), connections_.end(),
+ [connection](const auto& entry) { return entry.get() == connection; });
+ auto ret = std::move(*connection_iterator);
+ connections_.erase(connection_iterator);
+ return ret;
+}
+
+zx_status_t Node::PreClose(Connection* connection) { return ZX_OK; }
+
+zx_status_t Node::Sync() { return ZX_ERR_NOT_SUPPORTED; }
+
+zx_status_t Node::GetAttr(fuchsia::io::NodeAttributes* out_attributes) const {
+ return ZX_ERR_NOT_SUPPORTED;
+}
+
+void Node::Clone(uint32_t flags, uint32_t parent_flags, zx::channel request,
+ async_dispatcher_t* dispatcher) {
+ if (!Flags::InputPrecondition(flags)) {
+ SendOnOpenEventOnError(flags, std::move(request), ZX_ERR_INVALID_ARGS);
+ return;
+ }
+ // If SAME_RIGHTS is specified, the client cannot request any specific rights.
+ if (Flags::ShouldCloneWithSameRights(flags) && (flags & Flags::kFsRights)) {
+ SendOnOpenEventOnError(flags, std::move(request), ZX_ERR_INVALID_ARGS);
+ return;
+ }
+ flags |= (parent_flags & Flags::kStatusFlags);
+ // If SAME_RIGHTS is requested, cloned connection will inherit the same rights
+ // as those from the originating connection.
+ if (Flags::ShouldCloneWithSameRights(flags)) {
+ flags &= (~Flags::kFsRights);
+ flags |= (parent_flags & Flags::kFsRights);
+ flags &= ~fuchsia::io::CLONE_FLAG_SAME_RIGHTS;
+ }
+ if (!Flags::StricterOrSameRights(flags, parent_flags)) {
+ SendOnOpenEventOnError(flags, std::move(request), ZX_ERR_ACCESS_DENIED);
+ return;
+ }
+ Serve(flags, std::move(request), dispatcher);
+}
+
+zx_status_t Node::ValidateFlags(uint32_t flags) const {
+ if (!Flags::InputPrecondition(flags)) {
+ return ZX_ERR_INVALID_ARGS;
+ }
+ bool is_directory = IsDirectory();
+ if (!is_directory && Flags::IsDirectory(flags)) {
+ return ZX_ERR_NOT_DIR;
+ }
+ if (is_directory && Flags::IsNotDirectory(flags)) {
+ return ZX_ERR_NOT_FILE;
+ }
+
+ uint32_t allowed_flags = kCommonAllowedFlags | GetAllowedFlags();
+ if (is_directory) {
+ allowed_flags = allowed_flags | fuchsia::io::OPEN_FLAG_DIRECTORY;
+ } else {
+ allowed_flags = allowed_flags | fuchsia::io::OPEN_FLAG_NOT_DIRECTORY;
+ }
+
+ uint32_t prohibitive_flags = GetProhibitiveFlags();
+
+ if ((flags & prohibitive_flags) != 0) {
+ return ZX_ERR_INVALID_ARGS;
+ }
+ if ((flags & ~allowed_flags) != 0) {
+ return ZX_ERR_NOT_SUPPORTED;
+ }
+ return ZX_OK;
+}
+
+zx_status_t Node::ValidateMode(uint32_t mode) const {
+ fuchsia::io::NodeAttributes attr;
+ uint32_t mode_from_attr = 0;
+ zx_status_t status = GetAttr(&attr);
+ if (status == ZX_OK) {
+ mode_from_attr = attr.mode & fuchsia::io::MODE_TYPE_MASK;
+ }
+
+ if (((mode & ~fuchsia::io::MODE_PROTECTION_MASK) & ~mode_from_attr) != 0) {
+ return ZX_ERR_INVALID_ARGS;
+ }
+ return ZX_OK;
+}
+
+zx_status_t Node::Lookup(const std::string& name, Node** out_node) const {
+ ZX_ASSERT(!IsDirectory());
+ return ZX_ERR_NOT_DIR;
+}
+
+uint32_t Node::GetAllowedFlags() const {
+ NodeKind::Type kind = GetKind();
+ uint32_t flags = 0;
+ for (auto& tuple : kKindFlagMap) {
+ if ((kind & std::get<0>(tuple)) == std::get<0>(tuple)) {
+ flags = flags | std::get<1>(tuple);
+ }
+ }
+ return flags;
+}
+
+uint32_t Node::GetProhibitiveFlags() const {
+ NodeKind::Type kind = GetKind();
+ if (NodeKind::IsDirectory(kind)) {
+ return fuchsia::io::OPEN_FLAG_CREATE | fuchsia::io::OPEN_FLAG_CREATE_IF_ABSENT |
+ fuchsia::io::OPEN_FLAG_TRUNCATE | fuchsia::io::OPEN_FLAG_APPEND;
+ }
+ return 0;
+}
+
+zx_status_t Node::SetAttr(uint32_t flags, const fuchsia::io::NodeAttributes& attributes) {
+ return ZX_ERR_NOT_SUPPORTED;
+}
+
+uint32_t Node::FilterRefFlags(uint32_t flags) {
+ if (Flags::IsNodeReference(flags)) {
+ return flags & (kCommonAllowedFlags | fuchsia::io::OPEN_FLAG_DIRECTORY);
+ }
+ return flags;
+}
+
+zx_status_t Node::Serve(uint32_t flags, zx::channel request, async_dispatcher_t* dispatcher) {
+ flags = FilterRefFlags(flags);
+ zx_status_t status = ValidateFlags(flags);
+ if (status != ZX_OK) {
+ SendOnOpenEventOnError(flags, std::move(request), status);
+ return status;
+ }
+ return Connect(flags, std::move(request), dispatcher);
+}
+
+zx_status_t Node::Connect(uint32_t flags, zx::channel request, async_dispatcher_t* dispatcher) {
+ zx_status_t status;
+ std::unique_ptr<Connection> connection;
+ if (Flags::IsNodeReference(flags)) {
+ status = Node::CreateConnection(flags, &connection);
+ } else {
+ status = CreateConnection(flags, &connection);
+ }
+ if (status != ZX_OK) {
+ SendOnOpenEventOnError(flags, std::move(request), status);
+ return status;
+ }
+ status = connection->Bind(std::move(request), dispatcher);
+ if (status == ZX_OK) {
+ AddConnection(std::move(connection));
+ }
+ return status;
+}
+
+zx_status_t Node::ServeWithMode(uint32_t flags, uint32_t mode, zx::channel request,
+ async_dispatcher_t* dispatcher) {
+ zx_status_t status = ValidateMode(mode);
+ if (status != ZX_OK) {
+ SendOnOpenEventOnError(flags, std::move(request), status);
+ return status;
+ }
+ return Serve(flags, std::move(request), dispatcher);
+}
+
+void Node::SendOnOpenEventOnError(uint32_t flags, zx::channel request, zx_status_t status) {
+ ZX_DEBUG_ASSERT(status != ZX_OK);
+
+ if (!Flags::ShouldDescribe(flags)) {
+ return;
+ }
+
+ fidl::EventSender<fuchsia::io::Node> sender(std::move(request));
+ sender.events().OnOpen(status, nullptr);
+}
+
+uint64_t Node::GetConnectionCount() const {
+ std::lock_guard<std::mutex> guard(mutex_);
+ return connections_.size();
+}
+
+void Node::AddConnection(std::unique_ptr<Connection> connection) {
+ std::lock_guard<std::mutex> guard(mutex_);
+ connections_.push_back(std::move(connection));
+}
+
+zx_status_t Node::CreateConnection(uint32_t flags, std::unique_ptr<Connection>* connection) {
+ *connection = std::make_unique<internal::NodeConnection>(flags, this);
+ return ZX_OK;
+}
+
+} // namespace internal
+} // namespace vfs
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/internal/node_connection.cc b/third_party/fuchsia-sdk/pkg/vfs_cpp/internal/node_connection.cc
new file mode 100644
index 0000000..cba3ba7
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/internal/node_connection.cc
@@ -0,0 +1,57 @@
+// 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.
+
+#include <lib/vfs/cpp/flags.h>
+#include <lib/vfs/cpp/internal/node.h>
+#include <lib/vfs/cpp/internal/node_connection.h>
+
+#include <utility>
+
+namespace vfs {
+namespace internal {
+
+NodeConnection::NodeConnection(uint32_t flags, vfs::internal::Node* vn)
+ : Connection(flags), vn_(vn), binding_(this) {}
+
+NodeConnection::~NodeConnection() = default;
+
+zx_status_t NodeConnection::BindInternal(zx::channel request, async_dispatcher_t* dispatcher) {
+ if (binding_.is_bound()) {
+ return ZX_ERR_BAD_STATE;
+ }
+ zx_status_t status = binding_.Bind(std::move(request), dispatcher);
+ if (status != ZX_OK) {
+ return status;
+ }
+ binding_.set_error_handler([this](zx_status_t status) { vn_->Close(this); });
+ return ZX_OK;
+}
+
+void NodeConnection::Clone(uint32_t flags, fidl::InterfaceRequest<fuchsia::io::Node> object) {
+ Connection::Clone(vn_, flags, object.TakeChannel(), binding_.dispatcher());
+}
+
+void NodeConnection::Close(CloseCallback callback) { Connection::Close(vn_, std::move(callback)); }
+
+void NodeConnection::Describe(DescribeCallback callback) {
+ Connection::Describe(vn_, std::move(callback));
+}
+
+void NodeConnection::Sync(SyncCallback callback) { Connection::Sync(vn_, std::move(callback)); }
+
+void NodeConnection::GetAttr(GetAttrCallback callback) {
+ Connection::GetAttr(vn_, std::move(callback));
+}
+
+void NodeConnection::SetAttr(uint32_t flags, fuchsia::io::NodeAttributes attributes,
+ SetAttrCallback callback) {
+ Connection::SetAttr(vn_, flags, attributes, std::move(callback));
+}
+
+void NodeConnection::SendOnOpenEvent(zx_status_t status) {
+ binding_.events().OnOpen(status, NodeInfoIfStatusOk(vn_, status));
+}
+
+} // namespace internal
+} // namespace vfs
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/lazy_dir.cc b/third_party/fuchsia-sdk/pkg/vfs_cpp/lazy_dir.cc
new file mode 100644
index 0000000..f87add2
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/lazy_dir.cc
@@ -0,0 +1,79 @@
+// 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.
+
+#include <lib/fdio/vfs.h>
+#include <lib/vfs/cpp/internal/dirent_filler.h>
+#include <lib/vfs/cpp/lazy_dir.h>
+
+#include <algorithm>
+
+namespace vfs {
+
+bool LazyDir::LazyEntry::operator<(const LazyDir::LazyEntry& rhs) const { return id < rhs.id; }
+
+LazyDir::LazyDir() {}
+
+LazyDir::~LazyDir() = default;
+
+zx_status_t LazyDir::GetAttr(fuchsia::io::NodeAttributes* out_attributes) const {
+ out_attributes->mode = fuchsia::io::MODE_TYPE_DIRECTORY | V_IRUSR;
+ out_attributes->id = fuchsia::io::INO_UNKNOWN;
+ out_attributes->content_size = 0;
+ out_attributes->storage_size = 0;
+ out_attributes->link_count = 1;
+ out_attributes->creation_time = 0;
+ out_attributes->modification_time = 0;
+ return ZX_OK;
+}
+
+zx_status_t LazyDir::Lookup(const std::string& name, Node** out_node) const {
+ LazyEntryVector entries;
+ GetContents(&entries);
+ for (const auto& entry : entries) {
+ if (name == entry.name) {
+ return GetFile(out_node, entry.id, entry.name);
+ }
+ }
+ return ZX_ERR_NOT_FOUND;
+}
+
+zx_status_t LazyDir::Readdir(uint64_t offset, void* data, uint64_t len, uint64_t* out_offset,
+ uint64_t* out_actual) {
+ LazyEntryVector entries;
+ GetContents(&entries);
+ std::sort(entries.begin(), entries.end());
+
+ vfs::internal::DirentFiller filler(data, len);
+
+ const uint64_t ino = fuchsia::io::INO_UNKNOWN;
+ if (offset < kDotId) {
+ if (filler.Next(".", 1, fuchsia::io::DIRENT_TYPE_DIRECTORY, ino) != ZX_OK) {
+ *out_actual = filler.GetBytesFilled();
+ return ZX_ERR_INVALID_ARGS; // out_actual would be 0
+ }
+ offset++;
+ *out_offset = kDotId;
+ }
+ for (auto it = std::upper_bound(entries.begin(), entries.end(), offset,
+ [](uint64_t b_id, const LazyEntry&a) { return b_id < a.id; });
+ it != entries.end(); ++it) {
+ auto dtype = ((fuchsia::io::MODE_TYPE_MASK & it->type) >> 12);
+ if (filler.Next(it->name, dtype, ino) != ZX_OK) {
+ *out_actual = filler.GetBytesFilled();
+ if (*out_actual == 0) {
+ // no space to fill even 1 dentry
+ return ZX_ERR_INVALID_ARGS;
+ }
+ return ZX_OK;
+ }
+ *out_offset = it->id;
+ }
+
+ *out_actual = filler.GetBytesFilled();
+ return ZX_OK;
+}
+
+uint64_t LazyDir::GetStartingId() const { return kDotId + 1; }
+
+} // namespace vfs
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/meta.json b/third_party/fuchsia-sdk/pkg/vfs_cpp/meta.json
new file mode 100644
index 0000000..99893d2
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/meta.json
@@ -0,0 +1,52 @@
+{
+ "banjo_deps": [],
+ "deps": [
+ "fidl_cpp",
+ "async",
+ "fdio",
+ "zx"
+ ],
+ "fidl_deps": [
+ "fuchsia.io"
+ ],
+ "headers": [
+ "pkg/vfs_cpp/include/lib/vfs/cpp/composed_service_dir.h",
+ "pkg/vfs_cpp/include/lib/vfs/cpp/flags.h",
+ "pkg/vfs_cpp/include/lib/vfs/cpp/internal/connection.h",
+ "pkg/vfs_cpp/include/lib/vfs/cpp/internal/directory.h",
+ "pkg/vfs_cpp/include/lib/vfs/cpp/internal/directory_connection.h",
+ "pkg/vfs_cpp/include/lib/vfs/cpp/internal/dirent_filler.h",
+ "pkg/vfs_cpp/include/lib/vfs/cpp/internal/file.h",
+ "pkg/vfs_cpp/include/lib/vfs/cpp/internal/file_connection.h",
+ "pkg/vfs_cpp/include/lib/vfs/cpp/internal/node.h",
+ "pkg/vfs_cpp/include/lib/vfs/cpp/internal/node_connection.h",
+ "pkg/vfs_cpp/include/lib/vfs/cpp/lazy_dir.h",
+ "pkg/vfs_cpp/include/lib/vfs/cpp/node_kind.h",
+ "pkg/vfs_cpp/include/lib/vfs/cpp/pseudo_dir.h",
+ "pkg/vfs_cpp/include/lib/vfs/cpp/pseudo_file.h",
+ "pkg/vfs_cpp/include/lib/vfs/cpp/remote_dir.h",
+ "pkg/vfs_cpp/include/lib/vfs/cpp/service.h",
+ "pkg/vfs_cpp/include/lib/vfs/cpp/vmo_file.h"
+ ],
+ "include_dir": "pkg/vfs_cpp/include",
+ "name": "vfs_cpp",
+ "root": "pkg/vfs_cpp",
+ "sources": [
+ "pkg/vfs_cpp/composed_service_dir.cc",
+ "pkg/vfs_cpp/internal/connection.cc",
+ "pkg/vfs_cpp/internal/directory.cc",
+ "pkg/vfs_cpp/internal/directory_connection.cc",
+ "pkg/vfs_cpp/internal/dirent_filler.cc",
+ "pkg/vfs_cpp/internal/file.cc",
+ "pkg/vfs_cpp/internal/file_connection.cc",
+ "pkg/vfs_cpp/internal/node.cc",
+ "pkg/vfs_cpp/internal/node_connection.cc",
+ "pkg/vfs_cpp/lazy_dir.cc",
+ "pkg/vfs_cpp/pseudo_dir.cc",
+ "pkg/vfs_cpp/pseudo_file.cc",
+ "pkg/vfs_cpp/remote_dir.cc",
+ "pkg/vfs_cpp/service.cc",
+ "pkg/vfs_cpp/vmo_file.cc"
+ ],
+ "type": "cc_source_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/pseudo_dir.cc b/third_party/fuchsia-sdk/pkg/vfs_cpp/pseudo_dir.cc
new file mode 100644
index 0000000..8536106
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/pseudo_dir.cc
@@ -0,0 +1,148 @@
+// 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.
+
+#include <lib/fdio/vfs.h>
+#include <lib/vfs/cpp/internal/dirent_filler.h>
+#include <lib/vfs/cpp/pseudo_dir.h>
+
+#include <mutex>
+
+namespace vfs {
+
+PseudoDir::PseudoDir() : next_node_id_(kDotId + 1) {}
+
+PseudoDir::~PseudoDir() = default;
+
+zx_status_t PseudoDir::AddSharedEntry(std::string name, std::shared_ptr<Node> vn) {
+ ZX_DEBUG_ASSERT(vn);
+
+ auto id = next_node_id_++;
+ return AddEntry(std::make_unique<SharedEntry>(id, std::move(name), std::move(vn)));
+}
+
+zx_status_t PseudoDir::AddEntry(std::string name, std::unique_ptr<Node> vn) {
+ ZX_DEBUG_ASSERT(vn);
+
+ auto id = next_node_id_++;
+ return AddEntry(std::make_unique<UniqueEntry>(id, std::move(name), std::move(vn)));
+}
+
+zx_status_t PseudoDir::AddEntry(std::unique_ptr<Entry> entry) {
+ ZX_DEBUG_ASSERT(entry);
+
+ if (!vfs::internal::IsValidName(entry->name())) {
+ return ZX_ERR_INVALID_ARGS;
+ }
+
+ std::lock_guard<std::mutex> guard(mutex_);
+
+ if (entries_by_name_.find(entry->name()) != entries_by_name_.end()) {
+ return ZX_ERR_ALREADY_EXISTS;
+ }
+ entries_by_name_[entry->name()] = entry.get();
+ auto id = entry->id();
+ entries_by_id_.emplace_hint(entries_by_id_.end(), id, std::move(entry));
+
+ return ZX_OK;
+}
+
+zx_status_t PseudoDir::RemoveEntry(const std::string& name) {
+ std::lock_guard<std::mutex> guard(mutex_);
+ auto entry = entries_by_name_.find(name);
+ if (entry == entries_by_name_.end()) {
+ return ZX_ERR_NOT_FOUND;
+ }
+ entries_by_id_.erase(entry->second->id());
+ entries_by_name_.erase(name);
+
+ return ZX_OK;
+}
+
+zx_status_t PseudoDir::RemoveEntry(const std::string& name, Node* node) {
+ std::lock_guard<std::mutex> guard(mutex_);
+ auto entry = entries_by_name_.find(name);
+ if (entry == entries_by_name_.end() || entry->second->node() != node) {
+ return ZX_ERR_NOT_FOUND;
+ }
+ entries_by_id_.erase(entry->second->id());
+ entries_by_name_.erase(name);
+
+ return ZX_OK;
+}
+
+zx_status_t PseudoDir::Lookup(const std::string& name, vfs::internal::Node** out_node) const {
+ std::lock_guard<std::mutex> guard(mutex_);
+
+ auto search = entries_by_name_.find(name);
+ if (search != entries_by_name_.end()) {
+ *out_node = search->second->node();
+ return ZX_OK;
+ } else {
+ return ZX_ERR_NOT_FOUND;
+ }
+}
+
+zx_status_t PseudoDir::Readdir(uint64_t offset, void* data, uint64_t len, uint64_t* out_offset,
+ uint64_t* out_actual) {
+ vfs::internal::DirentFiller df(data, len);
+ *out_actual = 0;
+ *out_offset = offset;
+ if (offset < kDotId) {
+ if (df.Next(".", 1, fuchsia::io::DIRENT_TYPE_DIRECTORY, fuchsia::io::INO_UNKNOWN) != ZX_OK) {
+ *out_actual = df.GetBytesFilled();
+ return ZX_ERR_INVALID_ARGS; // out_actual would be 0
+ }
+ (*out_offset)++;
+ }
+
+ std::lock_guard<std::mutex> guard(mutex_);
+
+ for (auto it = entries_by_id_.upper_bound(*out_offset); it != entries_by_id_.end(); ++it) {
+ fuchsia::io::NodeAttributes attr;
+ auto d_type = fuchsia::io::DIRENT_TYPE_UNKNOWN;
+ auto ino = fuchsia::io::INO_UNKNOWN;
+ if (it->second->node()->GetAttr(&attr) == ZX_OK) {
+ d_type = ((fuchsia::io::MODE_TYPE_MASK & attr.mode) >> 12);
+ ino = attr.id;
+ }
+
+ if (df.Next(it->second->name(), d_type, ino) != ZX_OK) {
+ *out_actual = df.GetBytesFilled();
+ if (*out_actual == 0) {
+ // no space to fill even 1 dentry
+ return ZX_ERR_INVALID_ARGS;
+ }
+ return ZX_OK;
+ }
+ *out_offset = it->second->id();
+ }
+
+ *out_actual = df.GetBytesFilled();
+ return ZX_OK;
+}
+
+bool PseudoDir::IsEmpty() const {
+ std::lock_guard<std::mutex> guard(mutex_);
+ return entries_by_name_.size() == 0;
+}
+
+PseudoDir::Entry::Entry(uint64_t id, std::string name) : id_(id), name_(std::move(name)) {}
+
+PseudoDir::Entry::~Entry() = default;
+
+PseudoDir::SharedEntry::SharedEntry(uint64_t id, std::string name, std::shared_ptr<Node> node)
+ : Entry(id, std::move(name)), node_(std::move(node)) {}
+
+vfs::internal::Node* PseudoDir::SharedEntry::node() const { return node_.get(); }
+
+PseudoDir::SharedEntry::~SharedEntry() = default;
+
+PseudoDir::UniqueEntry::UniqueEntry(uint64_t id, std::string name, std::unique_ptr<Node> node)
+ : Entry(id, std::move(name)), node_(std::move(node)) {}
+
+vfs::internal::Node* PseudoDir::UniqueEntry::node() const { return node_.get(); }
+
+PseudoDir::UniqueEntry::~UniqueEntry() = default;
+
+} // namespace vfs
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/pseudo_file.cc b/third_party/fuchsia-sdk/pkg/vfs_cpp/pseudo_file.cc
new file mode 100644
index 0000000..593dd2f
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/pseudo_file.cc
@@ -0,0 +1,190 @@
+// 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.
+
+#include <lib/fdio/vfs.h>
+#include <lib/vfs/cpp/flags.h>
+#include <lib/vfs/cpp/internal/file_connection.h>
+#include <lib/vfs/cpp/pseudo_file.h>
+#include <zircon/assert.h>
+#include <zircon/errors.h>
+
+#include <sstream>
+
+namespace vfs {
+
+PseudoFile::PseudoFile(size_t max_file_size, ReadHandler read_handler, WriteHandler write_handler)
+ : read_handler_(std::move(read_handler)),
+ write_handler_(std::move(write_handler)),
+ max_file_size_(max_file_size) {
+ ZX_DEBUG_ASSERT(read_handler_ != nullptr);
+}
+
+PseudoFile::~PseudoFile() = default;
+
+zx_status_t PseudoFile::CreateConnection(uint32_t flags,
+ std::unique_ptr<vfs::internal::Connection>* connection) {
+ std::vector<uint8_t> output;
+ if (Flags::IsReadable(flags)) {
+ zx_status_t status = read_handler_(&output, max_file_size_);
+ if (status != ZX_OK) {
+ return status;
+ }
+ if (output.size() > max_file_size_) {
+ return ZX_ERR_FILE_BIG;
+ }
+ }
+ *connection = std::make_unique<PseudoFile::Content>(this, flags, std::move(output));
+ return ZX_OK;
+}
+
+zx_status_t PseudoFile::GetAttr(fuchsia::io::NodeAttributes* out_attributes) const {
+ out_attributes->mode = fuchsia::io::MODE_TYPE_FILE;
+ if (read_handler_ != nullptr)
+ out_attributes->mode |= V_IRUSR;
+ if (write_handler_)
+ out_attributes->mode |= V_IWUSR;
+ out_attributes->id = fuchsia::io::INO_UNKNOWN;
+ out_attributes->content_size = 0;
+ out_attributes->storage_size = 0;
+ out_attributes->link_count = 1;
+ out_attributes->creation_time = 0;
+ out_attributes->modification_time = 0;
+ return ZX_OK;
+}
+
+NodeKind::Type PseudoFile::GetKind() const {
+ auto kind = File::GetKind() | NodeKind::kReadable;
+ if (write_handler_ != nullptr) {
+ kind |= NodeKind::kWritable | NodeKind::kCanTruncate;
+ }
+ return kind;
+}
+
+uint64_t PseudoFile::GetLength() {
+ // this should never be called
+ ZX_ASSERT(false);
+
+ return 0u;
+}
+
+size_t PseudoFile::GetCapacity() {
+ // this should never be called
+ ZX_DEBUG_ASSERT(false);
+
+ return max_file_size_;
+}
+
+PseudoFile::Content::Content(PseudoFile* file, uint32_t flags, std::vector<uint8_t> content)
+ : Connection(flags), file_(file), buffer_(std::move(content)), flags_(flags) {
+ SetInputLength(buffer_.size());
+}
+
+PseudoFile::Content::~Content() { TryFlushIfRequired(); }
+
+zx_status_t PseudoFile::Content::TryFlushIfRequired() {
+ if (!dirty_) {
+ return ZX_OK;
+ }
+ dirty_ = false;
+ return file_->write_handler_(std::move(buffer_));
+}
+
+zx_status_t PseudoFile::Content::PreClose(Connection* connection) { return TryFlushIfRequired(); }
+
+NodeKind::Type PseudoFile::Content::GetKind() const { return file_->GetKind(); }
+
+zx_status_t PseudoFile::Content::ReadAt(uint64_t count, uint64_t offset,
+ std::vector<uint8_t>* out_data) {
+ if (offset >= buffer_.size()) {
+ return ZX_OK;
+ }
+ size_t actual = std::min(buffer_.size() - offset, count);
+ out_data->resize(actual);
+ std::copy_n(buffer_.begin() + offset, actual, out_data->begin());
+ return ZX_OK;
+}
+
+zx_status_t PseudoFile::Content::GetAttr(fuchsia::io::NodeAttributes* out_attributes) const {
+ auto status = file_->GetAttr(out_attributes);
+ if (status == ZX_OK) {
+ out_attributes->content_size = buffer_.size();
+ }
+ return status;
+}
+
+zx_status_t PseudoFile::Content::WriteAt(std::vector<uint8_t> data, uint64_t offset,
+ uint64_t* out_actual) {
+ if (offset >= file_->max_file_size_) {
+ *out_actual = 0u;
+ return ZX_OK;
+ }
+
+ size_t actual = std::min(data.size(), file_->max_file_size_ - offset);
+ if (actual == 0) {
+ *out_actual = 0u;
+ return ZX_OK;
+ }
+
+ dirty_ = true;
+ if (actual + offset > buffer_.size()) {
+ SetInputLength(offset + actual);
+ }
+
+ std::copy_n(data.begin(), actual, buffer_.begin() + offset);
+ *out_actual = actual;
+ return ZX_OK;
+}
+
+zx_status_t PseudoFile::Content::Truncate(uint64_t length) {
+ if (length > file_->max_file_size_) {
+ return ZX_ERR_NO_SPACE;
+ }
+
+ dirty_ = true;
+ SetInputLength(length);
+ return ZX_OK;
+}
+
+uint64_t PseudoFile::Content::GetLength() { return buffer_.size(); }
+
+size_t PseudoFile::Content::GetCapacity() { return file_->max_file_size_; }
+
+void PseudoFile::Content::SetInputLength(size_t length) {
+ ZX_ASSERT_MSG(length <= file_->max_file_size_, "Should not happen. Please report a bug.");
+
+ buffer_.resize(length);
+}
+
+zx_status_t PseudoFile::Content::BindInternal(zx::channel request, async_dispatcher_t* dispatcher) {
+ std::unique_ptr<Connection> connection;
+ zx_status_t status = CreateConnection(flags_, &connection);
+ if (status != ZX_OK) {
+ SendOnOpenEventOnError(flags_, std::move(request), status);
+ return status;
+ }
+ status = connection->Bind(std::move(request), dispatcher);
+
+ AddConnection(std::move(connection));
+
+ // only one connection allowed per content
+ ZX_DEBUG_ASSERT(GetConnectionCount() == 1);
+
+ return status;
+}
+
+std::unique_ptr<vfs::internal::Connection> PseudoFile::Content::Close(Connection* connection) {
+ File::Close(connection);
+ return file_->Close(this);
+}
+
+void PseudoFile::Content::Clone(uint32_t flags, uint32_t parent_flags, zx::channel request,
+ async_dispatcher_t* dispatcher) {
+ file_->Clone(flags, parent_flags, std::move(request), dispatcher);
+}
+
+void PseudoFile::Content::SendOnOpenEvent(zx_status_t status) {
+ // not needed as underlying connection should do this
+}
+
+} // namespace vfs
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/remote_dir.cc b/third_party/fuchsia-sdk/pkg/vfs_cpp/remote_dir.cc
new file mode 100644
index 0000000..1edf97b
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/remote_dir.cc
@@ -0,0 +1,43 @@
+// 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.
+
+#include <fuchsia/io/cpp/fidl.h>
+#include <lib/vfs/cpp/remote_dir.h>
+#include <lib/zx/channel.h>
+#include <zircon/assert.h>
+#include <zircon/errors.h>
+
+namespace vfs {
+
+RemoteDir::RemoteDir(zx::channel remote_dir, async_dispatcher_t* dispatcher) {
+ ZX_ASSERT(remote_dir.is_valid());
+ dir_ptr_.Bind(std::move(remote_dir), dispatcher);
+}
+
+RemoteDir::RemoteDir(fidl::InterfaceHandle<fuchsia::io::Directory> dir,
+ async_dispatcher_t* dispatcher) {
+ ZX_ASSERT(dir.is_valid());
+ dir_ptr_.Bind(std::move(dir), dispatcher);
+}
+
+RemoteDir::RemoteDir(fuchsia::io::DirectoryPtr dir_ptr) : dir_ptr_(std::move(dir_ptr)) {
+ ZX_ASSERT(dir_ptr_.is_bound());
+}
+
+RemoteDir::~RemoteDir() = default;
+
+zx_status_t RemoteDir::Connect(uint32_t flags, zx::channel request,
+ async_dispatcher_t* dispatcher) {
+ dir_ptr_->Clone(flags, fidl::InterfaceRequest<fuchsia ::io::Node>(std::move(request)));
+ return ZX_OK;
+}
+
+zx_status_t RemoteDir::Readdir(uint64_t offset, void* data, uint64_t len, uint64_t* out_offset,
+ uint64_t* out_actual) {
+ return ZX_ERR_NOT_SUPPORTED;
+}
+
+NodeKind::Type RemoteDir::GetKind() const { return Directory::GetKind() | NodeKind::kRemote; }
+
+} // namespace vfs
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/service.cc b/third_party/fuchsia-sdk/pkg/vfs_cpp/service.cc
new file mode 100644
index 0000000..b49bce7
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/service.cc
@@ -0,0 +1,51 @@
+// 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.
+
+#include <lib/fdio/vfs.h>
+#include <lib/vfs/cpp/flags.h>
+#include <lib/vfs/cpp/service.h>
+
+namespace vfs {
+
+Service::Service(Connector connector) : connector_(std::move(connector)) {}
+
+Service::~Service() = default;
+
+void Service::Describe(fuchsia::io::NodeInfo* out_info) {
+ out_info->set_service(fuchsia::io::Service());
+}
+
+zx_status_t Service::CreateConnection(uint32_t flags,
+ std::unique_ptr<vfs::internal::Connection>* connection) {
+ return ZX_ERR_NOT_SUPPORTED;
+}
+
+zx_status_t Service::Connect(uint32_t flags, zx::channel request, async_dispatcher_t* dispatcher) {
+ if (Flags::IsNodeReference(flags)) {
+ return Node::Connect(flags, std::move(request), dispatcher);
+ }
+ if (connector_ == nullptr) {
+ SendOnOpenEventOnError(flags, std::move(request), ZX_ERR_NOT_SUPPORTED);
+ return ZX_ERR_NOT_SUPPORTED;
+ }
+ connector_(std::move(request), dispatcher);
+ return ZX_OK;
+}
+
+zx_status_t Service::GetAttr(fuchsia::io::NodeAttributes* out_attributes) const {
+ out_attributes->mode = fuchsia::io::MODE_TYPE_SERVICE | V_IRUSR;
+ out_attributes->id = fuchsia::io::INO_UNKNOWN;
+ out_attributes->content_size = 0;
+ out_attributes->storage_size = 0;
+ out_attributes->link_count = 1;
+ out_attributes->creation_time = 0;
+ out_attributes->modification_time = 0;
+ return ZX_OK;
+}
+
+NodeKind::Type Service::GetKind() const {
+ return NodeKind::kService | NodeKind::kReadable | NodeKind::kWritable;
+}
+
+} // namespace vfs
diff --git a/third_party/fuchsia-sdk/pkg/vfs_cpp/vmo_file.cc b/third_party/fuchsia-sdk/pkg/vfs_cpp/vmo_file.cc
new file mode 100644
index 0000000..b4adf5c
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vfs_cpp/vmo_file.cc
@@ -0,0 +1,110 @@
+// 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.
+
+#include <lib/vfs/cpp/vmo_file.h>
+
+namespace vfs {
+
+VmoFile::VmoFile(zx::unowned_vmo unowned_vmo, size_t offset, size_t length,
+ WriteOption write_option, Sharing vmo_sharing)
+ : offset_(offset), length_(length), write_option_(write_option), vmo_sharing_(vmo_sharing) {
+ unowned_vmo->duplicate(ZX_RIGHT_SAME_RIGHTS, &vmo_);
+}
+
+VmoFile::VmoFile(zx::vmo vmo, size_t offset, size_t length, WriteOption write_option,
+ Sharing vmo_sharing)
+ : offset_(offset),
+ length_(length),
+ write_option_(write_option),
+ vmo_sharing_(vmo_sharing),
+ vmo_(std::move(vmo)) {}
+
+VmoFile::~VmoFile() = default;
+
+void VmoFile::Describe(fuchsia::io::NodeInfo* out_info) {
+ zx::vmo temp_vmo;
+ switch (vmo_sharing_) {
+ case Sharing::NONE:
+ out_info->set_file(fuchsia::io::FileObject());
+ break;
+ case Sharing::DUPLICATE:
+ if (vmo_.duplicate(write_option_ == WriteOption::WRITABLE
+ ? ZX_RIGHTS_BASIC | ZX_RIGHT_READ | ZX_RIGHT_WRITE
+ : ZX_RIGHTS_BASIC | ZX_RIGHT_READ,
+ &temp_vmo) != ZX_OK) {
+ return;
+ }
+ out_info->vmofile() =
+ fuchsia::io::Vmofile{.vmo = std::move(temp_vmo), .offset = offset_, .length = length_};
+ break;
+ case Sharing::CLONE_COW:
+ if (vmo_.create_child(ZX_VMO_CHILD_COPY_ON_WRITE, offset_, length_, &temp_vmo) != ZX_OK) {
+ return;
+ }
+ out_info->vmofile() =
+ fuchsia::io::Vmofile{.vmo = std::move(temp_vmo), .offset = offset_, .length = length_};
+ break;
+ }
+}
+
+zx_status_t VmoFile::ReadAt(uint64_t length, uint64_t offset, std::vector<uint8_t>* out_data) {
+ if (length == 0u || offset >= length_) {
+ return ZX_OK;
+ }
+
+ size_t remaining_length = length_ - offset;
+ if (length > remaining_length) {
+ length = remaining_length;
+ }
+
+ out_data->resize(length);
+ return vmo_.read(out_data->data(), offset_ + offset, length);
+}
+
+zx_status_t VmoFile::WriteAt(std::vector<uint8_t> data, uint64_t offset, uint64_t* out_actual) {
+ size_t length = data.size();
+ if (length == 0u) {
+ *out_actual = 0u;
+ return ZX_OK;
+ }
+ if (offset >= length_) {
+ return ZX_ERR_NO_SPACE;
+ }
+
+ size_t remaining_length = length_ - offset;
+ if (length > remaining_length) {
+ length = remaining_length;
+ }
+ zx_status_t status = vmo_.write(data.data(), offset_ + offset, length);
+ if (status == ZX_OK) {
+ *out_actual = length;
+ }
+ return status;
+}
+
+zx_status_t VmoFile::Truncate(uint64_t length) { return ZX_ERR_NOT_SUPPORTED; }
+
+size_t VmoFile::GetCapacity() { return length_; }
+
+size_t VmoFile::GetLength() { return length_; }
+
+zx_status_t VmoFile::GetAttr(fuchsia::io::NodeAttributes* out_attributes) const {
+ out_attributes->mode =
+ fuchsia::io::MODE_TYPE_FILE | fuchsia::io::OPEN_RIGHT_READABLE |
+ (write_option_ == WriteOption::WRITABLE ? fuchsia::io::OPEN_RIGHT_WRITABLE : 0);
+ out_attributes->id = fuchsia::io::INO_UNKNOWN;
+ out_attributes->content_size = length_;
+ out_attributes->storage_size = length_;
+ out_attributes->link_count = 1;
+ out_attributes->creation_time = 0;
+ out_attributes->modification_time = 0;
+ return ZX_OK;
+}
+
+NodeKind::Type VmoFile::GetKind() const {
+ return File::GetKind() | NodeKind::kVmo | NodeKind::kReadable |
+ (write_option_ == WriteOption::WRITABLE ? NodeKind::kWritable : 0);
+}
+
+} // namespace vfs
diff --git a/third_party/fuchsia-sdk/pkg/vulkan/BUILD.gn b/third_party/fuchsia-sdk/pkg/vulkan/BUILD.gn
new file mode 100644
index 0000000..3506297
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vulkan/BUILD.gn
@@ -0,0 +1,27 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("vulkan") {
+ shared_libs = [ "vulkan" ]
+
+ deps = [
+ "../async-default",
+ "../fdio",
+ ]
+ sources = [
+ ]
+ include_dirs = [ "include" ]
+}
+
+group("all"){
+ deps = [
+ ":vulkan",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/vulkan/meta.json b/third_party/fuchsia-sdk/pkg/vulkan/meta.json
new file mode 100644
index 0000000..715b275
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vulkan/meta.json
@@ -0,0 +1,26 @@
+{
+ "binaries": {
+ "arm64": {
+ "debug": ".build-id/85/7fd35c7c483025.debug",
+ "dist": "arch/arm64/dist/libvulkan.so",
+ "dist_path": "lib/libvulkan.so",
+ "link": "arch/arm64/lib/libvulkan.so"
+ },
+ "x64": {
+ "debug": ".build-id/e5/b5b39218398272.debug",
+ "dist": "arch/x64/dist/libvulkan.so",
+ "dist_path": "lib/libvulkan.so",
+ "link": "arch/x64/lib/libvulkan.so"
+ }
+ },
+ "deps": [
+ "async-default",
+ "fdio"
+ ],
+ "format": "shared",
+ "headers": [],
+ "include_dir": "pkg/vulkan/include",
+ "name": "vulkan",
+ "root": "pkg/vulkan",
+ "type": "cc_prebuilt_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/vulkan_layers/BUILD.gn b/third_party/fuchsia-sdk/pkg/vulkan_layers/BUILD.gn
new file mode 100644
index 0000000..ccf76c9
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vulkan_layers/BUILD.gn
@@ -0,0 +1,213 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+copy("VkLayer_core_validation_config") {
+ sources = [
+ "data/vulkan/explicit_layer.d/VkLayer_core_validation.json",
+ ]
+ outputs = [
+ "${root_gen_dir}/data/vulkan/explicit_layer.d/VkLayer_core_validation.json",
+ ]
+}
+
+copy("VkLayer_core_validation_lib") {
+ sources = [
+ "../../arch/${target_cpu}/dist/VkLayer_core_validation.so",
+ ]
+ outputs = [
+ "${root_out_dir}/lib/{{source_file_part}}",
+ ]
+}
+
+group("VkLayer_core_validation") {
+ data_deps = [
+ ":VkLayer_core_validation_config",
+ ":VkLayer_core_validation_lib",
+ ]
+}
+
+copy("VkLayer_object_lifetimes_config") {
+ sources = [
+ "data/vulkan/explicit_layer.d/VkLayer_object_lifetimes.json",
+ ]
+ outputs = [
+ "${root_gen_dir}/data/vulkan/explicit_layer.d/VkLayer_object_lifetimes.json",
+ ]
+}
+
+copy("VkLayer_object_lifetimes_lib") {
+ sources = [
+ "../../arch/${target_cpu}/dist/VkLayer_object_lifetimes.so",
+ ]
+ outputs = [
+ "${root_out_dir}/lib/{{source_file_part}}",
+ ]
+}
+
+group("VkLayer_object_lifetimes") {
+ data_deps = [
+ ":VkLayer_object_lifetimes_config",
+ ":VkLayer_object_lifetimes_lib",
+ ]
+}
+
+copy("VkLayer_thread_safety_config") {
+ sources = [
+ "data/vulkan/explicit_layer.d/VkLayer_thread_safety.json",
+ ]
+ outputs = [
+ "${root_gen_dir}/data/vulkan/explicit_layer.d/VkLayer_thread_safety.json",
+ ]
+}
+
+copy("VkLayer_thread_safety_lib") {
+ sources = [
+ "../../arch/${target_cpu}/dist/VkLayer_thread_safety.so",
+ ]
+ outputs = [
+ "${root_out_dir}/lib/{{source_file_part}}",
+ ]
+}
+
+group("VkLayer_thread_safety") {
+ data_deps = [
+ ":VkLayer_thread_safety_config",
+ ":VkLayer_thread_safety_lib",
+ ]
+}
+
+copy("VkLayer_stateless_validation_config") {
+ sources = [
+ "data/vulkan/explicit_layer.d/VkLayer_stateless_validation.json",
+ ]
+ outputs = [
+ "${root_gen_dir}/data/vulkan/explicit_layer.d/VkLayer_stateless_validation.json",
+ ]
+}
+
+copy("VkLayer_stateless_validation_lib") {
+ sources = [
+ "../../arch/${target_cpu}/dist/VkLayer_stateless_validation.so",
+ ]
+ outputs = [
+ "${root_out_dir}/lib/{{source_file_part}}",
+ ]
+}
+
+group("VkLayer_stateless_validation") {
+ data_deps = [
+ ":VkLayer_stateless_validation_config",
+ ":VkLayer_stateless_validation_lib",
+ ]
+}
+
+copy("VkLayer_unique_objects_config") {
+ sources = [
+ "data/vulkan/explicit_layer.d/VkLayer_unique_objects.json",
+ ]
+ outputs = [
+ "${root_gen_dir}/data/vulkan/explicit_layer.d/VkLayer_unique_objects.json",
+ ]
+}
+
+copy("VkLayer_unique_objects_lib") {
+ sources = [
+ "../../arch/${target_cpu}/dist/VkLayer_unique_objects.so",
+ ]
+ outputs = [
+ "${root_out_dir}/lib/{{source_file_part}}",
+ ]
+}
+
+group("VkLayer_unique_objects") {
+ data_deps = [
+ ":VkLayer_unique_objects_config",
+ ":VkLayer_unique_objects_lib",
+ ]
+}
+
+copy("VkLayer_khronos_validation_config") {
+ sources = [
+ "data/vulkan/explicit_layer.d/VkLayer_khronos_validation.json",
+ ]
+ outputs = [
+ "${root_gen_dir}/data/vulkan/explicit_layer.d/VkLayer_khronos_validation.json",
+ ]
+}
+
+copy("VkLayer_khronos_validation_lib") {
+ sources = [
+ "../../arch/${target_cpu}/dist/VkLayer_khronos_validation.so",
+ ]
+ outputs = [
+ "${root_out_dir}/lib/{{source_file_part}}",
+ ]
+}
+
+group("VkLayer_khronos_validation") {
+ data_deps = [
+ ":VkLayer_khronos_validation_config",
+ ":VkLayer_khronos_validation_lib",
+ ]
+}
+
+copy("VkLayer_standard_validation_config") {
+ sources = [
+ "data/vulkan/explicit_layer.d/VkLayer_standard_validation.json",
+ ]
+ outputs = [
+ "${root_gen_dir}/data/vulkan/explicit_layer.d/VkLayer_standard_validation.json",
+ ]
+}
+
+
+group("VkLayer_standard_validation") {
+ data_deps = [
+ ":VkLayer_standard_validation_config",
+ ":VkLayer_khronos_validation",
+ ]
+}
+
+copy("VkLayer_image_pipe_swapchain_config") {
+ sources = [
+ "data/vulkan/explicit_layer.d/VkLayer_image_pipe_swapchain.json",
+ ]
+ outputs = [
+ "${root_gen_dir}/data/vulkan/explicit_layer.d/VkLayer_image_pipe_swapchain.json",
+ ]
+}
+
+copy("VkLayer_image_pipe_swapchain_lib") {
+ sources = [
+ "../../arch/${target_cpu}/dist/VkLayer_image_pipe_swapchain.so",
+ ]
+ outputs = [
+ "${root_out_dir}/lib/{{source_file_part}}",
+ ]
+}
+
+group("VkLayer_image_pipe_swapchain") {
+ data_deps = [
+ ":VkLayer_image_pipe_swapchain_config",
+ ":VkLayer_image_pipe_swapchain_lib",
+ "../trace-engine",
+ ]
+}
+
+group("all"){
+ data_deps = [
+ ":VkLayer_core_validation",
+ ":VkLayer_object_lifetimes",
+ ":VkLayer_thread_safety",
+ ":VkLayer_stateless_validation",
+ ":VkLayer_unique_objects",
+ ":VkLayer_khronos_validation",
+ ":VkLayer_standard_validation",
+ ":VkLayer_image_pipe_swapchain",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_core_validation.json b/third_party/fuchsia-sdk/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_core_validation.json
new file mode 100644
index 0000000..639a5de
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_core_validation.json
@@ -0,0 +1,38 @@
+{
+ "file_format_version" : "1.1.0",
+ "layer" : {
+ "name": "VK_LAYER_LUNARG_core_validation",
+ "type": "GLOBAL",
+ "library_path": "VkLayer_core_validation.so",
+ "api_version": "1.1.121",
+ "implementation_version": "1",
+ "description": "LunarG Validation Layer",
+ "instance_extensions": [
+ {
+ "name": "VK_EXT_debug_report",
+ "spec_version": "6"
+ }
+ ],
+ "device_extensions": [
+ {
+ "name": "VK_EXT_debug_marker",
+ "spec_version": "4",
+ "entrypoints": ["vkDebugMarkerSetObjectTagEXT",
+ "vkDebugMarkerSetObjectNameEXT",
+ "vkCmdDebugMarkerBeginEXT",
+ "vkCmdDebugMarkerEndEXT",
+ "vkCmdDebugMarkerInsertEXT"
+ ]
+ },
+ {
+ "name": "VK_EXT_validation_cache",
+ "spec_version": "1",
+ "entrypoints": ["vkCreateValidationCacheEXT",
+ "vkDestroyValidationCacheEXT",
+ "vkGetValidationCacheDataEXT",
+ "vkMergeValidationCachesEXT"
+ ]
+ }
+ ]
+ }
+}
diff --git a/third_party/fuchsia-sdk/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_image_pipe_swapchain.json b/third_party/fuchsia-sdk/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_image_pipe_swapchain.json
new file mode 100644
index 0000000..83cf385
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_image_pipe_swapchain.json
@@ -0,0 +1,21 @@
+{
+ "file_format_version" : "1.0.0",
+ "layer" : {
+ "name": "VK_LAYER_FUCHSIA_imagepipe_swapchain",
+ "type": "GLOBAL",
+ "library_path": "VkLayer_image_pipe_swapchain.so",
+ "api_version": "1.0.38",
+ "implementation_version": "2",
+ "description": "Image Pipe Swapchain",
+ "disable_environment": {
+ "DISABLE_IMAGEPIPE_SWAPCHAIN_LAYER": "1"
+ },
+ "instance_extensions": [
+ { "name": "VK_KHR_surface", "spec_version": "25" },
+ { "name": "VK_FUCHSIA_imagepipe_surface", "spec_version": "1" }
+ ],
+ "device_extensions": [
+ { "name": "VK_KHR_swapchain", "spec_version": "68" }
+ ]
+ }
+}
diff --git a/third_party/fuchsia-sdk/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_khronos_validation.json b/third_party/fuchsia-sdk/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_khronos_validation.json
new file mode 100644
index 0000000..dc1a8ae
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_khronos_validation.json
@@ -0,0 +1,46 @@
+{
+ "file_format_version" : "1.1.0",
+ "layer" : {
+ "name": "VK_LAYER_KHRONOS_validation",
+ "type": "GLOBAL",
+ "library_path": "VkLayer_khronos_validation.so",
+ "api_version": "1.1.121",
+ "implementation_version": "1",
+ "description": "LunarG Validation Layer",
+ "instance_extensions": [
+ {
+ "name": "VK_EXT_debug_report",
+ "spec_version": "9"
+ },
+ {
+ "name": "VK_EXT_debug_utils",
+ "spec_version": "1"
+ },
+ {
+ "name": "VK_EXT_validation_features",
+ "spec_version": "2"
+ }
+ ],
+ "device_extensions": [
+ {
+ "name": "VK_EXT_debug_marker",
+ "spec_version": "4",
+ "entrypoints": ["vkDebugMarkerSetObjectTagEXT",
+ "vkDebugMarkerSetObjectNameEXT",
+ "vkCmdDebugMarkerBeginEXT",
+ "vkCmdDebugMarkerEndEXT",
+ "vkCmdDebugMarkerInsertEXT"
+ ]
+ },
+ {
+ "name": "VK_EXT_validation_cache",
+ "spec_version": "1",
+ "entrypoints": ["vkCreateValidationCacheEXT",
+ "vkDestroyValidationCacheEXT",
+ "vkGetValidationCacheDataEXT",
+ "vkMergeValidationCachesEXT"
+ ]
+ }
+ ]
+ }
+}
diff --git a/third_party/fuchsia-sdk/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_object_lifetimes.json b/third_party/fuchsia-sdk/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_object_lifetimes.json
new file mode 100644
index 0000000..330ce93
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_object_lifetimes.json
@@ -0,0 +1,29 @@
+{
+ "file_format_version" : "1.1.0",
+ "layer" : {
+ "name": "VK_LAYER_LUNARG_object_tracker",
+ "type": "GLOBAL",
+ "library_path": "VkLayer_object_lifetimes.so",
+ "api_version": "1.1.121",
+ "implementation_version": "1",
+ "description": "LunarG Validation Layer",
+ "instance_extensions": [
+ {
+ "name": "VK_EXT_debug_report",
+ "spec_version": "6"
+ }
+ ],
+ "device_extensions": [
+ {
+ "name": "VK_EXT_debug_marker",
+ "spec_version": "4",
+ "entrypoints": ["vkDebugMarkerSetObjectTagEXT",
+ "vkDebugMarkerSetObjectNameEXT",
+ "vkCmdDebugMarkerBeginEXT",
+ "vkCmdDebugMarkerEndEXT",
+ "vkCmdDebugMarkerInsertEXT"
+ ]
+ }
+ ]
+ }
+}
diff --git a/third_party/fuchsia-sdk/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_standard_validation.json b/third_party/fuchsia-sdk/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_standard_validation.json
new file mode 100644
index 0000000..d95b6a6
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_standard_validation.json
@@ -0,0 +1,13 @@
+{
+ "file_format_version": "1.1.1",
+ "layer": {
+ "name": "VK_LAYER_LUNARG_standard_validation",
+ "type": "GLOBAL",
+ "api_version": "1.1.121",
+ "implementation_version": "1",
+ "description": "LunarG Standard Validation",
+ "component_layers": [
+ "VK_LAYER_KHRONOS_validation"
+ ]
+ }
+}
diff --git a/third_party/fuchsia-sdk/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_stateless_validation.json b/third_party/fuchsia-sdk/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_stateless_validation.json
new file mode 100644
index 0000000..73aab94
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_stateless_validation.json
@@ -0,0 +1,29 @@
+{
+ "file_format_version" : "1.1.0",
+ "layer" : {
+ "name": "VK_LAYER_LUNARG_parameter_validation",
+ "type": "GLOBAL",
+ "library_path": "VkLayer_stateless_validation.so",
+ "api_version": "1.1.121",
+ "implementation_version": "1",
+ "description": "LunarG Validation Layer",
+ "instance_extensions": [
+ {
+ "name": "VK_EXT_debug_report",
+ "spec_version": "6"
+ }
+ ],
+ "device_extensions": [
+ {
+ "name": "VK_EXT_debug_marker",
+ "spec_version": "4",
+ "entrypoints": ["vkDebugMarkerSetObjectTagEXT",
+ "vkDebugMarkerSetObjectNameEXT",
+ "vkCmdDebugMarkerBeginEXT",
+ "vkCmdDebugMarkerEndEXT",
+ "vkCmdDebugMarkerInsertEXT"
+ ]
+ }
+ ]
+ }
+}
diff --git a/third_party/fuchsia-sdk/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_thread_safety.json b/third_party/fuchsia-sdk/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_thread_safety.json
new file mode 100644
index 0000000..732e960
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_thread_safety.json
@@ -0,0 +1,17 @@
+{
+ "file_format_version" : "1.1.0",
+ "layer" : {
+ "name": "VK_LAYER_GOOGLE_threading",
+ "type": "GLOBAL",
+ "library_path": "VkLayer_thread_safety.so",
+ "api_version": "1.1.121",
+ "implementation_version": "1",
+ "description": "Google Validation Layer",
+ "instance_extensions": [
+ {
+ "name": "VK_EXT_debug_report",
+ "spec_version": "6"
+ }
+ ]
+ }
+}
diff --git a/third_party/fuchsia-sdk/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_unique_objects.json b/third_party/fuchsia-sdk/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_unique_objects.json
new file mode 100644
index 0000000..2828858
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_unique_objects.json
@@ -0,0 +1,11 @@
+{
+ "file_format_version" : "1.1.0",
+ "layer" : {
+ "name": "VK_LAYER_GOOGLE_unique_objects",
+ "type": "GLOBAL",
+ "library_path": "VkLayer_unique_objects.so",
+ "api_version": "1.1.121",
+ "implementation_version": "1",
+ "description": "Google Validation Layer"
+ }
+}
diff --git a/third_party/fuchsia-sdk/pkg/vulkan_layers/meta.json b/third_party/fuchsia-sdk/pkg/vulkan_layers/meta.json
new file mode 100644
index 0000000..6f7d8a7
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/vulkan_layers/meta.json
@@ -0,0 +1,35 @@
+{
+ "binaries": {
+ "arm64": [
+ "arch/arm64/dist/VkLayer_core_validation.so",
+ "arch/arm64/dist/VkLayer_object_lifetimes.so",
+ "arch/arm64/dist/VkLayer_thread_safety.so",
+ "arch/arm64/dist/VkLayer_stateless_validation.so",
+ "arch/arm64/dist/VkLayer_unique_objects.so",
+ "arch/arm64/dist/VkLayer_khronos_validation.so",
+ "arch/arm64/dist/VkLayer_image_pipe_swapchain.so"
+ ],
+ "x64": [
+ "arch/x64/dist/VkLayer_core_validation.so",
+ "arch/x64/dist/VkLayer_object_lifetimes.so",
+ "arch/x64/dist/VkLayer_thread_safety.so",
+ "arch/x64/dist/VkLayer_stateless_validation.so",
+ "arch/x64/dist/VkLayer_unique_objects.so",
+ "arch/x64/dist/VkLayer_khronos_validation.so",
+ "arch/x64/dist/VkLayer_image_pipe_swapchain.so"
+ ]
+ },
+ "name": "vulkan_layers",
+ "resources": [
+ "pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_core_validation.json",
+ "pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_object_lifetimes.json",
+ "pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_thread_safety.json",
+ "pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_stateless_validation.json",
+ "pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_unique_objects.json",
+ "pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_khronos_validation.json",
+ "pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_standard_validation.json",
+ "pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_image_pipe_swapchain.json"
+ ],
+ "root": "pkg/vulkan_layers",
+ "type": "loadable_module"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/zx/BUILD.gn b/third_party/fuchsia-sdk/pkg/zx/BUILD.gn
new file mode 100644
index 0000000..baf244a
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/BUILD.gn
@@ -0,0 +1,76 @@
+# Copyright 2020 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.
+
+# DO NOT MANUALLY EDIT!
+# Generated by //scripts/sdk/gn/generate.py.
+
+
+import("../../build/fuchsia_sdk_pkg.gni")
+
+fuchsia_sdk_pkg("zx") {
+ sources = [
+ "bti.cc",
+ "channel.cc",
+ "debuglog.cc",
+ "event.cc",
+ "eventpair.cc",
+ "fifo.cc",
+ "guest.cc",
+ "interrupt.cc",
+ "iommu.cc",
+ "job.cc",
+ "pager.cc",
+ "port.cc",
+ "process.cc",
+ "profile.cc",
+ "resource.cc",
+ "socket.cc",
+ "stream.cc",
+ "thread.cc",
+ "timer.cc",
+ "vcpu.cc",
+ "vmar.cc",
+ "vmo.cc",
+ "include/lib/zx/bti.h",
+ "include/lib/zx/channel.h",
+ "include/lib/zx/clock.h",
+ "include/lib/zx/debuglog.h",
+ "include/lib/zx/event.h",
+ "include/lib/zx/eventpair.h",
+ "include/lib/zx/exception.h",
+ "include/lib/zx/fifo.h",
+ "include/lib/zx/guest.h",
+ "include/lib/zx/handle.h",
+ "include/lib/zx/interrupt.h",
+ "include/lib/zx/iommu.h",
+ "include/lib/zx/job.h",
+ "include/lib/zx/object.h",
+ "include/lib/zx/object_traits.h",
+ "include/lib/zx/pager.h",
+ "include/lib/zx/pmt.h",
+ "include/lib/zx/port.h",
+ "include/lib/zx/process.h",
+ "include/lib/zx/profile.h",
+ "include/lib/zx/resource.h",
+ "include/lib/zx/socket.h",
+ "include/lib/zx/stream.h",
+ "include/lib/zx/suspend_token.h",
+ "include/lib/zx/task.h",
+ "include/lib/zx/thread.h",
+ "include/lib/zx/time.h",
+ "include/lib/zx/timer.h",
+ "include/lib/zx/vcpu.h",
+ "include/lib/zx/vmar.h",
+ "include/lib/zx/vmo.h",
+ ]
+ include_dirs = [ "include" ]
+ public_deps = [
+ ]
+}
+
+group("all"){
+ deps = [
+ ":zx",
+ ]
+}
diff --git a/third_party/fuchsia-sdk/pkg/zx/bti.cc b/third_party/fuchsia-sdk/pkg/zx/bti.cc
new file mode 100644
index 0000000..bd53051
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/bti.cc
@@ -0,0 +1,15 @@
+// Copyright 2018 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.
+
+#include <lib/zx/bti.h>
+
+#include <zircon/syscalls.h>
+
+namespace zx {
+
+zx_status_t bti::create(const iommu& iommu, uint32_t options, uint64_t bti_id, bti* result) {
+ return zx_bti_create(iommu.get(), options, bti_id, result->reset_and_get_address());
+}
+
+} // namespace zx
diff --git a/third_party/fuchsia-sdk/pkg/zx/channel.cc b/third_party/fuchsia-sdk/pkg/zx/channel.cc
new file mode 100644
index 0000000..39b4da6
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/channel.cc
@@ -0,0 +1,23 @@
+// Copyright 2016 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.
+
+#include <lib/zx/channel.h>
+
+#include <zircon/syscalls.h>
+
+namespace zx {
+
+zx_status_t channel::create(uint32_t flags, channel* endpoint0, channel* endpoint1) {
+ // Ensure aliasing of both out parameters to the same container
+ // has a well-defined result, and does not leak.
+ channel h0;
+ channel h1;
+ zx_status_t status =
+ zx_channel_create(flags, h0.reset_and_get_address(), h1.reset_and_get_address());
+ endpoint0->reset(h0.release());
+ endpoint1->reset(h1.release());
+ return status;
+}
+
+} // namespace zx
diff --git a/third_party/fuchsia-sdk/pkg/zx/debuglog.cc b/third_party/fuchsia-sdk/pkg/zx/debuglog.cc
new file mode 100644
index 0000000..030c012
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/debuglog.cc
@@ -0,0 +1,15 @@
+// Copyright 2018 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.
+
+#include <lib/zx/debuglog.h>
+
+#include <zircon/syscalls.h>
+
+namespace zx {
+
+zx_status_t debuglog::create(const resource& resource, uint32_t options, debuglog* result) {
+ return zx_debuglog_create(resource.get(), options, result->reset_and_get_address());
+}
+
+} // namespace zx
diff --git a/third_party/fuchsia-sdk/pkg/zx/event.cc b/third_party/fuchsia-sdk/pkg/zx/event.cc
new file mode 100644
index 0000000..538aa99
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/event.cc
@@ -0,0 +1,15 @@
+// Copyright 2016 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.
+
+#include <lib/zx/event.h>
+
+#include <zircon/syscalls.h>
+
+namespace zx {
+
+zx_status_t event::create(uint32_t options, event* result) {
+ return zx_event_create(options, result->reset_and_get_address());
+}
+
+} // namespace zx
diff --git a/third_party/fuchsia-sdk/pkg/zx/eventpair.cc b/third_party/fuchsia-sdk/pkg/zx/eventpair.cc
new file mode 100644
index 0000000..480ea07
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/eventpair.cc
@@ -0,0 +1,23 @@
+// Copyright 2016 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.
+
+#include <lib/zx/eventpair.h>
+
+#include <zircon/syscalls.h>
+
+namespace zx {
+
+zx_status_t eventpair::create(uint32_t flags, eventpair* endpoint0, eventpair* endpoint1) {
+ // Ensure aliasing of both out parameters to the same container
+ // has a well-defined result, and does not leak.
+ eventpair h0;
+ eventpair h1;
+ zx_status_t status =
+ zx_eventpair_create(flags, h0.reset_and_get_address(), h1.reset_and_get_address());
+ endpoint0->reset(h0.release());
+ endpoint1->reset(h1.release());
+ return status;
+}
+
+} // namespace zx
diff --git a/third_party/fuchsia-sdk/pkg/zx/fifo.cc b/third_party/fuchsia-sdk/pkg/zx/fifo.cc
new file mode 100644
index 0000000..ea0e7d1
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/fifo.cc
@@ -0,0 +1,24 @@
+// Copyright 2017 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.
+
+#include <lib/zx/fifo.h>
+
+#include <zircon/syscalls.h>
+
+namespace zx {
+
+zx_status_t fifo::create(uint32_t elem_count, uint32_t elem_size, uint32_t options, fifo* out0,
+ fifo* out1) {
+ // Ensure aliasing of both out parameters to the same container
+ // has a well-defined result, and does not leak.
+ fifo h0;
+ fifo h1;
+ zx_status_t status = zx_fifo_create(elem_count, elem_size, options, h0.reset_and_get_address(),
+ h1.reset_and_get_address());
+ out0->reset(h0.release());
+ out1->reset(h1.release());
+ return status;
+}
+
+} // namespace zx
diff --git a/third_party/fuchsia-sdk/pkg/zx/guest.cc b/third_party/fuchsia-sdk/pkg/zx/guest.cc
new file mode 100644
index 0000000..b78effe
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/guest.cc
@@ -0,0 +1,20 @@
+// Copyright 2018 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.
+
+#include <lib/zx/guest.h>
+
+#include <zircon/syscalls.h>
+
+#include <lib/zx/vmar.h>
+
+namespace zx {
+
+zx_status_t guest::create(const resource& resource, uint32_t options, guest* guest, vmar* vmar) {
+ // Assume |resource|, |guest| and |vmar| must refer to different containers,
+ // due to strict aliasing.
+ return zx_guest_create(resource.get(), options, guest->reset_and_get_address(),
+ vmar->reset_and_get_address());
+}
+
+} // namespace zx
diff --git a/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/bti.h b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/bti.h
new file mode 100644
index 0000000..4ce438b
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/bti.h
@@ -0,0 +1,48 @@
+// Copyright 2018 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.
+
+#ifndef LIB_ZX_BTI_H_
+#define LIB_ZX_BTI_H_
+
+#include <lib/zx/handle.h>
+#include <lib/zx/iommu.h>
+#include <lib/zx/object.h>
+#include <lib/zx/pmt.h>
+#include <lib/zx/vmo.h>
+
+namespace zx {
+
+class bti final : public object<bti> {
+ public:
+ static constexpr zx_obj_type_t TYPE = ZX_OBJ_TYPE_BTI;
+
+ constexpr bti() = default;
+
+ explicit bti(zx_handle_t value) : object(value) {}
+
+ explicit bti(handle&& h) : object(h.release()) {}
+
+ bti(bti&& other) : object(other.release()) {}
+
+ bti& operator=(bti&& other) {
+ reset(other.release());
+ return *this;
+ }
+
+ static zx_status_t create(const iommu& iommu, uint32_t options, uint64_t bti_id, bti* result);
+
+ zx_status_t pin(uint32_t options, const vmo& vmo, uint64_t offset, uint64_t size,
+ zx_paddr_t* addrs, size_t addrs_count, pmt* pmt) const {
+ return zx_bti_pin(get(), options, vmo.get(), offset, size, addrs, addrs_count,
+ pmt->reset_and_get_address());
+ }
+
+ zx_status_t release_quarantine() const { return zx_bti_release_quarantine(get()); }
+};
+
+using unowned_bti = unowned<bti>;
+
+} // namespace zx
+
+#endif // LIB_ZX_BTI_H_
diff --git a/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/channel.h b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/channel.h
new file mode 100644
index 0000000..63b7c0a
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/channel.h
@@ -0,0 +1,66 @@
+// Copyright 2016 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.
+
+#ifndef LIB_ZX_CHANNEL_H_
+#define LIB_ZX_CHANNEL_H_
+
+#include <lib/zx/handle.h>
+#include <lib/zx/object.h>
+#include <lib/zx/time.h>
+
+namespace zx {
+
+class channel final : public object<channel> {
+ public:
+ static constexpr zx_obj_type_t TYPE = ZX_OBJ_TYPE_CHANNEL;
+
+ constexpr channel() = default;
+
+ explicit channel(zx_handle_t value) : object(value) {}
+
+ explicit channel(handle&& h) : object(h.release()) {}
+
+ channel(channel&& other) : object(other.release()) {}
+
+ channel& operator=(channel&& other) {
+ reset(other.release());
+ return *this;
+ }
+
+ static zx_status_t create(uint32_t flags, channel* endpoint0, channel* endpoint1);
+
+ zx_status_t read(uint32_t flags, void* bytes, zx_handle_t* handles, uint32_t num_bytes,
+ uint32_t num_handles, uint32_t* actual_bytes, uint32_t* actual_handles) const {
+ return zx_channel_read(get(), flags, bytes, handles, num_bytes, num_handles, actual_bytes,
+ actual_handles);
+ }
+
+ zx_status_t read_etc(uint32_t flags, void* bytes, zx_handle_info_t* handles, uint32_t num_bytes,
+ uint32_t num_handles, uint32_t* actual_bytes,
+ uint32_t* actual_handles) const {
+ return zx_channel_read_etc(get(), flags, bytes, handles, num_bytes, num_handles, actual_bytes,
+ actual_handles);
+ }
+
+ zx_status_t write(uint32_t flags, const void* bytes, uint32_t num_bytes,
+ const zx_handle_t* handles, uint32_t num_handles) const {
+ return zx_channel_write(get(), flags, bytes, num_bytes, handles, num_handles);
+ }
+
+ zx_status_t write_etc(uint32_t flags, const void* bytes, uint32_t num_bytes,
+ zx_handle_disposition_t* handles, uint32_t num_handles) {
+ return zx_channel_write_etc(get(), flags, bytes, num_bytes, handles, num_handles);
+ }
+
+ zx_status_t call(uint32_t flags, zx::time deadline, const zx_channel_call_args_t* args,
+ uint32_t* actual_bytes, uint32_t* actual_handles) const {
+ return zx_channel_call(get(), flags, deadline.get(), args, actual_bytes, actual_handles);
+ }
+};
+
+using unowned_channel = unowned<channel>;
+
+} // namespace zx
+
+#endif // LIB_ZX_CHANNEL_H_
diff --git a/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/clock.h b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/clock.h
new file mode 100644
index 0000000..39d1b80
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/clock.h
@@ -0,0 +1,102 @@
+// 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.
+
+#ifndef LIB_ZX_CLOCK_H_
+#define LIB_ZX_CLOCK_H_
+
+#include <lib/zx/handle.h>
+#include <lib/zx/object.h>
+#include <lib/zx/time.h>
+#include <zircon/syscalls/clock.h>
+
+namespace zx {
+
+class clock final : public object<clock> {
+ public:
+ class update_args {
+ public:
+ constexpr update_args() = default;
+
+ update_args& reset() {
+ options_ = 0;
+ return *this;
+ }
+
+ update_args& set_value(zx::time value) {
+ args_.value = value.get();
+ options_ |= ZX_CLOCK_UPDATE_OPTION_VALUE_VALID;
+ return *this;
+ }
+
+ update_args& set_rate_adjust(int32_t rate) {
+ args_.rate_adjust = rate;
+ options_ |= ZX_CLOCK_UPDATE_OPTION_RATE_ADJUST_VALID;
+ return *this;
+ }
+
+ update_args& set_error_bound(uint64_t error_bound) {
+ args_.error_bound = error_bound;
+ options_ |= ZX_CLOCK_UPDATE_OPTION_ERROR_BOUND_VALID;
+ return *this;
+ }
+
+ private:
+ friend class ::zx::clock;
+ zx_clock_update_args_v1_t args_{};
+ uint64_t options_ = 0;
+ };
+
+ static constexpr zx_obj_type_t TYPE = ZX_OBJ_TYPE_CLOCK;
+
+ // TODO(johngro) : remove this alias once we remove the static get method from
+ // this class. This static get method will no longer be needed once UTC
+ // leaves the kernel, and "thread" time becomes fetch-able only from a
+ // get_info request. At that point in time, zx_clock_get will disappear and
+ // the only kernel provided sources of time will be get_monotonic and ticks.
+ zx_handle_t get_handle() const { return object_base::get(); }
+
+ constexpr clock() = default;
+
+ explicit clock(zx_handle_t value) : object(value) {}
+
+ explicit clock(handle&& h) : object(h.release()) {}
+
+ clock(clock&& other) : object(other.release()) {}
+
+ clock& operator=(clock&& other) {
+ reset(other.release());
+ return *this;
+ }
+
+ static zx_status_t create(uint64_t options, const zx_clock_create_args_v1* args, clock* result) {
+ options = (options & ~ZX_CLOCK_ARGS_VERSION_MASK) |
+ ((args != nullptr) ? ZX_CLOCK_ARGS_VERSION(1) : 0);
+
+ return zx_clock_create(options, args, result->reset_and_get_address());
+ }
+
+ zx_status_t read(zx_time_t* now_out) const { return zx_clock_read(value_, now_out); }
+
+ zx_status_t get_details(zx_clock_details_v1_t* details_out) const {
+ return zx_clock_get_details(value_, ZX_CLOCK_ARGS_VERSION(1), details_out);
+ }
+
+ zx_status_t update(const update_args& args) const {
+ uint64_t options = args.options_ | ZX_CLOCK_ARGS_VERSION(1);
+ return zx_clock_update(value_, options, &args.args_);
+ }
+
+ template <zx_clock_t kClockId>
+ static zx_status_t get(basic_time<kClockId>* result) {
+ return zx_clock_get(kClockId, result->get_address());
+ }
+
+ static time get_monotonic() { return time(zx_clock_get_monotonic()); }
+};
+
+using unowned_clock = unowned<clock>;
+
+} // namespace zx
+
+#endif // LIB_ZX_CLOCK_H_
diff --git a/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/debuglog.h b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/debuglog.h
new file mode 100644
index 0000000..2e7cf41
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/debuglog.h
@@ -0,0 +1,46 @@
+// Copyright 2018 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.
+
+#ifndef LIB_ZX_DEBUGLOG_H_
+#define LIB_ZX_DEBUGLOG_H_
+
+#include <lib/zx/handle.h>
+#include <lib/zx/object.h>
+#include <lib/zx/resource.h>
+
+namespace zx {
+
+class debuglog final : public object<debuglog> {
+ public:
+ static constexpr zx_obj_type_t TYPE = ZX_OBJ_TYPE_LOG;
+
+ constexpr debuglog() = default;
+
+ explicit debuglog(zx_handle_t value) : object(value) {}
+
+ explicit debuglog(handle&& h) : object(h.release()) {}
+
+ debuglog(debuglog&& other) : object(other.release()) {}
+
+ debuglog& operator=(debuglog&& other) {
+ reset(other.release());
+ return *this;
+ }
+
+ static zx_status_t create(const resource& resource, uint32_t options, debuglog* result);
+
+ zx_status_t write(uint32_t options, const void* buffer, size_t buffer_size) const {
+ return zx_debuglog_write(get(), options, buffer, buffer_size);
+ }
+
+ zx_status_t read(uint32_t options, void* buffer, size_t buffer_size) const {
+ return zx_debuglog_read(get(), options, buffer, buffer_size);
+ }
+};
+
+using unowned_debuglog = unowned<debuglog>;
+
+} // namespace zx
+
+#endif // LIB_ZX_DEBUGLOG_H_
diff --git a/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/event.h b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/event.h
new file mode 100644
index 0000000..a9d62af
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/event.h
@@ -0,0 +1,37 @@
+// Copyright 2016 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.
+
+#ifndef LIB_ZX_EVENT_H_
+#define LIB_ZX_EVENT_H_
+
+#include <lib/zx/handle.h>
+#include <lib/zx/object.h>
+
+namespace zx {
+
+class event final : public object<event> {
+ public:
+ static constexpr zx_obj_type_t TYPE = ZX_OBJ_TYPE_EVENT;
+
+ constexpr event() = default;
+
+ explicit event(zx_handle_t value) : object(value) {}
+
+ explicit event(handle&& h) : object(h.release()) {}
+
+ event(event&& other) : object(other.release()) {}
+
+ event& operator=(event&& other) {
+ reset(other.release());
+ return *this;
+ }
+
+ static zx_status_t create(uint32_t options, event* result);
+};
+
+using unowned_event = unowned<event>;
+
+} // namespace zx
+
+#endif // LIB_ZX_EVENT_H_
diff --git a/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/eventpair.h b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/eventpair.h
new file mode 100644
index 0000000..a46a6b0
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/eventpair.h
@@ -0,0 +1,37 @@
+// Copyright 2016 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.
+
+#ifndef LIB_ZX_EVENTPAIR_H_
+#define LIB_ZX_EVENTPAIR_H_
+
+#include <lib/zx/handle.h>
+#include <lib/zx/object.h>
+
+namespace zx {
+
+class eventpair final : public object<eventpair> {
+ public:
+ static constexpr zx_obj_type_t TYPE = ZX_OBJ_TYPE_EVENTPAIR;
+
+ constexpr eventpair() = default;
+
+ explicit eventpair(zx_handle_t value) : object(value) {}
+
+ explicit eventpair(handle&& h) : object(h.release()) {}
+
+ eventpair(eventpair&& other) : object(other.release()) {}
+
+ eventpair& operator=(eventpair&& other) {
+ reset(other.release());
+ return *this;
+ }
+
+ static zx_status_t create(uint32_t options, eventpair* endpoint0, eventpair* endpoint1);
+};
+
+using unowned_eventpair = unowned<eventpair>;
+
+} // namespace zx
+
+#endif // LIB_ZX_EVENTPAIR_H_
diff --git a/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/exception.h b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/exception.h
new file mode 100644
index 0000000..d5cc756
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/exception.h
@@ -0,0 +1,43 @@
+// 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.
+
+#ifndef LIB_ZX_EXCEPTION_H_
+#define LIB_ZX_EXCEPTION_H_
+
+#include <lib/zx/handle.h>
+#include <lib/zx/object.h>
+#include <lib/zx/process.h>
+#include <lib/zx/thread.h>
+
+namespace zx {
+
+class exception final : public object<exception> {
+ public:
+ static constexpr zx_obj_type_t TYPE = ZX_OBJ_TYPE_EXCEPTION;
+
+ constexpr exception() = default;
+
+ explicit exception(zx_handle_t value) : object(value) {}
+
+ explicit exception(handle&& h) : object(h.release()) {}
+
+ exception(exception&& other) : object(other.release()) {}
+
+ exception& operator=(exception&& other) {
+ reset(other.release());
+ return *this;
+ }
+
+ zx_status_t get_thread(thread* thread) const {
+ return zx_exception_get_thread(get(), thread->reset_and_get_address());
+ }
+
+ zx_status_t get_process(process* process) const {
+ return zx_exception_get_process(get(), process->reset_and_get_address());
+ }
+};
+
+} // namespace zx
+
+#endif // LIB_ZX_EXCEPTION_H_
diff --git a/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/fifo.h b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/fifo.h
new file mode 100644
index 0000000..c95648b
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/fifo.h
@@ -0,0 +1,47 @@
+// Copyright 2017 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.
+
+#ifndef LIB_ZX_FIFO_H_
+#define LIB_ZX_FIFO_H_
+
+#include <lib/zx/handle.h>
+#include <lib/zx/object.h>
+
+namespace zx {
+
+class fifo final : public object<fifo> {
+ public:
+ static constexpr zx_obj_type_t TYPE = ZX_OBJ_TYPE_FIFO;
+
+ constexpr fifo() = default;
+
+ explicit fifo(zx_handle_t value) : object(value) {}
+
+ explicit fifo(handle&& h) : object(h.release()) {}
+
+ fifo(fifo&& other) : object(other.release()) {}
+
+ fifo& operator=(fifo&& other) {
+ reset(other.release());
+ return *this;
+ }
+
+ static zx_status_t create(uint32_t elem_count, uint32_t elem_size, uint32_t options, fifo* out0,
+ fifo* out1);
+
+ zx_status_t write(size_t elem_size, const void* buffer, size_t count,
+ size_t* actual_count) const {
+ return zx_fifo_write(get(), elem_size, buffer, count, actual_count);
+ }
+
+ zx_status_t read(size_t elem_size, void* buffer, size_t count, size_t* actual_count) const {
+ return zx_fifo_read(get(), elem_size, buffer, count, actual_count);
+ }
+};
+
+using unowned_fifo = unowned<fifo>;
+
+} // namespace zx
+
+#endif // LIB_ZX_FIFO_H_
diff --git a/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/guest.h b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/guest.h
new file mode 100644
index 0000000..2c4c7ef
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/guest.h
@@ -0,0 +1,45 @@
+// Copyright 2018 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.
+
+#ifndef LIB_ZX_GUEST_H_
+#define LIB_ZX_GUEST_H_
+
+#include <lib/zx/handle.h>
+#include <lib/zx/object.h>
+#include <lib/zx/port.h>
+#include <lib/zx/resource.h>
+#include <lib/zx/vmo.h>
+
+namespace zx {
+
+class guest final : public object<guest> {
+ public:
+ static constexpr zx_obj_type_t TYPE = ZX_OBJ_TYPE_GUEST;
+
+ constexpr guest() = default;
+
+ explicit guest(zx_handle_t value) : object(value) {}
+
+ explicit guest(handle&& h) : object(h.release()) {}
+
+ guest(guest&& other) : object(other.release()) {}
+
+ guest& operator=(guest&& other) {
+ reset(other.release());
+ return *this;
+ }
+
+ static zx_status_t create(const resource& resource, uint32_t options, guest* guest, vmar* vmar);
+
+ zx_status_t set_trap(uint32_t kind, zx_gpaddr_t addr, size_t len, const port& port,
+ uint64_t key) const {
+ return zx_guest_set_trap(get(), kind, addr, len, port.get(), key);
+ }
+};
+
+using unowned_guest = unowned<guest>;
+
+} // namespace zx
+
+#endif // LIB_ZX_GUEST_H_
diff --git a/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/handle.h b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/handle.h
new file mode 100644
index 0000000..930161d
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/handle.h
@@ -0,0 +1,17 @@
+// Copyright 2017 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.
+
+#ifndef LIB_ZX_HANDLE_H_
+#define LIB_ZX_HANDLE_H_
+
+#include <lib/zx/object.h>
+
+namespace zx {
+
+using handle = object<void>;
+using unowned_handle = unowned<handle>;
+
+} // namespace zx
+
+#endif // LIB_ZX_HANDLE_H_
diff --git a/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/interrupt.h b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/interrupt.h
new file mode 100644
index 0000000..bb55a08
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/interrupt.h
@@ -0,0 +1,62 @@
+// Copyright 2018 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.
+
+#ifndef LIB_ZX_INTERRUPT_H_
+#define LIB_ZX_INTERRUPT_H_
+
+#include <lib/zx/handle.h>
+#include <lib/zx/object.h>
+#include <lib/zx/port.h>
+#include <lib/zx/resource.h>
+#include <lib/zx/time.h>
+#include <lib/zx/vcpu.h>
+
+namespace zx {
+
+class interrupt final : public object<interrupt> {
+ public:
+ static constexpr zx_obj_type_t TYPE = ZX_OBJ_TYPE_INTERRUPT;
+
+ constexpr interrupt() = default;
+
+ explicit interrupt(zx_handle_t value) : object(value) {}
+
+ explicit interrupt(handle&& h) : object(h.release()) {}
+
+ interrupt(interrupt&& other) : object(other.release()) {}
+
+ interrupt& operator=(interrupt&& other) {
+ reset(other.release());
+ return *this;
+ }
+
+ static zx_status_t create(const resource& resource, uint32_t vector, uint32_t options,
+ interrupt* result);
+
+ zx_status_t wait(zx::time* timestamp) const {
+ return zx_interrupt_wait(get(), timestamp ? timestamp->get_address() : nullptr);
+ }
+
+ zx_status_t destroy() const { return zx_interrupt_destroy(get()); }
+
+ zx_status_t trigger(uint32_t options, zx::time timestamp) const {
+ return zx_interrupt_trigger(get(), options, timestamp.get());
+ }
+
+ zx_status_t bind(const zx::port& port, uint64_t key, uint32_t options) const {
+ return zx_interrupt_bind(get(), port.get(), key, options);
+ }
+
+ zx_status_t bind_vcpu(const zx::vcpu& vcpu, uint32_t options) const {
+ return zx_interrupt_bind_vcpu(get(), vcpu.get(), options);
+ }
+
+ zx_status_t ack() const { return zx_interrupt_ack(get()); }
+};
+
+using unowned_interrupt = unowned<interrupt>;
+
+} // namespace zx
+
+#endif // LIB_ZX_INTERRUPT_H_
diff --git a/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/iommu.h b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/iommu.h
new file mode 100644
index 0000000..b19a2bb
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/iommu.h
@@ -0,0 +1,38 @@
+// Copyright 2018 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.
+
+#ifndef LIB_ZX_IOMMU_H_
+#define LIB_ZX_IOMMU_H_
+
+#include <lib/zx/object.h>
+#include <lib/zx/resource.h>
+
+namespace zx {
+
+class iommu final : public object<iommu> {
+ public:
+ static constexpr zx_obj_type_t TYPE = ZX_OBJ_TYPE_IOMMU;
+
+ constexpr iommu() = default;
+
+ explicit iommu(zx_handle_t value) : object(value) {}
+
+ explicit iommu(handle&& h) : object(h.release()) {}
+
+ iommu(iommu&& other) : object(other.release()) {}
+
+ iommu& operator=(iommu&& other) {
+ reset(other.release());
+ return *this;
+ }
+
+ static zx_status_t create(const resource& resource, uint32_t type, const void* desc,
+ size_t desc_size, iommu* result);
+};
+
+using unowned_iommu = unowned<iommu>;
+
+} // namespace zx
+
+#endif // LIB_ZX_IOMMU_H_
diff --git a/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/job.h b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/job.h
new file mode 100644
index 0000000..7047ffc
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/job.h
@@ -0,0 +1,63 @@
+// Copyright 2016 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.
+
+#ifndef LIB_ZX_JOB_H_
+#define LIB_ZX_JOB_H_
+
+#include <lib/zx/task.h>
+#include <lib/zx/process.h>
+
+namespace zx {
+
+class process;
+
+class job final : public task<job> {
+ public:
+ static constexpr zx_obj_type_t TYPE = ZX_OBJ_TYPE_JOB;
+
+ constexpr job() = default;
+
+ explicit job(zx_handle_t value) : task(value) {}
+
+ explicit job(handle&& h) : task(h.release()) {}
+
+ job(job&& other) : task(other.release()) {}
+
+ job& operator=(job&& other) {
+ reset(other.release());
+ return *this;
+ }
+
+ static zx_status_t create(const zx::job& parent, uint32_t options, job* result);
+
+ // Provide strongly-typed overloads, in addition to get_child(handle*).
+ using task<job>::get_child;
+ zx_status_t get_child(uint64_t koid, zx_rights_t rights, job* result) const {
+ // Allow for |result| and |this| aliasing the same container.
+ job h;
+ zx_status_t status = zx_object_get_child(value_, koid, rights, h.reset_and_get_address());
+ result->reset(h.release());
+ return status;
+ }
+ zx_status_t get_child(uint64_t koid, zx_rights_t rights, process* result) const;
+
+ zx_status_t set_policy(uint32_t options, uint32_t topic, const void* policy,
+ uint32_t count) const {
+ return zx_job_set_policy(get(), options, topic, policy, count);
+ }
+
+ zx_status_t set_critical(uint32_t options, const zx::process& process) const {
+ return zx_job_set_critical(get(), options, process.get());
+ }
+
+ // Ideally this would be called zx::job::default(), but default is a
+ // C++ keyword and cannot be used as a function name.
+ static inline unowned<job> default_job() { return unowned<job>(zx_job_default()); }
+};
+
+using unowned_job = unowned<job>;
+
+} // namespace zx
+
+#endif // LIB_ZX_JOB_H_
diff --git a/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/object.h b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/object.h
new file mode 100644
index 0000000..710b474
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/object.h
@@ -0,0 +1,428 @@
+// Copyright 2016 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.
+
+#ifndef LIB_ZX_OBJECT_H_
+#define LIB_ZX_OBJECT_H_
+
+#include <lib/zx/object_traits.h>
+#include <lib/zx/time.h>
+#include <zircon/syscalls.h>
+#include <zircon/types.h>
+
+namespace zx {
+
+class port;
+class profile;
+
+// Wraps and takes ownership of a handle to an object.
+//
+// Used for code that wants to operate generically on the zx_handle_t value
+// inside a |zx::object| and doesn't otherwise need a template parameter.
+//
+// The handle is automatically closed when the wrapper is destroyed.
+class object_base {
+ public:
+ void reset(zx_handle_t value = ZX_HANDLE_INVALID) {
+ close();
+ value_ = value;
+ }
+
+ bool is_valid() const { return value_ != ZX_HANDLE_INVALID; }
+ explicit operator bool() const { return is_valid(); }
+
+ zx_handle_t get() const { return value_; }
+
+ // Reset the underlying handle, and then get the address of the
+ // underlying internal handle storage.
+ //
+ // Note: The intended purpose is to facilitate interactions with C
+ // APIs which expect to be provided a pointer to a handle used as
+ // an out parameter.
+ zx_handle_t* reset_and_get_address() {
+ reset();
+ return &value_;
+ }
+
+ __attribute__((warn_unused_result)) zx_handle_t release() {
+ zx_handle_t result = value_;
+ value_ = ZX_HANDLE_INVALID;
+ return result;
+ }
+
+ zx_status_t get_info(uint32_t topic, void* buffer, size_t buffer_size, size_t* actual_count,
+ size_t* avail_count) const {
+ return zx_object_get_info(get(), topic, buffer, buffer_size, actual_count, avail_count);
+ }
+
+ zx_status_t get_property(uint32_t property, void* value, size_t size) const {
+ return zx_object_get_property(get(), property, value, size);
+ }
+
+ zx_status_t set_property(uint32_t property, const void* value, size_t size) const {
+ return zx_object_set_property(get(), property, value, size);
+ }
+
+ protected:
+ constexpr object_base() : value_(ZX_HANDLE_INVALID) {}
+
+ explicit object_base(zx_handle_t value) : value_(value) {}
+
+ ~object_base() { close(); }
+
+ object_base(const object_base&) = delete;
+
+ void operator=(const object_base&) = delete;
+
+ void close() {
+ if (value_ != ZX_HANDLE_INVALID) {
+ zx_handle_close(value_);
+ value_ = ZX_HANDLE_INVALID;
+ }
+ }
+
+ zx_handle_t value_;
+};
+
+// Forward declaration for borrow method.
+template <typename T>
+class unowned;
+
+// Provides type-safe access to operations on a handle.
+template <typename T>
+class object : public object_base {
+ public:
+ constexpr object() = default;
+
+ explicit object(zx_handle_t value) : object_base(value) {}
+
+ template <typename U>
+ object(object<U>&& other) : object_base(other.release()) {
+ static_assert(is_same<T, void>::value, "Receiver must be compatible.");
+ }
+
+ template <typename U>
+ object<T>& operator=(object<U>&& other) {
+ static_assert(is_same<T, void>::value, "Receiver must be compatible.");
+ reset(other.release());
+ return *this;
+ }
+
+ void swap(object<T>& other) {
+ zx_handle_t tmp = value_;
+ value_ = other.value_;
+ other.value_ = tmp;
+ }
+
+ zx_status_t duplicate(zx_rights_t rights, object<T>* result) const {
+ static_assert(object_traits<T>::supports_duplication, "Object must support duplication.");
+ zx_handle_t h = ZX_HANDLE_INVALID;
+ zx_status_t status = zx_handle_duplicate(value_, rights, &h);
+ result->reset(h);
+ return status;
+ }
+
+ zx_status_t replace(zx_rights_t rights, object<T>* result) {
+ zx_handle_t h = ZX_HANDLE_INVALID;
+ zx_status_t status = zx_handle_replace(value_, rights, &h);
+ // We store ZX_HANDLE_INVALID to value_ before calling reset on result
+ // in case result == this.
+ value_ = ZX_HANDLE_INVALID;
+ result->reset(h);
+ return status;
+ }
+
+ zx_status_t wait_one(zx_signals_t signals, zx::time deadline, zx_signals_t* pending) const {
+ static_assert(object_traits<T>::supports_wait, "Object is not waitable.");
+ return zx_object_wait_one(value_, signals, deadline.get(), pending);
+ }
+
+ zx_status_t wait_async(const object<port>& port, uint64_t key, zx_signals_t signals,
+ uint32_t options) const {
+ static_assert(object_traits<T>::supports_wait, "Object is not waitable.");
+ return zx_object_wait_async(value_, port.get(), key, signals, options);
+ }
+
+ static zx_status_t wait_many(zx_wait_item_t* wait_items, uint32_t count, zx::time deadline) {
+ static_assert(object_traits<T>::supports_wait, "Object is not waitable.");
+ return zx_object_wait_many(wait_items, count, deadline.get());
+ }
+
+ zx_status_t signal(uint32_t clear_mask, uint32_t set_mask) const {
+ static_assert(object_traits<T>::supports_user_signal, "Object must support user signals.");
+ return zx_object_signal(get(), clear_mask, set_mask);
+ }
+
+ zx_status_t signal_peer(uint32_t clear_mask, uint32_t set_mask) const {
+ static_assert(object_traits<T>::supports_user_signal, "Object must support user signals.");
+ static_assert(object_traits<T>::has_peer_handle, "Object must have peer object.");
+ return zx_object_signal_peer(get(), clear_mask, set_mask);
+ }
+
+ zx_status_t get_child(uint64_t koid, zx_rights_t rights, object<void>* result) const {
+ static_assert(object_traits<T>::supports_get_child, "Object must support getting children.");
+ // Allow for |result| and |this| being the same container, though that
+ // can only happen for |T=void|, due to strict aliasing.
+ object<void> h;
+ zx_status_t status = zx_object_get_child(value_, koid, rights, h.reset_and_get_address());
+ result->reset(h.release());
+ return status;
+ }
+
+ zx_status_t set_profile(const object<profile>& profile, uint32_t options) const {
+ static_assert(object_traits<T>::supports_set_profile,
+ "Object must support scheduling profiles.");
+ return zx_object_set_profile(get(), profile.get(), options);
+ }
+
+ // Returns a type-safe wrapper of the underlying handle that does not claim ownership.
+ unowned<T> borrow() const { return unowned<T>(get()); }
+
+ private:
+ template <typename A, typename B>
+ struct is_same {
+ static const bool value = false;
+ };
+
+ template <typename A>
+ struct is_same<A, A> {
+ static const bool value = true;
+ };
+};
+
+template <typename T>
+bool operator==(const object<T>& a, const object<T>& b) {
+ return a.get() == b.get();
+}
+
+template <typename T>
+bool operator!=(const object<T>& a, const object<T>& b) {
+ return !(a == b);
+}
+
+template <typename T>
+bool operator<(const object<T>& a, const object<T>& b) {
+ return a.get() < b.get();
+}
+
+template <typename T>
+bool operator>(const object<T>& a, const object<T>& b) {
+ return a.get() > b.get();
+}
+
+template <typename T>
+bool operator<=(const object<T>& a, const object<T>& b) {
+ return !(a.get() > b.get());
+}
+
+template <typename T>
+bool operator>=(const object<T>& a, const object<T>& b) {
+ return !(a.get() < b.get());
+}
+
+template <typename T>
+bool operator==(zx_handle_t a, const object<T>& b) {
+ return a == b.get();
+}
+
+template <typename T>
+bool operator!=(zx_handle_t a, const object<T>& b) {
+ return !(a == b);
+}
+
+template <typename T>
+bool operator<(zx_handle_t a, const object<T>& b) {
+ return a < b.get();
+}
+
+template <typename T>
+bool operator>(zx_handle_t a, const object<T>& b) {
+ return a > b.get();
+}
+
+template <typename T>
+bool operator<=(zx_handle_t a, const object<T>& b) {
+ return !(a > b.get());
+}
+
+template <typename T>
+bool operator>=(zx_handle_t a, const object<T>& b) {
+ return !(a < b.get());
+}
+
+template <typename T>
+bool operator==(const object<T>& a, zx_handle_t b) {
+ return a.get() == b;
+}
+
+template <typename T>
+bool operator!=(const object<T>& a, zx_handle_t b) {
+ return !(a == b);
+}
+
+template <typename T>
+bool operator<(const object<T>& a, zx_handle_t b) {
+ return a.get() < b;
+}
+
+template <typename T>
+bool operator>(const object<T>& a, zx_handle_t b) {
+ return a.get() > b;
+}
+
+template <typename T>
+bool operator<=(const object<T>& a, zx_handle_t b) {
+ return !(a.get() > b);
+}
+
+template <typename T>
+bool operator>=(const object<T>& a, zx_handle_t b) {
+ return !(a.get() < b);
+}
+
+// Wraps a handle to an object to provide type-safe access to its operations
+// but does not take ownership of it. The handle is not closed when the
+// wrapper is destroyed.
+//
+// All use of unowned<object<T>> as an object<T> is via a dereference operator,
+// as illustrated below:
+//
+// void do_something(const zx::event& event);
+//
+// void example(zx_handle_t event_handle) {
+// do_something(*zx::unowned<event>(event_handle));
+// }
+//
+// Convenience aliases are provided for all object types, for example:
+//
+// zx::unowned_event(handle)->signal(..)
+template <typename T>
+class unowned final {
+ public:
+ explicit unowned(zx_handle_t h) : value_(h) {}
+ explicit unowned(const T& owner) : unowned(owner.get()) {}
+ explicit unowned(const unowned& other) : unowned(*other) {}
+ constexpr unowned() = default;
+ unowned(unowned&& other) = default;
+
+ ~unowned() { release_value(); }
+
+ unowned& operator=(const unowned& other) {
+ if (&other == this) {
+ return *this;
+ }
+
+ *this = unowned(other);
+ return *this;
+ }
+ unowned& operator=(unowned&& other) {
+ release_value();
+ value_ = static_cast<T&&>(other.value_);
+ return *this;
+ }
+
+ const T& operator*() const { return value_; }
+ const T* operator->() const { return &value_; }
+
+ private:
+ void release_value() {
+ zx_handle_t h = value_.release();
+ static_cast<void>(h);
+ }
+
+ T value_;
+};
+
+template <typename T>
+bool operator==(const unowned<T>& a, const unowned<T>& b) {
+ return a->get() == b->get();
+}
+
+template <typename T>
+bool operator!=(const unowned<T>& a, const unowned<T>& b) {
+ return !(a == b);
+}
+
+template <typename T>
+bool operator<(const unowned<T>& a, const unowned<T>& b) {
+ return a->get() < b->get();
+}
+
+template <typename T>
+bool operator>(const unowned<T>& a, const unowned<T>& b) {
+ return a->get() > b->get();
+}
+
+template <typename T>
+bool operator<=(const unowned<T>& a, const unowned<T>& b) {
+ return !(a > b);
+}
+
+template <typename T>
+bool operator>=(const unowned<T>& a, const unowned<T>& b) {
+ return !(a < b);
+}
+
+template <typename T>
+bool operator==(zx_handle_t a, const unowned<T>& b) {
+ return a == b->get();
+}
+
+template <typename T>
+bool operator!=(zx_handle_t a, const unowned<T>& b) {
+ return !(a == b);
+}
+
+template <typename T>
+bool operator<(zx_handle_t a, const unowned<T>& b) {
+ return a < b->get();
+}
+
+template <typename T>
+bool operator>(zx_handle_t a, const unowned<T>& b) {
+ return a > b->get();
+}
+
+template <typename T>
+bool operator<=(zx_handle_t a, const unowned<T>& b) {
+ return !(a > b);
+}
+
+template <typename T>
+bool operator>=(zx_handle_t a, const unowned<T>& b) {
+ return !(a < b);
+}
+
+template <typename T>
+bool operator==(const unowned<T>& a, zx_handle_t b) {
+ return a->get() == b;
+}
+
+template <typename T>
+bool operator!=(const unowned<T>& a, zx_handle_t b) {
+ return !(a == b);
+}
+
+template <typename T>
+bool operator<(const unowned<T>& a, zx_handle_t b) {
+ return a->get() < b;
+}
+
+template <typename T>
+bool operator>(const unowned<T>& a, zx_handle_t b) {
+ return a->get() > b;
+}
+
+template <typename T>
+bool operator<=(const unowned<T>& a, zx_handle_t b) {
+ return !(a > b);
+}
+
+template <typename T>
+bool operator>=(const unowned<T>& a, zx_handle_t b) {
+ return !(a < b);
+}
+
+} // namespace zx
+
+#endif // LIB_ZX_OBJECT_H_
diff --git a/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/object_traits.h b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/object_traits.h
new file mode 100644
index 0000000..cb3441b
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/object_traits.h
@@ -0,0 +1,196 @@
+// Copyright 2016 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.
+
+#ifndef LIB_ZX_OBJECT_TRAITS_H_
+#define LIB_ZX_OBJECT_TRAITS_H_
+
+namespace zx {
+
+class channel;
+class eventpair;
+class exception;
+class fifo;
+class guest;
+class interrupt;
+class job;
+class log;
+class port;
+class process;
+class pmt;
+class resource;
+class socket;
+class thread;
+class vmar;
+class vmo;
+
+// The default traits supports:
+// - bti
+// - event
+// - iommu
+// - profile
+// - timer
+// - vmo
+template <typename T>
+struct object_traits {
+ static constexpr bool supports_duplication = true;
+ static constexpr bool supports_get_child = false;
+ static constexpr bool supports_set_profile = false;
+ static constexpr bool supports_user_signal = true;
+ static constexpr bool supports_wait = true;
+ static constexpr bool has_peer_handle = false;
+};
+
+template <>
+struct object_traits<channel> {
+ static constexpr bool supports_duplication = false;
+ static constexpr bool supports_get_child = false;
+ static constexpr bool supports_set_profile = false;
+ static constexpr bool supports_user_signal = true;
+ static constexpr bool supports_wait = true;
+ static constexpr bool has_peer_handle = true;
+};
+
+template <>
+struct object_traits<eventpair> {
+ static constexpr bool supports_duplication = true;
+ static constexpr bool supports_get_child = false;
+ static constexpr bool supports_set_profile = false;
+ static constexpr bool supports_user_signal = true;
+ static constexpr bool supports_wait = true;
+ static constexpr bool has_peer_handle = true;
+};
+
+template <>
+struct object_traits<fifo> {
+ static constexpr bool supports_duplication = true;
+ static constexpr bool supports_get_child = false;
+ static constexpr bool supports_set_profile = false;
+ static constexpr bool supports_user_signal = true;
+ static constexpr bool supports_wait = true;
+ static constexpr bool has_peer_handle = true;
+};
+
+template <>
+struct object_traits<log> {
+ static constexpr bool supports_duplication = true;
+ static constexpr bool supports_get_child = false;
+ static constexpr bool supports_set_profile = false;
+ static constexpr bool supports_user_signal = true;
+ static constexpr bool supports_wait = true;
+ static constexpr bool has_peer_handle = false;
+};
+
+template <>
+struct object_traits<pmt> {
+ static constexpr bool supports_duplication = false;
+ static constexpr bool supports_get_child = false;
+ static constexpr bool supports_set_profile = false;
+ static constexpr bool supports_user_signal = false;
+ static constexpr bool supports_wait = false;
+ static constexpr bool has_peer_handle = false;
+};
+
+template <>
+struct object_traits<socket> {
+ static constexpr bool supports_duplication = true;
+ static constexpr bool supports_get_child = false;
+ static constexpr bool supports_set_profile = false;
+ static constexpr bool supports_user_signal = true;
+ static constexpr bool supports_wait = true;
+ static constexpr bool has_peer_handle = true;
+};
+
+template <>
+struct object_traits<port> {
+ static constexpr bool supports_duplication = true;
+ static constexpr bool supports_get_child = false;
+ static constexpr bool supports_set_profile = false;
+ static constexpr bool supports_user_signal = false;
+ static constexpr bool supports_wait = false;
+ static constexpr bool has_peer_handle = false;
+};
+
+template <>
+struct object_traits<vmar> {
+ static constexpr bool supports_duplication = true;
+ static constexpr bool supports_get_child = false;
+ static constexpr bool supports_set_profile = false;
+ static constexpr bool supports_user_signal = false;
+ static constexpr bool supports_wait = false;
+ static constexpr bool has_peer_handle = false;
+};
+
+template <>
+struct object_traits<interrupt> {
+ static constexpr bool supports_duplication = true;
+ static constexpr bool supports_get_child = false;
+ static constexpr bool supports_set_profile = false;
+ static constexpr bool supports_user_signal = false;
+ static constexpr bool supports_wait = true;
+ static constexpr bool has_peer_handle = false;
+};
+
+template <>
+struct object_traits<guest> {
+ static constexpr bool supports_duplication = true;
+ static constexpr bool supports_get_child = false;
+ static constexpr bool supports_set_profile = false;
+ static constexpr bool supports_user_signal = false;
+ static constexpr bool supports_wait = false;
+ static constexpr bool has_peer_handle = false;
+};
+
+template <>
+struct object_traits<exception> {
+ static constexpr bool supports_duplication = false;
+ static constexpr bool supports_get_child = false;
+ static constexpr bool supports_set_profile = false;
+ static constexpr bool supports_user_signal = false;
+ static constexpr bool supports_wait = false;
+ static constexpr bool has_peer_handle = false;
+};
+
+template <>
+struct object_traits<job> {
+ static constexpr bool supports_duplication = true;
+ static constexpr bool supports_get_child = true;
+ static constexpr bool supports_set_profile = false;
+ static constexpr bool supports_user_signal = true;
+ static constexpr bool supports_wait = true;
+ static constexpr bool has_peer_handle = false;
+};
+
+template <>
+struct object_traits<process> {
+ static constexpr bool supports_duplication = true;
+ static constexpr bool supports_get_child = true;
+ static constexpr bool supports_set_profile = false;
+ static constexpr bool supports_user_signal = true;
+ static constexpr bool supports_wait = true;
+ static constexpr bool has_peer_handle = false;
+};
+
+template <>
+struct object_traits<thread> {
+ static constexpr bool supports_duplication = true;
+ static constexpr bool supports_get_child = false;
+ static constexpr bool supports_set_profile = true;
+ static constexpr bool supports_user_signal = true;
+ static constexpr bool supports_wait = true;
+ static constexpr bool has_peer_handle = false;
+};
+
+template <>
+struct object_traits<resource> {
+ static constexpr bool supports_duplication = true;
+ static constexpr bool supports_get_child = true;
+ static constexpr bool supports_set_profile = false;
+ static constexpr bool supports_user_signal = true;
+ static constexpr bool supports_wait = true;
+ static constexpr bool has_peer_handle = false;
+};
+
+} // namespace zx
+
+#endif // LIB_ZX_OBJECT_TRAITS_H_
diff --git a/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/pager.h b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/pager.h
new file mode 100644
index 0000000..7c389f7
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/pager.h
@@ -0,0 +1,52 @@
+// 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.
+
+#ifndef LIB_ZX_PAGER_H_
+#define LIB_ZX_PAGER_H_
+
+#include <lib/zx/handle.h>
+#include <lib/zx/object.h>
+#include <lib/zx/port.h>
+#include <lib/zx/vmo.h>
+
+namespace zx {
+
+class pager final : public object<pager> {
+ public:
+ static constexpr zx_obj_type_t TYPE = ZX_OBJ_TYPE_PAGER;
+
+ constexpr pager() = default;
+
+ explicit pager(zx_handle_t value) : object(value) {}
+
+ explicit pager(handle&& h) : object(h.release()) {}
+
+ pager(pager&& other) : object(other.release()) {}
+
+ pager& operator=(pager&& other) {
+ reset(other.release());
+ return *this;
+ }
+
+ static zx_status_t create(uint32_t options, pager* result);
+
+ zx_status_t create_vmo(uint32_t options, const port& port, uint64_t key, uint64_t size,
+ vmo* result) const {
+ return zx_pager_create_vmo(get(), options, port.get(), key, size,
+ result->reset_and_get_address());
+ }
+
+ zx_status_t detach_vmo(const vmo& vmo) const { return zx_pager_detach_vmo(get(), vmo.get()); }
+
+ zx_status_t supply_pages(const vmo& pager_vmo, uint64_t offset, uint64_t length,
+ const vmo& aux_vmo, uint64_t aux_offset) const {
+ return zx_pager_supply_pages(get(), pager_vmo.get(), offset, length, aux_vmo.get(), aux_offset);
+ }
+};
+
+using unowned_pager = unowned<pager>;
+
+} // namespace zx
+
+#endif // LIB_ZX_PAGER_H_
diff --git a/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/pmt.h b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/pmt.h
new file mode 100644
index 0000000..8d095da
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/pmt.h
@@ -0,0 +1,37 @@
+// Copyright 2018 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.
+
+#ifndef LIB_ZX_PMT_H_
+#define LIB_ZX_PMT_H_
+
+#include <lib/zx/handle.h>
+#include <lib/zx/object.h>
+
+namespace zx {
+
+class pmt final : public object<pmt> {
+ public:
+ static constexpr zx_obj_type_t TYPE = ZX_OBJ_TYPE_PMT;
+
+ constexpr pmt() = default;
+
+ explicit pmt(zx_handle_t value) : object(value) {}
+
+ explicit pmt(handle&& h) : object(h.release()) {}
+
+ pmt(pmt&& other) : object(other.release()) {}
+
+ pmt& operator=(pmt&& other) {
+ reset(other.release());
+ return *this;
+ }
+
+ zx_status_t unpin() { return zx_pmt_unpin(release()); }
+};
+
+using unowned_pmt = unowned<pmt>;
+
+} // namespace zx
+
+#endif // LIB_ZX_PMT_H_
diff --git a/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/port.h b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/port.h
new file mode 100644
index 0000000..01a0fe5
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/port.h
@@ -0,0 +1,48 @@
+// Copyright 2016 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.
+
+#ifndef LIB_ZX_PORT_H_
+#define LIB_ZX_PORT_H_
+
+#include <lib/zx/handle.h>
+#include <lib/zx/object.h>
+#include <lib/zx/time.h>
+
+namespace zx {
+
+class port final : public object<port> {
+ public:
+ static constexpr zx_obj_type_t TYPE = ZX_OBJ_TYPE_PORT;
+
+ constexpr port() = default;
+
+ explicit port(zx_handle_t value) : object(value) {}
+
+ explicit port(handle&& h) : object(h.release()) {}
+
+ port(port&& other) : object(other.release()) {}
+
+ port& operator=(port&& other) {
+ reset(other.release());
+ return *this;
+ }
+
+ static zx_status_t create(uint32_t options, port* result);
+
+ zx_status_t queue(const zx_port_packet_t* packet) const { return zx_port_queue(get(), packet); }
+
+ zx_status_t wait(zx::time deadline, zx_port_packet_t* packet) const {
+ return zx_port_wait(get(), deadline.get(), packet);
+ }
+
+ zx_status_t cancel(const object_base& source, uint64_t key) const {
+ return zx_port_cancel(get(), source.get(), key);
+ }
+};
+
+using unowned_port = unowned<port>;
+
+} // namespace zx
+
+#endif // LIB_ZX_PORT_H_
diff --git a/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/process.h b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/process.h
new file mode 100644
index 0000000..7fca7dc
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/process.h
@@ -0,0 +1,64 @@
+// Copyright 2016 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.
+
+#ifndef LIB_ZX_PROCESS_H_
+#define LIB_ZX_PROCESS_H_
+
+#include <lib/zx/object.h>
+#include <lib/zx/task.h>
+#include <lib/zx/vmar.h>
+#include <lib/zx/vmo.h>
+#include <zircon/process.h>
+
+namespace zx {
+class job;
+class thread;
+
+class process final : public task<process> {
+ public:
+ static constexpr zx_obj_type_t TYPE = ZX_OBJ_TYPE_PROCESS;
+
+ constexpr process() = default;
+
+ explicit process(zx_handle_t value) : task(value) {}
+
+ explicit process(handle&& h) : task(h.release()) {}
+
+ process(process&& other) : task(other.release()) {}
+
+ process& operator=(process&& other) {
+ reset(other.release());
+ return *this;
+ }
+
+ // Rather than creating a process directly with this syscall,
+ // consider using the launchpad library, which properly sets up
+ // the many details of creating a process beyond simply creating
+ // the kernel structure.
+ static zx_status_t create(const job& job, const char* name, uint32_t name_len, uint32_t flags,
+ process* proc, vmar* root_vmar);
+
+ zx_status_t start(const thread& thread_handle, uintptr_t entry, uintptr_t stack,
+ handle arg_handle, uintptr_t arg2) const;
+
+ zx_status_t read_memory(uintptr_t vaddr, void* buffer, size_t len, size_t* actual) const {
+ return zx_process_read_memory(get(), vaddr, buffer, len, actual);
+ }
+
+ zx_status_t write_memory(uintptr_t vaddr, const void* buffer, size_t len, size_t* actual) const {
+ return zx_process_write_memory(get(), vaddr, buffer, len, actual);
+ }
+
+ // Provide strongly-typed overload, in addition to get_child(handle*).
+ using task<process>::get_child;
+ zx_status_t get_child(uint64_t koid, zx_rights_t rights, thread* result) const;
+
+ static inline unowned<process> self() { return unowned<process>(zx_process_self()); }
+};
+
+using unowned_process = unowned<process>;
+
+} // namespace zx
+
+#endif // LIB_ZX_PROCESS_H_
diff --git a/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/profile.h b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/profile.h
new file mode 100644
index 0000000..fa3814f
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/profile.h
@@ -0,0 +1,39 @@
+// Copyright 2018 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.
+
+#ifndef LIB_ZX_PROFILE_H_
+#define LIB_ZX_PROFILE_H_
+
+#include <lib/zx/handle.h>
+#include <lib/zx/job.h>
+#include <lib/zx/object.h>
+
+namespace zx {
+
+class profile final : public object<profile> {
+ public:
+ static constexpr zx_obj_type_t TYPE = ZX_OBJ_TYPE_PROFILE;
+
+ constexpr profile() = default;
+
+ explicit profile(zx_handle_t value) : object(value) {}
+
+ explicit profile(handle&& h) : object(h.release()) {}
+
+ profile(profile&& other) : object(other.release()) {}
+
+ profile& operator=(profile&& other) {
+ reset(other.release());
+ return *this;
+ }
+
+ static zx_status_t create(const job& job, uint32_t options, const zx_profile_info_t* info,
+ profile* result);
+};
+
+using unowned_profile = unowned<profile>;
+
+} // namespace zx
+
+#endif // LIB_ZX_PROFILE_H_
diff --git a/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/resource.h b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/resource.h
new file mode 100644
index 0000000..0f3afd1
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/resource.h
@@ -0,0 +1,38 @@
+// Copyright 2018 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.
+
+#ifndef LIB_ZX_RESOURCE_H_
+#define LIB_ZX_RESOURCE_H_
+
+#include <lib/zx/handle.h>
+#include <lib/zx/object.h>
+
+namespace zx {
+
+class resource final : public object<resource> {
+ public:
+ static constexpr zx_obj_type_t TYPE = ZX_OBJ_TYPE_RESOURCE;
+
+ constexpr resource() = default;
+
+ explicit resource(zx_handle_t value) : object(value) {}
+
+ explicit resource(handle&& h) : object(h.release()) {}
+
+ resource(resource&& other) : object(other.release()) {}
+
+ resource& operator=(resource&& other) {
+ reset(other.release());
+ return *this;
+ }
+
+ static zx_status_t create(const resource& parent, uint32_t options, uint64_t base, size_t len,
+ const char* name, size_t namelen, resource* result);
+};
+
+using unowned_resource = unowned<resource>;
+
+} // namespace zx
+
+#endif // LIB_ZX_RESOURCE_H_
diff --git a/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/socket.h b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/socket.h
new file mode 100644
index 0000000..d1563e3
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/socket.h
@@ -0,0 +1,47 @@
+// Copyright 2016 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.
+
+#ifndef LIB_ZX_SOCKET_H_
+#define LIB_ZX_SOCKET_H_
+
+#include <lib/zx/handle.h>
+#include <lib/zx/object.h>
+
+namespace zx {
+
+class socket final : public object<socket> {
+ public:
+ static constexpr zx_obj_type_t TYPE = ZX_OBJ_TYPE_SOCKET;
+
+ constexpr socket() = default;
+
+ explicit socket(zx_handle_t value) : object(value) {}
+
+ explicit socket(handle&& h) : object(h.release()) {}
+
+ socket(socket&& other) : object(other.release()) {}
+
+ socket& operator=(socket&& other) {
+ reset(other.release());
+ return *this;
+ }
+
+ static zx_status_t create(uint32_t options, socket* endpoint0, socket* endpoint1);
+
+ zx_status_t write(uint32_t options, const void* buffer, size_t len, size_t* actual) const {
+ return zx_socket_write(get(), options, buffer, len, actual);
+ }
+
+ zx_status_t read(uint32_t options, void* buffer, size_t len, size_t* actual) const {
+ return zx_socket_read(get(), options, buffer, len, actual);
+ }
+
+ zx_status_t shutdown(uint32_t options) const { return zx_socket_shutdown(get(), options); }
+};
+
+using unowned_socket = unowned<socket>;
+
+} // namespace zx
+
+#endif // LIB_ZX_SOCKET_H_
diff --git a/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/stream.h b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/stream.h
new file mode 100644
index 0000000..1d7080a
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/stream.h
@@ -0,0 +1,66 @@
+// Copyright 2020 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.
+
+#ifndef LIB_ZX_STREAM_H_
+#define LIB_ZX_STREAM_H_
+
+#include <lib/zx/handle.h>
+#include <lib/zx/object.h>
+#include <lib/zx/vmo.h>
+
+namespace zx {
+
+class stream final : public object<stream> {
+ public:
+ static constexpr zx_obj_type_t TYPE = ZX_OBJ_TYPE_STREAM;
+
+ constexpr stream() = default;
+
+ explicit stream(zx_handle_t value) : object(value) {}
+
+ explicit stream(handle&& h) : object(h.release()) {}
+
+ stream(stream&& other) : object(other.release()) {}
+
+ stream& operator=(stream&& other) {
+ reset(other.release());
+ return *this;
+ }
+
+ static zx_status_t create(uint32_t options, const vmo& vmo_handle, zx_off_t seek,
+ stream* out_stream);
+
+ zx_status_t writev(uint32_t options, const zx_iovec_t* vector, size_t vector_count,
+ size_t* actual) const {
+ return zx_stream_writev(get(), options, vector, vector_count, actual);
+ }
+
+ zx_status_t writev_at(uint32_t options, zx_off_t offset, const zx_iovec_t* vector,
+ size_t vector_count, size_t* actual) const {
+ return zx_stream_writev_at(get(), options, offset, vector, vector_count, actual);
+ }
+
+ zx_status_t readv(uint32_t options, const zx_iovec_t* vector, size_t vector_count,
+ size_t* actual) const {
+ // TODO: zx_stream_readv should accept a |const zx_iovec_t*|.
+ return zx_stream_readv(get(), options, const_cast<zx_iovec_t*>(vector), vector_count, actual);
+ }
+
+ zx_status_t readv_at(uint32_t options, zx_off_t offset, const zx_iovec_t* vector,
+ size_t vector_count, size_t* actual) const {
+ // TODO: zx_stream_readv should accept a |const zx_iovec_t*|.
+ return zx_stream_readv_at(get(), options, offset, const_cast<zx_iovec_t*>(vector), vector_count,
+ actual);
+ }
+
+ zx_status_t seek(zx_stream_seek_origin_t whence, int64_t offset, zx_off_t* out_seek) const {
+ return zx_stream_seek(get(), whence, offset, out_seek);
+ }
+};
+
+using unowned_stream = unowned<stream>;
+
+} // namespace zx
+
+#endif // LIB_ZX_STREAM_H_
diff --git a/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/suspend_token.h b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/suspend_token.h
new file mode 100644
index 0000000..691094f
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/suspend_token.h
@@ -0,0 +1,35 @@
+// Copyright 2018 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.
+
+#ifndef LIB_ZX_SUSPEND_TOKEN_H_
+#define LIB_ZX_SUSPEND_TOKEN_H_
+
+#include <lib/zx/handle.h>
+#include <lib/zx/object.h>
+
+namespace zx {
+
+// The only thing you can do with a suspend token is close it (which will
+// resume the thread).
+class suspend_token final : public object<suspend_token> {
+ public:
+ static constexpr zx_obj_type_t TYPE = ZX_OBJ_TYPE_SUSPEND_TOKEN;
+
+ constexpr suspend_token() = default;
+
+ explicit suspend_token(zx_handle_t value) : object<suspend_token>(value) {}
+
+ explicit suspend_token(handle&& h) : object<suspend_token>(h.release()) {}
+
+ suspend_token(suspend_token&& other) : object<suspend_token>(other.release()) {}
+
+ suspend_token& operator=(suspend_token&& other) {
+ reset(other.release());
+ return *this;
+ }
+};
+
+} // namespace zx
+
+#endif // LIB_ZX_SUSPEND_TOKEN_H_
diff --git a/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/task.h b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/task.h
new file mode 100644
index 0000000..57f7f3f
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/task.h
@@ -0,0 +1,45 @@
+// Copyright 2016 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.
+
+#ifndef LIB_ZX_TASK_H_
+#define LIB_ZX_TASK_H_
+
+#include <lib/zx/channel.h>
+#include <lib/zx/handle.h>
+#include <lib/zx/object.h>
+#include <lib/zx/suspend_token.h>
+
+namespace zx {
+
+class port;
+class suspend_token;
+
+template <typename T = void>
+class task : public object<T> {
+ public:
+ constexpr task() = default;
+
+ explicit task(zx_handle_t value) : object<T>(value) {}
+
+ explicit task(handle&& h) : object<T>(h.release()) {}
+
+ task(task&& other) : object<T>(other.release()) {}
+
+ zx_status_t kill() const { return zx_task_kill(object<T>::get()); }
+
+ zx_status_t suspend(suspend_token* result) const {
+ // Assume |result| must refer to a different container than |this|, due
+ // to strict aliasing.
+ return zx_task_suspend_token(object<T>::get(), result->reset_and_get_address());
+ }
+
+ zx_status_t create_exception_channel(uint32_t options, object<channel>* channel) const {
+ return zx_task_create_exception_channel(object<T>::get(), options,
+ channel->reset_and_get_address());
+ }
+};
+
+} // namespace zx
+
+#endif // LIB_ZX_TASK_H_
diff --git a/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/thread.h b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/thread.h
new file mode 100644
index 0000000..bb80bc6
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/thread.h
@@ -0,0 +1,64 @@
+// Copyright 2016 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.
+
+#ifndef LIB_ZX_THREAD_H_
+#define LIB_ZX_THREAD_H_
+
+#include <lib/zx/object.h>
+#include <lib/zx/task.h>
+#include <zircon/process.h>
+
+namespace zx {
+class process;
+
+class thread final : public task<thread> {
+ public:
+ static constexpr zx_obj_type_t TYPE = ZX_OBJ_TYPE_THREAD;
+
+ constexpr thread() = default;
+
+ explicit thread(zx_handle_t value) : task(value) {}
+
+ explicit thread(handle&& h) : task(h.release()) {}
+
+ thread(thread&& other) : task(other.release()) {}
+
+ thread& operator=(thread&& other) {
+ reset(other.release());
+ return *this;
+ }
+
+ // Rather than creating a thread directly with this syscall, consider using
+ // std::thread or thrd_create, which properly integrates with the
+ // thread-local data structures in libc.
+ static zx_status_t create(const process& process, const char* name, uint32_t name_len,
+ uint32_t flags, thread* result);
+
+ // The first variant maps exactly to the syscall and can be used for
+ // launching threads in remote processes. The second variant is for
+ // conveniently launching threads in the current process.
+ zx_status_t start(uintptr_t thread_entry, uintptr_t stack, uintptr_t arg1, uintptr_t arg2) const {
+ return zx_thread_start(get(), thread_entry, stack, arg1, arg2);
+ }
+ zx_status_t start(void (*thread_entry)(uintptr_t arg1, uintptr_t arg2), void* stack,
+ uintptr_t arg1, uintptr_t arg2) const {
+ return zx_thread_start(get(), reinterpret_cast<uintptr_t>(thread_entry),
+ reinterpret_cast<uintptr_t>(stack), arg1, arg2);
+ }
+
+ zx_status_t read_state(uint32_t kind, void* buffer, size_t len) const {
+ return zx_thread_read_state(get(), kind, buffer, len);
+ }
+ zx_status_t write_state(uint32_t kind, const void* buffer, size_t len) const {
+ return zx_thread_write_state(get(), kind, buffer, len);
+ }
+
+ static inline unowned<thread> self() { return unowned<thread>(zx_thread_self()); }
+};
+
+using unowned_thread = unowned<thread>;
+
+} // namespace zx
+
+#endif // LIB_ZX_THREAD_H_
diff --git a/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/time.h b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/time.h
new file mode 100644
index 0000000..6e01ba2
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/time.h
@@ -0,0 +1,286 @@
+// Copyright 2016 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.
+
+#ifndef LIB_ZX_TIME_H_
+#define LIB_ZX_TIME_H_
+
+#include <stdint.h>
+#include <zircon/compiler.h>
+#include <zircon/syscalls.h>
+#include <zircon/time.h>
+
+#include <limits>
+
+namespace zx {
+
+class duration final {
+ public:
+ constexpr duration() = default;
+
+ explicit constexpr duration(zx_duration_t value) : value_(value) {}
+
+ static constexpr duration infinite() { return duration(ZX_TIME_INFINITE); }
+
+ static constexpr duration infinite_past() { return duration(ZX_TIME_INFINITE_PAST); }
+
+ constexpr zx_duration_t get() const { return value_; }
+
+ constexpr duration operator+(duration other) const {
+ return duration(zx_duration_add_duration(value_, other.value_));
+ }
+
+ constexpr duration operator-(duration other) const {
+ return duration(zx_duration_sub_duration(value_, other.value_));
+ }
+
+ constexpr duration operator*(int64_t multiplier) const {
+ return duration(zx_duration_mul_int64(value_, multiplier));
+ }
+
+ constexpr duration operator/(int64_t divisor) const { return duration(value_ / divisor); }
+
+ constexpr int64_t operator/(duration other) const { return value_ / other.value_; }
+
+ constexpr duration operator%(int64_t divisor) const { return duration(value_ % divisor); }
+
+ constexpr int64_t operator%(duration other) const { return value_ % other.value_; }
+
+ constexpr duration& operator+=(duration other) {
+ value_ = zx_duration_add_duration(value_, other.value_);
+ return *this;
+ }
+
+ constexpr duration& operator-=(duration other) {
+ value_ = zx_duration_sub_duration(value_, other.value_);
+ return *this;
+ }
+
+ constexpr duration& operator*=(int64_t multiplier) {
+ value_ = zx_duration_mul_int64(value_, multiplier);
+ return *this;
+ }
+
+ constexpr duration& operator/=(int64_t divisor) {
+ value_ /= divisor;
+ return *this;
+ }
+
+ constexpr duration& operator%=(int64_t divisor) {
+ value_ %= divisor;
+ return *this;
+ }
+
+ constexpr bool operator==(duration other) const { return value_ == other.value_; }
+ constexpr bool operator!=(duration other) const { return value_ != other.value_; }
+ constexpr bool operator<(duration other) const { return value_ < other.value_; }
+ constexpr bool operator<=(duration other) const { return value_ <= other.value_; }
+ constexpr bool operator>(duration other) const { return value_ > other.value_; }
+ constexpr bool operator>=(duration other) const { return value_ >= other.value_; }
+
+ constexpr int64_t to_nsecs() const { return value_; }
+
+ constexpr int64_t to_usecs() const { return value_ / ZX_USEC(1); }
+
+ constexpr int64_t to_msecs() const { return value_ / ZX_MSEC(1); }
+
+ constexpr int64_t to_secs() const { return value_ / ZX_SEC(1); }
+
+ constexpr int64_t to_mins() const { return value_ / ZX_MIN(1); }
+
+ constexpr int64_t to_hours() const { return value_ / ZX_HOUR(1); }
+
+ private:
+ zx_duration_t value_ = 0;
+};
+
+class ticks final {
+ public:
+ constexpr ticks() = default;
+
+ explicit constexpr ticks(zx_ticks_t value) : value_(value) {}
+
+ // Constructs a tick object for the current tick counter in the system.
+ static ticks now() { return ticks(zx_ticks_get()); }
+
+ // Returns the number of ticks contained within one second.
+ static ticks per_second() { return ticks(zx_ticks_per_second()); }
+
+ // Acquires the number of ticks contained within this object.
+ constexpr zx_ticks_t get() const { return value_; }
+
+ static constexpr ticks infinite() { return ticks(INFINITE); }
+
+ static constexpr ticks infinite_past() { return ticks(INFINITE_PAST); }
+
+ constexpr ticks operator+(ticks other) const {
+ zx_ticks_t x = 0;
+
+ if (unlikely(add_overflow(value_, other.value_, &x))) {
+ if (x >= 0) {
+ return infinite_past();
+ } else {
+ return infinite();
+ }
+ }
+
+ return ticks(x);
+ }
+
+ constexpr ticks operator-(ticks other) const {
+ zx_ticks_t x = 0;
+
+ if (unlikely(sub_overflow(value_, other.value_, &x))) {
+ if (x >= 0) {
+ return infinite_past();
+ } else {
+ return infinite();
+ }
+ }
+
+ return ticks(x);
+ }
+
+ constexpr ticks operator*(uint64_t multiplier) const {
+ zx_ticks_t x = 0;
+
+ if (unlikely(mul_overflow(value_, multiplier, &x))) {
+ if (value_ < 0) {
+ return infinite_past();
+ } else {
+ return infinite();
+ }
+ }
+
+ return ticks(x);
+ }
+
+ constexpr ticks operator/(uint64_t divisor) const { return ticks(value_ / divisor); }
+
+ constexpr uint64_t operator/(ticks other) const { return value_ / other.value_; }
+
+ constexpr ticks operator%(uint64_t divisor) const { return ticks(value_ % divisor); }
+
+ constexpr uint64_t operator%(ticks other) const { return value_ % other.value_; }
+
+ constexpr ticks& operator+=(ticks other) {
+ *this = *this + other;
+ return *this;
+ }
+
+ constexpr ticks& operator-=(ticks other) {
+ *this = *this - other;
+ return *this;
+ }
+
+ constexpr ticks& operator*=(uint64_t multiplier) {
+ *this = *this * multiplier;
+ return *this;
+ }
+
+ constexpr ticks& operator/=(uint64_t divisor) {
+ value_ /= divisor;
+ return *this;
+ }
+
+ constexpr ticks& operator%=(uint64_t divisor) {
+ value_ %= divisor;
+ return *this;
+ }
+
+ constexpr bool operator==(ticks other) const { return value_ == other.value_; }
+ constexpr bool operator!=(ticks other) const { return value_ != other.value_; }
+ constexpr bool operator<(ticks other) const { return value_ < other.value_; }
+ constexpr bool operator<=(ticks other) const { return value_ <= other.value_; }
+ constexpr bool operator>(ticks other) const { return value_ > other.value_; }
+ constexpr bool operator>=(ticks other) const { return value_ >= other.value_; }
+
+ private:
+ static constexpr zx_ticks_t INFINITE = std::numeric_limits<zx_ticks_t>::max();
+ static constexpr zx_ticks_t INFINITE_PAST = std::numeric_limits<zx_ticks_t>::min();
+
+ zx_ticks_t value_ = 0;
+};
+
+template <zx_clock_t kClockId>
+class basic_time final {
+ public:
+ constexpr basic_time() = default;
+
+ explicit constexpr basic_time(zx_time_t value) : value_(value) {}
+
+ static constexpr basic_time<kClockId> infinite() {
+ return basic_time<kClockId>(ZX_TIME_INFINITE);
+ }
+
+ static constexpr basic_time<kClockId> infinite_past() {
+ return basic_time<kClockId>(ZX_TIME_INFINITE_PAST);
+ }
+
+ constexpr zx_time_t get() const { return value_; }
+
+ zx_time_t* get_address() { return &value_; }
+
+ constexpr duration operator-(basic_time<kClockId> other) const {
+ return duration(zx_time_sub_time(value_, other.value_));
+ }
+
+ constexpr basic_time<kClockId> operator+(duration delta) const {
+ return basic_time<kClockId>(zx_time_add_duration(value_, delta.get()));
+ }
+
+ constexpr basic_time<kClockId> operator-(duration delta) const {
+ return basic_time<kClockId>(zx_time_sub_duration(value_, delta.get()));
+ }
+
+ constexpr basic_time<kClockId>& operator+=(duration delta) {
+ value_ = zx_time_add_duration(value_, delta.get());
+ return *this;
+ }
+
+ constexpr basic_time<kClockId>& operator-=(duration delta) {
+ value_ = zx_time_sub_duration(value_, delta.get());
+ return *this;
+ }
+
+ constexpr bool operator==(basic_time<kClockId> other) const { return value_ == other.value_; }
+ constexpr bool operator!=(basic_time<kClockId> other) const { return value_ != other.value_; }
+ constexpr bool operator<(basic_time<kClockId> other) const { return value_ < other.value_; }
+ constexpr bool operator<=(basic_time<kClockId> other) const { return value_ <= other.value_; }
+ constexpr bool operator>(basic_time<kClockId> other) const { return value_ > other.value_; }
+ constexpr bool operator>=(basic_time<kClockId> other) const { return value_ >= other.value_; }
+
+ private:
+ zx_time_t value_ = 0;
+};
+
+template <zx_clock_t kClockId>
+constexpr basic_time<kClockId> operator+(duration delta, basic_time<kClockId> time) {
+ return time + delta;
+}
+
+using time = basic_time<ZX_CLOCK_MONOTONIC>;
+using time_utc = basic_time<ZX_CLOCK_UTC>;
+using time_thread = basic_time<ZX_CLOCK_THREAD>;
+
+constexpr inline duration nsec(int64_t n) { return duration(ZX_NSEC(n)); }
+
+constexpr inline duration usec(int64_t n) { return duration(ZX_USEC(n)); }
+
+constexpr inline duration msec(int64_t n) { return duration(ZX_MSEC(n)); }
+
+constexpr inline duration sec(int64_t n) { return duration(ZX_SEC(n)); }
+
+constexpr inline duration min(int64_t n) { return duration(ZX_MIN(n)); }
+
+constexpr inline duration hour(int64_t n) { return duration(ZX_HOUR(n)); }
+
+inline zx_status_t nanosleep(zx::time deadline) { return zx_nanosleep(deadline.get()); }
+
+inline time deadline_after(zx::duration nanoseconds) {
+ return time(zx_deadline_after(nanoseconds.get()));
+}
+
+} // namespace zx
+
+#endif // LIB_ZX_TIME_H_
diff --git a/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/timer.h b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/timer.h
new file mode 100644
index 0000000..c119fc0
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/timer.h
@@ -0,0 +1,45 @@
+// Copyright 2017 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.
+
+#ifndef LIB_ZX_TIMER_H_
+#define LIB_ZX_TIMER_H_
+
+#include <lib/zx/handle.h>
+#include <lib/zx/object.h>
+
+#include <zircon/types.h>
+
+namespace zx {
+
+class timer final : public object<timer> {
+ public:
+ static constexpr zx_obj_type_t TYPE = ZX_OBJ_TYPE_TIMER;
+
+ constexpr timer() = default;
+
+ explicit timer(zx_handle_t value) : object(value) {}
+
+ explicit timer(handle&& h) : object(h.release()) {}
+
+ timer(timer&& other) : object(other.release()) {}
+
+ timer& operator=(timer&& other) {
+ reset(other.release());
+ return *this;
+ }
+
+ static zx_status_t create(uint32_t options, zx_clock_t clock_id, timer* result);
+
+ zx_status_t set(zx::time deadline, zx::duration slack) const {
+ return zx_timer_set(get(), deadline.get(), slack.get());
+ }
+
+ zx_status_t cancel() const { return zx_timer_cancel(get()); }
+};
+
+using unowned_timer = unowned<timer>;
+
+} // namespace zx
+
+#endif // LIB_ZX_TIMER_H_
diff --git a/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/vcpu.h b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/vcpu.h
new file mode 100644
index 0000000..565d6fd
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/vcpu.h
@@ -0,0 +1,51 @@
+// Copyright 2018 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.
+
+#ifndef LIB_ZX_VCPU_H_
+#define LIB_ZX_VCPU_H_
+
+#include <lib/zx/guest.h>
+#include <lib/zx/handle.h>
+#include <lib/zx/object.h>
+#include <zircon/syscalls/port.h>
+
+namespace zx {
+
+class vcpu final : public object<vcpu> {
+ public:
+ static constexpr zx_obj_type_t TYPE = ZX_OBJ_TYPE_VCPU;
+
+ constexpr vcpu() = default;
+
+ explicit vcpu(zx_handle_t value) : object(value) {}
+
+ explicit vcpu(handle&& h) : object(h.release()) {}
+
+ vcpu(vcpu&& other) : object(other.release()) {}
+
+ vcpu& operator=(vcpu&& other) {
+ reset(other.release());
+ return *this;
+ }
+
+ static zx_status_t create(const guest& guest, uint32_t options, zx_gpaddr_t entry, vcpu* result);
+
+ zx_status_t resume(zx_port_packet_t* packet) const { return zx_vcpu_resume(get(), packet); }
+
+ zx_status_t interrupt(uint32_t interrupt) const { return zx_vcpu_interrupt(get(), interrupt); }
+
+ zx_status_t read_state(uint32_t kind, void* buf, size_t len) const {
+ return zx_vcpu_read_state(get(), kind, buf, len);
+ }
+
+ zx_status_t write_state(uint32_t kind, const void* buf, size_t len) const {
+ return zx_vcpu_write_state(get(), kind, buf, len);
+ }
+};
+
+using unowned_vcpu = unowned<vcpu>;
+
+} // namespace zx
+
+#endif // LIB_ZX_VCPU_H_
diff --git a/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/vmar.h b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/vmar.h
new file mode 100644
index 0000000..54a943c
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/vmar.h
@@ -0,0 +1,63 @@
+// Copyright 2016 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.
+
+#ifndef LIB_ZX_VMAR_H_
+#define LIB_ZX_VMAR_H_
+
+#include <lib/zx/object.h>
+#include <lib/zx/vmo.h>
+#include <zircon/process.h>
+
+namespace zx {
+
+// A wrapper for handles to VMARs. Note that vmar::~vmar() does not execute
+// vmar::destroy(), it just closes the handle.
+class vmar final : public object<vmar> {
+ public:
+ static constexpr zx_obj_type_t TYPE = ZX_OBJ_TYPE_VMAR;
+
+ constexpr vmar() = default;
+
+ explicit vmar(zx_handle_t value) : object(value) {}
+
+ explicit vmar(handle&& h) : object(h.release()) {}
+
+ vmar(vmar&& other) : vmar(other.release()) {}
+
+ vmar& operator=(vmar&& other) {
+ reset(other.release());
+ return *this;
+ }
+
+ zx_status_t map(size_t vmar_offset, const vmo& vmo_handle, uint64_t vmo_offset, size_t len,
+ zx_vm_option_t options, zx_vaddr_t* ptr) const {
+ return zx_vmar_map(get(), options, vmar_offset, vmo_handle.get(), vmo_offset, len, ptr);
+ }
+
+ zx_status_t unmap(uintptr_t address, size_t len) const {
+ return zx_vmar_unmap(get(), address, len);
+ }
+
+ zx_status_t protect(uintptr_t address, size_t len, zx_vm_option_t prot) const {
+ return zx_vmar_protect(get(), prot, address, len);
+ }
+
+ zx_status_t op_range(uint32_t op, uint64_t offset, uint64_t size, void* buffer,
+ size_t buffer_size) const {
+ return zx_vmar_op_range(get(), op, offset, size, buffer, buffer_size);
+ }
+
+ zx_status_t destroy() const { return zx_vmar_destroy(get()); }
+
+ zx_status_t allocate(size_t offset, size_t size, uint32_t options, vmar* child,
+ uintptr_t* child_addr) const;
+
+ static inline unowned<vmar> root_self() { return unowned<vmar>(zx_vmar_root_self()); }
+};
+
+using unowned_vmar = unowned<vmar>;
+
+} // namespace zx
+
+#endif // LIB_ZX_VMAR_H_
diff --git a/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/vmo.h b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/vmo.h
new file mode 100644
index 0000000..ae168a6
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/include/lib/zx/vmo.h
@@ -0,0 +1,84 @@
+// Copyright 2016 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.
+
+#ifndef LIB_ZX_VMO_H_
+#define LIB_ZX_VMO_H_
+
+#include <lib/zx/handle.h>
+#include <lib/zx/object.h>
+#include <lib/zx/resource.h>
+
+namespace zx {
+
+class bti;
+
+class vmo final : public object<vmo> {
+ public:
+ static constexpr zx_obj_type_t TYPE = ZX_OBJ_TYPE_VMO;
+
+ constexpr vmo() = default;
+
+ explicit vmo(zx_handle_t value) : object(value) {}
+
+ explicit vmo(handle&& h) : object(h.release()) {}
+
+ vmo(vmo&& other) : object(other.release()) {}
+
+ vmo& operator=(vmo&& other) {
+ reset(other.release());
+ return *this;
+ }
+
+ static zx_status_t create(uint64_t size, uint32_t options, vmo* result);
+ static zx_status_t create_contiguous(const bti& bti, size_t size, uint32_t alignment_log2,
+ vmo* result);
+ static zx_status_t create_physical(const resource& resource, zx_paddr_t paddr, size_t size,
+ vmo* result);
+
+ zx_status_t read(void* data, uint64_t offset, size_t len) const {
+ return zx_vmo_read(get(), data, offset, len);
+ }
+
+ zx_status_t write(const void* data, uint64_t offset, size_t len) const {
+ return zx_vmo_write(get(), data, offset, len);
+ }
+
+ zx_status_t get_size(uint64_t* size) const { return zx_vmo_get_size(get(), size); }
+
+ zx_status_t set_size(uint64_t size) const { return zx_vmo_set_size(get(), size); }
+
+ zx_status_t create_child(uint32_t options, uint64_t offset, uint64_t size, vmo* result) const {
+ // Allow for the caller aliasing |result| to |this|.
+ vmo h;
+ zx_status_t status =
+ zx_vmo_create_child(get(), options, offset, size, h.reset_and_get_address());
+ result->reset(h.release());
+ return status;
+ }
+
+ zx_status_t op_range(uint32_t op, uint64_t offset, uint64_t size, void* buffer,
+ size_t buffer_size) const {
+ return zx_vmo_op_range(get(), op, offset, size, buffer, buffer_size);
+ }
+
+ zx_status_t set_cache_policy(uint32_t cache_policy) const {
+ return zx_vmo_set_cache_policy(get(), cache_policy);
+ }
+
+ zx_status_t replace_as_executable(const resource& vmex, vmo* result) {
+ zx_handle_t h = ZX_HANDLE_INVALID;
+ zx_status_t status = zx_vmo_replace_as_executable(value_, vmex.get(), &h);
+ // We store ZX_HANDLE_INVALID to value_ before calling reset on result
+ // in case result == this.
+ value_ = ZX_HANDLE_INVALID;
+ result->reset(h);
+ return status;
+ }
+};
+
+using unowned_vmo = unowned<vmo>;
+
+} // namespace zx
+
+#endif // LIB_ZX_VMO_H_
diff --git a/third_party/fuchsia-sdk/pkg/zx/interrupt.cc b/third_party/fuchsia-sdk/pkg/zx/interrupt.cc
new file mode 100644
index 0000000..7cb0013
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/interrupt.cc
@@ -0,0 +1,18 @@
+// Copyright 2018 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.
+
+#include <lib/zx/interrupt.h>
+
+#include <zircon/syscalls.h>
+
+namespace zx {
+
+zx_status_t interrupt::create(const resource& resource, uint32_t vector, uint32_t options,
+ interrupt* result) {
+ // Assume |result| uses a distinct container from |resource|, due to
+ // strict aliasing.
+ return zx_interrupt_create(resource.get(), vector, options, result->reset_and_get_address());
+}
+
+} // namespace zx
diff --git a/third_party/fuchsia-sdk/pkg/zx/iommu.cc b/third_party/fuchsia-sdk/pkg/zx/iommu.cc
new file mode 100644
index 0000000..a059eea
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/iommu.cc
@@ -0,0 +1,16 @@
+// Copyright 2018 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.
+
+#include <lib/zx/iommu.h>
+
+#include <zircon/syscalls.h>
+
+namespace zx {
+
+zx_status_t iommu::create(const resource& resource, uint32_t type, const void* desc,
+ size_t desc_size, iommu* result) {
+ return zx_iommu_create(resource.get(), type, desc, desc_size, result->reset_and_get_address());
+}
+
+} // namespace zx
diff --git a/third_party/fuchsia-sdk/pkg/zx/job.cc b/third_party/fuchsia-sdk/pkg/zx/job.cc
new file mode 100644
index 0000000..2a63ab0
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/job.cc
@@ -0,0 +1,26 @@
+// Copyright 2016 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.
+
+#include <lib/zx/job.h>
+
+#include <lib/zx/process.h>
+#include <zircon/syscalls.h>
+
+namespace zx {
+
+zx_status_t job::create(const job& parent, uint32_t flags, job* result) {
+ // Allow for aliasing of the same container to |result| and |parent|.
+ job h;
+ zx_status_t status = zx_job_create(parent.get(), flags, h.reset_and_get_address());
+ result->reset(h.release());
+ return status;
+}
+
+zx_status_t job::get_child(uint64_t koid, zx_rights_t rights, process* result) const {
+ // Assume |result| and |this| are distinct containers, due to strict
+ // aliasing.
+ return zx_object_get_child(value_, koid, rights, result->reset_and_get_address());
+}
+
+} // namespace zx
diff --git a/third_party/fuchsia-sdk/pkg/zx/meta.json b/third_party/fuchsia-sdk/pkg/zx/meta.json
new file mode 100644
index 0000000..855540c
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/meta.json
@@ -0,0 +1,66 @@
+{
+ "banjo_deps": [],
+ "deps": [],
+ "fidl_deps": [],
+ "headers": [
+ "pkg/zx/include/lib/zx/bti.h",
+ "pkg/zx/include/lib/zx/channel.h",
+ "pkg/zx/include/lib/zx/clock.h",
+ "pkg/zx/include/lib/zx/debuglog.h",
+ "pkg/zx/include/lib/zx/event.h",
+ "pkg/zx/include/lib/zx/eventpair.h",
+ "pkg/zx/include/lib/zx/exception.h",
+ "pkg/zx/include/lib/zx/fifo.h",
+ "pkg/zx/include/lib/zx/guest.h",
+ "pkg/zx/include/lib/zx/handle.h",
+ "pkg/zx/include/lib/zx/interrupt.h",
+ "pkg/zx/include/lib/zx/iommu.h",
+ "pkg/zx/include/lib/zx/job.h",
+ "pkg/zx/include/lib/zx/object.h",
+ "pkg/zx/include/lib/zx/object_traits.h",
+ "pkg/zx/include/lib/zx/pager.h",
+ "pkg/zx/include/lib/zx/pmt.h",
+ "pkg/zx/include/lib/zx/port.h",
+ "pkg/zx/include/lib/zx/process.h",
+ "pkg/zx/include/lib/zx/profile.h",
+ "pkg/zx/include/lib/zx/resource.h",
+ "pkg/zx/include/lib/zx/socket.h",
+ "pkg/zx/include/lib/zx/stream.h",
+ "pkg/zx/include/lib/zx/suspend_token.h",
+ "pkg/zx/include/lib/zx/task.h",
+ "pkg/zx/include/lib/zx/thread.h",
+ "pkg/zx/include/lib/zx/time.h",
+ "pkg/zx/include/lib/zx/timer.h",
+ "pkg/zx/include/lib/zx/vcpu.h",
+ "pkg/zx/include/lib/zx/vmar.h",
+ "pkg/zx/include/lib/zx/vmo.h"
+ ],
+ "include_dir": "pkg/zx/include",
+ "name": "zx",
+ "root": "pkg/zx",
+ "sources": [
+ "pkg/zx/bti.cc",
+ "pkg/zx/channel.cc",
+ "pkg/zx/debuglog.cc",
+ "pkg/zx/event.cc",
+ "pkg/zx/eventpair.cc",
+ "pkg/zx/fifo.cc",
+ "pkg/zx/guest.cc",
+ "pkg/zx/interrupt.cc",
+ "pkg/zx/iommu.cc",
+ "pkg/zx/job.cc",
+ "pkg/zx/pager.cc",
+ "pkg/zx/port.cc",
+ "pkg/zx/process.cc",
+ "pkg/zx/profile.cc",
+ "pkg/zx/resource.cc",
+ "pkg/zx/socket.cc",
+ "pkg/zx/stream.cc",
+ "pkg/zx/thread.cc",
+ "pkg/zx/timer.cc",
+ "pkg/zx/vcpu.cc",
+ "pkg/zx/vmar.cc",
+ "pkg/zx/vmo.cc"
+ ],
+ "type": "cc_source_library"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/pkg/zx/pager.cc b/third_party/fuchsia-sdk/pkg/zx/pager.cc
new file mode 100644
index 0000000..b6131d6
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/pager.cc
@@ -0,0 +1,13 @@
+// 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.
+
+#include <lib/zx/pager.h>
+
+namespace zx {
+
+zx_status_t pager::create(uint32_t options, pager* result) {
+ return zx_pager_create(options, result->reset_and_get_address());
+}
+
+} // namespace zx
diff --git a/third_party/fuchsia-sdk/pkg/zx/port.cc b/third_party/fuchsia-sdk/pkg/zx/port.cc
new file mode 100644
index 0000000..7999684
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/port.cc
@@ -0,0 +1,15 @@
+// Copyright 2016 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.
+
+#include <lib/zx/port.h>
+
+#include <zircon/syscalls.h>
+
+namespace zx {
+
+zx_status_t port::create(uint32_t options, port* result) {
+ return zx_port_create(options, result->reset_and_get_address());
+}
+
+} // namespace zx
diff --git a/third_party/fuchsia-sdk/pkg/zx/process.cc b/third_party/fuchsia-sdk/pkg/zx/process.cc
new file mode 100644
index 0000000..d17fd3a
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/process.cc
@@ -0,0 +1,34 @@
+// Copyright 2016 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.
+
+#include <lib/zx/process.h>
+
+#include <zircon/syscalls.h>
+
+#include <lib/zx/job.h>
+#include <lib/zx/thread.h>
+#include <lib/zx/vmar.h>
+
+namespace zx {
+
+zx_status_t process::create(const job& job, const char* name, uint32_t name_len, uint32_t flags,
+ process* proc, vmar* vmar) {
+ // Assume |proc|, |vmar| and |job| must refer to different containers, due
+ // to strict aliasing.
+ return zx_process_create(job.get(), name, name_len, flags, proc->reset_and_get_address(),
+ vmar->reset_and_get_address());
+}
+
+zx_status_t process::start(const thread& thread_handle, uintptr_t entry, uintptr_t stack,
+ handle arg_handle, uintptr_t arg2) const {
+ return zx_process_start(get(), thread_handle.get(), entry, stack, arg_handle.release(), arg2);
+}
+
+zx_status_t process::get_child(uint64_t koid, zx_rights_t rights, thread* result) const {
+ // Assume |result| and |this| are distinct containers, due to strict
+ // aliasing.
+ return zx_object_get_child(value_, koid, rights, result->reset_and_get_address());
+}
+
+} // namespace zx
diff --git a/third_party/fuchsia-sdk/pkg/zx/profile.cc b/third_party/fuchsia-sdk/pkg/zx/profile.cc
new file mode 100644
index 0000000..40a424d
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/profile.cc
@@ -0,0 +1,17 @@
+// Copyright 2018 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.
+
+#include <lib/zx/profile.h>
+
+#include <zircon/syscalls.h>
+#include <zircon/syscalls/profile.h>
+
+namespace zx {
+
+zx_status_t profile::create(const job& job, uint32_t options, const zx_profile_info_t* info,
+ profile* result) {
+ return zx_profile_create(job.get(), options, info, result->reset_and_get_address());
+}
+
+} // namespace zx
diff --git a/third_party/fuchsia-sdk/pkg/zx/resource.cc b/third_party/fuchsia-sdk/pkg/zx/resource.cc
new file mode 100644
index 0000000..b4c2ec5
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/resource.cc
@@ -0,0 +1,20 @@
+// Copyright 2018 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.
+
+#include <lib/zx/resource.h>
+
+#include <zircon/syscalls.h>
+
+namespace zx {
+
+zx_status_t resource::create(const resource& parent, uint32_t options, uint64_t base, size_t len,
+ const char* name, size_t namelen, resource* result) {
+ resource h;
+ zx_status_t status = zx_resource_create(parent.get(), options, base, len, name, namelen,
+ h.reset_and_get_address());
+ result->reset(h.release());
+ return status;
+}
+
+} // namespace zx
diff --git a/third_party/fuchsia-sdk/pkg/zx/socket.cc b/third_party/fuchsia-sdk/pkg/zx/socket.cc
new file mode 100644
index 0000000..2d07ac7
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/socket.cc
@@ -0,0 +1,23 @@
+// Copyright 2016 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.
+
+#include <lib/zx/socket.h>
+
+#include <zircon/syscalls.h>
+
+namespace zx {
+
+zx_status_t socket::create(uint32_t flags, socket* endpoint0, socket* endpoint1) {
+ // Ensure aliasing of both out parameters to the same container
+ // has a well-defined result, and does not leak.
+ socket h0;
+ socket h1;
+ zx_status_t status =
+ zx_socket_create(flags, h0.reset_and_get_address(), h1.reset_and_get_address());
+ endpoint0->reset(h0.release());
+ endpoint1->reset(h1.release());
+ return status;
+}
+
+} // namespace zx
diff --git a/third_party/fuchsia-sdk/pkg/zx/stream.cc b/third_party/fuchsia-sdk/pkg/zx/stream.cc
new file mode 100644
index 0000000..f5b12cb
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/stream.cc
@@ -0,0 +1,17 @@
+// Copyright 2020 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.
+
+#include <lib/zx/stream.h>
+#include <zircon/syscalls.h>
+
+namespace zx {
+
+zx_status_t stream::create(uint32_t options, const vmo& vmo_handle, zx_off_t seek,
+ stream* out_stream) {
+ // Assume |out_stream| and |vmo_handle| must refer to different containers, due
+ // to strict aliasing.
+ return zx_stream_create(options, vmo_handle.get(), seek, out_stream->reset_and_get_address());
+}
+
+} // namespace zx
diff --git a/third_party/fuchsia-sdk/pkg/zx/thread.cc b/third_party/fuchsia-sdk/pkg/zx/thread.cc
new file mode 100644
index 0000000..9856c04
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/thread.cc
@@ -0,0 +1,20 @@
+// Copyright 2016 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.
+
+#include <lib/zx/thread.h>
+
+#include <zircon/syscalls.h>
+
+#include <lib/zx/process.h>
+
+namespace zx {
+
+zx_status_t thread::create(const process& process, const char* name, uint32_t name_len,
+ uint32_t flags, thread* result) {
+ // Assume |result| and |process| must refer to different containers, due
+ // to strict aliasing.
+ return zx_thread_create(process.get(), name, name_len, flags, result->reset_and_get_address());
+}
+
+} // namespace zx
diff --git a/third_party/fuchsia-sdk/pkg/zx/timer.cc b/third_party/fuchsia-sdk/pkg/zx/timer.cc
new file mode 100644
index 0000000..895e20c
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/timer.cc
@@ -0,0 +1,15 @@
+// Copyright 2017 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.
+
+#include <lib/zx/timer.h>
+
+#include <zircon/syscalls.h>
+
+namespace zx {
+
+zx_status_t timer::create(uint32_t options, zx_clock_t clock_id, timer* result) {
+ return zx_timer_create(options, clock_id, result->reset_and_get_address());
+}
+
+} // namespace zx
diff --git a/third_party/fuchsia-sdk/pkg/zx/vcpu.cc b/third_party/fuchsia-sdk/pkg/zx/vcpu.cc
new file mode 100644
index 0000000..1951adb
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/vcpu.cc
@@ -0,0 +1,17 @@
+// Copyright 2018 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.
+
+#include <lib/zx/vcpu.h>
+
+#include <zircon/syscalls.h>
+
+namespace zx {
+
+zx_status_t vcpu::create(const guest& guest, uint32_t options, zx_gpaddr_t entry, vcpu* vcpu) {
+ // Assume |guest| and |vcpu| must refer to different containers, due to
+ // strict aliasing.
+ return zx_vcpu_create(guest.get(), options, entry, vcpu->reset_and_get_address());
+}
+
+} // namespace zx
diff --git a/third_party/fuchsia-sdk/pkg/zx/vmar.cc b/third_party/fuchsia-sdk/pkg/zx/vmar.cc
new file mode 100644
index 0000000..cfb4fb4
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/vmar.cc
@@ -0,0 +1,21 @@
+// Copyright 2016 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.
+
+#include <lib/zx/vmar.h>
+
+#include <zircon/syscalls.h>
+
+namespace zx {
+
+zx_status_t vmar::allocate(size_t offset, size_t size, zx_vm_option_t options, vmar* child,
+ uintptr_t* child_addr) const {
+ // Allow for aliasing of |child| to the same container as |this|.
+ vmar h;
+ zx_status_t status =
+ zx_vmar_allocate(get(), options, offset, size, h.reset_and_get_address(), child_addr);
+ child->reset(h.release());
+ return status;
+}
+
+} // namespace zx
diff --git a/third_party/fuchsia-sdk/pkg/zx/vmo.cc b/third_party/fuchsia-sdk/pkg/zx/vmo.cc
new file mode 100644
index 0000000..9902a2e
--- /dev/null
+++ b/third_party/fuchsia-sdk/pkg/zx/vmo.cc
@@ -0,0 +1,26 @@
+// Copyright 2016 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.
+
+#include <lib/zx/vmo.h>
+#include <lib/zx/bti.h>
+
+#include <zircon/syscalls.h>
+
+namespace zx {
+
+zx_status_t vmo::create(uint64_t size, uint32_t options, vmo* result) {
+ return zx_vmo_create(size, options, result->reset_and_get_address());
+}
+
+zx_status_t vmo::create_contiguous(const bti& bti, size_t size, uint32_t alignment_log2,
+ vmo* result) {
+ return zx_vmo_create_contiguous(bti.get(), size, alignment_log2, result->reset_and_get_address());
+}
+
+zx_status_t vmo::create_physical(const resource& resource, zx_paddr_t paddr, size_t size,
+ vmo* result) {
+ return zx_vmo_create_physical(resource.get(), paddr, size, result->reset_and_get_address());
+}
+
+} // namespace zx
diff --git a/third_party/fuchsia-sdk/readme-meta.json b/third_party/fuchsia-sdk/readme-meta.json
new file mode 100644
index 0000000..f017d22
--- /dev/null
+++ b/third_party/fuchsia-sdk/readme-meta.json
@@ -0,0 +1,8 @@
+{
+ "docs": [
+ "README.GN.md",
+ ".gitignore"
+ ],
+ "name": "readme",
+ "type": "documentation"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/arm64/bootserver b/third_party/fuchsia-sdk/tools/arm64/bootserver
new file mode 100755
index 0000000..efdf403
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/arm64/bootserver
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/arm64/bootserver-meta.json b/third_party/fuchsia-sdk/tools/arm64/bootserver-meta.json
new file mode 100644
index 0000000..60be479
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/arm64/bootserver-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/arm64/bootserver"
+ ],
+ "name": "bootserver",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/arm64/dev_finder b/third_party/fuchsia-sdk/tools/arm64/dev_finder
new file mode 100755
index 0000000..c978cd1
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/arm64/dev_finder
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/arm64/dev_finder-meta.json b/third_party/fuchsia-sdk/tools/arm64/dev_finder-meta.json
new file mode 100644
index 0000000..92bb80d
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/arm64/dev_finder-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/arm64/dev_finder"
+ ],
+ "name": "dev_finder",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/arm64/device-finder b/third_party/fuchsia-sdk/tools/arm64/device-finder
new file mode 100755
index 0000000..c978cd1
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/arm64/device-finder
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/arm64/device-finder-meta.json b/third_party/fuchsia-sdk/tools/arm64/device-finder-meta.json
new file mode 100644
index 0000000..b46d986
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/arm64/device-finder-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/arm64/device-finder"
+ ],
+ "name": "device-finder",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/arm64/far b/third_party/fuchsia-sdk/tools/arm64/far
new file mode 100755
index 0000000..dcef211
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/arm64/far
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/arm64/far-meta.json b/third_party/fuchsia-sdk/tools/arm64/far-meta.json
new file mode 100644
index 0000000..850473e
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/arm64/far-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/arm64/far"
+ ],
+ "name": "far",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/arm64/fidl-format b/third_party/fuchsia-sdk/tools/arm64/fidl-format
new file mode 100755
index 0000000..6f0c157
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/arm64/fidl-format
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/arm64/fidl-format-meta.json b/third_party/fuchsia-sdk/tools/arm64/fidl-format-meta.json
new file mode 100644
index 0000000..c1dc371
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/arm64/fidl-format-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/arm64/fidl-format"
+ ],
+ "name": "fidl-format",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/arm64/fidlc b/third_party/fuchsia-sdk/tools/arm64/fidlc
new file mode 100755
index 0000000..0215b31
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/arm64/fidlc
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/arm64/fidlc-meta.json b/third_party/fuchsia-sdk/tools/arm64/fidlc-meta.json
new file mode 100644
index 0000000..ecb5bf5
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/arm64/fidlc-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/arm64/fidlc"
+ ],
+ "name": "fidlc",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/arm64/fidlgen b/third_party/fuchsia-sdk/tools/arm64/fidlgen
new file mode 100755
index 0000000..b8643e3
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/arm64/fidlgen
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/arm64/fidlgen-meta.json b/third_party/fuchsia-sdk/tools/arm64/fidlgen-meta.json
new file mode 100644
index 0000000..21b208e
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/arm64/fidlgen-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/arm64/fidlgen"
+ ],
+ "name": "fidlgen",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/arm64/fvm b/third_party/fuchsia-sdk/tools/arm64/fvm
new file mode 100755
index 0000000..aaad589
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/arm64/fvm
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/arm64/fvm-meta.json b/third_party/fuchsia-sdk/tools/arm64/fvm-meta.json
new file mode 100644
index 0000000..73b81ff
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/arm64/fvm-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/arm64/fvm"
+ ],
+ "name": "fvm",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/arm64/loglistener b/third_party/fuchsia-sdk/tools/arm64/loglistener
new file mode 100755
index 0000000..e8c61ed
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/arm64/loglistener
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/arm64/loglistener-meta.json b/third_party/fuchsia-sdk/tools/arm64/loglistener-meta.json
new file mode 100644
index 0000000..65cb625
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/arm64/loglistener-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/arm64/loglistener"
+ ],
+ "name": "loglistener",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/arm64/merkleroot b/third_party/fuchsia-sdk/tools/arm64/merkleroot
new file mode 100755
index 0000000..dc9fac1
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/arm64/merkleroot
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/arm64/merkleroot-meta.json b/third_party/fuchsia-sdk/tools/arm64/merkleroot-meta.json
new file mode 100644
index 0000000..b68db69
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/arm64/merkleroot-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/arm64/merkleroot"
+ ],
+ "name": "merkleroot",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/arm64/minfs b/third_party/fuchsia-sdk/tools/arm64/minfs
new file mode 100755
index 0000000..447dc27
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/arm64/minfs
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/arm64/minfs-meta.json b/third_party/fuchsia-sdk/tools/arm64/minfs-meta.json
new file mode 100644
index 0000000..1b225ed
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/arm64/minfs-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/arm64/minfs"
+ ],
+ "name": "minfs",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/arm64/pm b/third_party/fuchsia-sdk/tools/arm64/pm
new file mode 100755
index 0000000..b39c2c3
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/arm64/pm
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/arm64/pm-meta.json b/third_party/fuchsia-sdk/tools/arm64/pm-meta.json
new file mode 100644
index 0000000..8f0645d
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/arm64/pm-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/arm64/pm"
+ ],
+ "name": "pm",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/arm64/symbolize b/third_party/fuchsia-sdk/tools/arm64/symbolize
new file mode 100755
index 0000000..96a83fe
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/arm64/symbolize
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/arm64/symbolize-meta.json b/third_party/fuchsia-sdk/tools/arm64/symbolize-meta.json
new file mode 100644
index 0000000..63efd45
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/arm64/symbolize-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/arm64/symbolize"
+ ],
+ "name": "symbolize",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/arm64/zbi b/third_party/fuchsia-sdk/tools/arm64/zbi
new file mode 100755
index 0000000..3b1baef
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/arm64/zbi
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/arm64/zbi-meta.json b/third_party/fuchsia-sdk/tools/arm64/zbi-meta.json
new file mode 100644
index 0000000..1189c1c
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/arm64/zbi-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/arm64/zbi"
+ ],
+ "name": "zbi",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/bootserver b/third_party/fuchsia-sdk/tools/bootserver
new file mode 100755
index 0000000..f425723
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/bootserver
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/bootserver-meta.json b/third_party/fuchsia-sdk/tools/bootserver-meta.json
new file mode 100644
index 0000000..0cbb5b9
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/bootserver-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/bootserver"
+ ],
+ "name": "bootserver",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/cmc b/third_party/fuchsia-sdk/tools/cmc
new file mode 100755
index 0000000..a8ff66f
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/cmc
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/cmc-meta.json b/third_party/fuchsia-sdk/tools/cmc-meta.json
new file mode 100644
index 0000000..8d55752
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/cmc-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/cmc"
+ ],
+ "name": "cmc",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/dart b/third_party/fuchsia-sdk/tools/dart
new file mode 100755
index 0000000..feb4bec
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/dart
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/dart_kernel_compiler-meta.json b/third_party/fuchsia-sdk/tools/dart_kernel_compiler-meta.json
new file mode 100644
index 0000000..6f85a11
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/dart_kernel_compiler-meta.json
@@ -0,0 +1,13 @@
+{
+ "files": [
+ "tools/dart",
+ "tools/dart_prebuilts/dart_runner/platform_strong.dill",
+ "tools/dart_prebuilts/flutter_runner/platform_strong.dill",
+ "tools/dart_prebuilts/kernel_compiler.snapshot",
+ "tools/dart_prebuilts/frontend_server_tool.snapshot"
+ ],
+ "name": "dart_kernel_compiler",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/dart_prebuilts/dart_runner/platform_strong.dill b/third_party/fuchsia-sdk/tools/dart_prebuilts/dart_runner/platform_strong.dill
new file mode 100644
index 0000000..a3b6d03
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/dart_prebuilts/dart_runner/platform_strong.dill
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/dart_prebuilts/flutter_runner/platform_strong.dill b/third_party/fuchsia-sdk/tools/dart_prebuilts/flutter_runner/platform_strong.dill
new file mode 100644
index 0000000..156ff5f
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/dart_prebuilts/flutter_runner/platform_strong.dill
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/dart_prebuilts/frontend_server_tool.snapshot b/third_party/fuchsia-sdk/tools/dart_prebuilts/frontend_server_tool.snapshot
new file mode 100644
index 0000000..9cbb34f
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/dart_prebuilts/frontend_server_tool.snapshot
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/dart_prebuilts/kernel_compiler.snapshot b/third_party/fuchsia-sdk/tools/dart_prebuilts/kernel_compiler.snapshot
new file mode 100644
index 0000000..374b1cc
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/dart_prebuilts/kernel_compiler.snapshot
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/dev_finder b/third_party/fuchsia-sdk/tools/dev_finder
new file mode 100755
index 0000000..ac76f2f
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/dev_finder
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/dev_finder-meta.json b/third_party/fuchsia-sdk/tools/dev_finder-meta.json
new file mode 100644
index 0000000..b99f74e
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/dev_finder-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/dev_finder"
+ ],
+ "name": "dev_finder",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/device-finder b/third_party/fuchsia-sdk/tools/device-finder
new file mode 100755
index 0000000..ac76f2f
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/device-finder
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/device-finder-meta.json b/third_party/fuchsia-sdk/tools/device-finder-meta.json
new file mode 100644
index 0000000..c1c40ed
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/device-finder-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/device-finder"
+ ],
+ "name": "device-finder",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/far b/third_party/fuchsia-sdk/tools/far
new file mode 100755
index 0000000..378d8e3
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/far
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/far-meta.json b/third_party/fuchsia-sdk/tools/far-meta.json
new file mode 100644
index 0000000..2fb7302
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/far-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/far"
+ ],
+ "name": "far",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/fidl-format b/third_party/fuchsia-sdk/tools/fidl-format
new file mode 100755
index 0000000..d44218d
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/fidl-format
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/fidl-format-meta.json b/third_party/fuchsia-sdk/tools/fidl-format-meta.json
new file mode 100644
index 0000000..6db07d1
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/fidl-format-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/fidl-format"
+ ],
+ "name": "fidl-format",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/fidlc b/third_party/fuchsia-sdk/tools/fidlc
new file mode 100755
index 0000000..048d398
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/fidlc
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/fidlc-meta.json b/third_party/fuchsia-sdk/tools/fidlc-meta.json
new file mode 100644
index 0000000..683db92
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/fidlc-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/fidlc"
+ ],
+ "name": "fidlc",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/fidlcat b/third_party/fuchsia-sdk/tools/fidlcat
new file mode 100755
index 0000000..638b8a7
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/fidlcat
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/fidlcat-meta.json b/third_party/fuchsia-sdk/tools/fidlcat-meta.json
new file mode 100644
index 0000000..a375e23
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/fidlcat-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/fidlcat"
+ ],
+ "name": "fidlcat",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/fidlgen b/third_party/fuchsia-sdk/tools/fidlgen
new file mode 100755
index 0000000..5e10f59
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/fidlgen
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/fidlgen-meta.json b/third_party/fuchsia-sdk/tools/fidlgen-meta.json
new file mode 100644
index 0000000..497de51
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/fidlgen-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/fidlgen"
+ ],
+ "name": "fidlgen",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/fidlgen_dart b/third_party/fuchsia-sdk/tools/fidlgen_dart
new file mode 100755
index 0000000..f7a41cd
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/fidlgen_dart
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/fidlgen_dart-meta.json b/third_party/fuchsia-sdk/tools/fidlgen_dart-meta.json
new file mode 100644
index 0000000..e5e962a
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/fidlgen_dart-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/fidlgen_dart"
+ ],
+ "name": "fidlgen_dart",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/fvm b/third_party/fuchsia-sdk/tools/fvm
new file mode 100755
index 0000000..99cdbd3
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/fvm
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/fvm-meta.json b/third_party/fuchsia-sdk/tools/fvm-meta.json
new file mode 100644
index 0000000..5bfae72
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/fvm-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/fvm"
+ ],
+ "name": "fvm",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/gen_snapshot-meta.json b/third_party/fuchsia-sdk/tools/gen_snapshot-meta.json
new file mode 100644
index 0000000..cfd92e3
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/gen_snapshot-meta.json
@@ -0,0 +1,15 @@
+{
+ "name": "gen_snapshot",
+ "root": "tools",
+ "target_files": {
+ "arm64": [
+ "tools/gen_snapshot.arm64",
+ "tools/gen_snapshot_product.arm64"
+ ],
+ "x64": [
+ "tools/gen_snapshot.x64",
+ "tools/gen_snapshot_product.x64"
+ ]
+ },
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/gen_snapshot.arm64 b/third_party/fuchsia-sdk/tools/gen_snapshot.arm64
new file mode 100755
index 0000000..3d527d8
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/gen_snapshot.arm64
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/gen_snapshot.x64 b/third_party/fuchsia-sdk/tools/gen_snapshot.x64
new file mode 100755
index 0000000..9871a81
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/gen_snapshot.x64
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/gen_snapshot_product.arm64 b/third_party/fuchsia-sdk/tools/gen_snapshot_product.arm64
new file mode 100755
index 0000000..fa3efc4
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/gen_snapshot_product.arm64
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/gen_snapshot_product.x64 b/third_party/fuchsia-sdk/tools/gen_snapshot_product.x64
new file mode 100755
index 0000000..b05c88a
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/gen_snapshot_product.x64
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/loglistener b/third_party/fuchsia-sdk/tools/loglistener
new file mode 100755
index 0000000..8cb9e5c
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/loglistener
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/loglistener-meta.json b/third_party/fuchsia-sdk/tools/loglistener-meta.json
new file mode 100644
index 0000000..ff3fe1f
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/loglistener-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/loglistener"
+ ],
+ "name": "loglistener",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/merkleroot b/third_party/fuchsia-sdk/tools/merkleroot
new file mode 100755
index 0000000..a38a646
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/merkleroot
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/merkleroot-meta.json b/third_party/fuchsia-sdk/tools/merkleroot-meta.json
new file mode 100644
index 0000000..137fa29
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/merkleroot-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/merkleroot"
+ ],
+ "name": "merkleroot",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/minfs b/third_party/fuchsia-sdk/tools/minfs
new file mode 100755
index 0000000..43efb37
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/minfs
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/minfs-meta.json b/third_party/fuchsia-sdk/tools/minfs-meta.json
new file mode 100644
index 0000000..4e61b8e
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/minfs-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/minfs"
+ ],
+ "name": "minfs",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/pm b/third_party/fuchsia-sdk/tools/pm
new file mode 100755
index 0000000..e266cec
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/pm
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/pm-meta.json b/third_party/fuchsia-sdk/tools/pm-meta.json
new file mode 100644
index 0000000..14b0031
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/pm-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/pm"
+ ],
+ "name": "pm",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/symbolize b/third_party/fuchsia-sdk/tools/symbolize
new file mode 100755
index 0000000..23ec6c2
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/symbolize
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/symbolize-meta.json b/third_party/fuchsia-sdk/tools/symbolize-meta.json
new file mode 100644
index 0000000..5b8c978
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/symbolize-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/symbolize"
+ ],
+ "name": "symbolize",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/x64/bootserver b/third_party/fuchsia-sdk/tools/x64/bootserver
new file mode 100755
index 0000000..f425723
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/bootserver
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/x64/bootserver-meta.json b/third_party/fuchsia-sdk/tools/x64/bootserver-meta.json
new file mode 100644
index 0000000..5fe2c88
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/bootserver-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/x64/bootserver"
+ ],
+ "name": "bootserver",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/x64/cmc b/third_party/fuchsia-sdk/tools/x64/cmc
new file mode 100755
index 0000000..a8ff66f
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/cmc
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/x64/cmc-meta.json b/third_party/fuchsia-sdk/tools/x64/cmc-meta.json
new file mode 100644
index 0000000..ace9737
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/cmc-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/x64/cmc"
+ ],
+ "name": "cmc",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/x64/dev_finder b/third_party/fuchsia-sdk/tools/x64/dev_finder
new file mode 100755
index 0000000..ac76f2f
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/dev_finder
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/x64/dev_finder-meta.json b/third_party/fuchsia-sdk/tools/x64/dev_finder-meta.json
new file mode 100644
index 0000000..b3c20b5
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/dev_finder-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/x64/dev_finder"
+ ],
+ "name": "dev_finder",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/x64/device-finder b/third_party/fuchsia-sdk/tools/x64/device-finder
new file mode 100755
index 0000000..ac76f2f
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/device-finder
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/x64/device-finder-meta.json b/third_party/fuchsia-sdk/tools/x64/device-finder-meta.json
new file mode 100644
index 0000000..d669e27
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/device-finder-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/x64/device-finder"
+ ],
+ "name": "device-finder",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/x64/far b/third_party/fuchsia-sdk/tools/x64/far
new file mode 100755
index 0000000..378d8e3
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/far
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/x64/far-meta.json b/third_party/fuchsia-sdk/tools/x64/far-meta.json
new file mode 100644
index 0000000..24e4330
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/far-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/x64/far"
+ ],
+ "name": "far",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/x64/fidl-format b/third_party/fuchsia-sdk/tools/x64/fidl-format
new file mode 100755
index 0000000..d44218d
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/fidl-format
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/x64/fidl-format-meta.json b/third_party/fuchsia-sdk/tools/x64/fidl-format-meta.json
new file mode 100644
index 0000000..93050c3
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/fidl-format-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/x64/fidl-format"
+ ],
+ "name": "fidl-format",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/x64/fidlc b/third_party/fuchsia-sdk/tools/x64/fidlc
new file mode 100755
index 0000000..048d398
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/fidlc
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/x64/fidlc-meta.json b/third_party/fuchsia-sdk/tools/x64/fidlc-meta.json
new file mode 100644
index 0000000..29e1970
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/fidlc-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/x64/fidlc"
+ ],
+ "name": "fidlc",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/x64/fidlcat b/third_party/fuchsia-sdk/tools/x64/fidlcat
new file mode 100755
index 0000000..638b8a7
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/fidlcat
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/x64/fidlcat-meta.json b/third_party/fuchsia-sdk/tools/x64/fidlcat-meta.json
new file mode 100644
index 0000000..1fdc6e7
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/fidlcat-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/x64/fidlcat"
+ ],
+ "name": "fidlcat",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/x64/fidlgen b/third_party/fuchsia-sdk/tools/x64/fidlgen
new file mode 100755
index 0000000..5e10f59
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/fidlgen
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/x64/fidlgen-meta.json b/third_party/fuchsia-sdk/tools/x64/fidlgen-meta.json
new file mode 100644
index 0000000..0b86cd4
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/fidlgen-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/x64/fidlgen"
+ ],
+ "name": "fidlgen",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/x64/fvm b/third_party/fuchsia-sdk/tools/x64/fvm
new file mode 100755
index 0000000..99cdbd3
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/fvm
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/x64/fvm-meta.json b/third_party/fuchsia-sdk/tools/x64/fvm-meta.json
new file mode 100644
index 0000000..392744f
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/fvm-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/x64/fvm"
+ ],
+ "name": "fvm",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/x64/loglistener b/third_party/fuchsia-sdk/tools/x64/loglistener
new file mode 100755
index 0000000..8cb9e5c
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/loglistener
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/x64/loglistener-meta.json b/third_party/fuchsia-sdk/tools/x64/loglistener-meta.json
new file mode 100644
index 0000000..3d1d821
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/loglistener-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/x64/loglistener"
+ ],
+ "name": "loglistener",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/x64/merkleroot b/third_party/fuchsia-sdk/tools/x64/merkleroot
new file mode 100755
index 0000000..a38a646
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/merkleroot
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/x64/merkleroot-meta.json b/third_party/fuchsia-sdk/tools/x64/merkleroot-meta.json
new file mode 100644
index 0000000..5b9216d
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/merkleroot-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/x64/merkleroot"
+ ],
+ "name": "merkleroot",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/x64/minfs b/third_party/fuchsia-sdk/tools/x64/minfs
new file mode 100755
index 0000000..43efb37
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/minfs
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/x64/minfs-meta.json b/third_party/fuchsia-sdk/tools/x64/minfs-meta.json
new file mode 100644
index 0000000..faddc6d
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/minfs-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/x64/minfs"
+ ],
+ "name": "minfs",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/x64/pm b/third_party/fuchsia-sdk/tools/x64/pm
new file mode 100755
index 0000000..e266cec
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/pm
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/x64/pm-meta.json b/third_party/fuchsia-sdk/tools/x64/pm-meta.json
new file mode 100644
index 0000000..97d50d9
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/pm-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/x64/pm"
+ ],
+ "name": "pm",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/x64/symbolize b/third_party/fuchsia-sdk/tools/x64/symbolize
new file mode 100755
index 0000000..23ec6c2
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/symbolize
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/x64/symbolize-meta.json b/third_party/fuchsia-sdk/tools/x64/symbolize-meta.json
new file mode 100644
index 0000000..47ab693
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/symbolize-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/x64/symbolize"
+ ],
+ "name": "symbolize",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/x64/zbi b/third_party/fuchsia-sdk/tools/x64/zbi
new file mode 100755
index 0000000..bb22073
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/zbi
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/x64/zbi-meta.json b/third_party/fuchsia-sdk/tools/x64/zbi-meta.json
new file mode 100644
index 0000000..320bb21
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/zbi-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/x64/zbi"
+ ],
+ "name": "zbi",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/x64/zxdb b/third_party/fuchsia-sdk/tools/x64/zxdb
new file mode 100755
index 0000000..6b04415
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/zxdb
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/x64/zxdb-meta.json b/third_party/fuchsia-sdk/tools/x64/zxdb-meta.json
new file mode 100644
index 0000000..f641923
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/x64/zxdb-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/x64/zxdb"
+ ],
+ "name": "zxdb",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/zbi b/third_party/fuchsia-sdk/tools/zbi
new file mode 100755
index 0000000..bb22073
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/zbi
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/zbi-meta.json b/third_party/fuchsia-sdk/tools/zbi-meta.json
new file mode 100644
index 0000000..7277d59
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/zbi-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/zbi"
+ ],
+ "name": "zbi",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file
diff --git a/third_party/fuchsia-sdk/tools/zxdb b/third_party/fuchsia-sdk/tools/zxdb
new file mode 100755
index 0000000..6b04415
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/zxdb
Binary files differ
diff --git a/third_party/fuchsia-sdk/tools/zxdb-meta.json b/third_party/fuchsia-sdk/tools/zxdb-meta.json
new file mode 100644
index 0000000..48a8de8
--- /dev/null
+++ b/third_party/fuchsia-sdk/tools/zxdb-meta.json
@@ -0,0 +1,9 @@
+{
+ "files": [
+ "tools/zxdb"
+ ],
+ "name": "zxdb",
+ "root": "tools",
+ "target_files": {},
+ "type": "host_tool"
+}
\ No newline at end of file