<pre style='margin:0'>
Andrea D'Amore (anddam) pushed a commit to branch master
in repository macports-ports.

</pre>
<p><a href="https://github.com/macports/macports-ports/commit/e72a14ed15c184f6c43b6d701c70b07b224b0fee">https://github.com/macports/macports-ports/commit/e72a14ed15c184f6c43b6d701c70b07b224b0fee</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit e72a14ed15c184f6c43b6d701c70b07b224b0fee
</span>Author: Jeremy Huddleston Sequoia <jeremyhu@macports.org>
AuthorDate: Sun Dec 18 00:47:33 2016 -0800

<span style='display:block; white-space:pre;color:#404040;'>    ld64: Bump to 274.1 (modulo tapiv2/libtapi support)
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@macports.org>
</span>---
 devel/ld64/Portfile                             |   27 +-
 devel/ld64/files/{Makefile-264 => Makefile-274} |    0
 devel/ld64/files/PR-29679726.patch              | 1120 +++++++++++++++++++++++
 devel/ld64/files/PR-29723276.patch              |   12 +
 4 files changed, 1146 insertions(+), 13 deletions(-)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/devel/ld64/Portfile b/devel/ld64/Portfile
</span><span style='display:block; white-space:pre;color:#808080;'>index dcdd2ee..13add04 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/devel/ld64/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/devel/ld64/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -6,7 +6,7 @@ PortGroup               compiler_blacklist_versions 1.0
</span> name                    ld64
 epoch                   2
 version                 2
