From 411533bcfbe491afd5c7facdf2d3cd85b8e476e7 Mon Sep 17 00:00:00 2001
From: Drew Fisher <zarvox@google.com>
Date: Wed, 8 May 2019 23:24:45 +0000
Subject: [PATCH] [zxcrypt] statically link most dependencies

This change:

* splits //zircon/system/ulib/zxcrypt into two libraries, so that the
  FDIO dependencies don't leak into the driver, and vice versa
* reduces the set of dependencies of the driver to those actually
  required
* cuts out some transitive dependencies on libraries that are not used
  at all by dependencies of zxcrypt

Tests: added some assert_no_deps in the build, and checked the
dependencies of the new artifact:

(15:24:39) zarvox@zarvox-linux ~/fuchsia/out $ readelf -d ./default.zircon/user-x64-gcc.shlib/obj/system/dev/block/zxcrypt/zxcrypt.so | grep Shared
 0x0000000000000001 (NEEDED)             Shared library: [libzircon.so]
 0x0000000000000001 (NEEDED)             Shared library: [libdriver.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so]

DNO-492 #comment zxcrypt.so links most things statically

Change-Id: Ic7d179ae77af6e1efbaa10624ecadcd8b27134f9
---
 zircon/system/core/devmgr/fshost/BUILD.gn   |  2 +-
 zircon/system/dev/block/zxcrypt/BUILD.gn    | 21 +++++++++-
 zircon/system/ulib/BUILD.gn                 |  3 +-
 zircon/system/ulib/crypto/BUILD.gn          |  1 -
 zircon/system/ulib/paver/BUILD.gn           |  2 +-
 zircon/system/ulib/pretty/BUILD.gn          |  6 +--
 zircon/system/ulib/unittest/BUILD.gn        |  1 +
 zircon/system/ulib/zxcrypt/BUILD.gn         | 44 +++++++++++++++++----
 zircon/system/utest/zxcrypt/BUILD.gn        |  2 +-
 zircon/third_party/ulib/uboringssl/BUILD.gn |  1 -
 10 files changed, 62 insertions(+), 21 deletions(-)

diff --git a/zircon/system/core/devmgr/fshost/BUILD.gn b/zircon/system/core/devmgr/fshost/BUILD.gn
index b766170bfe2..0f169c9c1cd 100644
--- a/zircon/system/core/devmgr/fshost/BUILD.gn
+++ b/zircon/system/core/devmgr/fshost/BUILD.gn
@@ -63,7 +63,7 @@ source_set("block-watcher") {
     "$zx/system/ulib/zircon",
     "$zx/system/ulib/zx",
     "$zx/system/ulib/zxcpp",
-    "$zx/system/ulib/zxcrypt",
+    "$zx/system/ulib/zxcrypt:zxcrypt-fdio",
   ]
 }
 
diff --git a/zircon/system/dev/block/zxcrypt/BUILD.gn b/zircon/system/dev/block/zxcrypt/BUILD.gn
index 50b5d08ab23..6a1a4e820b4 100644
--- a/zircon/system/dev/block/zxcrypt/BUILD.gn
+++ b/zircon/system/dev/block/zxcrypt/BUILD.gn
@@ -12,13 +12,18 @@ driver("zxcrypt") {
     "worker.cpp",
   ]
   configs += [ "$zx/public/gn/config:integer-paranoia" ]
+
+  # Until library loading is fully async, dynamically linking libraries can
+  # deadlock block device drviers. All dependencies for zxcrypt should be
+  # static or already linked by the devhost.  We consider libc, libzircon, and
+  # libdriver safe to depend on dynamically here.
   deps = [
     "$zx/system/banjo/ddk.protocol.block",
     "$zx/system/banjo/ddk.protocol.block.partition",
     "$zx/system/banjo/ddk.protocol.block.volume",
     "$zx/system/fidl/fuchsia-hardware-zxcrypt:c",
     "$zx/system/ulib/bitmap",
-    "$zx/system/ulib/crypto",
+    "$zx/system/ulib/crypto:zircon-crypto.static",
     "$zx/system/ulib/ddk",
     "$zx/system/ulib/ddktl",
     "$zx/system/ulib/fbl",
@@ -26,6 +31,18 @@ driver("zxcrypt") {
     "$zx/system/ulib/zircon",
     "$zx/system/ulib/zx",
     "$zx/system/ulib/zxcpp",
-    "$zx/system/ulib/zxcrypt",
+    "$zx/system/ulib/zxcrypt:zxcrypt-dev.static",
+  ]
+
+  # Make sure we don't accidentally pull in a couple of easily-added dynamic
+  # library dependencies.
+  assert_no_deps = [
+    "$zx/system/ulib/trace-engine",
+    "$zx/system/ulib/crypto:zircon-crypto",
+    # Some day, we'd also like to be able to assert we don't pull in fdio here,
+    # but it is pulled in transitively by //$zx/system/ulib/driver, which is
+    # needed by //$zx/system/ulib/zxcrypt-dev for the symbol
+    # |device_get_protocol|.
+    #"$zx/system/ulib/fdio",
   ]
 }
