[hid-parser] Add example fuzzer

This CL adds a simple fuzzer of the hid-parser as an example of how to
add fuzz targets to Zircon.

NOTE: make/engine.mk is broken in this change; the attempt to add only
the static libFuzzer library without and C++ or C++ ABI shared objects
causes clang to fail.

SEC-44 #comment Example of Zircon layer implementation

Change-Id: Iac402d5b6ce9dbab74bc37b6a1e9a8c88a2605c5
diff --git a/make/engine.mk b/make/engine.mk
index 9838ed1..83b62c4 100644
--- a/make/engine.mk
+++ b/make/engine.mk
@@ -494,7 +494,7 @@
 # Every userland executable and shared library compiled with ASan
 # needs to link with $(ASAN_SOLIB).  module-user{app,lib}.mk adds it
 # to MODULE_EXTRA_OBJS so the linking target will depend on it.
-ASAN_SONAME := libclang_rt.asan-$(CLANG_ARCH).so
+ASAN_SONAME := libclang_rt.asan-${CLANG_ARCH}.so
 ASAN_SOLIB_MANIFEST := $(call find-clang-solib,$(ASAN_SONAME))
 ASAN_SOLIB := $(word 2,$(subst =, ,$(ASAN_SOLIB_MANIFEST)))
 USER_MANIFEST_LINES += {core}$(ASAN_SOLIB_MANIFEST)
@@ -518,21 +518,12 @@
 NO_SANCOV :=
 endif
 
-# To use LibFuzzer, we need to provide it and its dependency to the linker
-# since we're not using Clang and its '-fsanitize=fuzzer' flag as a driver to
-# lld.  Additionally, we need to make sure the shared objects are available on
-# the device.
+# To use LibFuzzer, we need to provide it to the linker since we're not using
+# Clang and its '-fsanitize=fuzzer' flag as a driver to lld.
 ifeq ($(call TOBOOL,$(USE_ASAN)),true)
-FUZZ_ANAME := libclang_rt.fuzzer-$(CLANG_ARCH).a
-FUZZ_ALIB := $(shell $(CLANG_TOOLCHAIN_PREFIX)clang \
+FUZZ_EXTRA_OBJS := $(shell $(CLANG_TOOLCHAIN_PREFIX)clang \
 				 $(GLOBAL_COMPILEFLAGS) $(ARCH_COMPILEFLAGS)\
-				 -print-file-name=$(FUZZ_ANAME))
-
-FUZZ_RUNTIME_SONAMES := libc++.so.2 libc++abi.so.1
-FUZZ_RUNTIME_SOLIBS := $(foreach soname,$(FUZZ_RUNTIME_SONAMES),\
-				 $(word 2,$(subst =, ,$(call find-clang-asan-solib,$(soname)))))
-
-FUZZ_EXTRA_OBJS := $(FUZZ_ALIB) $(FUZZ_RUNTIME_SOLIBS)
+				 -print-file-name=libclang_rt.fuzzer-${CLANG_ARCH}.a)
 else
 FUZZ_EXTRA_OBJS :=
 endif
diff --git a/system/utest/hid-parser/hid-parser-fuzz.cpp b/system/utest/hid-parser/hid-parser-fuzz.cpp
new file mode 100644
index 0000000..fdb6ca3
--- /dev/null
+++ b/system/utest/hid-parser/hid-parser-fuzz.cpp
@@ -0,0 +1,23 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stddef.h>
+
+#include <fbl/auto_call.h>
+#include <hid-parser/parser.h>
+
+// fuzz_target.cc
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    hid::DeviceDescriptor* dd = nullptr;
+    auto result = hid::ParseReportDescriptor(data, size, &dd);
+    if (result != hid::ParseResult::kParseOk) {
+        return 0;
+    }
+    auto cleanup = fbl::MakeAutoCall([dd]() { hid::FreeDeviceDescriptor(dd); });
+
+    size_t ff_count = 0u;
+    auto collection __attribute__((unused)) =
+        hid::GetAppCollection(hid::GetFirstInputField(dd, &ff_count));
+    return 0;
+}
diff --git a/system/utest/hid-parser/rules.mk b/system/utest/hid-parser/rules.mk
index 263bdc9..7f00e9f 100644
--- a/system/utest/hid-parser/rules.mk
+++ b/system/utest/hid-parser/rules.mk
@@ -25,3 +25,22 @@
     system/ulib/c
 
 include make/module.mk
+
+
+MODULE := $(LOCAL_DIR).fuzzer
+
+MODULE_TYPE := fuzztest
+
+MODULE_SRCS = \
+    $(LOCAL_DIR)/hid-parser-fuzz.cpp
+
+MODULE_STATIC_LIBS := \
+    system/ulib/hid-parser \
+    system/ulib/fbl \
+
+MODULE_LIBS := \
+    system/ulib/fdio \
+    system/ulib/unittest \
+    system/ulib/c \
+
+include make/module.mk