<span style='display:block; white-space:pre;background:#ffe0e0;'>-set dyld_version        360.18
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+set dyld_version        421.2
</span> categories              devel
 platforms               darwin
 maintainers             jeremyhu
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -19,12 +19,12 @@ description             ld64 is the new mach-o linker
</span> long_description        ld64 combines several object files and libraries, \
                         resolves references, and produces an ouput file.
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-checksums           ld64-97-standalone-libunwind-headers.patch \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+checksums           dyld-421.2.tar.gz \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    rmd160  8985a77c70b6018f456634f89142670834489a4d \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    sha256  e922c4e78af8f7af14dd158f1db986f8eb260403e7a0dc67fa35279d2cfdceb7 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    ld64-97-standalone-libunwind-headers.patch \
</span>                     rmd160  f6da71e097aa61b1055b3fdc12cd39aafed5f492 \
                     sha256  370d02757ea628b5dd145c099e42fc4eb88cc09cf459a59e32d14bbc9b4a105e \
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                    dyld-360.18.tar.gz \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    rmd160  aeb3144549ec276b028b979680f5056da4d63747 \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    sha256  a5bec8c2e3bded111aec7e447b35c110038e822f95e11e55b9a4d331fbaeff08 \
</span>                     ld64-97.17.tar.gz \
                     rmd160  d52df7d7f741c8bedd29cbac73dbb9db992b4795 \
                     sha256  02bd46af0809eaa415d096d7d41c3e8e7d80f7d8d181840866fb87f036b4e089 \
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -37,9 +37,9 @@ checksums           ld64-97-standalone-libunwind-headers.patch \
</span>                     ld64-236.3.tar.gz \
                     rmd160  6a3f44aa9ae57a60d2cff5b3d47be7972ad83029 \
                     sha256  8ef36729b643201081ab45ebd8586ede8f9968bc17614b679a940faa82875ca6 \
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                    ld64-264.3.102.tar.gz \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    rmd160  c8169a8dd591989abdf45c0834397891ec72b458 \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    sha256  307f73678a3e5c9ed4d1bcf77da7399d84efac32916c5df6cd477c3b5c36f953
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    ld64-274.1.tar.gz \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    rmd160  c86030f9d6d44a6a53d262952d9508b5eff46353 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    sha256  6cbe886717de833789fa562ec4889ebf9136ae5f7573d17d39836d3f5755b7ab
</span> 
 
 subport ld64-97 {
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -159,15 +159,14 @@ subport ld64-236 {
</span> }
 
 subport ld64-latest {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    # XCode 7.3.1
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    version             264.3.102
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    revision            4
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # XCode 8.1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    version             274.1
</span> 
     # https://trac.macports.org/ticket/43737
     # https://trac.macports.org/ticket/50130
     compiler.blacklist-append *gcc* {clang < 300}
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    set makefile        "Makefile-264"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set makefile        "Makefile-274"
</span>     set ld64_ver        latest
 
     patchfiles-append \
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -177,7 +176,9 @@ subport ld64-latest {
</span>         ld64-136-i386-badAddress.patch \
         ld64-ppc-9610466.patch \
         PR-49393.patch \
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        PR-29117886.patch
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        PR-29117886.patch \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        PR-29679726.patch \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        PR-29723276.patch
</span> 
     depends_lib-append port:libcxx
     configure.cxx_stdlib libc++
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/devel/ld64/files/Makefile-264 b/devel/ld64/files/Makefile-274
</span>similarity index 100%
rename from devel/ld64/files/Makefile-264
rename to devel/ld64/files/Makefile-274
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/devel/ld64/files/PR-29679726.patch b/devel/ld64/files/PR-29679726.patch
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 0000000..4fa5871
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/devel/ld64/files/PR-29679726.patch
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,1120 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+From 08ebdd8bde8f21872f1ba716eaf887ef1628d738 Mon Sep 17 00:00:00 2001
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+From: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Date: Sun, 18 Dec 2016 00:24:11 -0800
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Subject: [PATCH] Revert textstub_dylib_file.cpp back to ld64-264.3.102 version
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+---
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ld64.xcodeproj/project.pbxproj         |   6 -
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/ld/Options.cpp                     |  35 +-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/ld/parsers/generic_dylib_file.hpp  |  63 +++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/ld/parsers/macho_dylib_file.cpp    |  64 ---
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/ld/parsers/textstub_dylib_file.cpp | 717 +++++++++++++++++++++++++++------
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 5 files changed, 658 insertions(+), 227 deletions(-)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git ld64.xcodeproj/project.pbxproj ld64.xcodeproj/project.pbxproj
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 600aeac9..db20e783 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- ld64.xcodeproj/project.pbxproj
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ ld64.xcodeproj/project.pbxproj
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1284,8 +1284,6 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                   "-Wl,-lazy_library,$(DT_TOOLCHAIN_DIR)/usr/lib/libLTO.dylib",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                   "@$(DERIVED_FILE_DIR)/linkExtras",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                   "-Wl,-exported_symbol,__mh_execute_header",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  "-L$(DT_TOOLCHAIN_DIR)/usr/lib",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  "-ltapi",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           PREBINDING = NO;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           PRODUCT_NAME = ld;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1358,8 +1356,6 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                   "-Wl,-lazy_library,$(DT_TOOLCHAIN_DIR)/usr/lib/libLTO.dylib",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                   "@$(DERIVED_FILE_DIR)/linkExtras",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                   "-Wl,-exported_symbol,__mh_execute_header",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  "-L$(DT_TOOLCHAIN_DIR)/usr/lib",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  "-ltapi",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           PREBINDING = NO;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           PRODUCT_NAME = ld;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1577,8 +1573,6 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                   "-Wl,-lazy_library,$(DT_TOOLCHAIN_DIR)/usr/lib/libLTO.dylib",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                   "@$(DERIVED_FILE_DIR)/linkExtras",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                   "-Wl,-exported_symbol,__mh_execute_header",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  "-L$(DT_TOOLCHAIN_DIR)/usr/lib",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  "-ltapi",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           PREBINDING = NO;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           PRODUCT_NAME = ld;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/ld/Options.cpp src/ld/Options.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index b7e17091..227b0d84 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/ld/Options.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/ld/Options.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -34,7 +34,6 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <spawn.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <cxxabi.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <Availability.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#include <tapi/tapi.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <vector>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <map>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -832,13 +831,7 @@ bool Options::findFile(const std::string &path, const std::vector<std::string> &
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           bool found = tbdInfo.checkFileExists(*this, newPath.c_str());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if ( fTraceDylibSearching )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   printf("[Logging for XBS]%sfound library: '%s'\n", (found ? " " : " not "), newPath.c_str());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          if ( found )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  // If we found a text-based stub file, check if it should be used.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  if ( !tbdInfo.missing() ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          if (tapi::LinkerInterfaceFile::shouldPreferTextBasedStubFile(tbdInfo.path)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if ( found ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   result = tbdInfo;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   return true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -848,31 +841,10 @@ bool Options::findFile(const std::string &path, const std::vector<std::string> &
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           bool found = dylibInfo.checkFileExists(*this, path.c_str());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if ( fTraceDylibSearching )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   printf("[Logging for XBS]%sfound library: '%s'\n", (found ? " " : " not "), path.c_str());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  // There is only a text-based stub file.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  if ( !tbdInfo.missing() && dylibInfo.missing() ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          result = tbdInfo;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          return true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  // There is only a dynamic library file.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  else if ( tbdInfo.missing() && !dylibInfo.missing() ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          result = dylibInfo;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          return true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  // There are both - a text-based stub file and a dynamic library file.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  else if ( !tbdInfo.missing() && !dylibInfo.missing() ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          // If the files are still in synv we can use and should use the text-based stub file.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          if (tapi::LinkerInterfaceFile::areEquivalent(tbdInfo.path, dylibInfo.path)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  result = tbdInfo;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          // Otherwise issue a warning and fall-back to the dynamic library file.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  warning("text-based stub file %s and library file %s are out of sync. Falling back to library file for linking.", tbdInfo.path, dylibInfo.path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if ( found ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   result = dylibInfo;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  return true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          return true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   return false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -3959,7 +3931,6 @@ void Options::buildSearchPaths(int argc, const char* argv[])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           const char* ltoVers = lto::version();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           if ( ltoVers != NULL )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                   fprintf(stderr, "LTO support using: %s\n", ltoVers);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                          fprintf(stderr, "TAPI support using: %s\n", tapi::Version::getFullVersionAsString().c_str());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           exit(0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/ld/parsers/generic_dylib_file.hpp src/ld/parsers/generic_dylib_file.hpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 529e4ab6..d581ab37 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/ld/parsers/generic_dylib_file.hpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/ld/parsers/generic_dylib_file.hpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -191,6 +191,7 @@ private:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ protected:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   bool                                            isPublicLocation(const char* path) const;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void                                            addSymbol(const char* name, bool weak = false, bool tlv = false, pint_t address = 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ private:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   ld::Section                                                     _importProxySection;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -479,6 +480,68 @@ bool File<A>::isPublicLocation(const char* path) const
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   return false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++template <typename A>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void File<A>::addSymbol(const char* name, bool weakDef, bool tlv, pint_t address)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  // symbols that start with $ld$ are meta-data to the static linker
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  // <rdar://problem/5182537> need way for ld and dyld to see different exported symbols in a dylib
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if ( strncmp(name, "$ld$", 4) == 0 ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          //    $ld$ <action> $ <condition> $ <symbol-name>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          const char* symAction = &name[4];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          const char* symCond = strchr(symAction, '$');
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if ( symCond != nullptr ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  char curOSVers[16];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  sprintf(curOSVers, "$os%d.%d$", (this->_linkMinOSVersion >> 16), ((this->_linkMinOSVersion >> 8) & 0xFF));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  if ( strncmp(symCond, curOSVers, strlen(curOSVers)) == 0 ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          const char* symName = strchr(&symCond[1], '$');
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          if ( symName != nullptr ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  ++symName;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  if ( strncmp(symAction, "hide$", 5) == 0 ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                          if ( this->_s_logHashtable )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                                  fprintf(stderr, "  adding %s to ignore set for %s\n", symName, this->path());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                          this->_ignoreExports.insert(strdup(symName));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                          return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  else if ( strncmp(symAction, "add$", 4) == 0 ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                          this->addSymbol(symName, weakDef);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                          return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  else if ( strncmp(symAction, "weak$", 5) == 0 ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                          if ( !this->_allowWeakImports )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                                  this->_ignoreExports.insert(strdup(symName));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  else if ( strncmp(symAction, "install_name$", 13) == 0 ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                          this->_dylibInstallPath = symName;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                          this->_installPathOverride = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                          // <rdar://problem/14448206> CoreGraphics redirects to ApplicationServices, but with wrong compat version
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                          if ( strcmp(this->_dylibInstallPath, "/System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices") == 0 )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                                  this->_dylibCompatibilityVersion = Options::parseVersionNumber32("1.0");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                          return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  else if ( strncmp(symAction, "compatibility_version$", 22) == 0 ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                          this->_dylibCompatibilityVersion = Options::parseVersionNumber32(symName);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                          return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                          warning("bad symbol action: %s in dylib %s", name, this->path());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  warning("bad symbol condition: %s in dylib %s", name, this->path());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  // add symbol as possible export if we are not supposed to ignore it
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if ( this->_ignoreExports.count(name) == 0 ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          AtomAndWeak bucket = { nullptr, weakDef, tlv, address };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if ( this->_s_logHashtable )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  fprintf(stderr, "  adding %s to hash table for %s\n", name, this->path());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          this->_atoms[strdup(name)] = bucket;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ // <rdar://problem/5529626> If only weak_import symbols are used, linker should use LD_LOAD_WEAK_DYLIB
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ template <typename A>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ bool File<A>::allSymbolsAreWeakImported() const
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/ld/parsers/macho_dylib_file.cpp src/ld/parsers/macho_dylib_file.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 16d3f5d7..a8233055 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/ld/parsers/macho_dylib_file.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/ld/parsers/macho_dylib_file.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -70,7 +70,6 @@ public:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ private:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   using P = typename A::P;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   using E = typename A::P::E;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  using pint_t = typename A::P::uint_t;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   void                            addDyldFastStub();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   void                            buildExportHashTableFromExportInfo(const macho_dyld_info_command<P>* dyldInfo,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -78,7 +77,6 @@ private:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   void                            buildExportHashTableFromSymbolTable(const macho_dysymtab_command<P>* dynamicInfo,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                                                                                           const macho_nlist<P>* symbolTable, const char* strings,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                                                                                           const uint8_t* fileContent);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  void                            addSymbol(const char* name, bool weakDef = false, bool tlv = false, pint_t address = 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   static const char*      objCInfoSegmentName();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   static const char*      objCInfoSectionName();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -526,68 +524,6 @@ void File<A>::buildExportHashTableFromExportInfo(const macho_dyld_info_command<P
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-template <typename A>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-void File<A>::addSymbol(const char* name, bool weakDef, bool tlv, pint_t address)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  // symbols that start with $ld$ are meta-data to the static linker
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  // <rdar://problem/5182537> need way for ld and dyld to see different exported symbols in a dylib
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  if ( strncmp(name, "$ld$", 4) == 0 ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          //    $ld$ <action> $ <condition> $ <symbol-name>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          const char* symAction = &name[4];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          const char* symCond = strchr(symAction, '$');
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          if ( symCond != nullptr ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  char curOSVers[16];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  sprintf(curOSVers, "$os%d.%d$", (this->_linkMinOSVersion >> 16), ((this->_linkMinOSVersion >> 8) & 0xFF));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  if ( strncmp(symCond, curOSVers, strlen(curOSVers)) == 0 ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                          const char* symName = strchr(&symCond[1], '$');
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                          if ( symName != nullptr ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  ++symName;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  if ( strncmp(symAction, "hide$", 5) == 0 ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                          if ( this->_s_logHashtable )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                                  fprintf(stderr, "  adding %s to ignore set for %s\n", symName, this->path());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                          this->_ignoreExports.insert(strdup(symName));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                          return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  else if ( strncmp(symAction, "add$", 4) == 0 ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                          this->addSymbol(symName, weakDef);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                          return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  else if ( strncmp(symAction, "weak$", 5) == 0 ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                          if ( !this->_allowWeakImports )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                                  this->_ignoreExports.insert(strdup(symName));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  else if ( strncmp(symAction, "install_name$", 13) == 0 ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                          this->_dylibInstallPath = symName;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                          this->_installPathOverride = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                          // <rdar://problem/14448206> CoreGraphics redirects to ApplicationServices, but with wrong compat version
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                          if ( strcmp(this->_dylibInstallPath, "/System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices") == 0 )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                                  this->_dylibCompatibilityVersion = Options::parseVersionNumber32("1.0");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                          return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  else if ( strncmp(symAction, "compatibility_version$", 22) == 0 ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                          this->_dylibCompatibilityVersion = Options::parseVersionNumber32(symName);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                          return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                          warning("bad symbol action: %s in dylib %s", name, this->path());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                          }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  warning("bad symbol condition: %s in dylib %s", name, this->path());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  // add symbol as possible export if we are not supposed to ignore it
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  if ( this->_ignoreExports.count(name) == 0 ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          typename Base::AtomAndWeak bucket = { nullptr, weakDef, tlv, address };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          if ( this->_s_logHashtable )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  fprintf(stderr, "  adding %s to hash table for %s\n", name, this->path());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          this->_atoms[strdup(name)] = bucket;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ template <>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void File<x86_64>::addDyldFastStub()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/ld/parsers/textstub_dylib_file.cpp src/ld/parsers/textstub_dylib_file.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 58544625..74dbcd7c 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/ld/parsers/textstub_dylib_file.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/ld/parsers/textstub_dylib_file.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -25,7 +25,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <sys/param.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <sys/mman.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#include <tapi/tapi.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <vector>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "Architectures.hpp"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -35,6 +35,469 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "generic_dylib_file.hpp"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "textstub_dylib_file.hpp"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++namespace {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++///
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/// A token is a light-weight reference to the content of an nmap'ed file. It
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/// doesn't own the data and it doesn't make a copy of it. The referenced data
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/// is only valid as long as the file is mapped in.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++///
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++class Token {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  const char* _p;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  size_t _size;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  int compareMemory(const char* lhs, const char* rhs, size_t size) const {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if (size == 0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  return 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          return ::memcmp(lhs, rhs, size);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++public:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  Token() : _p(nullptr), _size(0) {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  Token(const char* p) : _p(p), _size(0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if (p)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  _size = ::strlen(p);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  Token(const char* p, size_t s) : _p(p), _size(s) {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  const char* data() const { return _p; }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  size_t size() const { return _size; }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::string str() const { return std::string(_p, _size); }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  bool empty() const { return _size == 0; }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  bool operator==(Token other) const {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if (_size != other._size)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  return false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          return compareMemory(_p, other._p, _size) == 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  bool operator!=(Token other) const {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          return !(*this == other);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++///
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/// Simple text-based dynamic library file tokenizer.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++///
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++class Tokenizer {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  const char* _start;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  const char* _current;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  const char* _end;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  Token _currentToken;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void fetchNextToken();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void scanToNextToken();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void skip(unsigned distance) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          _current += distance;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          assert(_current <= _end && "Skipped past the end");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  const char* skipLineBreak(const char* pos) const;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  bool isDelimiter(const char* pos) const;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++public:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  Tokenizer(const char* data, uint64_t size) : _start(data), _current(data), _end(data + size) {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void reset() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          _current = _start;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          fetchNextToken();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  Token peek() { return _currentToken; }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  Token next() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          Token token = peek();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          fetchNextToken();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          return token;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++const char* Tokenizer::skipLineBreak(const char* pos) const
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if ( pos == _end )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          return pos;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  // Carriage return.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if ( *pos == 0x0D ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          // line feed.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if ( pos + 1 != _end && *(pos + 1) == 0x0A)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  return pos + 2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          return pos + 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  // line feed.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if ( *pos == 0x0A )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          return pos + 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return pos;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void Tokenizer::scanToNextToken() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  while (true) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          while ( isDelimiter(_current) )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  skip(1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          const char* i = skipLineBreak(_current);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if ( i == _current )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          _current = i;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++bool Tokenizer::isDelimiter(const char* pos) const {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if ( pos == _end )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          return false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if ( *pos == ' ' || *pos == '\t' || *pos == '\r' || *pos == '\n' || *pos == ',' || *pos == ':' || *pos == '\'' || *pos == '\"' )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          return true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void Tokenizer::fetchNextToken() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  scanToNextToken();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (_current == _end) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          _currentToken = Token();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  auto start = _current;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  while ( !isDelimiter(_current) ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          ++_current;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  _currentToken = Token(start, _current - start);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++///
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/// Representation of a parsed text-based dynamic library file.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++///
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++struct DynamicLibrary {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  Token _installName;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t _currentVersion;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t _compatibilityVersion;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint8_t _swiftVersion;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  ld::File::ObjcConstraint _objcConstraint;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  Options::Platform _platform;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::vector<Token> _allowedClients;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::vector<Token> _reexportedLibraries;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::vector<Token> _symbols;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::vector<Token> _classes;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::vector<Token> _ivars;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::vector<Token> _weakDefSymbols;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::vector<Token> _tlvSymbols;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  DynamicLibrary() : _currentVersion(0x10000), _compatibilityVersion(0x10000), _swiftVersion(0),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          _objcConstraint(ld::File::objcConstraintNone)  {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++///
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/// A simple text-based dynamic library file parser.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++///
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++class TBDFile {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  Tokenizer _tokenizer;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  Token peek() { return _tokenizer.peek(); }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  Token next() { return _tokenizer.next(); }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void expectToken(Token str) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          Token token = next();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if (token != str)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  throwf("unexpected token: %s", token.str().c_str());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  bool hasOptionalToken(Token str) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          auto token = peek();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if ( token == str ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  next();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  return true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          return false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void parseFlowSequence(std::function<void (Token)> func) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          expectToken("[");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          while ( true ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  auto token = peek();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  if ( token == "]" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  token = next();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  func(token);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          expectToken("]");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void parseAllowedClients(DynamicLibrary& lib) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if ( !hasOptionalToken("allowed-clients") )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          parseFlowSequence([&](Token name) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  lib._allowedClients.emplace_back(name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          });
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void parseReexportedDylibs(DynamicLibrary& lib) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if ( !hasOptionalToken("re-exports") )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          parseFlowSequence([&](Token name) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  lib._reexportedLibraries.emplace_back(name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          });
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void parseSymbols(DynamicLibrary& lib) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if ( hasOptionalToken("symbols") ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  parseFlowSequence([&](Token name) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          lib._symbols.emplace_back(name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  });
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if ( hasOptionalToken("objc-classes") ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  parseFlowSequence([&](Token name) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          lib._classes.emplace_back(name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  });
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if ( hasOptionalToken("objc-ivars") ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  parseFlowSequence([&](Token name) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          lib._ivars.emplace_back(name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  });
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if ( hasOptionalToken("weak-def-symbols") ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  parseFlowSequence([&](Token name) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          lib._weakDefSymbols.emplace_back(name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  });
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if ( hasOptionalToken("thread-local-symbols") ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  parseFlowSequence([&](Token name) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          lib._tlvSymbols.emplace_back(name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  });
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::vector<std::string> parseArchFlowSequence() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          std::vector<std::string> availabledArchitectures;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          expectToken("archs");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          parseFlowSequence([&](Token name) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  availabledArchitectures.emplace_back(name.str());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          });
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          return availabledArchitectures;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  bool parseArchFlowSequence(std::string &selectedArchName) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          auto availabledArchitectures = parseArchFlowSequence();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          for (const auto &archName : availabledArchitectures) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  if (archName == selectedArchName)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          return true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          return false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void parsePlatform(DynamicLibrary& lib) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          expectToken("platform");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          auto token =  next();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if (token == "macosx")
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  lib._platform = Options::kPlatformOSX;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          else if (token == "ios")
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  lib._platform = Options::kPlatformiOS;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          else if (token == "watchos")
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  lib._platform = Options::kPlatformWatchOS;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#if SUPPORT_APPLE_TV
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          else if (token == "tvos")
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  lib._platform = Options::kPlatform_tvOS;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  lib._platform = Options::kPlatformUnknown;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void parseInstallName(DynamicLibrary& lib) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          expectToken("install-name");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          lib._installName = next();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if ( lib._installName.empty() )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  throwf("no install name specified");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t parseVersionNumber32(Token token) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if ( token.size() >= 128 )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  throwf("malformed version number");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          // Make a null-terminated string.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          char buffer[128];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          ::memcpy(buffer, token.data(), token.size());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          buffer[token.size()] = '\0';
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          return Options::parseVersionNumber32(buffer);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void parseCurrentVersion(DynamicLibrary& lib) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if ( !hasOptionalToken("current-version") )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          lib._currentVersion = parseVersionNumber32(next());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void parseCompatibilityVersion(DynamicLibrary& lib) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if ( !hasOptionalToken("compatibility-version") )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          lib._compatibilityVersion = parseVersionNumber32(next());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void parseSwiftVersion(DynamicLibrary& lib) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if ( !hasOptionalToken("swift-version") )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          auto token = next();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if ( token == "1.0" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  lib._swiftVersion = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          else if ( token == "1.1" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  lib._swiftVersion = 2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          else if ( token == "2.0" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  lib._swiftVersion = 3;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  throwf("unsupported Swift ABI version: %s", token.str().c_str());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void parseObjCConstraint(DynamicLibrary& lib) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if ( !hasOptionalToken("objc-constraint") )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          auto token = next();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if ( token == "none" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  lib._objcConstraint = ld::File::objcConstraintNone;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          else if ( token == "retain_release" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  lib._objcConstraint = ld::File::objcConstraintRetainRelease;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          else if ( token == "retain_release_for_simulator" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  lib._objcConstraint = ld::File::objcConstraintRetainReleaseForSimulator;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          else if ( token == "retain_release_or_gc" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  lib._objcConstraint = ld::File::objcConstraintRetainReleaseOrGC;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          else if ( token == "gc" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  lib._objcConstraint = ld::File::objcConstraintGC;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  throwf("unexpected token: %s", token.str().c_str());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void parseExportsBlock(DynamicLibrary& lib, std::string &selectedArchName) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if ( !hasOptionalToken("exports") )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if ( !hasOptionalToken("-") )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          while ( true ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  if ( !parseArchFlowSequence(selectedArchName) ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          Token token;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          while ( true ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  token = peek();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  if ( token == "archs" || token == "..." || token.empty() )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                          break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  next();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          if (token == "..." || token.empty() )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  parseAllowedClients(lib);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  parseReexportedDylibs(lib);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  parseSymbols(lib);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  if ( !hasOptionalToken("-") )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::vector<std::string> getCompatibleArchList(std::string &requestedArchName) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if (requestedArchName == "i386")
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  return {"i386"};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          else if (requestedArchName == "x86_64" || requestedArchName == "x86_64h")
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  return {"x86_64", "x86_64h"};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          else if (requestedArchName == "armv7" || requestedArchName == "armv7s")
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  return {"armv7", "armv7s"};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          else if (requestedArchName == "armv7k")
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  return {"armv7k"};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          else if (requestedArchName == "arm64")
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  return {"arm64"};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  return {};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::string parseAndSelectArchitecture(std::string &requestedArchName) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          auto availabledArchitectures = parseArchFlowSequence();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          // First try to find an exact match (cpu type and sub-cpu type).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if (std::find(availabledArchitectures.begin(), availabledArchitectures.end(), requestedArchName)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  != availabledArchitectures.end())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  return requestedArchName;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          // If there is no exact match, then try to find an ABI compatible slice.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          auto compatibleArchitectures = getCompatibleArchList(requestedArchName);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          std::vector<std::string> result;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          std::sort(availabledArchitectures.begin(), availabledArchitectures.end());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          std::sort(compatibleArchitectures.begin(), compatibleArchitectures.end());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          std::set_intersection(availabledArchitectures.begin(), availabledArchitectures.end(),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                                    compatibleArchitectures.begin(), compatibleArchitectures.end(),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                                    std::back_inserter(result));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if (result.empty())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  return std::string();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  return result.front();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void parseDocument(DynamicLibrary& lib, std::string &requestedArchName) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          auto selectedArchName = parseAndSelectArchitecture(requestedArchName);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if (selectedArchName.empty())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  throwf("invalid arch");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          parsePlatform(lib);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          parseInstallName(lib);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          parseCurrentVersion(lib);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          parseCompatibilityVersion(lib);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          parseSwiftVersion(lib);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          parseObjCConstraint(lib);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          parseExportsBlock(lib, selectedArchName);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++public:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  TBDFile(const char* data, uint64_t size) : _tokenizer(data, size) {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  DynamicLibrary parseFileForArch(std::string requestedArchName) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          _tokenizer.reset();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          DynamicLibrary lib;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          expectToken("---");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          parseDocument(lib, requestedArchName);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          expectToken("...");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          return lib;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  bool validForArch(std::string requestedArchName) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          _tokenizer.reset();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          auto token = next();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if ( token != "---" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  return false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          return !parseAndSelectArchitecture(requestedArchName).empty();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void dumpTokens() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          _tokenizer.reset();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          Token token;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          do {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  token = next();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  printf("token: %s\n", token.str().c_str());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          } while ( !token.empty() );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++} // end anonymous namespace
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ namespace textstub {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ namespace dylib {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -50,94 +513,51 @@ class File final : public generic::dylib::File<A>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   using Base = generic::dylib::File<A>;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ public:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  File(const char* path, const uint8_t* fileContent, uint64_t fileLength,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  static bool             validFile(const uint8_t* fileContent, bool executableOrDylib);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  File(const uint8_t* fileContent, uint64_t fileLength, const char* path,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                            time_t mTime, ld::File::Ordinal ordinal, bool linkingFlatNamespace,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                           bool linkingMainExecutable, bool hoistImplicitPublicDylibs,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                           Options::Platform platform, uint32_t linkMinOSVersion, bool allowWeakImports,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                           cpu_type_t cpuType, cpu_subtype_t cpuSubType, bool enforceDylibSubtypesMatch,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                           bool allowSimToMacOSX, bool addVers, bool buildingForSimulator,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                           bool hoistImplicitPublicDylibs, Options::Platform platform,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                           cpu_type_t cpuType, const char* archName, uint32_t linkMinOSVersion,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                           bool allowWeakImports, bool allowSimToMacOSX, bool addVers, bool buildingForSimulator,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                            bool logAllFiles, const char* installPath, bool indirectDylib);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   virtual                 ~File() noexcept {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ private:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  void                    buildExportHashTable(const tapi::LinkerInterfaceFile* file);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-static ld::File::ObjcConstraint mapObjCConstraint(tapi::ObjCConstraint constraint) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  switch (constraint) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  case tapi::ObjCConstraint::None:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          return ld::File::objcConstraintNone;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  case tapi::ObjCConstraint::Retain_Release:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          return ld::File::objcConstraintRetainRelease;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  case tapi::ObjCConstraint::Retain_Release_For_Simulator:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          return ld::File::objcConstraintRetainReleaseForSimulator;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  case tapi::ObjCConstraint::Retain_Release_Or_GC:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          return ld::File::objcConstraintRetainReleaseOrGC;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  case tapi::ObjCConstraint::GC:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          return ld::File::objcConstraintGC;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  return ld::File::objcConstraintNone;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void                    buildExportHashTable(const DynamicLibrary &lib);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-static Options::Platform mapPlatform(tapi::Platform platform) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  switch (platform) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  case tapi::Platform::Unknown:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          return Options::kPlatformUnknown;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  case tapi::Platform::OSX:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          return Options::kPlatformOSX;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  case tapi::Platform::iOS:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          return Options::kPlatformiOS;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  case tapi::Platform::watchOS:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          return Options::kPlatformWatchOS;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  case tapi::Platform::tvOS:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          return Options::kPlatform_tvOS;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  return Options::kPlatformUnknown;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  cpu_type_t              _cpuType;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ template <typename A>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  File<A>::File(const char* path, const uint8_t* fileContent, uint64_t fileLength,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                    time_t mTime, ld::File::Ordinal ord, bool linkingFlatNamespace,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                    bool linkingMainExecutable, bool hoistImplicitPublicDylibs, Options::Platform platform,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                    uint32_t linkMinOSVersion, bool allowWeakImports, cpu_type_t cpuType, cpu_subtype_t cpuSubType,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                          bool enforceDylibSubtypesMatch, bool allowSimToMacOSX, bool addVers,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++File<A>::File(const uint8_t* fileContent, uint64_t fileLength, const char* path, time_t mTime,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                    ld::File::Ordinal ord, bool linkingFlatNamespace, bool hoistImplicitPublicDylibs,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                    Options::Platform platform, cpu_type_t cpuType, const char* archName,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                    uint32_t linkMinOSVersion, bool allowWeakImports, bool allowSimToMacOSX, bool addVers,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                     bool buildingForSimulator, bool logAllFiles, const char* targetInstallPath,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                     bool indirectDylib)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   : Base(strdup(path), mTime, ord, platform, linkMinOSVersion, allowWeakImports, linkingFlatNamespace,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-             hoistImplicitPublicDylibs, allowSimToMacOSX, addVers)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++             hoistImplicitPublicDylibs, allowSimToMacOSX, addVers),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    _cpuType(cpuType)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  auto matchingType = enforceDylibSubtypesMatch ?
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  tapi::CpuSubTypeMatching::Exact : tapi::CpuSubTypeMatching::ABI_Compatible;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  std::string errorMessage;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  auto file = std::unique_ptr<tapi::LinkerInterfaceFile>(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          tapi::LinkerInterfaceFile::create(path, fileContent, fileLength, cpuType,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                                                            cpuSubType, matchingType,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                                                            tapi::PackedVersion32(linkMinOSVersion), errorMessage));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  if (file == nullptr)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          throw strdup(errorMessage.c_str());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  // unmap file - it is no longer needed.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  munmap((caddr_t)fileContent, fileLength);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  this->_bitcode = std::unique_ptr<ld::Bitcode>(new ld::Bitcode(nullptr, 0));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  // Text stubs are implicit app extension safe.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  this->_appExtensionSafe = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   // write out path for -t option
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if ( logAllFiles )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           printf("%s\n", path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  this->_bitcode = std::unique_ptr<ld::Bitcode>(new ld::Bitcode(nullptr, 0));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  this->_noRexports = !file->hasReexportedLibraries();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  this->_hasWeakExports = file->hasWeakDefinedExports();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  this->_dylibInstallPath = strdup(file->getInstallName().c_str());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  this->_installPathOverride = file->isInstallNameVersionSpecific();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  this->_dylibCurrentVersion = file->getCurrentVersion();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  this->_dylibCompatibilityVersion = file->getCompatibilityVersion();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  this->_swiftVersion = file->getSwiftVersion();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  this->_objcConstraint = mapObjCConstraint(file->getObjCConstraint());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  this->_parentUmbrella = file->getParentFrameworkName().empty() ? nullptr : strdup(file->getParentFrameworkName().c_str());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  this->_appExtensionSafe = file->isApplicationExtensionSafe();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  TBDFile stub((const char*)fileContent, fileLength);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  auto lib = stub.parseFileForArch(archName);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  this->_noRexports = lib._reexportedLibraries.empty();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  this->_hasWeakExports = !lib._weakDefSymbols.empty();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  this->_dylibInstallPath = strdup(lib._installName.str().c_str());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  this->_dylibCurrentVersion = lib._currentVersion;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  this->_dylibCompatibilityVersion = lib._compatibilityVersion;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  this->_swiftVersion = lib._swiftVersion;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  this->_objcConstraint = lib._objcConstraint;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  this->_hasPublicInstallName = this->isPublicLocation(this->_dylibInstallPath);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   // if framework, capture framework name
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   const char* lastSlash = strrchr(this->_dylibInstallPath, '/');
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -151,69 +571,100 @@ template <typename A>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   this->_frameworkName = leafName;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  for (auto &client : file->allowableClients())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          this->_allowableClients.push_back(strdup(client.c_str()));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  // TEMPORARY HACK BEGIN: Support ancient re-export command LC_SUB_FRAMEWORK.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  // <rdar://problem/23614899> [TAPI] Support LC_SUB_FRAMEWORK as re-export indicator.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  auto installName = std::string(this->_dylibInstallPath);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  // All sub-frameworks of ApplicationServices use LC_SUB_FRAMEWORK.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (installName.find("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/") == 0 &&
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  installName.find(".dylib") == std::string::npos) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          this->_parentUmbrella = "ApplicationServices";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  } else if (installName.find("/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/") == 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          this->_parentUmbrella = "Carbon";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  } else if (installName.find("/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/") == 0 &&
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                   installName.find(".dylib") == std::string::npos) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          this->_parentUmbrella = "CoreServices";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  } else if (installName.find("/System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libLinearAlgebra.dylib") == 0 ||
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                   installName.find("/System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libQuadrature.dylib") == 0 ||
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                   installName.find("System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libSparseBLAS.dylib") == 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          this->_parentUmbrella = "vecLib";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  } else if (installName.find("/System/Library/Frameworks/WebKit.framework/Versions/A/Frameworks/WebCore.framework/Versions/A/WebCore") == 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          this->_parentUmbrella = "WebKit";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  } else if (installName.find("/usr/lib/system/") == 0 &&
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                     installName != "/usr/lib/system/libkxld.dylib") {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          this->_parentUmbrella = "System";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  // TEMPORARY HACK END
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  for (auto &client : lib._allowedClients) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if ((this->_parentUmbrella != nullptr) && (client.str() != this->_parentUmbrella))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  this->_allowableClients.push_back(strdup(client.str().c_str()));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   // <rdar://problem/20659505> [TAPI] Don't hoist "public" (in /usr/lib/) dylibs that should not be directly linked
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  this->_hasPublicInstallName = file->hasAllowableClients() ? false : this->isPublicLocation(file->getInstallName().c_str());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  for (const auto &client : file->allowableClients())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          this->_allowableClients.emplace_back(strdup(client.c_str()));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if ( !this->_allowableClients.empty() )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          this->_hasPublicInstallName = false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  auto dylibPlatform = mapPlatform(file->getPlatform());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  if ( (dylibPlatform != platform) && (platform != Options::kPlatformUnknown) ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if ( (lib._platform != platform) && (platform != Options::kPlatformUnknown) ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           this->_wrongOS = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if ( this->_addVersionLoadCommand && !indirectDylib ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   if ( buildingForSimulator ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           if ( !this->_allowSimToMacOSXLinking )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                   throwf("building for %s simulator, but linking against dylib built for %s (%s).",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                                  Options::platformName(platform), Options::platformName(dylibPlatform), path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                                  Options::platformName(platform), Options::platformName(lib._platform), path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           throwf("building for %s, but linking against dylib built for %s (%s).",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                          Options::platformName(platform), Options::platformName(dylibPlatform), path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                          Options::platformName(platform), Options::platformName(lib._platform), path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  for (const auto& reexport : file->reexportedLibraries()) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          const char *path = strdup(reexport.c_str());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  this->_dependentDylibs.reserve(lib._reexportedLibraries.size());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  for ( const auto& reexport : lib._reexportedLibraries ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          const char *path = strdup(reexport.str().c_str());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if ( (targetInstallPath == nullptr) || (strcmp(targetInstallPath, path) != 0) )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   this->_dependentDylibs.emplace_back(path, true);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  for (const auto& symbol : file->ignoreExports())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          this->_ignoreExports.insert(strdup(symbol.c_str()));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  // if linking flat and this is a flat dylib, create one atom that references all imported symbols.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  if ( linkingFlatNamespace && linkingMainExecutable && (file->hasTwoLevelNamespace() == false) ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          std::vector<const char*> importNames;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          importNames.reserve(file->undefineds().size());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          // We do not need to strdup the name, because that will be done by the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          // ImportAtom constructor.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          for (const auto &sym : file->undefineds())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  importNames.emplace_back(sym.getName().c_str());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          this->_importAtom = new generic::dylib::ImportAtom<A>(*this, importNames);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   // build hash table
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  buildExportHashTable(file.get());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  buildExportHashTable(lib);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  munmap((caddr_t)fileContent, fileLength);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ template <typename A>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-void File<A>::buildExportHashTable(const tapi::LinkerInterfaceFile* file) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void File<A>::buildExportHashTable(const DynamicLibrary& lib) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (this->_s_logHashtable )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           fprintf(stderr, "ld: building hashtable from text-stub info in %s\n", this->path());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  for (const auto &sym : file->exports()) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          const char* name = sym.getName().c_str();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          bool weakDef = sym.isWeakDefined();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          bool tlv = sym.isThreadLocalValue();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  for (auto &sym : lib._symbols)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          this->addSymbol(sym.str().c_str());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          typename Base::AtomAndWeak bucket = { nullptr, weakDef, tlv, 0 };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          if ( this->_s_logHashtable )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  fprintf(stderr, "  adding %s to hash table for %s\n", name, this->path());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          this->_atoms[strdup(name)] = bucket;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#if SUPPORT_ARCH_i386
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (this->_platform == Options::kPlatformOSX && _cpuType == CPU_TYPE_I386) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          for (auto &sym : lib._classes)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  this->addSymbol((".objc_class_name" + sym.str()).c_str());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          for (auto &sym : lib._classes) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  this->addSymbol(("_OBJC_CLASS_$" + sym.str()).c_str());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  this->addSymbol(("_OBJC_METACLASS_$" + sym.str()).c_str());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  for (auto &sym : lib._classes) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          this->addSymbol(("_OBJC_CLASS_$" + sym.str()).c_str());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          this->addSymbol(("_OBJC_METACLASS_$" + sym.str()).c_str());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  for (auto &sym : lib._ivars)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          this->addSymbol(("_OBJC_IVAR_$" + sym.str()).c_str());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  for (auto &sym : lib._weakDefSymbols)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          this->addSymbol(sym.str().c_str(), /*weak=*/true);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  for (auto &sym : lib._tlvSymbols)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          this->addSymbol(sym.str().c_str(), /*weak=*/false, /*tlv=*/true);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ template <typename A>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -222,21 +673,20 @@ class Parser
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ public:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   using P = typename A::P;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  static ld::dylib::File* parse(const char* path, const uint8_t* fileContent,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                                            uint64_t fileLength, time_t mTime,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                                            ld::File::Ordinal ordinal, const Options& opts,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  static bool                             validFile(const uint8_t* fileContent, uint64_t fileLength,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                                                    const std::string &path, const char* archName);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  static ld::dylib::File* parse(const uint8_t* fileContent, uint64_t fileLength, const char* path,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                                            time_t mTime, ld::File::Ordinal ordinal, const Options& opts,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                                             bool indirectDylib)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          return new File<A>(path, fileContent, fileLength,mTime, ordinal,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          return new File<A>(fileContent, fileLength, path, mTime, ordinal,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                              opts.flatNamespace(),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                             opts.linkingMainExecutable(),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                              opts.implicitlyLinkIndirectPublicDylibs(),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                              opts.platform(),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                             opts.architecture(),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                             opts.architectureName(),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                              opts.minOSversion(),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                              opts.allowWeakImports(),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                             opts.architecture(),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                             opts.subArchitecture(),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                             opts.enforceDylibSubtypesMatch(),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                              opts.allowSimulatorToLinkWithMacOSX(),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                              opts.addVersionLoadCommand(),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                              opts.targetIOSSimulator(),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -246,6 +696,20 @@ public:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++template <typename A>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++bool Parser<A>::validFile(const uint8_t* fileContent, uint64_t fileLength, const std::string &path,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                            const char* archName)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if ( path.find(".tbd", path.size()-4) == std::string::npos )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          return false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  TBDFile stub((const char*)fileContent, fileLength);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if ( !stub.validForArch(archName) )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          throwf("missing required architecture %s in file %s", archName, path.c_str());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ //
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ // main function used by linker to instantiate ld::Files
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ //
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -253,27 +717,30 @@ ld::dylib::File* parse(const uint8_t* fileContent, uint64_t fileLength, const ch
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                      time_t modTime, const Options& opts, ld::File::Ordinal ordinal,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                      bool bundleLoader, bool indirectDylib)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   switch ( opts.architecture() ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #if SUPPORT_ARCH_x86_64
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           case CPU_TYPE_X86_64:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          if (tapi::LinkerInterfaceFile::isSupported(path, fileContent, fileLength))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  return Parser<x86_64>::parse(path, fileContent, fileLength, modTime, ordinal, opts, indirectDylib);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  if ( Parser<x86_64>::validFile(fileContent, fileLength, path, opts.architectureName()) )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          return Parser<x86_64>::parse(fileContent, fileLength, path, modTime, ordinal, opts, indirectDylib);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #if SUPPORT_ARCH_i386
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           case CPU_TYPE_I386:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          if (tapi::LinkerInterfaceFile::isSupported(path, fileContent, fileLength))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  return Parser<x86>::parse(path, fileContent, fileLength, modTime, ordinal, opts, indirectDylib);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  if ( Parser<x86>::validFile(fileContent, fileLength, path, opts.architectureName()) )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          return Parser<x86>::parse(fileContent, fileLength, path, modTime, ordinal, opts, indirectDylib);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #if SUPPORT_ARCH_arm_any
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           case CPU_TYPE_ARM:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          if (tapi::LinkerInterfaceFile::isSupported(path, fileContent, fileLength))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  return Parser<arm>::parse(path, fileContent, fileLength, modTime, ordinal, opts, indirectDylib);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  if ( Parser<arm>::validFile(fileContent, fileLength, path, opts.architectureName()) )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          return Parser<arm>::parse(fileContent, fileLength, path, modTime, ordinal, opts, indirectDylib);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #if SUPPORT_ARCH_arm64
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           case CPU_TYPE_ARM64:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          if (tapi::LinkerInterfaceFile::isSupported(path, fileContent, fileLength))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  return Parser<arm64>::parse(path, fileContent, fileLength, modTime, ordinal, opts, indirectDylib);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  if ( Parser<arm64>::validFile(fileContent, fileLength, path, opts.architectureName()) )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          return Parser<arm64>::parse(fileContent, fileLength, path, modTime, ordinal, opts, indirectDylib);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   return nullptr;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-- 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+2.11.0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/devel/ld64/files/PR-29723276.patch b/devel/ld64/files/PR-29723276.patch
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 0000000..fb5a32a
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/devel/ld64/files/PR-29723276.patch
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,12 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/other/ObjectDump.cpp.orig  2016-03-09 13:27:56.000000000 -0800
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/other/ObjectDump.cpp       2016-12-18 00:12:47.000000000 -0800
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -843,9 +843,6 @@ void dumper::dumpFixup(const ld::Fixup* 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           case ld::Fixup::kindStoreARM64PCRelToGOT:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   printf(", then store as 32-bit delta to GOT entry");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          case ld::Fixup::kindStoreARM64PointerToGOT32:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  printf(", then store as 32-bit pointer to GOT entry");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           case ld::Fixup::kindDtraceExtra:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   printf("dtrace static probe extra info");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   break;
</span></pre><pre style='margin:0'>

</pre>