diff --git a/zircon/system/ulib/BUILD.gn b/zircon/system/ulib/BUILD.gn
index 8615d6b1fe7..e2addc857f1 100644
--- a/zircon/system/ulib/BUILD.gn
+++ b/zircon/system/ulib/BUILD.gn
@@ -135,7 +135,8 @@ group("ulib") {
     "zircon-internal",
     "zx",
     "zxcpp",
-    "zxcrypt",
+    "zxcrypt:zxcrypt-dev",
+    "zxcrypt:zxcrypt-fdio",
     "zxio",
     "zxs",
     "zxtest",
diff --git a/zircon/system/ulib/crypto/BUILD.gn b/zircon/system/ulib/crypto/BUILD.gn
index f0546052faf..99b118600a4 100644
--- a/zircon/system/ulib/crypto/BUILD.gn
+++ b/zircon/system/ulib/crypto/BUILD.gn
@@ -33,7 +33,6 @@ library("zircon-crypto") {
   deps = [
     "$zx/system/ulib/explicit-memory",
     "$zx/system/ulib/fbl",
-    "$zx/system/ulib/fdio",
     "$zx/system/ulib/zircon",
     "$zx/system/ulib/zircon-internal",
     "$zx/system/ulib/zxcpp",
diff --git a/zircon/system/ulib/paver/BUILD.gn b/zircon/system/ulib/paver/BUILD.gn
index eecea0846ad..0a1d4135e7d 100644
--- a/zircon/system/ulib/paver/BUILD.gn
+++ b/zircon/system/ulib/paver/BUILD.gn
@@ -38,7 +38,7 @@ library("paver") {
     "$zx/system/ulib/zircon",
     "$zx/system/ulib/zx",
     "$zx/system/ulib/zxcpp",
-    "$zx/system/ulib/zxcrypt",
+    "$zx/system/ulib/zxcrypt:zxcrypt-fdio",
     "$zx/third_party/ulib/cksum",
     "$zx/third_party/ulib/lz4",
     "$zx/third_party/ulib/uboringssl",
diff --git a/zircon/system/ulib/pretty/BUILD.gn b/zircon/system/ulib/pretty/BUILD.gn
index 0acc3648cfc..068a64a7915 100644
--- a/zircon/system/ulib/pretty/BUILD.gn
+++ b/zircon/system/ulib/pretty/BUILD.gn
@@ -17,11 +17,6 @@ library("pretty") {
   if (!is_kernel) {
     sources += [ "hexdump.c" ]
   }
-  if (!is_kernel && is_fuchsia) {
-    deps = [
-      "$zx/system/ulib/fdio",
-    ]
-  }
 }
 
 test("pretty-test") {
@@ -30,6 +25,7 @@ test("pretty-test") {
   ]
   deps = [
     ":pretty",
+    "$zx/system/ulib/fdio",
     "$zx/system/ulib/unittest",
   ]
 }
diff --git a/zircon/system/ulib/unittest/BUILD.gn b/zircon/system/ulib/unittest/BUILD.gn
index 6000aea9b89..ad35626106f 100644
--- a/zircon/system/ulib/unittest/BUILD.gn
+++ b/zircon/system/ulib/unittest/BUILD.gn
@@ -15,6 +15,7 @@ library("unittest") {
     "watchdog.cpp",
   ]
   deps = [
+    "$zx/system/ulib/fdio",
     "$zx/system/ulib/pretty",
   ]
   if (is_fuchsia) {
diff --git a/zircon/system/ulib/zxcrypt/BUILD.gn b/zircon/system/ulib/zxcrypt/BUILD.gn
index 11e3a354588..ae17c7662f4 100644
--- a/zircon/system/ulib/zxcrypt/BUILD.gn
+++ b/zircon/system/ulib/zxcrypt/BUILD.gn
@@ -2,37 +2,65 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-library("zxcrypt") {
+library("zxcrypt-dev") {
   shared = true
+  static = true
   sources = [
     "ddk-volume.cpp",
-    "fdio-volume.cpp",
     "volume.cpp",
   ]
+
   public_deps = [
-    # <zxcrypt/volume.h> has #include <crypto/aead.h>.
+    # <zxcrypt/volume.h> has #include <crypto/aead.h> (among others).
     "$zx/system/ulib/crypto:headers",
 
-    # <zxcrypt/volume.h> has #include <ddk/device.h>.
+    # <zxcrypt/ddk-volume.h> has #include <ddk/device.h>.
     "$zx/system/ulib/ddk:headers",
   ]
+
   configs += [ "$zx/public/gn/config:integer-paranoia" ]
+
+  # To minimize the set of libraries that we depend on that need to be loaded
+  # from /boot/lib in early boot, we statically link most of our dependencies.
   deps = [
     "$zx/system/banjo/ddk.protocol.block",
     "$zx/system/banjo/ddk.protocol.block.volume",
+    "$zx/system/ulib/crypto:zircon-crypto.static",
+    "$zx/system/ulib/ddk",
+    "$zx/system/ulib/driver",
+    "$zx/system/ulib/fbl",
+    "$zx/system/ulib/fs-management:headers", # only used for zxcrypt_magic
+    "$zx/system/ulib/sync",
+    "$zx/system/ulib/zircon",
+    "$zx/system/ulib/zircon-internal",
+    "$zx/system/ulib/zx",
+    "$zx/system/ulib/zxcpp",
+    "$zx/third_party/ulib/uboringssl",
+  ]
+}
+
+library("zxcrypt-fdio") {
+  shared = true
+  sources = [
+    "fdio-volume.cpp",
+    "volume.cpp",
+  ]
+  public_deps = [
+    # <zxcrypt/volume.h> has #include <crypto/aead.h> (among others).
+    "$zx/system/ulib/crypto:headers",
+  ]
+  configs += [ "$zx/public/gn/config:integer-paranoia" ]
+  deps = [
     "$zx/system/fidl/fuchsia-device:c",
     "$zx/system/fidl/fuchsia-hardware-block:c",
     "$zx/system/fidl/fuchsia-hardware-block-volume:c",
     "$zx/system/fidl/fuchsia-hardware-zxcrypt:c",
     "$zx/system/ulib/crypto",
-    "$zx/system/ulib/ddk",
-    "$zx/system/ulib/driver",
     "$zx/system/ulib/fbl",
     "$zx/system/ulib/fdio",
-    "$zx/system/ulib/fs-management",
+    "$zx/system/ulib/fs-management:headers", # only used for zxcrypt_magic
     "$zx/system/ulib/fzl",
     "$zx/system/ulib/kms-stateless",
-    "$zx/system/ulib/pretty",
     "$zx/system/ulib/ramdevice-client:static",
     "$zx/system/ulib/sync",
     "$zx/system/ulib/zircon",
diff --git a/zircon/system/utest/zxcrypt/BUILD.gn b/zircon/system/utest/zxcrypt/BUILD.gn
index 9f13ad199dc..661d0ebe533 100644
--- a/zircon/system/utest/zxcrypt/BUILD.gn
+++ b/zircon/system/utest/zxcrypt/BUILD.gn
@@ -36,7 +36,7 @@ test("zxcrypt") {
     "$zx/system/ulib/zircon-internal",
     "$zx/system/ulib/zx",
     "$zx/system/ulib/zxcpp",
-    "$zx/system/ulib/zxcrypt",
+    "$zx/system/ulib/zxcrypt:zxcrypt-fdio",
     "$zx/third_party/ulib/cryptolib",
     "$zx/third_party/ulib/uboringssl",
   ]
diff --git a/zircon/third_party/ulib/uboringssl/BUILD.gn b/zircon/third_party/ulib/uboringssl/BUILD.gn
index 853b4a0feec..6bd4b7a0cc0 100644
--- a/zircon/third_party/ulib/uboringssl/BUILD.gn
+++ b/zircon/third_party/ulib/uboringssl/BUILD.gn
@@ -28,7 +28,6 @@ library("uboringssl") {
 
     if (is_fuchsia) {
       deps = [
-        "$zx/system/ulib/fdio",
         "$zx/system/ulib/zircon",
       ]
     } else {
-- 
GitLab