hfuzz_cc: repeat -c options with linking as well
diff --git a/hfuzz_cc/hfuzz-clang-cc.c b/hfuzz_cc/hfuzz-clang-cc.c new file mode 100644 index 0000000..057a5aa --- /dev/null +++ b/hfuzz_cc/hfuzz-clang-cc.c
@@ -0,0 +1,134 @@ +#include <inttypes.h> +#include <limits.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#if !defined(_HF_BUILD_DIR) +#error "_HF_BUILD_DIR not defined" +#endif + +#define ARGS_MAX 4096 +#define __XSTR(x) #x +#define _XSTR(x) __XSTR(x) +#define CLANG_BIN "clang" + +static char *getClangCC() +{ + const char *cc_path = getenv("HFUZZ_CC_PATH"); + if (cc_path != NULL) { + return (char *)cc_path; + } + return (char *)CLANG_BIN; +} + +static bool useASAN() +{ + if (getenv("HFUZZ_CC_ASAN") != NULL) { + return true; + } + return false; +} + +static bool useMSAN() +{ + if (getenv("HFUZZ_CC_MSAN") != NULL) { + return true; + } + return false; +} + +static bool useUBSAN() +{ + if (getenv("HFUZZ_CC_UBSAN") != NULL) { + return true; + } + return false; +} + +static bool containsDashC(int argc, char **argv) +{ + for (int i = 1; i < argc; i++) { + if (strcmp(argv[i], "-c") == 0) { + return true; + } + } + return false; +} + +static int execCC(int argc, char **argv) +{ + if (useASAN()) { + argv[argc++] = "-fsanitize=address"; + } + if (useMSAN()) { + argv[argc++] = "-fsanitize=memory"; + } + if (useUBSAN()) { + argv[argc++] = "-fsanitize=undefined"; + } + + argv[argc] = NULL; + execvp(argv[0], argv); + perror("execv"); + return EXIT_FAILURE; +} + +static int ccMode(int argc, char **argv) +{ + char *args[4096]; + + int j = 0; + args[j++] = getClangCC(); + args[j++] = "-fsanitize-coverage=trace-pc-guard,trace-cmp,indirect-calls"; + args[j++] = "-funroll-loops"; + args[j++] = "-fno-inline"; + args[j++] = "-fno-builtin"; + + for (int i = 1; i < argc; i++) { + args[j++] = argv[i]; + } + + return execCC(j, args); +} + +static int ldMode(int argc, char **argv) +{ + char *args[4096]; + + char lHFuzzPath[PATH_MAX]; + snprintf(lHFuzzPath, sizeof(lHFuzzPath), "%s/libhfuzz/libhfuzz.a", _XSTR(_HF_BUILD_DIR)); + + int j = 0; + args[j++] = getClangCC(); + args[j++] = "-Wl,--whole-archive"; + args[j++] = lHFuzzPath; + args[j++] = "-Wl,--no-whole-archive"; + args[j++] = "-fsanitize-coverage=trace-pc-guard,trace-cmp,indirect-calls"; + args[j++] = "-funroll-loops"; + args[j++] = "-fno-inline"; + args[j++] = "-fno-builtin"; + + int i; + for (i = 1; i < argc; i++) { + args[j++] = argv[i]; + } + args[j++] = lHFuzzPath; + + return execCC(j, args); +} + +int main(int argc, char **argv) +{ + if (argc > (ARGS_MAX - 4)) { + fprintf(stderr, "Too many positional arguments\n"); + return EXIT_FAILURE; + } + + if (containsDashC(argc, argv)) { + return ccMode(argc, argv); + } + return ldMode(argc, argv); +}