Hack together MSAN build.

  - Build our own: freetype.
  - Avoid using: fontconfig, expat, GPU drivers.
  - Lie about safety: libjpeg (only from src/images... need to in src/codec?)

To run:
  $ tools/xsan_build memory dm
  $ out/Debug/dm -v --match ~Codec ~BlurLargeImage ~FontMgrAndroidParser

Notes:
  - Codec triggers issues in piex.
  - BlurLargeImage probably has bugs in the GM only.
  - FontMgrAndroidParser uses expat.

BUG=skia:4550
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1665823002

NOTREECHECKS=true

Review URL: https://codereview.chromium.org/1665823002
diff --git a/src/core/SkMSAN.h b/src/core/SkMSAN.h
index 7e54477..1f32e53 100644
--- a/src/core/SkMSAN.h
+++ b/src/core/SkMSAN.h
@@ -8,11 +8,12 @@
 #ifndef SkMSAN_DEFINED
 #define SkMSAN_DEFINED
 
-#include <stddef.h>  // size_t
+#include "SkTypes.h"
 
 // Typically declared in LLVM's msan_interface.h.  Easier for us to just re-declare.
 extern "C" {
     void __msan_check_mem_is_initialized(const volatile void*, size_t);
+    void __msan_unpoison                (const volatile void*, size_t);
 }
 
 // Code that requires initialized inputs can call this to make it clear that
@@ -25,4 +26,15 @@
 #endif
 }
 
+// Lie to MSAN that this range of memory is initialized.
+// This can hide serious problems if overused.  Every use of this should refer to a bug.
+static inline void sk_msan_mark_initialized(const void* begin, const void* end, const char* skbug) {
+    SkASSERT(skbug && 0 != strcmp(skbug, ""));
+#if defined(__has_feature)
+    #if __has_feature(memory_sanitizer)
+        __msan_unpoison(begin, (const char*)end - (const char*)begin);
+    #endif
+#endif
+}
+
 #endif//SkMSAN_DEFINED
diff --git a/src/images/SkImageDecoder_libjpeg.cpp b/src/images/SkImageDecoder_libjpeg.cpp
index 6a032fd..6a3ae87 100644
--- a/src/images/SkImageDecoder_libjpeg.cpp
+++ b/src/images/SkImageDecoder_libjpeg.cpp
@@ -11,6 +11,7 @@
 #include "SkJpegUtility.h"
 #include "SkColorPriv.h"
 #include "SkDither.h"
+#include "SkMSAN.h"
 #include "SkScaledBitmapSampler.h"
 #include "SkStream.h"
 #include "SkTemplates.h"
@@ -524,6 +525,9 @@
             convert_CMYK_to_RGB(srcRow, cinfo.output_width);
         }
 
+        sk_msan_mark_initialized(srcRow, srcRow + cinfo.output_width * srcBytesPerPixel,
+                                 "skbug.com/4550");
+
         sampler.next(srcRow);
         if (bm->height() - 1 == y) {
             // we're done
diff --git a/tools/xsan_build b/tools/xsan_build
index f3c4d74..d1960bc 100755
--- a/tools/xsan_build
+++ b/tools/xsan_build
@@ -10,22 +10,16 @@
 #   http://clang.llvm.org/docs/UsersManual.html#controlling-code-generation
 
 set -e
+set -x
 
-sanitizer=$1
-shift
-args="$@"
-
-export CC="$(which clang)"
-export CXX="$(which clang++)"
-
-if [[ -z "${CC}" ]] || [[ -z "${CXX}" ]]; then
-  echo "Couldn't find Clang on this machine!"
-  exit 1
-fi
-
-echo "CC=$CC"
-echo "CXX=$CXX"
+export CC=clang
+export CXX=clang++
 $CC --version
 
-export GYP_DEFINES="skia_sanitizer=$sanitizer ${GYP_DEFINES}"
-make ${args}
+if [[ "$1" == "memory" ]]; then
+    export GYP_DEFINES="skia_gpu=0 skia_no_fontconfig=1 skia_freetype_static=1 ${GYP_DEFINES}"
+fi
+export GYP_DEFINES="skia_sanitizer=$1 ${GYP_DEFINES}"
+
+shift
+make $@