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_, &copy.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